📄 qtableview.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#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>#endifclass QTableCornerButton : public QAbstractButton{ Q_OBJECTpublic: 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) return; Span sp(row, column, rowSpan, columnSpan); QList<Span>::iterator it; for (it = spans.begin(); it != spans.end(); ++it) { if (((*it).top() == sp.top()) && ((*it).left() == sp.left())) { if ((sp.height() == 1) && (sp.width() == 1)) spans.erase(it); // "Implicit" span (1, 1), no need to store it else *it = sp; // Replace return; } } spans.append(sp);}/*! \internal Gets the span information for the cell at (\a row, \a column).*/QTableViewPrivate::Span QTableViewPrivate::span(int row, int column) const{ QList<Span>::const_iterator it; for (it = spans.begin(); it != spans.end(); ++it) { Span span = *it; if (isInSpan(row, column, span)) return span; } return 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); if (header->isSectionHidden(logical)) continue; ++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 (header->isSectionHidden(spanLogical)) continue; if (logical == spanLogical) return true; ++i; } return false;}/*! \internal Returns true if one or more spans intersect column \a column.*/bool QTableViewPrivate::spansIntersectColumn(int column) const{ QList<Span>::const_iterator it; for (it = spans.begin(); it != spans.end(); ++it) { Span span = *it; if (spanContainsColumn(column, span.left(), span.width())) return true; } return false;}/*! \internal Returns true if one or more spans intersect row \a row.*/bool QTableViewPrivate::spansIntersectRow(int row) const{ QList<Span>::const_iterator it; for (it = spans.begin(); it != spans.end(); ++it) { Span span = *it; if (spanContainsRow(row, span.top(), span.height())) return true; } return false;}/*! \internal Returns true if one or more spans intersect one or more columns.*/bool QTableViewPrivate::spansIntersectColumns(const QList<int> &columns) const{ QList<int>::const_iterator it; for (it = columns.begin(); it != columns.end(); ++it) { if (spansIntersectColumn(*it)) return true; } return false;}/*! \internal Returns true if one or more spans intersect one or more rows.*/bool QTableViewPrivate::spansIntersectRows(const QList<int> &rows) const{ QList<int>::const_iterator it; for (it = rows.begin(); it != rows.end(); ++it) { if (spansIntersectRow(*it)) return true; } return false;}/*! \internal Returns the visual rect for the given \a span.*/QRect QTableViewPrivate::visualSpanRect(const Span &span) const{ // vertical int row = span.top(); int rowp = verticalHeader->sectionViewportPosition(row); int rowh = rowSpanHeight(row, span.height()); // horizontal int column = span.left(); int colp = horizontalHeader->sectionViewportPosition(column); int colw = columnSpanWidth(column, span.width()); const int i = showGrid ? 1 : 0; 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.*/QBitArray QTableViewPrivate::drawAndClipSpans(const QRect &area, QPainter *painter, const QStyleOptionViewItemV3 &option){ int rowCount = model->rowCount(root); int columnCount = model->columnCount(root); QBitArray cells(rowCount * columnCount); bool alternateBase = false; QRegion region = viewport->rect(); QList<Span>::const_iterator it; for (it = spans.constBegin(); it != spans.constEnd(); ++it) { Span span = *it; for (int r = span.top(); r <= span.bottom(); ++r) { if (r < 0 || r >= rowCount) continue; for (int c = span.left(); c <= span.right(); ++c) { if (c < 0 || c >= columnCount) continue; cells.setBit(r * columnCount + c); } } int row = span.top(); int col = span.left(); if (isHidden(row, col)) continue; QModelIndex index = model->index(row, col, root); if (!index.isValid()) continue; QRect rect = visualSpanRect(span); rect.translate(scrollDelayOffset); if (!rect.intersects(area)) continue; QStyleOptionViewItemV3 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; } painter->setClipRegion(region); return cells;}/*! \internal Draws a table cell.*/void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV3 &option, const QModelIndex &index){ Q_Q(QTableView); QStyleOptionViewItemV3 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -