218 return p->fragmentMap().position(fragment) + 1;
236 return p->fragmentMap().position(
f);
290 fmt.setColumns(cols);
307 d->blockFragmentUpdates =
true;
310 d->cells.append(
d->fragment_start);
313 for (
int i = 1;
i < rows*cols; ++
i) {
323 d->blockFragmentUpdates =
false;
404 nCols =
q->format().columns();
419 int rowspan =
fmt.tableCellRowSpan();
420 int colspan =
fmt.tableCellColumnSpan();
430 if (
r + rowspan >
nRows) {
436 for (
int ii = 0; ii < rowspan; ++ii) {
437 for (
int jj = 0; jj < colspan; ++jj) {
552 if (row < 0 || row >=
d->nRows || col < 0 || col >=
d->nCols)
576 auto it = std::lower_bound(
d->cells.begin(),
d->cells.end(), helper);
577 if (
it !=
d->cells.begin())
608 int nRows = this->
rows();
611 if (rows == nRows && cols == nCols)
614 d->pieceTable->beginEditBlock();
618 else if (nCols > cols)
623 else if (nRows >
rows)
626 d->pieceTable->endEditBlock();
654 int insert_before = 0;
655 if (
pos > 0 && pos < d->nRows) {
657 for (
int i = 0;
i <
d->nCols; ++
i) {
658 int cell =
d->grid[
pos*
d->nCols +
i];
659 if (cell ==
d->grid[(
pos-1)*
d->nCols+
i]) {
661 if (cell != lastCell) {
664 fmt.setTableCellRowSpan(
fmt.tableCellRowSpan() +
num);
665 p->setCharFormat(
it.position(), 1,
fmt);
668 }
else if (!insert_before) {
669 insert_before = cell;
674 insert_before = (
pos == 0 ?
d->grid[0] :
d->fragment_end);
676 if (extended < d->nCols) {
680 fmt.setTableCellRowSpan(1);
681 fmt.setTableCellColumnSpan(1);
683 int pos =
it.position();
684 int cfmt =
p->formatCollection()->indexForFormat(
fmt);
687 for (
int i = 0;
i <
num*(
d->nCols-extended); ++
i)
720 for (
int i = 0;
i <
d->nRows; ++
i) {
722 if (
i ==
d->nRows - 1 &&
pos ==
d->nCols) {
723 cell =
d->fragment_end;
725 int logicalGridIndexBeforePosition =
pos > 0
726 ?
d->findCellIndex(
d->grid[
i*
d->nCols +
pos - 1])
732 int logicalGridIndex;
733 int gridArrayOffset =
i*
d->nCols +
pos;
735 cell =
d->grid[gridArrayOffset];
736 logicalGridIndex =
d->findCellIndex(cell);
738 }
while (logicalGridIndex < logicalGridIndexBeforePosition
739 && gridArrayOffset < d->nRows*
d->nCols);
741 if (logicalGridIndex < logicalGridIndexBeforePosition
742 && gridArrayOffset ==
d->nRows*
d->nCols)
743 cell =
d->fragment_end;
746 if (
pos > 0 && pos < d->nCols && cell ==
d->grid[
i*
d->nCols +
pos - 1]) {
748 if (!extendedSpans.
contains(cell)) {
751 fmt.setTableCellColumnSpan(
fmt.tableCellColumnSpan() +
num);
752 p->setCharFormat(
it.position(), 1,
fmt);
754 extendedSpans << cell;
759 if (
i > 0 && pos < d->nCols && cell ==
d->grid[(
i-1) *
d->nCols +
pos]) {
760 int gridIndex =
i*
d->nCols +
pos;
761 const int gridEnd =
d->nRows *
d->nCols - 1;
762 while (gridIndex < gridEnd && cell == d->grid[gridIndex]) {
765 if (gridIndex == gridEnd)
766 cell =
d->fragment_end;
768 cell =
d->grid[gridIndex];
772 fmt.setTableCellRowSpan(1);
773 fmt.setTableCellColumnSpan(1);
776 int cfmt =
p->formatCollection()->indexForFormat(
fmt);
778 for (
int i = 0;
i <
num; ++
i)
786 if (! columnWidths.
isEmpty()) {
787 for (
int i =
num;
i > 0; --
i)
845 if (
pos == 0 &&
num ==
d->nRows) {
846 const int pos =
p->fragmentMap().position(
d->fragment_start);
847 p->remove(
pos,
p->fragmentMap().position(
d->fragment_end) -
pos + 1);
856 for (
int c = 0;
c <
d->nCols; ++
c) {
857 int cell =
d->grid[
r*
d->nCols +
c];
860 touchedCells << cell;
863 int span =
fmt.tableCellRowSpan();
865 fmt.setTableCellRowSpan(
span - 1);
866 p->setCharFormat(
it.position(), 1,
fmt);
869 int index =
d->cells.indexOf(cell) + 1;
870 int f_end =
index <
d->cells.size() ?
d->cells.at(
index) :
d->fragment_end;
871 p->remove(
it.position(),
p->fragmentMap().position(f_end) -
it.position());
907 if (
pos == 0 &&
num ==
d->nCols) {
908 const int pos =
p->fragmentMap().position(
d->fragment_start);
909 p->remove(
pos,
p->fragmentMap().position(
d->fragment_end) -
pos + 1);
917 for (
int r = 0;
r <
d->nRows; ++
r) {
919 int cell =
d->grid[
r*
d->nCols +
c];
922 int span =
fmt.tableCellColumnSpan();
925 touchedCells << cell;
928 fmt.setTableCellColumnSpan(
span - 1);
929 p->setCharFormat(
it.position(), 1,
fmt);
932 int index =
d->cells.indexOf(cell) + 1;
933 int f_end =
index <
d->cells.size() ?
d->cells.at(
index) :
d->fragment_end;
934 p->remove(
it.position(),
p->fragmentMap().position(f_end) -
it.position());
942 if (columnWidths.
size() >
pos) {
977 const int rowSpan =
fmt.tableCellRowSpan();
978 const int colSpan =
fmt.tableCellColumnSpan();
984 if (numRows < rowSpan || numCols < colSpan)
988 for (
int r =
row;
r <
row + numRows; ++
r) {
1002 p->beginEditBlock();
1006 const int cellFragment =
d->grid[
row *
d->nCols +
column];
1010 const auto begin =
d->cells.cbegin();
1011 const auto it = std::lower_bound(
begin,
d->cells.cend(), helper);
1015 const int insertCellIndex =
it -
begin;
1016 int insertFragment =
d->cells.value(insertCellIndex + 1,
d->fragment_end);
1017 uint insertPos =
p->fragmentMap().position(insertFragment);
1019 d->blockFragmentUpdates =
true;
1022 bool needsParagraph = rowHasText && colSpan == numCols;
1025 for (
int r =
row;
r <
row + numRows; ++
r) {
1029 int firstCellIndex =
r ==
row ? insertCellIndex + 1 : -1;
1030 int cellIndex = firstCellIndex;
1032 for (
int c = firstColumn;
c <
column + numCols; ++
c) {
1033 const int fragment =
d->grid[
r *
d->nCols +
c];
1036 if (fragment == cellFragment)
1042 if (firstCellIndex == -1) {
1044 const auto begin =
d->cells.cbegin();
1045 const auto it = std::lower_bound(
begin,
d->cells.cend(), helper);
1049 firstCellIndex = cellIndex =
it -
begin;
1056 const int cellRowSpan =
fmt.tableCellRowSpan();
1057 const int cellColSpan =
fmt.tableCellColumnSpan();
1060 for (
int i =
r;
i <
r + cellRowSpan; ++
i)
1061 for (
int j =
c;
j <
c + cellColSpan; ++
j)
1062 d->grid[
i *
d->nCols +
j] = cellFragment;
1067 const int nextFragment =
d->cells.value(cellIndex,
d->fragment_end);
1068 const uint nextPos =
p->fragmentMap().position(nextFragment);
1073 if (nextPos >
pos) {
1074 if (needsParagraph) {
1075 needsParagraph =
false;
1077 p->move(
pos + 1, insertPos, nextPos -
pos);
1078 }
else if (rowHasText) {
1080 p->move(
pos + 1, insertPos, nextPos -
pos);
1082 p->move(
pos, insertPos, nextPos -
pos);
1085 insertPos += nextPos -
pos;
1091 needsParagraph =
true;
1096 if (firstCellIndex >= 0) {
1097 d->cellIndices.remove(firstCellIndex, cellIndex - firstCellIndex);
1098 d->cells.erase(
d->cells.begin() + firstCellIndex,
d->cells.begin() + cellIndex);
1102 d->fragment_start =
d->cells.constFirst();
1104 fmt.setTableCellRowSpan(numRows);
1105 fmt.setTableCellColumnSpan(numCols);
1106 p->setCharFormat(origCellPosition, 1,
fmt);
1108 d->blockFragmentUpdates =
false;
1124 if (!
cursor.hasComplexSelection())
1127 int firstRow, numRows, firstColumn, numColumns;
1128 cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);
1129 mergeCells(firstRow, firstColumn, numRows, numColumns);
1160 const int rowSpan =
fmt.tableCellRowSpan();
1161 const int colSpan =
fmt.tableCellColumnSpan();
1164 if (numRows > rowSpan || numCols > colSpan)
1167 p->beginEditBlock();
1175 for (
int r =
row + 1;
r <
row + rowSpan; ++
r) {
1177 int gridIndex =
r *
d->nCols +
column;
1178 const auto begin =
d->cellIndices.cbegin();
1179 const auto it = std::upper_bound(
begin,
d->cellIndices.cend(), gridIndex);
1180 int fragment =
d->cells.value(
it -
begin,
d->fragment_end);
1181 rowPositions[
r -
row] =
p->fragmentMap().position(fragment);
1184 fmt.setTableCellColumnSpan(1);
1185 fmt.setTableCellRowSpan(1);
1186 const int fmtIndex =
c->indexForFormat(
fmt);
1187 const int blockIndex =
p->blockMap().find(cell.
lastPosition())->format;
1189 int insertAdjustement = 0;
1190 for (
int i = 0;
i < numRows; ++
i) {
1191 for (
int c = 0;
c < colSpan - numCols; ++
c)
1193 insertAdjustement += colSpan - numCols;
1196 for (
int i = numRows;
i < rowSpan; ++
i) {
1197 for (
int c = 0;
c < colSpan; ++
c)
1199 insertAdjustement += colSpan;
1202 fmt.setTableCellRowSpan(numRows);
1203 fmt.setTableCellColumnSpan(numCols);
1204 p->setCharFormat(origCellPosition, 1,
fmt);
1273 int row = cell.
row() + 1;
1274 int fragment =
row <
d->nRows ?
d->grid[
row*
d->nCols] :
d->fragment_end;
1305#include "moc_qtexttable.cpp"
uint position(uint node, uint field=0) const
qsizetype size() const noexcept
bool isEmpty() const noexcept
iterator insert(qsizetype i, parameter_type t)
const_reference at(qsizetype i) const noexcept
T value(qsizetype i) const
const_iterator constBegin() const noexcept
void remove(qsizetype i, qsizetype n=1)
qsizetype removeAll(const AT &t)
void resize(qsizetype size)
const_iterator constEnd() const noexcept
int length() const
Returns the length of the block in characters.
int tableCellColumnSpan() const
int tableCellRowSpan() const
static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos)
\reentrant \inmodule QtGui
QTextBlock block() const
Returns the block that contains the cursor.
void insertText(const QString &text)
Inserts text at the current position, using the current character format.
void insertBlock()
Inserts a new empty block at the cursor position() with the current blockFormat() and charFormat().
QTextFormatCollection * formatCollection()
int insertBlock(int pos, int blockFormat, int charFormat, QTextUndoCommand::Operation=QTextUndoCommand::MoveCursor)
const FragmentMap & fragmentMap() const
QTextObject * createObject(const QTextFormat &newFormat, int objectIndex=-1)
static const QTextDocumentPrivate * get(const QTextDocument *document)
FragmentMap::ConstIterator FragmentIterator
@ SetFormatAndPreserveObjectIndices
\reentrant \inmodule QtGui
int indexForFormat(const QTextFormat &f)
QTextCharFormat charFormat(int index) const
void setObjectType(int type)
Sets the text format's object type to type.
void setObjectIndex(int object)
Sets the format object's object index.
virtual void fragmentRemoved(QChar type, uint fragment)
virtual void fragmentAdded(QChar type, uint fragment)
iterator begin() const
Returns an iterator pointing to the first document element inside the frame.
int firstPosition() const
Returns the first document position inside the frame.
QTextDocumentPrivate * pieceTable
int objectIndex() const
Returns the object index of this object.
void setFormat(const QTextFormat &format)
Sets the text object's format.
QTextCharFormat format() const
Returns the cell's character format.
int columnSpan() const
Returns the number of columns this cell spans.
int firstPosition() const
QTextFrame::iterator end() const
Returns a frame iterator pointing to the end of the table's cell.
int row() const
Returns the number of the row in the table that contains this cell.
QTextCursor firstCursorPosition() const
Returns the first valid cursor position in this cell.
int rowSpan() const
Returns the number of rows this cell spans.
void setFormat(const QTextCharFormat &format)
QTextCursor lastCursorPosition() const
Returns the last valid cursor position in this cell.
bool isValid() const
Returns true if this is a valid table cell; otherwise returns false.
int column() const
Returns the number of the column in the table that contains this cell.
int tableCellFormatIndex() const
QTextFrame::iterator begin() const
Returns a frame iterator pointing to the beginning of the table's cell.
QList< QTextLength > columnWidthConstraints() const
Returns a list of constraints used by this table format to control the appearance of columns in a tab...
void setColumnWidthConstraints(const QList< QTextLength > &constraints)
Sets the column width constraints for the table.
int columns() const
Returns the number of columns specified by the table format.
void setColumns(int columns)
static QTextTable * createTable(QTextDocumentPrivate *, int pos, int rows, int cols, const QTextTableFormat &tableFormat)
void fragmentRemoved(QChar type, uint fragment) override
int findCellIndex(int fragment) const
void fragmentAdded(QChar type, uint fragment) override
void update() const
/fn void QTextTablePrivate::update() const
bool blockFragmentUpdates
int columns() const
Returns the number of columns in the table.
void removeRows(int pos, int num)
Removes a number of rows starting with the row at the specified index.
QTextTableFormat format() const
Returns the table's format.
QTextCursor rowStart(const QTextCursor &c) const
Returns a cursor pointing to the start of the row that contains the given cursor.
friend class QTextTableCell
void appendRows(int count)
void removeColumns(int pos, int num)
Removes a number of columns starting with the column at the specified index.
void insertRows(int pos, int num)
Inserts a number of rows before the row with the specified index.
void splitCell(int row, int col, int numRows, int numCols)
QTextTable(QTextDocument *doc)
void appendColumns(int count)
QTextCursor rowEnd(const QTextCursor &c) const
Returns a cursor pointing to the end of the row that contains the given cursor.
void setFormat(const QTextTableFormat &format)
Sets the table's format.
int rows() const
Returns the number of rows in the table.
void insertColumns(int pos, int num)
Inserts a number of columns before the column with the specified index.
QTextTableCell cellAt(int row, int col) const
Returns the table cell at the given row and column in the table.
void mergeCells(int row, int col, int numRows, int numCols)
void resize(int rows, int cols)
Resizes the table to contain the required number of rows and columns.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum format
GLenum GLenum GLsizei void GLsizei void * column
GLdouble GLdouble GLdouble GLdouble q
GLenum GLenum GLsizei void * row
GLenum GLenum GLsizei void GLsizei void void * span
GLenum GLenum GLsizei void * table
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define QTextBeginningOfFrame
static bool operator<(int fragment, const QFragmentFindHelper &helper)
QVideoFrameFormat::PixelFormat fmt
QFragmentFindHelper(int _pos, const QTextDocumentPrivate::FragmentMap &map)
const QTextDocumentPrivate::FragmentMap & fragmentMap
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
bool contains(const AT &t) const noexcept