📄 qtexttable.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 "qtexttable.h"#include "qtextcursor.h"#include "qtextformat.h"#include <qdebug.h>#include "qtexttable_p.h"#include "qvarlengtharray.h"#include <stdlib.h>/*! \class QTextTableCell qtexttable.h \brief The QTextTableCell class represents the properties of a cell in a QTextTable. \ingroup text Table cells are pieces of document structure that belong to a table. The table orders cells into particular rows and columns; cells can also span multiple columns and rows. Cells are usually created when a table is inserted into a document with QTextCursor::insertTable(), but they are also created and destroyed when a table is resized. Cells contain information about their location in a table; you can obtain the row() and column() numbers of a cell, and its rowSpan() and columnSpan(). The format() of a cell describes the default character format of its contents. The firstCursorPosition() and lastCursorPosition() functions are used to obtain the extent of the cell in the document. \sa QTextTable QTextTableFormat*//*! \fn QTextTableCell::QTextTableCell() Constructs an invalid table cell. \sa isValid()*//*! \fn QTextTableCell::QTextTableCell(const QTextTableCell &other) Copy constructor. Creates a new QTextTableCell object based on the \a other cell.*//*! \fn QTextTableCell& QTextTableCell::operator=(const QTextTableCell &other) Assigns the \a other table cell to this table cell.*//*! \since 4.2 Sets the cell's character format to \a format. This can for example be used to change the background color of the entire cell: QTextTableCell cell = table->cellAt(2, 3); QTextCharFormat format = cell.format(); format.setBackground(Qt::blue); cell.setFormat(format); Note that the cell's row or column span cannot be changed through this function. You have to use QTextTable::mergeCells and QTextTable::splitCell instead. \sa format()*/void QTextTableCell::setFormat(const QTextCharFormat &format){ QTextCharFormat fmt = format; fmt.clearProperty(QTextFormat::ObjectIndex); QTextDocumentPrivate *p = table->docHandle(); QTextDocumentPrivate::FragmentIterator frag(&p->fragmentMap(), fragment); QTextFormatCollection *c = p->formatCollection(); QTextCharFormat oldFormat = c->charFormat(frag->format); fmt.setTableCellRowSpan(oldFormat.tableCellRowSpan()); fmt.setTableCellColumnSpan(oldFormat.tableCellColumnSpan()); p->setCharFormat(frag.position(), 1, fmt, QTextDocumentPrivate::SetFormatAndPreserveObjectIndices);}/*! Returns the cell's character format.*/QTextCharFormat QTextTableCell::format() const{ QTextDocumentPrivate *p = table->docHandle(); QTextFormatCollection *c = p->formatCollection(); return c->charFormat(QTextDocumentPrivate::FragmentIterator(&p->fragmentMap(), fragment)->format);}/*! Returns the number of the row in the table that contains this cell. \sa column()*/int QTextTableCell::row() const{ const QTextTablePrivate *tp = table->d_func(); if (tp->dirty) tp->update(); int idx = tp->findCellIndex(fragment); if (idx == -1) return idx; return tp->cellIndices.at(idx) / tp->nCols;}/*! Returns the number of the column in the table that contains this cell. \sa row()*/int QTextTableCell::column() const{ const QTextTablePrivate *tp = table->d_func(); if (tp->dirty) tp->update(); int idx = tp->findCellIndex(fragment); if (idx == -1) return idx; return tp->cellIndices.at(idx) % tp->nCols;}/*! Returns the number of rows this cell spans. The default is 1. \sa columnSpan()*/int QTextTableCell::rowSpan() const{ return format().tableCellRowSpan();}/*! Returns the number of columns this cell spans. The default is 1. \sa rowSpan()*/int QTextTableCell::columnSpan() const{ return format().tableCellColumnSpan();}/*! \fn bool QTextTableCell::isValid() const Returns true if this is a valid table cell; otherwise returns false.*//*! Returns the first valid cursor position in this cell. \sa lastCursorPosition()*/QTextCursor QTextTableCell::firstCursorPosition() const{ return QTextCursor(table->d_func()->pieceTable, firstPosition());}/*! Returns the last valid cursor position in this cell. \sa firstCursorPosition()*/QTextCursor QTextTableCell::lastCursorPosition() const{ return QTextCursor(table->d_func()->pieceTable, lastPosition());}/*! \internal Returns the first valid position in the document occupied by this cell.*/int QTextTableCell::firstPosition() const{ QTextDocumentPrivate *p = table->docHandle(); return p->fragmentMap().position(fragment) + 1;}/*! \internal Returns the last valid position in the document occupied by this cell.*/int QTextTableCell::lastPosition() const{ QTextDocumentPrivate *p = table->docHandle(); const QTextTablePrivate *td = table->d_func(); int index = table->d_func()->findCellIndex(fragment); int f; if (index != -1) f = td->cells.value(index + 1, td->fragment_end); else f = td->fragment_end; return p->fragmentMap().position(f);}/*! Returns a frame iterator pointing to the beginning of the table's cell. \sa end()*/QTextFrame::iterator QTextTableCell::begin() const{ QTextDocumentPrivate *p = table->docHandle(); int b = p->blockMap().findNode(firstPosition()); int e = p->blockMap().findNode(lastPosition()+1); return QTextFrame::iterator(const_cast<QTextTable *>(table), b, b, e);}/*! Returns a frame iterator pointing to the end of the table's cell. \sa begin()*/QTextFrame::iterator QTextTableCell::end() const{ QTextDocumentPrivate *p = table->docHandle(); int b = p->blockMap().findNode(firstPosition()); int e = p->blockMap().findNode(lastPosition()+1); return QTextFrame::iterator(const_cast<QTextTable *>(table), e, b, e);}/*! \fn QTextCursor QTextTableCell::operator==(const QTextTableCell &other) const Returns true if this cell object and the \a other cell object describe the same cell; otherwise returns false.*//*! \fn QTextCursor QTextTableCell::operator!=(const QTextTableCell &other) const Returns true if this cell object and the \a other cell object describe different cells; otherwise returns false.*//*! \fn QTextTableCell::~QTextTableCell() Destroys the table cell.*/QTextTablePrivate::~QTextTablePrivate(){ if (grid) free(grid);}QTextTable *QTextTablePrivate::createTable(QTextDocumentPrivate *pieceTable, int pos, int rows, int cols, const QTextTableFormat &tableFormat){ QTextTableFormat fmt = tableFormat; fmt.setColumns(cols); QTextTable *table = qobject_cast<QTextTable *>(pieceTable->createObject(fmt)); Q_ASSERT(table); pieceTable->beginEditBlock();// qDebug("---> createTable: rows=%d, cols=%d at %d", rows, cols, pos); // add block after table QTextCharFormat charFmt; charFmt.setObjectIndex(table->objectIndex()); int charIdx = pieceTable->formatCollection()->indexForFormat(charFmt); int cellIdx = pieceTable->formatCollection()->indexForFormat(QTextBlockFormat()); QTextTablePrivate *d = table->d_func(); d->blockFragmentUpdates = true; d->fragment_start = pieceTable->insertBlock(QTextBeginningOfFrame, pos, cellIdx, charIdx); d->cells.append(d->fragment_start); ++pos; for (int i = 1; i < rows*cols; ++i) { d->cells.append(pieceTable->insertBlock(QTextBeginningOfFrame, pos, cellIdx, charIdx));// qDebug(" addCell at %d", pos); ++pos; } d->fragment_end = pieceTable->insertBlock(QTextEndOfFrame, pos, cellIdx, charIdx);// qDebug(" addEOR at %d", pos); ++pos; d->blockFragmentUpdates = false; d->dirty = true; pieceTable->endEditBlock(); return table;}struct QFragmentFindHelper{ inline QFragmentFindHelper(int _pos, const QTextDocumentPrivate::FragmentMap &map) : pos(_pos), fragmentMap(map) {} uint pos; const QTextDocumentPrivate::FragmentMap &fragmentMap;};static inline bool operator<(int fragment, const QFragmentFindHelper &helper){ return helper.fragmentMap.position(fragment) < helper.pos;}static inline bool operator<(const QFragmentFindHelper &helper, int fragment){ return helper.pos < helper.fragmentMap.position(fragment);}int QTextTablePrivate::findCellIndex(int fragment) const{ QFragmentFindHelper helper(pieceTable->fragmentMap().position(fragment), pieceTable->fragmentMap()); QList<int>::ConstIterator it = qBinaryFind(cells.begin(), cells.end(), helper); if (it == cells.end()) return -1; return it - cells.begin();}void QTextTablePrivate::fragmentAdded(const QChar &type, uint fragment){ dirty = true; if (blockFragmentUpdates) return; if (type == QTextBeginningOfFrame) { Q_ASSERT(cells.indexOf(fragment) == -1); const uint pos = pieceTable->fragmentMap().position(fragment); QFragmentFindHelper helper(pos, pieceTable->fragmentMap()); QList<int>::Iterator it = qLowerBound(cells.begin(), cells.end(), helper); cells.insert(it, fragment); if (!fragment_start || pos < pieceTable->fragmentMap().position(fragment_start)) fragment_start = fragment; return; } QTextFramePrivate::fragmentAdded(type, fragment);}void QTextTablePrivate::fragmentRemoved(const QChar &type, uint fragment){ dirty = true; if (blockFragmentUpdates) return; if (type == QTextBeginningOfFrame) { Q_ASSERT(cells.indexOf(fragment) != -1); cells.removeAll(fragment); if (fragment_start == fragment && cells.size()) { fragment_start = cells.at(0); } if (fragment_start != fragment) return; } QTextFramePrivate::fragmentRemoved(type, fragment);}void QTextTablePrivate::update() const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -