summaryrefslogtreecommitdiffstats
path: root/src/gui/itemviews/qtableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemviews/qtableview.cpp')
-rw-r--r--src/gui/itemviews/qtableview.cpp3198
1 files changed, 0 insertions, 3198 deletions
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
deleted file mode 100644
index e494ee5564..0000000000
--- a/src/gui/itemviews/qtableview.cpp
+++ /dev/null
@@ -1,3198 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtableview.h"
-
-#ifndef QT_NO_TABLEVIEW
-#include <qheaderview.h>
-#include <qitemdelegate.h>
-#include <qapplication.h>
-#include <qpainter.h>
-#include <qstyle.h>
-#include <qsize.h>
-#include <qevent.h>
-#include <qbitarray.h>
-#include <qscrollbar.h>
-#include <qabstractbutton.h>
-#include <private/qtableview_p.h>
-#ifndef QT_NO_ACCESSIBILITY
-#include <qaccessible.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/** \internal
- Add a span to the collection. the collection takes the ownership.
- */
-void QSpanCollection::addSpan(QSpanCollection::Span *span)
-{
- spans.append(span);
- Index::iterator it_y = index.lowerBound(-span->top());
- if (it_y == index.end() || it_y.key() != -span->top()) {
- //there is no spans that starts with the row in the index, so create a sublist for it.
- SubIndex sub_index;
- if (it_y != index.end()) {
- //the previouslist is the list of spans that sarts _before_ the row of the span.
- // and which may intersect this row.
- const SubIndex previousList = it_y.value();
- foreach(Span *s, previousList) {
- //If a subspans intersect the row, we need to split it into subspans
- if(s->bottom() >= span->top())
- sub_index.insert(-s->left(), s);
- }
- }
- it_y = index.insert(-span->top(), sub_index);
- //we will insert span to *it_y in the later loop
- }
-
- //insert the span as supspan in all the lists that intesects the span
- while(-it_y.key() <= span->bottom()) {
- (*it_y).insert(-span->left(), span);
- if(it_y == index.begin())
- break;
- --it_y;
- }
-}
-
-
-/** \internal
-* Has to be called after the height and width of a span is changed.
-*
-* old_height is the height before the change
-*
-* if the size of the span is now 0x0 the span will be deleted.
-*/
-void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
-{
- if (old_height < span->height()) {
- //add the span as subspan in all the lists that intersect the new covered columns
- Index::iterator it_y = index.lowerBound(-(span->top() + old_height - 1));
- Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
- while (-it_y.key() <= span->bottom()) {
- (*it_y).insert(-span->left(), span);
- if(it_y == index.begin())
- break;
- --it_y;
- }
- } else if (old_height > span->height()) {
- //remove the span from all the subspans lists that intersect the columns not covered anymore
- Index::iterator it_y = index.lowerBound(-qMax(span->bottom(), span->top())); //qMax useful if height is 0
- Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
- while (-it_y.key() <= span->top() + old_height -1) {
- if (-it_y.key() > span->bottom()) {
- int removed = (*it_y).remove(-span->left());
- Q_ASSERT(removed == 1); Q_UNUSED(removed);
- if (it_y->isEmpty()) {
- it_y = index.erase(it_y);
- }
- }
- if(it_y == index.begin())
- break;
- --it_y;
- }
- }
-
- if (span->width() == 0 && span->height() == 0) {
- spans.removeOne(span);
- delete span;
- }
-}
-
-/** \internal
- * \return a spans that spans over cell x,y (column,row) or 0 if there is none.
- */
-QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const
-{
- Index::const_iterator it_y = index.lowerBound(-y);
- if (it_y == index.end())
- return 0;
- SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);
- if (it_x == (*it_y).end())
- return 0;
- Span *span = *it_x;
- if (span->right() >= x && span->bottom() >= y)
- return span;
- return 0;
-}
-
-
-/** \internal
-* remove and deletes all spans inside the collection
-*/
-void QSpanCollection::clear()
-{
- qDeleteAll(spans);
- index.clear();
- spans.clear();
-}
-
-/** \internal
- * return a list to all the spans that spans over cells in the given rectangle
- */
-QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w, int h) const
-{
- QSet<Span *> list;
- Index::const_iterator it_y = index.lowerBound(-y);
- if(it_y == index.end())
- --it_y;
- while(-it_y.key() <= y + h) {
- SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);
- if (it_x == (*it_y).end())
- --it_x;
- while(-it_x.key() <= x + w) {
- Span *s = *it_x;
- if (s->bottom() >= y && s->right() >= x)
- list << s;
- if (it_x == (*it_y).begin())
- break;
- --it_x;
- }
- if(it_y == index.begin())
- break;
- --it_y;
- }
- return list.toList();
-}
-
-#undef DEBUG_SPAN_UPDATE
-
-#ifdef DEBUG_SPAN_UPDATE
-QDebug operator<<(QDebug str, const QSpanCollection::Span &span)
-{
- str << "(" << span.top() << "," << span.left() << "," << span.bottom() << "," << span.right() << ")";
- return str;
-}
-#endif
-
-/** \internal
-* Updates the span collection after row insertion.
-*/
-void QSpanCollection::updateInsertedRows(int start, int end)
-{
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << Q_FUNC_INFO;
- qDebug() << start << end;
- qDebug() << index;
-#endif
- if (spans.isEmpty())
- return;
-
- int delta = end - start + 1;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("Before");
-#endif
- for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
- Span *span = *it;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << span << *span;
-#endif
- if (span->m_bottom < start)
- continue;
- if (span->m_top >= start)
- span->m_top += delta;
- span->m_bottom += delta;
- }
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
-#endif
-
- for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
- int y = -it_y.key();
- if (y < start) {
- ++it_y;
- continue;
- }
-
- index.insert(-y - delta, it_y.value());
- it_y = index.erase(it_y);
- }
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << index;
-#endif
-}
-
-/** \internal
-* Updates the span collection after column insertion.
-*/
-void QSpanCollection::updateInsertedColumns(int start, int end)
-{
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << Q_FUNC_INFO;
- qDebug() << start << end;
- qDebug() << index;
-#endif
- if (spans.isEmpty())
- return;
-
- int delta = end - start + 1;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("Before");
-#endif
- for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
- Span *span = *it;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << span << *span;
-#endif
- if (span->m_right < start)
- continue;
- if (span->m_left >= start)
- span->m_left += delta;
- span->m_right += delta;
- }
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
-#endif
-
- for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
- SubIndex &subindex = it_y.value();
- for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
- int x = -it.key();
- if (x < start) {
- ++it;
- continue;
- }
- subindex.insert(-x - delta, it.value());
- it = subindex.erase(it);
- }
- }
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << index;
-#endif
-}
-
-/** \internal
-* Cleans a subindex from to be deleted spans. The update argument is used
-* to move the spans inside the subindex, in case their anchor changed.
-* \return true if no span in this subindex starts at y, and should thus be deleted.
-*/
-bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int y, bool update)
-{
- if (subindex.isEmpty())
- return true;
-
- bool should_be_deleted = true;
- SubIndex::iterator it = subindex.end();
- do {
- --it;
- int x = -it.key();
- Span *span = it.value();
- if (span->will_be_deleted) {
- it = subindex.erase(it);
- continue;
- }
- if (update && span->m_left != x) {
- subindex.insert(-span->m_left, span);
- it = subindex.erase(it);
- }
- if (should_be_deleted && span->m_top == y)
- should_be_deleted = false;
- } while (it != subindex.begin());
-
- return should_be_deleted;
-}
-
-/** \internal
-* Updates the span collection after row removal.
-*/
-void QSpanCollection::updateRemovedRows(int start, int end)
-{
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << Q_FUNC_INFO;
- qDebug() << start << end;
- qDebug() << index;
-#endif
- if (spans.isEmpty())
- return;
-
- SpanList spansToBeDeleted;
- int delta = end - start + 1;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("Before");
-#endif
- for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
- Span *span = *it;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << span << *span;
-#endif
- if (span->m_bottom < start) {
- ++it;
- continue;
- }
- if (span->m_top < start) {
- if (span->m_bottom <= end)
- span->m_bottom = start - 1;
- else
- span->m_bottom -= delta;
- } else {
- if (span->m_bottom > end) {
- if (span->m_top <= end)
- span->m_top = start;
- else
- span->m_top -= delta;
- span->m_bottom -= delta;
- } else {
- span->will_be_deleted = true;
- }
- }
- if (span->m_top == span->m_bottom && span->m_left == span->m_right)
- span->will_be_deleted = true;
- if (span->will_be_deleted) {
- spansToBeDeleted.append(span);
- it = spans.erase(it);
- } else {
- ++it;
- }
- }
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
-#endif
- if (spans.isEmpty()) {
- qDeleteAll(spansToBeDeleted);
- index.clear();
- return;
- }
-
- Index::iterator it_y = index.end();
- do {
- --it_y;
- int y = -it_y.key();
- SubIndex &subindex = it_y.value();
- if (y < start) {
- if (cleanSpanSubIndex(subindex, y))
- it_y = index.erase(it_y);
- } else if (y >= start && y <= end) {
- bool span_at_start = false;
- SubIndex spansToBeMoved;
- for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {
- Span *span = it.value();
- if (span->will_be_deleted)
- continue;
- if (!span_at_start && span->m_top == start)
- span_at_start = true;
- spansToBeMoved.insert(it.key(), span);
- }
-
- if (y == start && span_at_start)
- subindex.clear();
- else
- it_y = index.erase(it_y);
-
- if (span_at_start) {
- Index::iterator it_start;
- if (y == start)
- it_start = it_y;
- else {
- it_start = index.find(-start);
- if (it_start == index.end())
- it_start = index.insert(-start, SubIndex());
- }
- SubIndex &start_subindex = it_start.value();
- for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)
- start_subindex.insert(it.key(), it.value());
- }
- } else {
- if (y == end + 1) {
- Index::iterator it_top = index.find(-y + delta);
- if (it_top == index.end())
- it_top = index.insert(-y + delta, SubIndex());
- for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
- Span *span = it.value();
- if (!span->will_be_deleted)
- it_top.value().insert(it.key(), span);
- ++it;
- }
- } else {
- index.insert(-y + delta, subindex);
- }
- it_y = index.erase(it_y);
- }
- } while (it_y != index.begin());
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << index;
- qDebug("Deleted");
- foreach (QSpanCollection::Span *span, spansToBeDeleted)
- qDebug() << span << *span;
-#endif
- qDeleteAll(spansToBeDeleted);
-}
-
-/** \internal
-* Updates the span collection after column removal.
-*/
-void QSpanCollection::updateRemovedColumns(int start, int end)
-{
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << Q_FUNC_INFO;
- qDebug() << start << end;
- qDebug() << index;
-#endif
- if (spans.isEmpty())
- return;
-
- SpanList toBeDeleted;
- int delta = end - start + 1;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("Before");
-#endif
- for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
- Span *span = *it;
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << span << *span;
-#endif
- if (span->m_right < start) {
- ++it;
- continue;
- }
- if (span->m_left < start) {
- if (span->m_right <= end)
- span->m_right = start - 1;
- else
- span->m_right -= delta;
- } else {
- if (span->m_right > end) {
- if (span->m_left <= end)
- span->m_left = start;
- else
- span->m_left -= delta;
- span->m_right -= delta;
- } else {
- span->will_be_deleted = true;
- }
- }
- if (span->m_top == span->m_bottom && span->m_left == span->m_right)
- span->will_be_deleted = true;
- if (span->will_be_deleted) {
- toBeDeleted.append(span);
- it = spans.erase(it);
- } else {
- ++it;
- }
- }
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
-#endif
- if (spans.isEmpty()) {
- qDeleteAll(toBeDeleted);
- index.clear();
- return;
- }
-
- for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
- int y = -it_y.key();
- if (cleanSpanSubIndex(it_y.value(), y, true))
- it_y = index.erase(it_y);
- else
- ++it_y;
- }
-
-#ifdef DEBUG_SPAN_UPDATE
- qDebug() << index;
- qDebug("Deleted");
- foreach (QSpanCollection::Span *span, toBeDeleted)
- qDebug() << span << *span;
-#endif
- qDeleteAll(toBeDeleted);
-}
-
-#ifdef QT_BUILD_INTERNAL
-/*!
- \internal
- Checks whether the span index structure is self-consistent, and consistent with the spans list.
-*/
-bool QSpanCollection::checkConsistency() const
-{
- for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
- int y = -it_y.key();
- const SubIndex &subIndex = it_y.value();
- for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) {
- int x = -it.key();
- Span *span = it.value();
- if (!spans.contains(span) || span->left() != x
- || y < span->top() || y > span->bottom())
- return false;
- }
- }
-
- foreach (const Span *span, spans) {
- if (span->width() < 1 || span->height() < 1
- || (span->width() == 1 && span->height() == 1))
- return false;
- for (int y = span->top(); y <= span->bottom(); ++y) {
- Index::const_iterator it_y = index.find(-y);
- if (it_y == index.end()) {
- if (y == span->top())
- return false;
- else
- continue;
- }
- const SubIndex &subIndex = it_y.value();
- SubIndex::const_iterator it = subIndex.find(-span->left());
- if (it == subIndex.end() || it.value() != span)
- return false;
- }
- }
- return true;
-}
-#endif
-
-class QTableCornerButton : public QAbstractButton
-{
- Q_OBJECT
-public:
- QTableCornerButton(QWidget *parent) : QAbstractButton(parent) {}
- void paintEvent(QPaintEvent*) {
- QStyleOptionHeader opt;
- opt.init(this);
- QStyle::State state = QStyle::State_None;
- if (isEnabled())
- state |= QStyle::State_Enabled;
- if (isActiveWindow())
- state |= QStyle::State_Active;
- if (isDown())
- state |= QStyle::State_Sunken;
- opt.state = state;
- opt.rect = rect();
- opt.position = QStyleOptionHeader::OnlyOneSection;
- QPainter painter(this);
- style()->drawControl(QStyle::CE_Header, &opt, &painter, this);
- }
-};
-
-void QTableViewPrivate::init()
-{
- Q_Q(QTableView);
-
- q->setEditTriggers(editTriggers|QAbstractItemView::AnyKeyPressed);
-
- QHeaderView *vertical = new QHeaderView(Qt::Vertical, q);
- vertical->setClickable(true);
- vertical->setHighlightSections(true);
- q->setVerticalHeader(vertical);
-
- QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, q);
- horizontal->setClickable(true);
- horizontal->setHighlightSections(true);
- q->setHorizontalHeader(horizontal);
-
- tabKeyNavigation = true;
-
- cornerWidget = new QTableCornerButton(q);
- cornerWidget->setFocusPolicy(Qt::NoFocus);
- QObject::connect(cornerWidget, SIGNAL(clicked()), q, SLOT(selectAll()));
-}
-
-/*!
- \internal
- Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections.
-*/
-void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const
-{
- Q_ASSERT(range && range->isValid());
-
- int top = range->top();
- int left = range->left();
- int bottom = range->bottom();
- int right = range->right();
-
- while (bottom >= top && verticalHeader->isSectionHidden(bottom))
- --bottom;
- while (right >= left && horizontalHeader->isSectionHidden(right))
- --right;
-
- if (top > bottom || left > right) { // everything is hidden
- *range = QItemSelectionRange();
- return;
- }
-
- while (verticalHeader->isSectionHidden(top) && top <= bottom)
- ++top;
- while (horizontalHeader->isSectionHidden(left) && left <= right)
- ++left;
-
- if (top > bottom || left > right) { // everything is hidden
- *range = QItemSelectionRange();
- return;
- }
-
- QModelIndex bottomRight = model->index(bottom, right, range->parent());
- QModelIndex topLeft = model->index(top, left, range->parent());
- *range = QItemSelectionRange(topLeft, bottomRight);
-}
-
-/*!
- \internal
- Sets the span for the cell at (\a row, \a column).
-*/
-void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan)
-{
- if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) {
- qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')';
- return;
- }
- QSpanCollection::Span *sp = spans.spanAt(column, row);
- if (sp) {
- if (sp->top() != row || sp->left() != column) {
- qWarning() << "QTableView::setSpan: span cannot overlap";
- return;
- }
- if (rowSpan == 1 && columnSpan == 1) {
- rowSpan = columnSpan = 0;
- }
- const int old_height = sp->height();
- sp->m_bottom = row + rowSpan - 1;
- sp->m_right = column + columnSpan - 1;
- spans.updateSpan(sp, old_height);
- return;
- } else if (rowSpan == 1 && columnSpan == 1) {
- qWarning() << "QTableView::setSpan: single cell span won't be added";
- return;
- }
- sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan);
- spans.addSpan(sp);
-}
-
-/*!
- \internal
- Gets the span information for the cell at (\a row, \a column).
-*/
-QSpanCollection::Span QTableViewPrivate::span(int row, int column) const
-{
- QSpanCollection::Span *sp = spans.spanAt(column, row);
- if (sp)
- return *sp;
-
- return QSpanCollection::Span(row, column, 1, 1);
-}
-
-/*!
- \internal
- Returns the logical index of the last section that's part of the span.
-*/
-int QTableViewPrivate::sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const
-{
- int visual = header->visualIndex(logical);
- for (int i = 1; i < span; ) {
- if (++visual >= header->count())
- break;
- logical = header->logicalIndex(visual);
- ++i;
- }
- return logical;
-}
-
-/*!
- \internal
- Returns the size of the span starting at logical index \a logical
- and spanning \a span sections.
-*/
-int QTableViewPrivate::sectionSpanSize(const QHeaderView *header, int logical, int span) const
-{
- int endLogical = sectionSpanEndLogical(header, logical, span);
- return header->sectionPosition(endLogical)
- - header->sectionPosition(logical)
- + header->sectionSize(endLogical);
-}
-
-/*!
- \internal
- Returns true if the section at logical index \a logical is part of the span
- starting at logical index \a spanLogical and spanning \a span sections;
- otherwise, returns false.
-*/
-bool QTableViewPrivate::spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const
-{
- if (logical == spanLogical)
- return true; // it's the start of the span
- int visual = header->visualIndex(spanLogical);
- for (int i = 1; i < span; ) {
- if (++visual >= header->count())
- break;
- spanLogical = header->logicalIndex(visual);
- if (logical == spanLogical)
- return true;
- ++i;
- }
- return false;
-}
-
-/*!
- \internal
- Returns the visual rect for the given \a span.
-*/
-QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const
-{
- Q_Q(const QTableView);
- // vertical
- int row = span.top();
- int rowp = verticalHeader->sectionViewportPosition(row);
- int rowh = rowSpanHeight(row, span.height());
- // horizontal
- int column = span.left();
- int colw = columnSpanWidth(column, span.width());
- if (q->isRightToLeft())
- column = span.right();
- int colp = horizontalHeader->sectionViewportPosition(column);
-
- const int i = showGrid ? 1 : 0;
- if (q->isRightToLeft())
- return QRect(colp + i, rowp, colw - i, rowh - i);
- return QRect(colp, rowp, colw - i, rowh - i);
-}
-
-/*!
- \internal
- Draws the spanning cells within rect \a area, and clips them off as
- preparation for the main drawing loop.
- \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn
-*/
-void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
- const QStyleOptionViewItemV4 &option, QBitArray *drawn,
- int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)
-{
- bool alternateBase = false;
- QRegion region = viewport->rect();
-
- QList<QSpanCollection::Span *> visibleSpans;
- bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved();
-
- if (!sectionMoved) {
- visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),
- lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);
- } else {
- QSet<QSpanCollection::Span *> set;
- for(int x = firstVisualColumn; x <= lastVisualColumn; x++)
- for(int y = firstVisualRow; y <= lastVisualRow; y++)
- set.insert(spans.spanAt(x,y));
- set.remove(0);
- visibleSpans = set.toList();
- }
-
- foreach (QSpanCollection::Span *span, visibleSpans) {
- int row = span->top();
- int col = span->left();
- QModelIndex index = model->index(row, col, root);
- if (!index.isValid())
- continue;
- QRect rect = visualSpanRect(*span);
- rect.translate(scrollDelayOffset);
- if (!area.intersects(rect))
- continue;
- QStyleOptionViewItemV4 opt = option;
- opt.rect = rect;
- alternateBase = alternatingColors && (span->top() & 1);
- if (alternateBase)
- opt.features |= QStyleOptionViewItemV2::Alternate;
- else
- opt.features &= ~QStyleOptionViewItemV2::Alternate;
- drawCell(painter, opt, index);
- region -= rect;
- for (int r = span->top(); r <= span->bottom(); ++r) {
- const int vr = visualRow(r);
- if (vr < firstVisualRow || vr > lastVisualRow)
- continue;
- for (int c = span->left(); c <= span->right(); ++c) {
- const int vc = visualColumn(c);
- if (vc < firstVisualColumn || vc > lastVisualColumn)
- continue;
- drawn->setBit((vr - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
- + vc - firstVisualColumn);
- }
- }
-
- }
- painter->setClipRegion(region);
-}
-
-/*!
- \internal
- Updates spans after row insertion.
-*/
-void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end)
-{
- Q_UNUSED(parent)
- spans.updateInsertedRows(start, end);
-}
-
-/*!
- \internal
- Updates spans after column insertion.
-*/
-void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)
-{
- Q_UNUSED(parent)
- spans.updateInsertedColumns(start, end);
-}
-
-/*!
- \internal
- Updates spans after row removal.
-*/
-void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end)
-{
- Q_UNUSED(parent)
- spans.updateRemovedRows(start, end);
-}
-
-/*!
- \internal
- Updates spans after column removal.
-*/
-void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)
-{
- Q_UNUSED(parent)
- spans.updateRemovedColumns(start, end);
-}
-
-/*!
- \internal
- Draws a table cell.
-*/
-void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index)
-{
- Q_Q(QTableView);
- QStyleOptionViewItemV4 opt = option;
-
- if (selectionModel && selectionModel->isSelected(index))
- opt.state |= QStyle::State_Selected;
- if (index == hover)
- opt.state |= QStyle::State_MouseOver;
- if (option.state & QStyle::State_Enabled) {
- QPalette::ColorGroup cg;
- if ((model->flags(index) & Qt::ItemIsEnabled) == 0) {
- opt.state &= ~QStyle::State_Enabled;
- cg = QPalette::Disabled;
- } else {
- cg = QPalette::Normal;
- }
- opt.palette.setCurrentColorGroup(cg);
- }
-
- if (index == q->currentIndex()) {
- const bool focus = (q->hasFocus() || viewport->hasFocus()) && q->currentIndex().isValid();
- if (focus)
- opt.state |= QStyle::State_HasFocus;
- }
-
- q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);
-
- q->itemDelegate(index)->paint(painter, opt, index);
-}
-
-/*!
- \class QTableView
-
- \brief The QTableView class provides a default model/view
- implementation of a table view.
-
- \ingroup model-view
- \ingroup advanced
-
-
- A QTableView implements a table view that displays items from a
- model. This class is used to provide standard tables that were
- previously provided by the QTable class, but using the more
- flexible approach provided by Qt's model/view architecture.
-
- The QTableView class is one of the \l{Model/View Classes}
- and is part of Qt's \l{Model/View Programming}{model/view framework}.
-
- QTableView implements the interfaces defined by the
- QAbstractItemView class to allow it to display data provided by
- models derived from the QAbstractItemModel class.
-
- \section1 Navigation
-
- You can navigate the cells in the table by clicking on a cell with the
- mouse, or by using the arrow keys. Because QTableView enables
- \l{QAbstractItemView::tabKeyNavigation}{tabKeyNavigation} by default, you
- can also hit Tab and Backtab to move from cell to cell.
-
- \section1 Visual Appearance
-
- The table has a vertical header that can be obtained using the
- verticalHeader() function, and a horizontal header that is available
- through the horizontalHeader() function. The height of each row in the
- table can be found by using rowHeight(); similarly, the width of
- columns can be found using columnWidth(). Since both of these are plain
- widgets, you can hide either of them using their hide() functions.
-
- Rows and columns can be hidden and shown with hideRow(), hideColumn(),
- showRow(), and showColumn(). They can be selected with selectRow()
- and selectColumn(). The table will show a grid depending on the
- \l showGrid property.
-
- The items shown in a table view, like those in the other item views, are
- rendered and edited using standard \l{QItemDelegate}{delegates}. However,
- for some tasks it is sometimes useful to be able to insert widgets in a
- table instead. Widgets are set for particular indexes with the
- \l{QAbstractItemView::}{setIndexWidget()} function, and
- later retrieved with \l{QAbstractItemView::}{indexWidget()}.
-
- \table
- \row \o \inlineimage qtableview-resized.png
- \o By default, the cells in a table do not expand to fill the available space.
-
- You can make the cells fill the available space by stretching the last
- header section. Access the relevant header using horizontalHeader()
- or verticalHeader() and set the header's \l{QHeaderView::}{stretchLastSection}
- property.
-
- To distribute the available space according to the space requirement of
- each column or row, call the view's resizeColumnsToContents() or
- resizeRowsToContents() functions.
- \endtable
-
- \section1 Coordinate Systems
-
- For some specialized forms of tables it is useful to be able to
- convert between row and column indexes and widget coordinates.
- The rowAt() function provides the y-coordinate within the view of the
- specified row; the row index can be used to obtain a corresponding
- y-coordinate with rowViewportPosition(). The columnAt() and
- columnViewportPosition() functions provide the equivalent conversion
- operations between x-coordinates and column indexes.
-
- \section1 Styles
-
- QTableView is styled appropriately for each platform. The following images show
- how it looks on three different platforms. Go to the \l{Qt Widget Gallery} to see
- its appearance in other styles.
-
- \table 100%
- \row \o \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table view
- \o \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table view
- \o \inlineimage plastique-tableview.png Screenshot of a Plastique style table view
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} table view.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} table view.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} table view.
- \endtable
-
- \sa QTableWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,
- {Chart Example}, {Pixelator Example}, {Table Model Example}
-*/
-
-/*!
- Constructs a table view with a \a parent to represent the data.
-
- \sa QAbstractItemModel
-*/
-
-QTableView::QTableView(QWidget *parent)
- : QAbstractItemView(*new QTableViewPrivate, parent)
-{
- Q_D(QTableView);
- d->init();
-}
-
-/*!
- \internal
-*/
-QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent)
- : QAbstractItemView(dd, parent)
-{
- Q_D(QTableView);
- d->init();
-}
-
-/*!
- Destroys the table view.
-*/
-QTableView::~QTableView()
-{
-}
-
-/*!
- \reimp
-*/
-void QTableView::setModel(QAbstractItemModel *model)
-{
- Q_D(QTableView);
- if (model == d->model)
- return;
- //let's disconnect from the old model
- if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
- }
- if (model) { //and connect to the new one
- connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
- connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
- connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
- connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
- }
- d->verticalHeader->setModel(model);
- d->horizontalHeader->setModel(model);
- QAbstractItemView::setModel(model);
-}
-
-/*!
- \reimp
-*/
-void QTableView::setRootIndex(const QModelIndex &index)
-{
- Q_D(QTableView);
- if (index == d->root) {
- viewport()->update();
- return;
- }
- d->verticalHeader->setRootIndex(index);
- d->horizontalHeader->setRootIndex(index);
- QAbstractItemView::setRootIndex(index);
-}
-
-/*!
- \reimp
-*/
-void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
-{
- Q_D(QTableView);
- Q_ASSERT(selectionModel);
- d->verticalHeader->setSelectionModel(selectionModel);
- d->horizontalHeader->setSelectionModel(selectionModel);
- QAbstractItemView::setSelectionModel(selectionModel);
-}
-
-/*!
- Returns the table view's horizontal header.
-
- \sa setHorizontalHeader(), verticalHeader(), QAbstractItemModel::headerData()
-*/
-QHeaderView *QTableView::horizontalHeader() const
-{
- Q_D(const QTableView);
- return d->horizontalHeader;
-}
-
-/*!
- Returns the table view's vertical header.
-
- \sa setVerticalHeader(), horizontalHeader(), QAbstractItemModel::headerData()
-*/
-QHeaderView *QTableView::verticalHeader() const
-{
- Q_D(const QTableView);
- return d->verticalHeader;
-}
-
-/*!
- Sets the widget to use for the horizontal header to \a header.
-
- \sa horizontalHeader() setVerticalHeader()
-*/
-void QTableView::setHorizontalHeader(QHeaderView *header)
-{
- Q_D(QTableView);
-
- if (!header || header == d->horizontalHeader)
- return;
- if (d->horizontalHeader && d->horizontalHeader->parent() == this)
- delete d->horizontalHeader;
- d->horizontalHeader = header;
- d->horizontalHeader->setParent(this);
- if (!d->horizontalHeader->model()) {
- d->horizontalHeader->setModel(d->model);
- if (d->selectionModel)
- d->horizontalHeader->setSelectionModel(d->selectionModel);
- }
-
- connect(d->horizontalHeader,SIGNAL(sectionResized(int,int,int)),
- this, SLOT(columnResized(int,int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionMoved(int,int,int)),
- this, SLOT(columnMoved(int,int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionCountChanged(int,int)),
- this, SLOT(columnCountChanged(int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));
- connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int)));
- connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
- this, SLOT(resizeColumnToContents(int)));
- connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
-
- //update the sorting enabled states on the new header
- setSortingEnabled(d->sortingEnabled);
-}
-
-/*!
- Sets the widget to use for the vertical header to \a header.
-
- \sa verticalHeader() setHorizontalHeader()
-*/
-void QTableView::setVerticalHeader(QHeaderView *header)
-{
- Q_D(QTableView);
-
- if (!header || header == d->verticalHeader)
- return;
- if (d->verticalHeader && d->verticalHeader->parent() == this)
- delete d->verticalHeader;
- d->verticalHeader = header;
- d->verticalHeader->setParent(this);
- if (!d->verticalHeader->model()) {
- d->verticalHeader->setModel(d->model);
- if (d->selectionModel)
- d->verticalHeader->setSelectionModel(d->selectionModel);
- }
-
- connect(d->verticalHeader, SIGNAL(sectionResized(int,int,int)),
- this, SLOT(rowResized(int,int,int)));
- connect(d->verticalHeader, SIGNAL(sectionMoved(int,int,int)),
- this, SLOT(rowMoved(int,int,int)));
- connect(d->verticalHeader, SIGNAL(sectionCountChanged(int,int)),
- this, SLOT(rowCountChanged(int,int)));
- connect(d->verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int)));
- connect(d->verticalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectRow(int)));
- connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
- this, SLOT(resizeRowToContents(int)));
- connect(d->verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
-}
-
-/*!
- \internal
-
- Scroll the contents of the table view by (\a dx, \a dy).
-*/
-void QTableView::scrollContentsBy(int dx, int dy)
-{
- Q_D(QTableView);
-
- d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
-
- dx = isRightToLeft() ? -dx : dx;
- if (dx) {
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->horizontalHeader->offset();
- if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
- d->horizontalHeader->setOffsetToLastSection();
- else
- d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
- int newOffset = d->horizontalHeader->offset();
- dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
- } else {
- d->horizontalHeader->setOffset(horizontalScrollBar()->value());
- }
- }
- if (dy) {
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->verticalHeader->offset();
- if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
- d->verticalHeader->setOffsetToLastSection();
- else
- d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
- int newOffset = d->verticalHeader->offset();
- dy = oldOffset - newOffset;
- } else {
- d->verticalHeader->setOffset(verticalScrollBar()->value());
- }
- }
- d->scrollContentsBy(dx, dy);
-
- if (d->showGrid) {
- //we need to update the first line of the previous top item in the view
- //because it has the grid drawn if the header is invisible.
- //It is strictly related to what's done at then end of the paintEvent
- if (dy > 0 && d->horizontalHeader->isHidden() && d->verticalScrollMode == ScrollPerItem) {
- d->viewport->update(0, dy, d->viewport->width(), dy);
- }
- if (dx > 0 && d->verticalHeader->isHidden() && d->horizontalScrollMode == ScrollPerItem) {
- d->viewport->update(dx, 0, dx, d->viewport->height());
- }
- }
-}
-
-/*!
- \reimp
-*/
-QStyleOptionViewItem QTableView::viewOptions() const
-{
- QStyleOptionViewItem option = QAbstractItemView::viewOptions();
- option.showDecorationSelected = true;
- return option;
-}
-
-/*!
- Paints the table on receipt of the given paint event \a event.
-*/
-void QTableView::paintEvent(QPaintEvent *event)
-{
- Q_D(QTableView);
- // setup temp variables for the painting
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- const QPoint offset = d->scrollDelayOffset;
- const bool showGrid = d->showGrid;
- const int gridSize = showGrid ? 1 : 0;
- const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);
- const QColor gridColor = static_cast<QRgb>(gridHint);
- const QPen gridPen = QPen(gridColor, 0, d->gridStyle);
- const QHeaderView *verticalHeader = d->verticalHeader;
- const QHeaderView *horizontalHeader = d->horizontalHeader;
- const QStyle::State state = option.state;
- const bool alternate = d->alternatingColors;
- const bool rightToLeft = isRightToLeft();
-
- QPainter painter(d->viewport);
-
- // if there's nothing to do, clear the area and return
- if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate)
- return;
-
- uint x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
- uint y = verticalHeader->length() - verticalHeader->offset() - 1;
-
- const QRegion region = event->region().translated(offset);
- const QVector<QRect> rects = region.rects();
-
- //firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
- //same goes for ...VisualColumn
- int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
- int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->viewport()->height());
- if (lastVisualRow == -1)
- lastVisualRow = d->model->rowCount(d->root) - 1;
-
- int firstVisualColumn = horizontalHeader->visualIndexAt(0);
- int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->viewport()->width());
- if (rightToLeft)
- qSwap(firstVisualColumn, lastVisualColumn);
- if (firstVisualColumn == -1)
- firstVisualColumn = 0;
- if (lastVisualColumn == -1)
- lastVisualColumn = horizontalHeader->count() - 1;
-
- QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
-
- if (d->hasSpans()) {
- d->drawAndClipSpans(region, &painter, option, &drawn,
- firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
- }
-
- for (int i = 0; i < rects.size(); ++i) {
- QRect dirtyArea = rects.at(i);
- dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));
- if (rightToLeft) {
- dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() - int(x)));
- } else {
- dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));
- }
-
- // get the horizontal start and end visual sections
- int left = horizontalHeader->visualIndexAt(dirtyArea.left());
- int right = horizontalHeader->visualIndexAt(dirtyArea.right());
- if (rightToLeft)
- qSwap(left, right);
- if (left == -1) left = 0;
- if (right == -1) right = horizontalHeader->count() - 1;
-
- // get the vertical start and end visual sections and if alternate color
- int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom());
- if (bottom == -1) bottom = verticalHeader->count() - 1;
- int top = 0;
- bool alternateBase = false;
- if (alternate && verticalHeader->sectionsHidden()) {
- uint verticalOffset = verticalHeader->offset();
- int row = verticalHeader->logicalIndex(top);
- for (int y = 0;
- ((uint)(y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom);
- ++top) {
- row = verticalHeader->logicalIndex(top);
- if (alternate && !verticalHeader->isSectionHidden(row))
- alternateBase = !alternateBase;
- }
- } else {
- top = verticalHeader->visualIndexAt(dirtyArea.top());
- alternateBase = (top & 1) && alternate;
- }
- if (top == -1 || top > bottom)
- continue;
-
- // Paint each row item
- for (int visualRowIndex = top; visualRowIndex <= bottom; ++visualRowIndex) {
- int row = verticalHeader->logicalIndex(visualRowIndex);
- if (verticalHeader->isSectionHidden(row))
- continue;
- int rowY = rowViewportPosition(row);
- rowY += offset.y();
- int rowh = rowHeight(row) - gridSize;
-
- // Paint each column item
- for (int visualColumnIndex = left; visualColumnIndex <= right; ++visualColumnIndex) {
- int currentBit = (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
- + visualColumnIndex - firstVisualColumn;
-
- if (currentBit < 0 || currentBit >= drawn.size() || drawn.testBit(currentBit))
- continue;
- drawn.setBit(currentBit);
-
- int col = horizontalHeader->logicalIndex(visualColumnIndex);
- if (horizontalHeader->isSectionHidden(col))
- continue;
- int colp = columnViewportPosition(col);
- colp += offset.x();
- int colw = columnWidth(col) - gridSize;
-
- const QModelIndex index = d->model->index(row, col, d->root);
- if (index.isValid()) {
- option.rect = QRect(colp + (showGrid && rightToLeft ? 1 : 0), rowY, colw, rowh);
- if (alternate) {
- if (alternateBase)
- option.features |= QStyleOptionViewItemV2::Alternate;
- else
- option.features &= ~QStyleOptionViewItemV2::Alternate;
- }
- d->drawCell(&painter, option, index);
- }
- }
- alternateBase = !alternateBase && alternate;
- }
-
- if (showGrid) {
- // Find the bottom right (the last rows/columns might be hidden)
- while (verticalHeader->isSectionHidden(verticalHeader->logicalIndex(bottom))) --bottom;
- QPen old = painter.pen();
- painter.setPen(gridPen);
- // Paint each row
- for (int visualIndex = top; visualIndex <= bottom; ++visualIndex) {
- int row = verticalHeader->logicalIndex(visualIndex);
- if (verticalHeader->isSectionHidden(row))
- continue;
- int rowY = rowViewportPosition(row);
- rowY += offset.y();
- int rowh = rowHeight(row) - gridSize;
- painter.drawLine(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
- }
-
- // Paint each column
- for (int h = left; h <= right; ++h) {
- int col = horizontalHeader->logicalIndex(h);
- if (horizontalHeader->isSectionHidden(col))
- continue;
- int colp = columnViewportPosition(col);
- colp += offset.x();
- if (!rightToLeft)
- colp += columnWidth(col) - gridSize;
- painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());
- }
-
- //draw the top & left grid lines if the headers are not visible.
- //We do update this line when subsequent scroll happen (see scrollContentsBy)
- if (horizontalHeader->isHidden() && verticalScrollMode() == ScrollPerItem)
- painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
- if (verticalHeader->isHidden() && horizontalScrollMode() == ScrollPerItem)
- painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
- painter.setPen(old);
- }
- }
-
-#ifndef QT_NO_DRAGANDDROP
- // Paint the dropIndicator
- d->paintDropIndicator(&painter);
-#endif
-}
-
-/*!
- Returns the index position of the model item corresponding to the
- table item at position \a pos in contents coordinates.
-*/
-QModelIndex QTableView::indexAt(const QPoint &pos) const
-{
- Q_D(const QTableView);
- d->executePostedLayout();
- int r = rowAt(pos.y());
- int c = columnAt(pos.x());
- if (r >= 0 && c >= 0) {
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(r, c);
- r = span.top();
- c = span.left();
- }
- return d->model->index(r, c, d->root);
- }
- return QModelIndex();
-}
-
-/*!
- Returns the horizontal offset of the items in the table view.
-
- Note that the table view uses the horizontal header section
- positions to determine the positions of columns in the view.
-
- \sa verticalOffset()
-*/
-int QTableView::horizontalOffset() const
-{
- Q_D(const QTableView);
- return d->horizontalHeader->offset();
-}
-
-/*!
- Returns the vertical offset of the items in the table view.
-
- Note that the table view uses the vertical header section
- positions to determine the positions of rows in the view.
-
- \sa horizontalOffset()
-*/
-int QTableView::verticalOffset() const
-{
- Q_D(const QTableView);
- return d->verticalHeader->offset();
-}
-
-/*!
- \fn QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
-
- Moves the cursor in accordance with the given \a cursorAction, using the
- information provided by the \a modifiers.
-
- \sa QAbstractItemView::CursorAction
-*/
-QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
-{
- Q_D(QTableView);
- Q_UNUSED(modifiers);
-
- int bottom = d->model->rowCount(d->root) - 1;
- // make sure that bottom is the bottommost *visible* row
- while (bottom >= 0 && isRowHidden(d->logicalRow(bottom)))
- --bottom;
-
- int right = d->model->columnCount(d->root) - 1;
-
- while (right >= 0 && isColumnHidden(d->logicalColumn(right)))
- --right;
-
- if (bottom == -1 || right == -1)
- return QModelIndex(); // model is empty
-
- QModelIndex current = currentIndex();
-
- if (!current.isValid()) {
- int row = 0;
- int column = 0;
- while (column < right && isColumnHidden(d->logicalColumn(column)))
- ++column;
- while (isRowHidden(d->logicalRow(row)) && row < bottom)
- ++row;
- d->visualCursor = QPoint(column, row);
- return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);
- }
-
- // Update visual cursor if current index has changed.
- QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));
- if (visualCurrent != d->visualCursor) {
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(current.row(), current.column());
- if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()
- || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())
- d->visualCursor = visualCurrent;
- } else {
- d->visualCursor = visualCurrent;
- }
- }
-
- int visualRow = d->visualCursor.y();
- if (visualRow > bottom)
- visualRow = bottom;
- Q_ASSERT(visualRow != -1);
- int visualColumn = d->visualCursor.x();
- if (visualColumn > right)
- visualColumn = right;
- Q_ASSERT(visualColumn != -1);
-
- if (isRightToLeft()) {
- if (cursorAction == MoveLeft)
- cursorAction = MoveRight;
- else if (cursorAction == MoveRight)
- cursorAction = MoveLeft;
- }
-
- switch (cursorAction) {
- case MoveUp: {
- int originalRow = visualRow;
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && visualRow == 0)
- visualRow = d->visualRow(model()->rowCount() - 1) + 1;
- // FIXME? visualRow = bottom + 1;
-#endif
- int r = d->logicalRow(visualRow);
- int c = d->logicalColumn(visualColumn);
- if (r != -1 && d->hasSpans()) {
- QSpanCollection::Span span = d->span(r, c);
- if (span.width() > 1 || span.height() > 1)
- visualRow = d->visualRow(span.top());
- }
- while (visualRow >= 0) {
- --visualRow;
- r = d->logicalRow(visualRow);
- c = d->logicalColumn(visualColumn);
- if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
- break;
- }
- if (visualRow < 0)
- visualRow = originalRow;
- break;
- }
- case MoveDown: {
- int originalRow = visualRow;
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(current.row(), current.column());
- visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
- }
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && visualRow >= bottom)
- visualRow = -1;
-#endif
- int r = d->logicalRow(visualRow);
- int c = d->logicalColumn(visualColumn);
- if (r != -1 && d->hasSpans()) {
- QSpanCollection::Span span = d->span(r, c);
- if (span.width() > 1 || span.height() > 1)
- visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
- }
- while (visualRow <= bottom) {
- ++visualRow;
- r = d->logicalRow(visualRow);
- c = d->logicalColumn(visualColumn);
- if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
- break;
- }
- if (visualRow > bottom)
- visualRow = originalRow;
- break;
- }
- case MovePrevious:
- case MoveLeft: {
- int originalRow = visualRow;
- int originalColumn = visualColumn;
- bool firstTime = true;
- bool looped = false;
- bool wrapped = false;
- do {
- int r = d->logicalRow(visualRow);
- int c = d->logicalColumn(visualColumn);
- if (firstTime && c != -1 && d->hasSpans()) {
- firstTime = false;
- QSpanCollection::Span span = d->span(r, c);
- if (span.width() > 1 || span.height() > 1)
- visualColumn = d->visualColumn(span.left());
- }
- while (visualColumn >= 0) {
- --visualColumn;
- r = d->logicalRow(visualRow);
- c = d->logicalColumn(visualColumn);
- if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
- break;
- if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {
- looped = true;
- break;
- }
- }
- if (cursorAction == MoveLeft || visualColumn >= 0)
- break;
- visualColumn = right + 1;
- if (visualRow == 0) {
- wrapped = true;
- visualRow = bottom;
- } else {
- --visualRow;
- }
- } while (!looped);
- if (visualColumn < 0)
- visualColumn = originalColumn;
- break;
- }
- case MoveNext:
- case MoveRight: {
- int originalRow = visualRow;
- int originalColumn = visualColumn;
- bool firstTime = true;
- bool looped = false;
- bool wrapped = false;
- do {
- int r = d->logicalRow(visualRow);
- int c = d->logicalColumn(visualColumn);
- if (firstTime && c != -1 && d->hasSpans()) {
- firstTime = false;
- QSpanCollection::Span span = d->span(r, c);
- if (span.width() > 1 || span.height() > 1)
- visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
- }
- while (visualColumn <= right) {
- ++visualColumn;
- r = d->logicalRow(visualRow);
- c = d->logicalColumn(visualColumn);
- if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
- break;
- if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {
- looped = true;
- break;
- }
- }
- if (cursorAction == MoveRight || visualColumn <= right)
- break;
- visualColumn = -1;
- if (visualRow == bottom) {
- wrapped = true;
- visualRow = 0;
- } else {
- ++visualRow;
- }
- } while (!looped);
- if (visualColumn > right)
- visualColumn = originalColumn;
- break;
- }
- case MoveHome:
- visualColumn = 0;
- while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
- ++visualColumn;
- if (modifiers & Qt::ControlModifier) {
- visualRow = 0;
- while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
- ++visualRow;
- }
- break;
- case MoveEnd:
- visualColumn = right;
- if (modifiers & Qt::ControlModifier)
- visualRow = bottom;
- break;
- case MovePageUp: {
- int newRow = rowAt(visualRect(current).top() - d->viewport->height());
- if (newRow == -1)
- newRow = d->logicalRow(0);
- return d->model->index(newRow, current.column(), d->root);
- }
- case MovePageDown: {
- int newRow = rowAt(visualRect(current).bottom() + d->viewport->height());
- if (newRow == -1)
- newRow = d->logicalRow(bottom);
- return d->model->index(newRow, current.column(), d->root);
- }}
-
- d->visualCursor = QPoint(visualColumn, visualRow);
- int logicalRow = d->logicalRow(visualRow);
- int logicalColumn = d->logicalColumn(visualColumn);
- if (!d->model->hasIndex(logicalRow, logicalColumn, d->root))
- return QModelIndex();
-
- QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
- if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result))
- return result;
-
- return QModelIndex();
-}
-
-/*!
- \fn void QTableView::setSelection(const QRect &rect,
- QItemSelectionModel::SelectionFlags flags)
-
- Selects the items within the given \a rect and in accordance with
- the specified selection \a flags.
-*/
-void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
-{
- Q_D(QTableView);
- QModelIndex tl = indexAt(QPoint(isRightToLeft() ? qMax(rect.left(), rect.right())
- : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom())));
- QModelIndex br = indexAt(QPoint(isRightToLeft() ? qMin(rect.left(), rect.right()) :
- qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom())));
- if (!d->selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br))
- return;
-
- bool verticalMoved = verticalHeader()->sectionsMoved();
- bool horizontalMoved = horizontalHeader()->sectionsMoved();
-
- QItemSelection selection;
-
- if (d->hasSpans()) {
- bool expanded;
- int top = qMin(d->visualRow(tl.row()), d->visualRow(br.row()));
- int left = qMin(d->visualColumn(tl.column()), d->visualColumn(br.column()));
- int bottom = qMax(d->visualRow(tl.row()), d->visualRow(br.row()));
- int right = qMax(d->visualColumn(tl.column()), d->visualColumn(br.column()));
- do {
- expanded = false;
- foreach (QSpanCollection::Span *it, d->spans.spans) {
- const QSpanCollection::Span &span = *it;
- int t = d->visualRow(span.top());
- int l = d->visualColumn(span.left());
- int b = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
- int r = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
- if ((t > bottom) || (l > right) || (top > b) || (left > r))
- continue; // no intersect
- if (t < top) {
- top = t;
- expanded = true;
- }
- if (l < left) {
- left = l;
- expanded = true;
- }
- if (b > bottom) {
- bottom = b;
- expanded = true;
- }
- if (r > right) {
- right = r;
- expanded = true;
- }
- if (expanded)
- break;
- }
- } while (expanded);
- for (int horizontal = left; horizontal <= right; ++horizontal) {
- int column = d->logicalColumn(horizontal);
- for (int vertical = top; vertical <= bottom; ++vertical) {
- int row = d->logicalRow(vertical);
- QModelIndex index = d->model->index(row, column, d->root);
- selection.append(QItemSelectionRange(index));
- }
- }
- } else if (verticalMoved && horizontalMoved) {
- int top = d->visualRow(tl.row());
- int left = d->visualColumn(tl.column());
- int bottom = d->visualRow(br.row());
- int right = d->visualColumn(br.column());
- for (int horizontal = left; horizontal <= right; ++horizontal) {
- int column = d->logicalColumn(horizontal);
- for (int vertical = top; vertical <= bottom; ++vertical) {
- int row = d->logicalRow(vertical);
- QModelIndex index = d->model->index(row, column, d->root);
- selection.append(QItemSelectionRange(index));
- }
- }
- } else if (horizontalMoved) {
- int left = d->visualColumn(tl.column());
- int right = d->visualColumn(br.column());
- for (int visual = left; visual <= right; ++visual) {
- int column = d->logicalColumn(visual);
- QModelIndex topLeft = d->model->index(tl.row(), column, d->root);
- QModelIndex bottomRight = d->model->index(br.row(), column, d->root);
- selection.append(QItemSelectionRange(topLeft, bottomRight));
- }
- } else if (verticalMoved) {
- int top = d->visualRow(tl.row());
- int bottom = d->visualRow(br.row());
- for (int visual = top; visual <= bottom; ++visual) {
- int row = d->logicalRow(visual);
- QModelIndex topLeft = d->model->index(row, tl.column(), d->root);
- QModelIndex bottomRight = d->model->index(row, br.column(), d->root);
- selection.append(QItemSelectionRange(topLeft, bottomRight));
- }
- } else { // nothing moved
- QItemSelectionRange range(tl, br);
- if (!range.isEmpty())
- selection.append(range);
- }
-
- d->selectionModel->select(selection, command);
-}
-
-/*!
- \internal
-
- Returns the rectangle from the viewport of the items in the given
- \a selection.
-
- Since 4.7, the returned region only contains rectangles intersecting
- (or included in) the viewport.
-*/
-QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) const
-{
- Q_D(const QTableView);
-
- if (selection.isEmpty())
- return QRegion();
-
- QRegion selectionRegion;
- const QRect &viewportRect = d->viewport->rect();
- bool verticalMoved = verticalHeader()->sectionsMoved();
- bool horizontalMoved = horizontalHeader()->sectionsMoved();
-
- if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
- if (range.parent() != d->root || !range.isValid())
- continue;
- for (int r = range.top(); r <= range.bottom(); ++r)
- for (int c = range.left(); c <= range.right(); ++c) {
- const QRect &rangeRect = visualRect(d->model->index(r, c, d->root));
- if (viewportRect.intersects(rangeRect))
- selectionRegion += rangeRect;
- }
- }
- } else if (horizontalMoved) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
- if (range.parent() != d->root || !range.isValid())
- continue;
- int top = rowViewportPosition(range.top());
- int bottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
- if (top > bottom)
- qSwap<int>(top, bottom);
- int height = bottom - top;
- for (int c = range.left(); c <= range.right(); ++c) {
- const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
- if (viewportRect.intersects(rangeRect))
- selectionRegion += rangeRect;
- }
- }
- } else if (verticalMoved) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
- if (range.parent() != d->root || !range.isValid())
- continue;
- int left = columnViewportPosition(range.left());
- int right = columnViewportPosition(range.right()) + columnWidth(range.right());
- if (left > right)
- qSwap<int>(left, right);
- int width = right - left;
- for (int r = range.top(); r <= range.bottom(); ++r) {
- const QRect rangeRect(left, rowViewportPosition(r), width, rowHeight(r));
- if (viewportRect.intersects(rangeRect))
- selectionRegion += rangeRect;
- }
- }
- } else { // nothing moved
- const int gridAdjust = showGrid() ? 1 : 0;
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
- if (range.parent() != d->root || !range.isValid())
- continue;
- d->trimHiddenSelections(&range);
-
- const int rtop = rowViewportPosition(range.top());
- const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
- int rleft;
- int rright;
- if (isLeftToRight()) {
- rleft = columnViewportPosition(range.left());
- rright = columnViewportPosition(range.right()) + columnWidth(range.right());
- } else {
- rleft = columnViewportPosition(range.right());
- rright = columnViewportPosition(range.left()) + columnWidth(range.left());
- }
- const QRect rangeRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
- if (viewportRect.intersects(rangeRect))
- selectionRegion += rangeRect;
- if (d->hasSpans()) {
- foreach (QSpanCollection::Span *s,
- d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) {
- if (range.contains(s->top(), s->left(), range.parent())) {
- const QRect &visualSpanRect = d->visualSpanRect(*s);
- if (viewportRect.intersects(visualSpanRect))
- selectionRegion += visualSpanRect;
- }
- }
- }
- }
- }
-
- return selectionRegion;
-}
-
-
-/*!
- \reimp
-*/
-QModelIndexList QTableView::selectedIndexes() const
-{
- Q_D(const QTableView);
- QModelIndexList viewSelected;
- QModelIndexList modelSelected;
- if (d->selectionModel)
- modelSelected = d->selectionModel->selectedIndexes();
- for (int i = 0; i < modelSelected.count(); ++i) {
- QModelIndex index = modelSelected.at(i);
- if (!isIndexHidden(index) && index.parent() == d->root)
- viewSelected.append(index);
- }
- return viewSelected;
-}
-
-
-/*!
- This slot is called whenever rows are added or deleted. The
- previous number of rows is specified by \a oldCount, and the new
- number of rows is specified by \a newCount.
-*/
-void QTableView::rowCountChanged(int /*oldCount*/, int /*newCount*/ )
-{
- Q_D(QTableView);
- d->doDelayedItemsLayout();
-}
-
-/*!
- This slot is called whenever columns are added or deleted. The
- previous number of columns is specified by \a oldCount, and the new
- number of columns is specified by \a newCount.
-*/
-void QTableView::columnCountChanged(int, int)
-{
- Q_D(QTableView);
- updateGeometries();
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem)
- d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
- else
- d->horizontalHeader->setOffset(horizontalScrollBar()->value());
- d->viewport->update();
-}
-
-/*!
- \reimp
-*/
-void QTableView::updateGeometries()
-{
- Q_D(QTableView);
- if (d->geometryRecursionBlock)
- return;
- d->geometryRecursionBlock = true;
-
- int width = 0;
- if (!d->verticalHeader->isHidden()) {
- width = qMax(d->verticalHeader->minimumWidth(), d->verticalHeader->sizeHint().width());
- width = qMin(width, d->verticalHeader->maximumWidth());
- }
- int height = 0;
- if (!d->horizontalHeader->isHidden()) {
- height = qMax(d->horizontalHeader->minimumHeight(), d->horizontalHeader->sizeHint().height());
- height = qMin(height, d->horizontalHeader->maximumHeight());
- }
- bool reverse = isRightToLeft();
- if (reverse)
- setViewportMargins(0, height, width, 0);
- else
- setViewportMargins(width, height, 0, 0);
-
- // update headers
-
- QRect vg = d->viewport->geometry();
-
- int verticalLeft = reverse ? vg.right() + 1 : (vg.left() - width);
- d->verticalHeader->setGeometry(verticalLeft, vg.top(), width, vg.height());
- if (d->verticalHeader->isHidden())
- QMetaObject::invokeMethod(d->verticalHeader, "updateGeometries");
-
- int horizontalTop = vg.top() - height;
- d->horizontalHeader->setGeometry(vg.left(), horizontalTop, vg.width(), height);
- if (d->horizontalHeader->isHidden())
- QMetaObject::invokeMethod(d->horizontalHeader, "updateGeometries");
-
- // update cornerWidget
- if (d->horizontalHeader->isHidden() || d->verticalHeader->isHidden()) {
- d->cornerWidget->setHidden(true);
- } else {
- d->cornerWidget->setHidden(false);
- d->cornerWidget->setGeometry(verticalLeft, horizontalTop, width, height);
- }
-
- // update scroll bars
-
- // ### move this block into the if
- QSize vsize = d->viewport->size();
- QSize max = maximumViewportSize();
- uint horizontalLength = d->horizontalHeader->length();
- uint verticalLength = d->verticalHeader->length();
- if ((uint)max.width() >= horizontalLength && (uint)max.height() >= verticalLength)
- vsize = max;
-
- // horizontal scroll bar
- const int columnCount = d->horizontalHeader->count();
- const int viewportWidth = vsize.width();
- int columnsInViewport = 0;
- for (int width = 0, column = columnCount - 1; column >= 0; --column) {
- int logical = d->horizontalHeader->logicalIndex(column);
- if (!d->horizontalHeader->isSectionHidden(logical)) {
- width += d->horizontalHeader->sectionSize(logical);
- if (width > viewportWidth)
- break;
- ++columnsInViewport;
- }
- }
- columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column
-
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();
- horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport);
- horizontalScrollBar()->setPageStep(columnsInViewport);
- if (columnsInViewport >= visibleColumns)
- d->horizontalHeader->setOffset(0);
- horizontalScrollBar()->setSingleStep(1);
- } else { // ScrollPerPixel
- horizontalScrollBar()->setPageStep(vsize.width());
- horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());
- horizontalScrollBar()->setSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
- }
-
- // vertical scroll bar
- const int rowCount = d->verticalHeader->count();
- const int viewportHeight = vsize.height();
- int rowsInViewport = 0;
- for (int height = 0, row = rowCount - 1; row >= 0; --row) {
- int logical = d->verticalHeader->logicalIndex(row);
- if (!d->verticalHeader->isSectionHidden(logical)) {
- height += d->verticalHeader->sectionSize(logical);
- if (height > viewportHeight)
- break;
- ++rowsInViewport;
- }
- }
- rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row
-
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();
- verticalScrollBar()->setRange(0, visibleRows - rowsInViewport);
- verticalScrollBar()->setPageStep(rowsInViewport);
- if (rowsInViewport >= visibleRows)
- d->verticalHeader->setOffset(0);
- verticalScrollBar()->setSingleStep(1);
- } else { // ScrollPerPixel
- verticalScrollBar()->setPageStep(vsize.height());
- verticalScrollBar()->setRange(0, verticalLength - vsize.height());
- verticalScrollBar()->setSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
- }
-
- d->geometryRecursionBlock = false;
- QAbstractItemView::updateGeometries();
-}
-
-/*!
- Returns the size hint for the given \a row's height or -1 if there
- is no model.
-
- If you need to set the height of a given row to a fixed value, call
- QHeaderView::resizeSection() on the table's vertical header.
-
- If you reimplement this function in a subclass, note that the value you
- return is only used when resizeRowToContents() is called. In that case,
- if a larger row height is required by either the vertical header or
- the item delegate, that width will be used instead.
-
- \sa QWidget::sizeHint, verticalHeader()
-*/
-int QTableView::sizeHintForRow(int row) const
-{
- Q_D(const QTableView);
-
- if (!model())
- return -1;
-
- ensurePolished();
-
- int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
- int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
- if (right == -1) // the table don't have enough columns to fill the viewport
- right = d->model->columnCount(d->root) - 1;
-
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
-
- int hint = 0;
- QModelIndex index;
- for (int column = left; column <= right; ++column) {
- int logicalColumn = d->horizontalHeader->logicalIndex(column);
- if (d->horizontalHeader->isSectionHidden(logicalColumn))
- continue;
- index = d->model->index(row, logicalColumn, d->root);
- if (d->wrapItemText) {// for wrapping boundaries
- option.rect.setY(rowViewportPosition(index.row()));
- option.rect.setHeight(rowHeight(index.row()));
- option.rect.setX(columnViewportPosition(index.column()));
- option.rect.setWidth(columnWidth(index.column()));
- }
-
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().height());
- int min = editor->minimumSize().height();
- int max = editor->maximumSize().height();
- hint = qBound(min, hint, max);
- }
-
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).height());
- }
-
- return d->showGrid ? hint + 1 : hint;
-}
-
-/*!
- Returns the size hint for the given \a column's width or -1 if
- there is no model.
-
- If you need to set the width of a given column to a fixed value, call
- QHeaderView::resizeSection() on the table's horizontal header.
-
- If you reimplement this function in a subclass, note that the value you
- return will be used when resizeColumnToContents() or
- QHeaderView::resizeSections() is called. If a larger column width is
- required by either the horizontal header or the item delegate, the larger
- width will be used instead.
-
- \sa QWidget::sizeHint, horizontalHeader()
-*/
-int QTableView::sizeHintForColumn(int column) const
-{
- Q_D(const QTableView);
-
- if (!model())
- return -1;
-
- ensurePolished();
-
- int top = qMax(0, d->verticalHeader->visualIndexAt(0));
- int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
- if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
- bottom = d->model->rowCount(d->root) - 1;
-
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
-
- int hint = 0;
- QModelIndex index;
- for (int row = top; row <= bottom; ++row) {
- int logicalRow = d->verticalHeader->logicalIndex(row);
- if (d->verticalHeader->isSectionHidden(logicalRow))
- continue;
- index = d->model->index(logicalRow, column, d->root);
-
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().width());
- int min = editor->minimumSize().width();
- int max = editor->maximumSize().width();
- hint = qBound(min, hint, max);
- }
-
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).width());
- }
-
- return d->showGrid ? hint + 1 : hint;
-}
-
-/*!
- Returns the y-coordinate in contents coordinates of the given \a
- row.
-*/
-int QTableView::rowViewportPosition(int row) const
-{
- Q_D(const QTableView);
- return d->verticalHeader->sectionViewportPosition(row);
-}
-
-/*!
- Returns the row in which the given y-coordinate, \a y, in contents
- coordinates is located.
-
- \note This function returns -1 if the given coordinate is not valid
- (has no row).
-
- \sa columnAt()
-*/
-int QTableView::rowAt(int y) const
-{
- Q_D(const QTableView);
- return d->verticalHeader->logicalIndexAt(y);
-}
-
-/*!
- \since 4.1
-
- Sets the height of the given \a row to be \a height.
-*/
-void QTableView::setRowHeight(int row, int height)
-{
- Q_D(const QTableView);
- d->verticalHeader->resizeSection(row, height);
-}
-
-/*!
- Returns the height of the given \a row.
-
- \sa resizeRowToContents(), columnWidth()
-*/
-int QTableView::rowHeight(int row) const
-{
- Q_D(const QTableView);
- return d->verticalHeader->sectionSize(row);
-}
-
-/*!
- Returns the x-coordinate in contents coordinates of the given \a
- column.
-*/
-int QTableView::columnViewportPosition(int column) const
-{
- Q_D(const QTableView);
- return d->horizontalHeader->sectionViewportPosition(column);
-}
-
-/*!
- Returns the column in which the given x-coordinate, \a x, in contents
- coordinates is located.
-
- \note This function returns -1 if the given coordinate is not valid
- (has no column).
-
- \sa rowAt()
-*/
-int QTableView::columnAt(int x) const
-{
- Q_D(const QTableView);
- return d->horizontalHeader->logicalIndexAt(x);
-}
-
-/*!
- \since 4.1
-
- Sets the width of the given \a column to be \a width.
-*/
-void QTableView::setColumnWidth(int column, int width)
-{
- Q_D(const QTableView);
- d->horizontalHeader->resizeSection(column, width);
-}
-
-/*!
- Returns the width of the given \a column.
-
- \sa resizeColumnToContents(), rowHeight()
-*/
-int QTableView::columnWidth(int column) const
-{
- Q_D(const QTableView);
- return d->horizontalHeader->sectionSize(column);
-}
-
-/*!
- Returns true if the given \a row is hidden; otherwise returns false.
-
- \sa isColumnHidden()
-*/
-bool QTableView::isRowHidden(int row) const
-{
- Q_D(const QTableView);
- return d->verticalHeader->isSectionHidden(row);
-}
-
-/*!
- If \a hide is true \a row will be hidden, otherwise it will be shown.
-
- \sa setColumnHidden()
-*/
-void QTableView::setRowHidden(int row, bool hide)
-{
- Q_D(QTableView);
- if (row < 0 || row >= d->verticalHeader->count())
- return;
- d->verticalHeader->setSectionHidden(row, hide);
-}
-
-/*!
- Returns true if the given \a column is hidden; otherwise returns false.
-
- \sa isRowHidden()
-*/
-bool QTableView::isColumnHidden(int column) const
-{
- Q_D(const QTableView);
- return d->horizontalHeader->isSectionHidden(column);
-}
-
-/*!
- If \a hide is true the given \a column will be hidden; otherwise it
- will be shown.
-
- \sa setRowHidden()
-*/
-void QTableView::setColumnHidden(int column, bool hide)
-{
- Q_D(QTableView);
- if (column < 0 || column >= d->horizontalHeader->count())
- return;
- d->horizontalHeader->setSectionHidden(column, hide);
-}
-
-/*!
- \since 4.2
- \property QTableView::sortingEnabled
- \brief whether sorting is enabled
-
- If this property is true, sorting is enabled for the table. If
- this property is false, sorting is not enabled. The default value
- is false.
-
- \note. Setting the property to true with setSortingEnabled()
- immediately triggers a call to sortByColumn() with the current
- sort section and order.
-
- \sa sortByColumn()
-*/
-
-/*!
- If \a enabled true enables sorting for the table and immediately
- trigger a call to sortByColumn() with the current sort section and
- order
- */
-void QTableView::setSortingEnabled(bool enable)
-{
- Q_D(QTableView);
- d->sortingEnabled = enable;
- horizontalHeader()->setSortIndicatorShown(enable);
- if (enable) {
- disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
- this, SLOT(_q_selectColumn(int)));
- disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
- this, SLOT(selectColumn(int)));
- connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(sortByColumn(int)), Qt::UniqueConnection);
- sortByColumn(horizontalHeader()->sortIndicatorSection(),
- horizontalHeader()->sortIndicatorOrder());
- } else {
- connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
- this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
- connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
- this, SLOT(selectColumn(int)), Qt::UniqueConnection);
- disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(sortByColumn(int)));
- }
-}
-
-bool QTableView::isSortingEnabled() const
-{
- Q_D(const QTableView);
- return d->sortingEnabled;
-}
-
-/*!
- \property QTableView::showGrid
- \brief whether the grid is shown
-
- If this property is true a grid is drawn for the table; if the
- property is false, no grid is drawn. The default value is true.
-*/
-bool QTableView::showGrid() const
-{
- Q_D(const QTableView);
- return d->showGrid;
-}
-
-void QTableView::setShowGrid(bool show)
-{
- Q_D(QTableView);
- if (d->showGrid != show) {
- d->showGrid = show;
- d->viewport->update();
- }
-}
-
-/*!
- \property QTableView::gridStyle
- \brief the pen style used to draw the grid.
-
- This property holds the style used when drawing the grid (see \l{showGrid}).
-*/
-Qt::PenStyle QTableView::gridStyle() const
-{
- Q_D(const QTableView);
- return d->gridStyle;
-}
-
-void QTableView::setGridStyle(Qt::PenStyle style)
-{
- Q_D(QTableView);
- if (d->gridStyle != style) {
- d->gridStyle = style;
- d->viewport->update();
- }
-}
-
-/*!
- \property QTableView::wordWrap
- \brief the item text word-wrapping policy
- \since 4.3
-
- If this property is true then the item text is wrapped where
- necessary at word-breaks; otherwise it is not wrapped at all.
- This property is true by default.
-
- Note that even of wrapping is enabled, the cell will not be
- expanded to fit all text. Ellipsis will be inserted according to
- the current \l{QAbstractItemView::}{textElideMode}.
-
-*/
-void QTableView::setWordWrap(bool on)
-{
- Q_D(QTableView);
- if (d->wrapItemText == on)
- return;
- d->wrapItemText = on;
- QMetaObject::invokeMethod(d->verticalHeader, "resizeSections");
- QMetaObject::invokeMethod(d->horizontalHeader, "resizeSections");
-}
-
-bool QTableView::wordWrap() const
-{
- Q_D(const QTableView);
- return d->wrapItemText;
-}
-
-/*!
- \property QTableView::cornerButtonEnabled
- \brief whether the button in the top-left corner is enabled
- \since 4.3
-
- If this property is true then button in the top-left corner
- of the table view is enabled. Clicking on this button will
- select all the cells in the table view.
-
- This property is true by default.
-*/
-void QTableView::setCornerButtonEnabled(bool enable)
-{
- Q_D(QTableView);
- d->cornerWidget->setEnabled(enable);
-}
-
-bool QTableView::isCornerButtonEnabled() const
-{
- Q_D(const QTableView);
- return d->cornerWidget->isEnabled();
-}
-
-/*!
- \internal
-
- Returns the rectangle on the viewport occupied by the given \a
- index.
- If the index is hidden in the view it will return a null QRect.
-*/
-QRect QTableView::visualRect(const QModelIndex &index) const
-{
- Q_D(const QTableView);
- if (!d->isIndexValid(index) || index.parent() != d->root
- || (!d->hasSpans() && isIndexHidden(index)))
- return QRect();
-
- d->executePostedLayout();
-
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(index.row(), index.column());
- return d->visualSpanRect(span);
- }
-
- int rowp = rowViewportPosition(index.row());
- int rowh = rowHeight(index.row());
- int colp = columnViewportPosition(index.column());
- int colw = columnWidth(index.column());
-
- const int i = showGrid() ? 1 : 0;
- return QRect(colp, rowp, colw - i, rowh - i);
-}
-
-/*!
- \internal
-
- Makes sure that the given \a item is visible in the table view,
- scrolling if necessary.
-*/
-void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)
-{
- Q_D(QTableView);
-
- // check if we really need to do anything
- if (!d->isIndexValid(index)
- || (d->model->parent(index) != d->root)
- || isRowHidden(index.row()) || isColumnHidden(index.column()))
- return;
-
- QSpanCollection::Span span;
- if (d->hasSpans())
- span = d->span(index.row(), index.column());
-
- // Adjust horizontal position
-
- int viewportWidth = d->viewport->width();
- int horizontalOffset = d->horizontalHeader->offset();
- int horizontalPosition = d->horizontalHeader->sectionPosition(index.column());
- int horizontalIndex = d->horizontalHeader->visualIndex(index.column());
- int cellWidth = d->hasSpans()
- ? d->columnSpanWidth(index.column(), span.width())
- : d->horizontalHeader->sectionSize(index.column());
-
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
-
- bool positionAtLeft = (horizontalPosition - horizontalOffset < 0);
- bool positionAtRight = (horizontalPosition - horizontalOffset + cellWidth > viewportWidth);
-
- if (hint == PositionAtCenter || positionAtRight) {
- int w = (hint == PositionAtCenter ? viewportWidth / 2 : viewportWidth);
- int x = cellWidth;
- while (horizontalIndex > 0) {
- x += columnWidth(d->horizontalHeader->logicalIndex(horizontalIndex-1));
- if (x > w)
- break;
- --horizontalIndex;
- }
- }
-
- if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {
- int hiddenSections = 0;
- if (d->horizontalHeader->sectionsHidden()) {
- for (int s = horizontalIndex - 1; s >= 0; --s) {
- int column = d->horizontalHeader->logicalIndex(s);
- if (d->horizontalHeader->isSectionHidden(column))
- ++hiddenSections;
- }
- }
- horizontalScrollBar()->setValue(horizontalIndex - hiddenSections);
- }
-
- } else { // ScrollPerPixel
- if (hint == PositionAtCenter) {
- horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
- } else {
- if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
- horizontalScrollBar()->setValue(horizontalPosition);
- else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
- horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
- }
- }
-
- // Adjust vertical position
-
- int viewportHeight = d->viewport->height();
- int verticalOffset = d->verticalHeader->offset();
- int verticalPosition = d->verticalHeader->sectionPosition(index.row());
- int verticalIndex = d->verticalHeader->visualIndex(index.row());
- int cellHeight = d->hasSpans()
- ? d->rowSpanHeight(index.row(), span.height())
- : d->verticalHeader->sectionSize(index.row());
-
- if (verticalPosition - verticalOffset < 0 || cellHeight > viewportHeight) {
- if (hint == EnsureVisible)
- hint = PositionAtTop;
- } else if (verticalPosition - verticalOffset + cellHeight > viewportHeight) {
- if (hint == EnsureVisible)
- hint = PositionAtBottom;
- }
-
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
-
- if (hint == PositionAtBottom || hint == PositionAtCenter) {
- int h = (hint == PositionAtCenter ? viewportHeight / 2 : viewportHeight);
- int y = cellHeight;
- while (verticalIndex > 0) {
- int row = d->verticalHeader->logicalIndex(verticalIndex - 1);
- y += d->verticalHeader->sectionSize(row);
- if (y > h)
- break;
- --verticalIndex;
- }
- }
-
- if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {
- int hiddenSections = 0;
- if (d->verticalHeader->sectionsHidden()) {
- for (int s = verticalIndex - 1; s >= 0; --s) {
- int row = d->verticalHeader->logicalIndex(s);
- if (d->verticalHeader->isSectionHidden(row))
- ++hiddenSections;
- }
- }
- verticalScrollBar()->setValue(verticalIndex - hiddenSections);
- }
-
- } else { // ScrollPerPixel
- if (hint == PositionAtTop) {
- verticalScrollBar()->setValue(verticalPosition);
- } else if (hint == PositionAtBottom) {
- verticalScrollBar()->setValue(verticalPosition - viewportHeight + cellHeight);
- } else if (hint == PositionAtCenter) {
- verticalScrollBar()->setValue(verticalPosition - ((viewportHeight - cellHeight) / 2));
- }
- }
-
- update(index);
-}
-
-/*!
- This slot is called to change the height of the given \a row. The
- old height is specified by \a oldHeight, and the new height by \a
- newHeight.
-
- \sa columnResized()
-*/
-void QTableView::rowResized(int row, int, int)
-{
- Q_D(QTableView);
- d->rowsToUpdate.append(row);
- if (d->rowResizeTimerID == 0)
- d->rowResizeTimerID = startTimer(0);
-}
-
-/*!
- This slot is called to change the width of the given \a column.
- The old width is specified by \a oldWidth, and the new width by \a
- newWidth.
-
- \sa rowResized()
-*/
-void QTableView::columnResized(int column, int, int)
-{
- Q_D(QTableView);
- d->columnsToUpdate.append(column);
- if (d->columnResizeTimerID == 0)
- d->columnResizeTimerID = startTimer(0);
-}
-
-/*!
- \reimp
- */
-void QTableView::timerEvent(QTimerEvent *event)
-{
- Q_D(QTableView);
-
- if (event->timerId() == d->columnResizeTimerID) {
- updateGeometries();
- killTimer(d->columnResizeTimerID);
- d->columnResizeTimerID = 0;
-
- QRect rect;
- int viewportHeight = d->viewport->height();
- int viewportWidth = d->viewport->width();
- if (d->hasSpans()) {
- rect = QRect(0, 0, viewportWidth, viewportHeight);
- } else {
- for (int i = d->columnsToUpdate.size()-1; i >= 0; --i) {
- int column = d->columnsToUpdate.at(i);
- int x = columnViewportPosition(column);
- if (isRightToLeft())
- rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);
- else
- rect |= QRect(x, 0, viewportWidth - x, viewportHeight);
- }
- }
-
- d->viewport->update(rect.normalized());
- d->columnsToUpdate.clear();
- }
-
- if (event->timerId() == d->rowResizeTimerID) {
- updateGeometries();
- killTimer(d->rowResizeTimerID);
- d->rowResizeTimerID = 0;
-
- int viewportHeight = d->viewport->height();
- int viewportWidth = d->viewport->width();
- int top;
- if (d->hasSpans()) {
- top = 0;
- } else {
- top = viewportHeight;
- for (int i = d->rowsToUpdate.size()-1; i >= 0; --i) {
- int y = rowViewportPosition(d->rowsToUpdate.at(i));
- top = qMin(top, y);
- }
- }
-
- d->viewport->update(QRect(0, top, viewportWidth, viewportHeight - top));
- d->rowsToUpdate.clear();
- }
-
- QAbstractItemView::timerEvent(event);
-}
-
-/*!
- This slot is called to change the index of the given \a row in the
- table view. The old index is specified by \a oldIndex, and the new
- index by \a newIndex.
-
- \sa columnMoved()
-*/
-void QTableView::rowMoved(int, int oldIndex, int newIndex)
-{
- Q_D(QTableView);
-
- updateGeometries();
- int logicalOldIndex = d->verticalHeader->logicalIndex(oldIndex);
- int logicalNewIndex = d->verticalHeader->logicalIndex(newIndex);
- if (d->hasSpans()) {
- d->viewport->update();
- } else {
- int oldTop = rowViewportPosition(logicalOldIndex);
- int newTop = rowViewportPosition(logicalNewIndex);
- int oldBottom = oldTop + rowHeight(logicalOldIndex);
- int newBottom = newTop + rowHeight(logicalNewIndex);
- int top = qMin(oldTop, newTop);
- int bottom = qMax(oldBottom, newBottom);
- int height = bottom - top;
- d->viewport->update(0, top, d->viewport->width(), height);
- }
-}
-
-/*!
- This slot is called to change the index of the given \a column in
- the table view. The old index is specified by \a oldIndex, and
- the new index by \a newIndex.
-
- \sa rowMoved()
-*/
-void QTableView::columnMoved(int, int oldIndex, int newIndex)
-{
- Q_D(QTableView);
-
- updateGeometries();
- int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex);
- int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex);
- if (d->hasSpans()) {
- d->viewport->update();
- } else {
- int oldLeft = columnViewportPosition(logicalOldIndex);
- int newLeft = columnViewportPosition(logicalNewIndex);
- int oldRight = oldLeft + columnWidth(logicalOldIndex);
- int newRight = newLeft + columnWidth(logicalNewIndex);
- int left = qMin(oldLeft, newLeft);
- int right = qMax(oldRight, newRight);
- int width = right - left;
- d->viewport->update(left, 0, width, d->viewport->height());
- }
-}
-
-/*!
- Selects the given \a row in the table view if the current
- SelectionMode and SelectionBehavior allows rows to be selected.
-
- \sa selectColumn()
-*/
-void QTableView::selectRow(int row)
-{
- Q_D(QTableView);
- d->selectRow(row, true);
-}
-
-/*!
- Selects the given \a column in the table view if the current
- SelectionMode and SelectionBehavior allows columns to be selected.
-
- \sa selectRow()
-*/
-void QTableView::selectColumn(int column)
-{
- Q_D(QTableView);
- d->selectColumn(column, true);
-}
-
-/*!
- Hide the given \a row.
-
- \sa showRow() hideColumn()
-*/
-void QTableView::hideRow(int row)
-{
- Q_D(QTableView);
- d->verticalHeader->hideSection(row);
-}
-
-/*!
- Hide the given \a column.
-
- \sa showColumn() hideRow()
-*/
-void QTableView::hideColumn(int column)
-{
- Q_D(QTableView);
- d->horizontalHeader->hideSection(column);
-}
-
-/*!
- Show the given \a row.
-
- \sa hideRow() showColumn()
-*/
-void QTableView::showRow(int row)
-{
- Q_D(QTableView);
- d->verticalHeader->showSection(row);
-}
-
-/*!
- Show the given \a column.
-
- \sa hideColumn() showRow()
-*/
-void QTableView::showColumn(int column)
-{
- Q_D(QTableView);
- d->horizontalHeader->showSection(column);
-}
-
-/*!
- Resizes the given \a row based on the size hints of the delegate
- used to render each item in the row.
-*/
-void QTableView::resizeRowToContents(int row)
-{
- Q_D(QTableView);
- int content = sizeHintForRow(row);
- int header = d->verticalHeader->sectionSizeHint(row);
- d->verticalHeader->resizeSection(row, qMax(content, header));
-}
-
-/*!
- Resizes all rows based on the size hints of the delegate
- used to render each item in the rows.
-*/
-void QTableView::resizeRowsToContents()
-{
- Q_D(QTableView);
- d->verticalHeader->resizeSections(QHeaderView::ResizeToContents);
-}
-
-/*!
- Resizes the given \a column based on the size hints of the delegate
- used to render each item in the column.
-
- \note Only visible columns will be resized. Reimplement sizeHintForColumn()
- to resize hidden columns as well.
-*/
-void QTableView::resizeColumnToContents(int column)
-{
- Q_D(QTableView);
- int content = sizeHintForColumn(column);
- int header = d->horizontalHeader->sectionSizeHint(column);
- d->horizontalHeader->resizeSection(column, qMax(content, header));
-}
-
-/*!
- Resizes all columns based on the size hints of the delegate
- used to render each item in the columns.
-*/
-void QTableView::resizeColumnsToContents()
-{
- Q_D(QTableView);
- d->horizontalHeader->resizeSections(QHeaderView::ResizeToContents);
-}
-
-/*!
- \obsolete
- \overload
-
- Sorts the model by the values in the given \a column.
-*/
-void QTableView::sortByColumn(int column)
-{
- Q_D(QTableView);
- if (column == -1)
- return;
- d->model->sort(column, d->horizontalHeader->sortIndicatorOrder());
-}
-
-/*!
- \since 4.2
-
- Sorts the model by the values in the given \a column in the given \a order.
-
- \sa sortingEnabled
- */
-void QTableView::sortByColumn(int column, Qt::SortOrder order)
-{
- Q_D(QTableView);
- d->horizontalHeader->setSortIndicator(column, order);
- sortByColumn(column);
-}
-
-/*!
- \internal
-*/
-void QTableView::verticalScrollbarAction(int action)
-{
- QAbstractItemView::verticalScrollbarAction(action);
-}
-
-/*!
- \internal
-*/
-void QTableView::horizontalScrollbarAction(int action)
-{
- QAbstractItemView::horizontalScrollbarAction(action);
-}
-
-/*!
- \reimp
-*/
-bool QTableView::isIndexHidden(const QModelIndex &index) const
-{
- Q_D(const QTableView);
- Q_ASSERT(d->isIndexValid(index));
- if (isRowHidden(index.row()) || isColumnHidden(index.column()))
- return true;
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(index.row(), index.column());
- return !((span.top() == index.row()) && (span.left() == index.column()));
- }
- return false;
-}
-
-/*!
- \fn void QTableView::setSpan(int row, int column, int rowSpanCount, int columnSpanCount)
- \since 4.2
-
- Sets the span of the table element at (\a row, \a column) to the number of
- rows and columns specified by (\a rowSpanCount, \a columnSpanCount).
-
- \sa rowSpan(), columnSpan()
-*/
-void QTableView::setSpan(int row, int column, int rowSpan, int columnSpan)
-{
- Q_D(QTableView);
- if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0)
- return;
- d->setSpan(row, column, rowSpan, columnSpan);
- d->viewport->update();
-}
-
-/*!
- \since 4.2
-
- Returns the row span of the table element at (\a row, \a column).
- The default is 1.
-
- \sa setSpan(), columnSpan()
-*/
-int QTableView::rowSpan(int row, int column) const
-{
- Q_D(const QTableView);
- return d->rowSpan(row, column);
-}
-
-/*!
- \since 4.2
-
- Returns the column span of the table element at (\a row, \a
- column). The default is 1.
-
- \sa setSpan(), rowSpan()
-*/
-int QTableView::columnSpan(int row, int column) const
-{
- Q_D(const QTableView);
- return d->columnSpan(row, column);
-}
-
-/*!
- \since 4.4
-
- Removes all row and column spans in the table view.
-
- \sa setSpan()
-*/
-
-void QTableView::clearSpans()
-{
- Q_D(QTableView);
- d->spans.clear();
- d->viewport->update();
-}
-
-void QTableViewPrivate::_q_selectRow(int row)
-{
- selectRow(row, false);
-}
-
-void QTableViewPrivate::_q_selectColumn(int column)
-{
- selectColumn(column, false);
-}
-
-void QTableViewPrivate::selectRow(int row, bool anchor)
-{
- Q_Q(QTableView);
-
- if (q->selectionBehavior() == QTableView::SelectColumns
- || (q->selectionMode() == QTableView::SingleSelection
- && q->selectionBehavior() == QTableView::SelectItems))
- return;
-
- if (row >= 0 && row < model->rowCount(root)) {
- int column = horizontalHeader->logicalIndexAt(q->isRightToLeft() ? viewport->width() : 0);
- QModelIndex index = model->index(row, column, root);
- QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
- selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- if ((anchor && !(command & QItemSelectionModel::Current))
- || (q->selectionMode() == QTableView::SingleSelection))
- rowSectionAnchor = row;
-
- if (q->selectionMode() != QTableView::SingleSelection
- && command.testFlag(QItemSelectionModel::Toggle)) {
- if (anchor)
- ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows().contains(index)
- ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
- command &= ~QItemSelectionModel::Toggle;
- command |= ctrlDragSelectionFlag;
- if (!anchor)
- command |= QItemSelectionModel::Current;
- }
-
- QModelIndex tl = model->index(qMin(rowSectionAnchor, row), 0, root);
- QModelIndex br = model->index(qMax(rowSectionAnchor, row), model->columnCount(root) - 1, root);
- if (verticalHeader->sectionsMoved() && tl.row() != br.row())
- q->setSelection(q->visualRect(tl)|q->visualRect(br), command);
- else
- selectionModel->select(QItemSelection(tl, br), command);
- }
-}
-
-void QTableViewPrivate::selectColumn(int column, bool anchor)
-{
- Q_Q(QTableView);
-
- if (q->selectionBehavior() == QTableView::SelectRows
- || (q->selectionMode() == QTableView::SingleSelection
- && q->selectionBehavior() == QTableView::SelectItems))
- return;
-
- if (column >= 0 && column < model->columnCount(root)) {
- int row = verticalHeader->logicalIndexAt(0);
- QModelIndex index = model->index(row, column, root);
- QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
- selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- if ((anchor && !(command & QItemSelectionModel::Current))
- || (q->selectionMode() == QTableView::SingleSelection))
- columnSectionAnchor = column;
-
- if (q->selectionMode() != QTableView::SingleSelection
- && command.testFlag(QItemSelectionModel::Toggle)) {
- if (anchor)
- ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
- ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
- command &= ~QItemSelectionModel::Toggle;
- command |= ctrlDragSelectionFlag;
- if (!anchor)
- command |= QItemSelectionModel::Current;
- }
-
- QModelIndex tl = model->index(0, qMin(columnSectionAnchor, column), root);
- QModelIndex br = model->index(model->rowCount(root) - 1,
- qMax(columnSectionAnchor, column), root);
- if (horizontalHeader->sectionsMoved() && tl.column() != br.column())
- q->setSelection(q->visualRect(tl)|q->visualRect(br), command);
- else
- selectionModel->select(QItemSelection(tl, br), command);
- }
-}
-
-/*!
- \reimp
- */
-void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
-{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- if (current.isValid()) {
- int entry = visualIndex(current) + 1;
- if (horizontalHeader())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
- }
- }
-#endif
- QAbstractItemView::currentChanged(current, previous);
-}
-
-/*!
- \reimp
- */
-void QTableView::selectionChanged(const QItemSelection &selected,
- const QItemSelection &deselected)
-{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- // ### does not work properly for selection ranges.
- QModelIndex sel = selected.indexes().value(0);
- if (sel.isValid()) {
- int entry = visualIndex(sel);
- if (horizontalHeader())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
- }
- QModelIndex desel = deselected.indexes().value(0);
- if (desel.isValid()) {
- int entry = visualIndex(sel);
- if (horizontalHeader())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
- }
- }
-#endif
- QAbstractItemView::selectionChanged(selected, deselected);
-}
-
-int QTableView::visualIndex(const QModelIndex &index) const
-{
- return index.row();
-}
-
-QT_END_NAMESPACE
-
-#include "qtableview.moc"
-
-#include "moc_qtableview.cpp"
-
-#endif // QT_NO_TABLEVIEW