qtexttable.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qtexttable.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qtexttable.h"-
35#include "qtextcursor.h"-
36#include "qtextformat.h"-
37#include <qdebug.h>-
38#include "qtextcursor_p.h"-
39#include "qtexttable_p.h"-
40#include "qvarlengtharray.h"-
41-
42#include <algorithm>-
43#include <stdlib.h>-
44-
45QT_BEGIN_NAMESPACE-
46-
47/*!-
48 \class QTextTableCell-
49 \reentrant-
50-
51 \brief The QTextTableCell class represents the properties of a-
52 cell in a QTextTable.-
53 \inmodule QtGui-
54-
55 \ingroup richtext-processing-
56-
57 Table cells are pieces of document structure that belong to a table.-
58 The table orders cells into particular rows and columns; cells can-
59 also span multiple columns and rows.-
60-
61 Cells are usually created when a table is inserted into a document with-
62 QTextCursor::insertTable(), but they are also created and destroyed when-
63 a table is resized.-
64-
65 Cells contain information about their location in a table; you can-
66 obtain the row() and column() numbers of a cell, and its rowSpan()-
67 and columnSpan().-
68-
69 The format() of a cell describes the default character format of its-
70 contents. The firstCursorPosition() and lastCursorPosition() functions-
71 are used to obtain the extent of the cell in the document.-
72-
73 \sa QTextTable, QTextTableFormat-
74*/-
75-
76/*!-
77 \fn QTextTableCell::QTextTableCell()-
78-
79 Constructs an invalid table cell.-
80-
81 \sa isValid()-
82*/-
83-
84/*!-
85 \fn QTextTableCell::QTextTableCell(const QTextTableCell &other)-
86-
87 Copy constructor. Creates a new QTextTableCell object based on the-
88 \a other cell.-
89*/-
90-
91/*!-
92 \fn QTextTableCell& QTextTableCell::operator=(const QTextTableCell &other)-
93-
94 Assigns the \a other table cell to this table cell.-
95*/-
96-
97/*!-
98 \since 4.2-
99-
100 Sets the cell's character format to \a format. This can for example be used to change-
101 the background color of the entire cell:-
102-
103 QTextTableCell cell = table->cellAt(2, 3);-
104 QTextCharFormat format = cell.format();-
105 format.setBackground(Qt::blue);-
106 cell.setFormat(format);-
107-
108 Note that the cell's row or column span cannot be changed through this function. You have-
109 to use QTextTable::mergeCells and QTextTable::splitCell instead.-
110-
111 \sa format()-
112*/-
113void QTextTableCell::setFormat(const QTextCharFormat &format)-
114{-
115 QTextCharFormat fmt = format;-
116 fmt.clearProperty(QTextFormat::ObjectIndex);-
117 fmt.setObjectType(QTextFormat::TableCellObject);-
118 QTextDocumentPrivate *p = table->docHandle();-
119 QTextDocumentPrivate::FragmentIterator frag(&p->fragmentMap(), fragment);-
120-
121 QTextFormatCollection *c = p->formatCollection();-
122 QTextCharFormat oldFormat = c->charFormat(frag->format);-
123 fmt.setTableCellRowSpan(oldFormat.tableCellRowSpan());-
124 fmt.setTableCellColumnSpan(oldFormat.tableCellColumnSpan());-
125-
126 p->setCharFormat(frag.position(), 1, fmt, QTextDocumentPrivate::SetFormatAndPreserveObjectIndices);-
127}
never executed: end of block
0
128-
129/*!-
130 Returns the cell's character format.-
131*/-
132QTextCharFormat QTextTableCell::format() const-
133{-
134 QTextDocumentPrivate *p = table->docHandle();-
135 QTextFormatCollection *c = p->formatCollection();-
136-
137 QTextCharFormat fmt = c->charFormat(tableCellFormatIndex());-
138 fmt.setObjectType(QTextFormat::TableCellObject);-
139 return fmt;
never executed: return fmt;
0
140}-
141-
142/*!-
143 \since 4.5-
144-
145 Returns the index of the tableCell's format in the document's internal list of formats.-
146-
147 \sa QTextDocument::allFormats()-
148*/-
149int QTextTableCell::tableCellFormatIndex() const-
150{-
151 QTextDocumentPrivate *p = table->docHandle();-
152 return QTextDocumentPrivate::FragmentIterator(&p->fragmentMap(), fragment)->format;
never executed: return QTextDocumentPrivate::FragmentIterator(&p->fragmentMap(), fragment)->format;
0
153}-
154-
155/*!-
156 Returns the number of the row in the table that contains this cell.-
157-
158 \sa column()-
159*/-
160int QTextTableCell::row() const-
161{-
162 const QTextTablePrivate *tp = table->d_func();-
163 if (tp->dirty)
tp->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
164 tp->update();
never executed: tp->update();
0
165-
166 int idx = tp->findCellIndex(fragment);-
167 if (idx == -1)
idx == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
168 return idx;
never executed: return idx;
0
169 return tp->cellIndices.at(idx) / tp->nCols;
never executed: return tp->cellIndices.at(idx) / tp->nCols;
0
170}-
171-
172/*!-
173 Returns the number of the column in the table that contains this cell.-
174-
175 \sa row()-
176*/-
177int QTextTableCell::column() const-
178{-
179 const QTextTablePrivate *tp = table->d_func();-
180 if (tp->dirty)
tp->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
181 tp->update();
never executed: tp->update();
0
182-
183 int idx = tp->findCellIndex(fragment);-
184 if (idx == -1)
idx == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
185 return idx;
never executed: return idx;
0
186 return tp->cellIndices.at(idx) % tp->nCols;
never executed: return tp->cellIndices.at(idx) % tp->nCols;
0
187}-
188-
189/*!-
190 Returns the number of rows this cell spans. The default is 1.-
191-
192 \sa columnSpan()-
193*/-
194int QTextTableCell::rowSpan() const-
195{-
196 return format().tableCellRowSpan();
never executed: return format().tableCellRowSpan();
0
197}-
198-
199/*!-
200 Returns the number of columns this cell spans. The default is 1.-
201-
202 \sa rowSpan()-
203*/-
204int QTextTableCell::columnSpan() const-
205{-
206 return format().tableCellColumnSpan();
never executed: return format().tableCellColumnSpan();
0
207}-
208-
209/*!-
210 \fn bool QTextTableCell::isValid() const-
211-
212 Returns \c true if this is a valid table cell; otherwise returns-
213 false.-
214*/-
215-
216-
217/*!-
218 Returns the first valid cursor position in this cell.-
219-
220 \sa lastCursorPosition()-
221*/-
222QTextCursor QTextTableCell::firstCursorPosition() const-
223{-
224 return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, firstPosition());
never executed: return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, firstPosition());
0
225}-
226-
227/*!-
228 Returns the last valid cursor position in this cell.-
229-
230 \sa firstCursorPosition()-
231*/-
232QTextCursor QTextTableCell::lastCursorPosition() const-
233{-
234 return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, lastPosition());
never executed: return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, lastPosition());
0
235}-
236-
237-
238/*!-
239 \internal-
240-
241 Returns the first valid position in the document occupied by this cell.-
242*/-
243int QTextTableCell::firstPosition() const-
244{-
245 QTextDocumentPrivate *p = table->docHandle();-
246 return p->fragmentMap().position(fragment) + 1;
never executed: return p->fragmentMap().position(fragment) + 1;
0
247}-
248-
249/*!-
250 \internal-
251-
252 Returns the last valid position in the document occupied by this cell.-
253*/-
254int QTextTableCell::lastPosition() const-
255{-
256 QTextDocumentPrivate *p = table->docHandle();-
257 const QTextTablePrivate *td = table->d_func();-
258 int index = table->d_func()->findCellIndex(fragment);-
259 int f;-
260 if (index != -1)
index != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
261 f = td->cells.value(index + 1, td->fragment_end);
never executed: f = td->cells.value(index + 1, td->fragment_end);
0
262 else-
263 f = td->fragment_end;
never executed: f = td->fragment_end;
0
264 return p->fragmentMap().position(f);
never executed: return p->fragmentMap().position(f);
0
265}-
266-
267-
268/*!-
269 Returns a frame iterator pointing to the beginning of the table's cell.-
270-
271 \sa end()-
272*/-
273QTextFrame::iterator QTextTableCell::begin() const-
274{-
275 QTextDocumentPrivate *p = table->docHandle();-
276 int b = p->blockMap().findNode(firstPosition());-
277 int e = p->blockMap().findNode(lastPosition()+1);-
278 return QTextFrame::iterator(const_cast<QTextTable *>(table), b, b, e);
never executed: return QTextFrame::iterator(const_cast<QTextTable *>(table), b, b, e);
0
279}-
280-
281/*!-
282 Returns a frame iterator pointing to the end of the table's cell.-
283-
284 \sa begin()-
285*/-
286QTextFrame::iterator QTextTableCell::end() const-
287{-
288 QTextDocumentPrivate *p = table->docHandle();-
289 int b = p->blockMap().findNode(firstPosition());-
290 int e = p->blockMap().findNode(lastPosition()+1);-
291 return QTextFrame::iterator(const_cast<QTextTable *>(table), e, b, e);
never executed: return QTextFrame::iterator(const_cast<QTextTable *>(table), e, b, e);
0
292}-
293-
294-
295/*!-
296 \fn QTextCursor QTextTableCell::operator==(const QTextTableCell &other) const-
297-
298 Returns \c true if this cell object and the \a other cell object-
299 describe the same cell; otherwise returns \c false.-
300*/-
301-
302/*!-
303 \fn QTextCursor QTextTableCell::operator!=(const QTextTableCell &other) const-
304-
305 Returns \c true if this cell object and the \a other cell object-
306 describe different cells; otherwise returns \c false.-
307*/-
308-
309/*!-
310 \fn QTextTableCell::~QTextTableCell()-
311-
312 Destroys the table cell.-
313*/-
314-
315QTextTablePrivate::~QTextTablePrivate()-
316{-
317 if (grid)
gridDescription
TRUEnever evaluated
FALSEnever evaluated
0
318 free(grid);
never executed: free(grid);
0
319}
never executed: end of block
0
320-
321-
322QTextTable *QTextTablePrivate::createTable(QTextDocumentPrivate *pieceTable, int pos, int rows, int cols, const QTextTableFormat &tableFormat)-
323{-
324 QTextTableFormat fmt = tableFormat;-
325 fmt.setColumns(cols);-
326 QTextTable *table = qobject_cast<QTextTable *>(pieceTable->createObject(fmt));-
327 Q_ASSERT(table);-
328-
329 pieceTable->beginEditBlock();-
330-
331// qDebug("---> createTable: rows=%d, cols=%d at %d", rows, cols, pos);-
332 // add block after table-
333 QTextCharFormat charFmt;-
334 charFmt.setObjectIndex(table->objectIndex());-
335 charFmt.setObjectType(QTextFormat::TableCellObject);-
336-
337-
338 int charIdx = pieceTable->formatCollection()->indexForFormat(charFmt);-
339 int cellIdx = pieceTable->formatCollection()->indexForFormat(QTextBlockFormat());-
340-
341 QTextTablePrivate *d = table->d_func();-
342 d->blockFragmentUpdates = true;-
343-
344 d->fragment_start = pieceTable->insertBlock(QTextBeginningOfFrame, pos, cellIdx, charIdx);-
345 d->cells.append(d->fragment_start);-
346 ++pos;-
347-
348 for (int i = 1; i < rows*cols; ++i) {
i < rows*colsDescription
TRUEnever evaluated
FALSEnever evaluated
0
349 d->cells.append(pieceTable->insertBlock(QTextBeginningOfFrame, pos, cellIdx, charIdx));-
350// qDebug(" addCell at %d", pos);-
351 ++pos;-
352 }
never executed: end of block
0
353-
354 d->fragment_end = pieceTable->insertBlock(QTextEndOfFrame, pos, cellIdx, charIdx);-
355// qDebug(" addEOR at %d", pos);-
356 ++pos;-
357-
358 d->blockFragmentUpdates = false;-
359 d->dirty = true;-
360-
361 pieceTable->endEditBlock();-
362-
363 return table;
never executed: return table;
0
364}-
365-
366struct QFragmentFindHelper-
367{-
368 inline QFragmentFindHelper(int _pos, const QTextDocumentPrivate::FragmentMap &map)-
369 : pos(_pos), fragmentMap(map) {}
never executed: end of block
0
370 uint pos;-
371 const QTextDocumentPrivate::FragmentMap &fragmentMap;-
372};-
373-
374static inline bool operator<(int fragment, const QFragmentFindHelper &helper)-
375{-
376 return helper.fragmentMap.position(fragment) < helper.pos;
never executed: return helper.fragmentMap.position(fragment) < helper.pos;
0
377}-
378-
379static inline bool operator<(const QFragmentFindHelper &helper, int fragment)-
380{-
381 return helper.pos < helper.fragmentMap.position(fragment);
never executed: return helper.pos < helper.fragmentMap.position(fragment);
0
382}-
383-
384int QTextTablePrivate::findCellIndex(int fragment) const-
385{-
386 QFragmentFindHelper helper(pieceTable->fragmentMap().position(fragment),-
387 pieceTable->fragmentMap());-
388 QList<int>::ConstIterator it = std::lower_bound(cells.constBegin(), cells.constEnd(), helper);-
389 if ((it == cells.constEnd()) || (helper < *it))
(it == cells.constEnd())Description
TRUEnever evaluated
FALSEnever evaluated
(helper < *it)Description
TRUEnever evaluated
FALSEnever evaluated
0
390 return -1;
never executed: return -1;
0
391 return it - cells.constBegin();
never executed: return it - cells.constBegin();
0
392}-
393-
394void QTextTablePrivate::fragmentAdded(QChar type, uint fragment)-
395{-
396 dirty = true;-
397 if (blockFragmentUpdates)
blockFragmentUpdatesDescription
TRUEnever evaluated
FALSEnever evaluated
0
398 return;
never executed: return;
0
399 if (type == QTextBeginningOfFrame) {
type == QChar(0xfdd0)Description
TRUEnever evaluated
FALSEnever evaluated
0
400 Q_ASSERT(cells.indexOf(fragment) == -1);-
401 const uint pos = pieceTable->fragmentMap().position(fragment);-
402 QFragmentFindHelper helper(pos, pieceTable->fragmentMap());-
403 QList<int>::Iterator it = std::lower_bound(cells.begin(), cells.end(), helper);-
404 cells.insert(it, fragment);-
405 if (!fragment_start || pos < pieceTable->fragmentMap().position(fragment_start))
!fragment_startDescription
TRUEnever evaluated
FALSEnever evaluated
pos < pieceTab...ragment_start)Description
TRUEnever evaluated
FALSEnever evaluated
0
406 fragment_start = fragment;
never executed: fragment_start = fragment;
0
407 return;
never executed: return;
0
408 }-
409 QTextFramePrivate::fragmentAdded(type, fragment);-
410}
never executed: end of block
0
411-
412void QTextTablePrivate::fragmentRemoved(QChar type, uint fragment)-
413{-
414 dirty = true;-
415 if (blockFragmentUpdates)
blockFragmentUpdatesDescription
TRUEnever evaluated
FALSEnever evaluated
0
416 return;
never executed: return;
0
417 if (type == QTextBeginningOfFrame) {
type == QChar(0xfdd0)Description
TRUEnever evaluated
FALSEnever evaluated
0
418 Q_ASSERT(cells.indexOf(fragment) != -1);-
419 cells.removeAll(fragment);-
420 if (fragment_start == fragment && cells.size()) {
fragment_start == fragmentDescription
TRUEnever evaluated
FALSEnever evaluated
cells.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
421 fragment_start = cells.at(0);-
422 }
never executed: end of block
0
423 if (fragment_start != fragment)
fragment_start != fragmentDescription
TRUEnever evaluated
FALSEnever evaluated
0
424 return;
never executed: return;
0
425 }
never executed: end of block
0
426 QTextFramePrivate::fragmentRemoved(type, fragment);-
427}
never executed: end of block
0
428-
429/*!-
430 /fn void QTextTablePrivate::update() const-
431-
432 This function is usually called when the table is "dirty".-
433 It seems to update all kind of table information.-
434-
435*/-
436void QTextTablePrivate::update() const-
437{-
438 Q_Q(const QTextTable);-
439 nCols = q->format().columns();-
440 nRows = (cells.size() + nCols-1)/nCols;-
441// qDebug(">>>> QTextTablePrivate::update, nRows=%d, nCols=%d", nRows, nCols);-
442-
443 grid = q_check_ptr((int *)realloc(grid, nRows*nCols*sizeof(int)));-
444 memset(grid, 0, nRows*nCols*sizeof(int));-
445-
446 QTextDocumentPrivate *p = pieceTable;-
447 QTextFormatCollection *c = p->formatCollection();-
448-
449 cellIndices.resize(cells.size());-
450-
451 int cell = 0;-
452 for (int i = 0; i < cells.size(); ++i) {
i < cells.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
453 int fragment = cells.at(i);-
454 QTextCharFormat fmt = c->charFormat(QTextDocumentPrivate::FragmentIterator(&p->fragmentMap(), fragment)->format);-
455 int rowspan = fmt.tableCellRowSpan();-
456 int colspan = fmt.tableCellColumnSpan();-
457-
458 // skip taken cells-
459 while (cell < nRows*nCols && grid[cell])
cell < nRows*nColsDescription
TRUEnever evaluated
FALSEnever evaluated
grid[cell]Description
TRUEnever evaluated
FALSEnever evaluated
0
460 ++cell;
never executed: ++cell;
0
461-
462 int r = cell/nCols;-
463 int c = cell%nCols;-
464 cellIndices[i] = cell;-
465-
466 if (r + rowspan > nRows) {
r + rowspan > nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
467 grid = q_check_ptr((int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols));-
468 memset(grid + (nRows*nCols), 0, sizeof(int)*(r+rowspan-nRows)*nCols);-
469 nRows = r + rowspan;-
470 }
never executed: end of block
0
471-
472 Q_ASSERT(c + colspan <= nCols);-
473 for (int ii = 0; ii < rowspan; ++ii) {
ii < rowspanDescription
TRUEnever evaluated
FALSEnever evaluated
0
474 for (int jj = 0; jj < colspan; ++jj) {
jj < colspanDescription
TRUEnever evaluated
FALSEnever evaluated
0
475 Q_ASSERT(grid[(r+ii)*nCols + c+jj] == 0);-
476 grid[(r+ii)*nCols + c+jj] = fragment;-
477// qDebug(" setting cell %d span=%d/%d at %d/%d", fragment, rowspan, colspan, r+ii, c+jj);-
478 }
never executed: end of block
0
479 }
never executed: end of block
0
480 }
never executed: end of block
0
481// qDebug("<<<< end: nRows=%d, nCols=%d", nRows, nCols);-
482-
483 dirty = false;-
484}
never executed: end of block
0
485-
486-
487-
488-
489-
490/*!-
491 \class QTextTable-
492 \reentrant-
493-
494 \brief The QTextTable class represents a table in a QTextDocument.-
495 \inmodule QtGui-
496-
497 \ingroup richtext-processing-
498-
499 A table is a group of cells ordered into rows and columns. Each table-
500 contains at least one row and one column. Each cell contains a block, and-
501 is surrounded by a frame.-
502-
503 Tables are usually created and inserted into a document with the-
504 QTextCursor::insertTable() function.-
505 For example, we can insert a table with three rows and two columns at the-
506 current cursor position in an editor using the following lines of code:-
507-
508 \snippet textdocument-tables/mainwindow.cpp 1-
509 \codeline-
510 \snippet textdocument-tables/mainwindow.cpp 3-
511-
512 The table format is either defined when the table is created or changed-
513 later with setFormat().-
514-
515 The table currently being edited by the cursor is found with-
516 QTextCursor::currentTable(). This allows its format or dimensions to be-
517 changed after it has been inserted into a document.-
518-
519 A table's size can be changed with resize(), or by using-
520 insertRows(), insertColumns(), removeRows(), or removeColumns().-
521 Use cellAt() to retrieve table cells.-
522-
523 The starting and ending positions of table rows can be found by moving-
524 a cursor within a table, and using the rowStart() and rowEnd() functions-
525 to obtain cursors at the start and end of each row.-
526-
527 Rows and columns within a QTextTable can be merged and split using-
528 the mergeCells() and splitCell() functions. However, only cells that span multiple-
529 rows or columns can be split. (Merging or splitting does not increase or decrease-
530 the number of rows and columns.)-
531-
532 Note that if you have merged multiple columns and rows into one cell, you will not-
533 be able to split the merged cell into new cells spanning over more than one row-
534 or column. To be able to split cells spanning over several rows and columns you-
535 need to do this over several iterations.-
536-
537 \table 80%-
538 \row-
539 \li \inlineimage texttable-split.png Original Table-
540 \li Suppose we have a 2x3 table of names and addresses. To merge both-
541 columns in the first row we invoke mergeCells() with \a row = 0,-
542 \a column = 0, \a numRows = 1 and \a numColumns = 2.-
543 \snippet textdocument-texttable/main.cpp 0-
544-
545 \row-
546 \li \inlineimage texttable-merge.png-
547 \li This gives us the following table. To split the first row of the table-
548 back into two cells, we invoke the splitCell() function with \a numRows-
549 and \a numCols = 1.-
550 \snippet textdocument-texttable/main.cpp 1-
551-
552 \row-
553 \li \inlineimage texttable-split.png Split Table-
554 \li This results in the original table.-
555 \endtable-
556-
557 \sa QTextTableFormat-
558*/-
559-
560/*! \internal-
561 */-
562QTextTable::QTextTable(QTextDocument *doc)-
563 : QTextFrame(*new QTextTablePrivate(doc), doc)-
564{-
565}
never executed: end of block
0
566-
567/*! \internal-
568-
569Destroys the table.-
570 */-
571QTextTable::~QTextTable()-
572{-
573}-
574-
575-
576/*!-
577 \fn QTextTableCell QTextTable::cellAt(int row, int column) const-
578-
579 Returns the table cell at the given \a row and \a column in the table.-
580-
581 \sa columns(), rows()-
582*/-
583QTextTableCell QTextTable::cellAt(int row, int col) const-
584{-
585 Q_D(const QTextTable);-
586 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
587 d->update();
never executed: d->update();
0
588-
589 if (row < 0 || row >= d->nRows || col < 0 || col >= d->nCols)
row < 0Description
TRUEnever evaluated
FALSEnever evaluated
row >= d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
col < 0Description
TRUEnever evaluated
FALSEnever evaluated
col >= d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
590 return QTextTableCell();
never executed: return QTextTableCell();
0
591-
592 return QTextTableCell(this, d->grid[row*d->nCols + col]);
never executed: return QTextTableCell(this, d->grid[row*d->nCols + col]);
0
593}-
594-
595/*!-
596 \overload-
597-
598 Returns the table cell that contains the character at the given \a position-
599 in the document.-
600*/-
601QTextTableCell QTextTable::cellAt(int position) const-
602{-
603 Q_D(const QTextTable);-
604 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
605 d->update();
never executed: d->update();
0
606-
607 uint pos = (uint)position;-
608 const QTextDocumentPrivate::FragmentMap &map = d->pieceTable->fragmentMap();-
609 if (position < 0 || map.position(d->fragment_start) >= pos || map.position(d->fragment_end) < pos)
position < 0Description
TRUEnever evaluated
FALSEnever evaluated
map.position(d..._start) >= posDescription
TRUEnever evaluated
FALSEnever evaluated
map.position(d...ent_end) < posDescription
TRUEnever evaluated
FALSEnever evaluated
0
610 return QTextTableCell();
never executed: return QTextTableCell();
0
611-
612 QFragmentFindHelper helper(position, map);-
613 QList<int>::ConstIterator it = std::lower_bound(d->cells.begin(), d->cells.end(), helper);-
614 if (it != d->cells.begin())
it != d->cells.begin()Description
TRUEnever evaluated
FALSEnever evaluated
0
615 --it;
never executed: --it;
0
616-
617 return QTextTableCell(this, *it);
never executed: return QTextTableCell(this, *it);
0
618}-
619-
620/*!-
621 \fn QTextTableCell QTextTable::cellAt(const QTextCursor &cursor) const-
622-
623 \overload-
624-
625 Returns the table cell containing the given \a cursor.-
626*/-
627QTextTableCell QTextTable::cellAt(const QTextCursor &c) const-
628{-
629 return cellAt(c.position());
never executed: return cellAt(c.position());
0
630}-
631-
632/*!-
633 \fn void QTextTable::resize(int rows, int columns)-
634-
635 Resizes the table to contain the required number of \a rows and \a columns.-
636-
637 \sa insertRows(), insertColumns(), removeRows(), removeColumns()-
638*/-
639void QTextTable::resize(int rows, int cols)-
640{-
641 Q_D(QTextTable);-
642 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
643 d->update();
never executed: d->update();
0
644-
645 int nRows = this->rows();-
646 int nCols = this->columns();-
647-
648 if (rows == nRows && cols == nCols)
rows == nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
cols == nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
649 return;
never executed: return;
0
650-
651 d->pieceTable->beginEditBlock();-
652-
653 if (nCols < cols)
nCols < colsDescription
TRUEnever evaluated
FALSEnever evaluated
0
654 insertColumns(nCols, cols - nCols);
never executed: insertColumns(nCols, cols - nCols);
0
655 else if (nCols > cols)
nCols > colsDescription
TRUEnever evaluated
FALSEnever evaluated
0
656 removeColumns(cols, nCols - cols);
never executed: removeColumns(cols, nCols - cols);
0
657-
658 if (nRows < rows)
nRows < rowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
659 insertRows(nRows, rows-nRows);
never executed: insertRows(nRows, rows-nRows);
0
660 else if (nRows > rows)
nRows > rowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
661 removeRows(rows, nRows-rows);
never executed: removeRows(rows, nRows-rows);
0
662-
663 d->pieceTable->endEditBlock();-
664}
never executed: end of block
0
665-
666/*!-
667 \fn void QTextTable::insertRows(int index, int rows)-
668-
669 Inserts a number of \a rows before the row with the specified \a index.-
670-
671 \sa resize(), insertColumns(), removeRows(), removeColumns(), appendRows(), appendColumns()-
672*/-
673void QTextTable::insertRows(int pos, int num)-
674{-
675 Q_D(QTextTable);-
676 if (num <= 0)
num <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
677 return;
never executed: return;
0
678-
679 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
680 d->update();
never executed: d->update();
0
681-
682 if (pos > d->nRows || pos < 0)
pos > d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
pos < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
683 pos = d->nRows;
never executed: pos = d->nRows;
0
684-
685// qDebug() << "-------- insertRows" << pos << num;-
686 QTextDocumentPrivate *p = d->pieceTable;-
687 QTextFormatCollection *c = p->formatCollection();-
688 p->beginEditBlock();-
689-
690 int extended = 0;-
691 int insert_before = 0;-
692 if (pos > 0 && pos < d->nRows) {
pos > 0Description
TRUEnever evaluated
FALSEnever evaluated
pos < d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
693 for (int i = 0; i < d->nCols; ++i) {
i < d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
694 int cell = d->grid[pos*d->nCols + i];-
695 if (cell == d->grid[(pos-1)*d->nCols+i]) {
cell == d->gri...1)*d->nCols+i]Description
TRUEnever evaluated
FALSEnever evaluated
0
696 // cell spans the insertion place, extend it-
697 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);-
698 QTextCharFormat fmt = c->charFormat(it->format);-
699 fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num);-
700 p->setCharFormat(it.position(), 1, fmt);-
701 extended++;-
702 } else if (!insert_before) {
never executed: end of block
!insert_beforeDescription
TRUEnever evaluated
FALSEnever evaluated
0
703 insert_before = cell;-
704 }
never executed: end of block
0
705 }
never executed: end of block
0
706 } else {
never executed: end of block
0
707 insert_before = (pos == 0 ? d->grid[0] : d->fragment_end);
pos == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
708 }
never executed: end of block
0
709 if (extended < d->nCols) {
extended < d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
710 Q_ASSERT(insert_before);-
711 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), insert_before);-
712 QTextCharFormat fmt = c->charFormat(it->format);-
713 fmt.setTableCellRowSpan(1);-
714 fmt.setTableCellColumnSpan(1);-
715 Q_ASSERT(fmt.objectIndex() == objectIndex());-
716 int pos = it.position();-
717 int cfmt = p->formatCollection()->indexForFormat(fmt);-
718 int bfmt = p->formatCollection()->indexForFormat(QTextBlockFormat());-
719// qDebug("inserting %d cells, nCols=%d extended=%d", num*(d->nCols-extended), d->nCols, extended);-
720 for (int i = 0; i < num*(d->nCols-extended); ++i)
i < num*(d->nCols-extended)Description
TRUEnever evaluated
FALSEnever evaluated
0
721 p->insertBlock(QTextBeginningOfFrame, pos, bfmt, cfmt, QTextUndoCommand::MoveCursor);
never executed: p->insertBlock(QChar(0xfdd0), pos, bfmt, cfmt, QTextUndoCommand::MoveCursor);
0
722 }
never executed: end of block
0
723-
724// qDebug() << "-------- end insertRows" << pos << num;-
725 p->endEditBlock();-
726}
never executed: end of block
0
727-
728/*!-
729 \fn void QTextTable::insertColumns(int index, int columns)-
730-
731 Inserts a number of \a columns before the column with the specified \a index.-
732-
733 \sa insertRows(), resize(), removeRows(), removeColumns(), appendRows(), appendColumns()-
734*/-
735void QTextTable::insertColumns(int pos, int num)-
736{-
737 Q_D(QTextTable);-
738 if (num <= 0)
num <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
739 return;
never executed: return;
0
740-
741 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
742 d->update();
never executed: d->update();
0
743-
744 if (pos > d->nCols || pos < 0)
pos > d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
pos < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
745 pos = d->nCols;
never executed: pos = d->nCols;
0
746-
747// qDebug() << "-------- insertCols" << pos << num;-
748 QTextDocumentPrivate *p = d->pieceTable;-
749 QTextFormatCollection *c = p->formatCollection();-
750 p->beginEditBlock();-
751-
752 QList<int> extendedSpans;-
753 for (int i = 0; i < d->nRows; ++i) {
i < d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
754 int cell;-
755 if (i == d->nRows - 1 && pos == d->nCols) {
i == d->nRows - 1Description
TRUEnever evaluated
FALSEnever evaluated
pos == d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
756 cell = d->fragment_end;-
757 } else {
never executed: end of block
0
758 int logicalGridIndexBeforePosition = pos > 0
pos > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
759 ? d->findCellIndex(d->grid[i*d->nCols + pos - 1])-
760 : -1;-
761-
762 // Search for the logical insertion point by skipping past cells which are not the first-
763 // cell in a rowspan. This means any cell for which the logical grid index is-
764 // less than the logical cell index of the cell before the insertion.-
765 int logicalGridIndex;-
766 int gridArrayOffset = i*d->nCols + pos;-
767 do {-
768 cell = d->grid[gridArrayOffset];-
769 logicalGridIndex = d->findCellIndex(cell);-
770 gridArrayOffset++;-
771 } while (logicalGridIndex < logicalGridIndexBeforePosition
never executed: end of block
logicalGridInd...BeforePositionDescription
TRUEnever evaluated
FALSEnever evaluated
0
772 && gridArrayOffset < d->nRows*d->nCols);
gridArrayOffse...nRows*d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
773-
774 if (logicalGridIndex < logicalGridIndexBeforePosition
logicalGridInd...BeforePositionDescription
TRUEnever evaluated
FALSEnever evaluated
0
775 && gridArrayOffset == d->nRows*d->nCols)
gridArrayOffse...nRows*d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
776 cell = d->fragment_end;
never executed: cell = d->fragment_end;
0
777 }
never executed: end of block
0
778-
779 if (pos > 0 && pos < d->nCols && cell == d->grid[i*d->nCols + pos - 1]) {
pos > 0Description
TRUEnever evaluated
FALSEnever evaluated
pos < d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
cell == d->gri...ols + pos - 1]Description
TRUEnever evaluated
FALSEnever evaluated
0
780 // cell spans the insertion place, extend it-
781 if (!extendedSpans.contains(cell)) {
!extendedSpans.contains(cell)Description
TRUEnever evaluated
FALSEnever evaluated
0
782 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);-
783 QTextCharFormat fmt = c->charFormat(it->format);-
784 fmt.setTableCellColumnSpan(fmt.tableCellColumnSpan() + num);-
785 p->setCharFormat(it.position(), 1, fmt);-
786 d->dirty = true;-
787 extendedSpans << cell;-
788 }
never executed: end of block
0
789 } else {
never executed: end of block
0
790 /* If the next cell is spanned from the row above, we need to find the right position-
791 to insert to */-
792 if (i > 0 && pos < d->nCols && cell == d->grid[(i-1) * d->nCols + pos]) {
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
pos < d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
cell == d->gri...->nCols + pos]Description
TRUEnever evaluated
FALSEnever evaluated
0
793 int gridIndex = i*d->nCols + pos;-
794 const int gridEnd = d->nRows * d->nCols - 1;-
795 while (gridIndex < gridEnd && cell == d->grid[gridIndex]) {
gridIndex < gridEndDescription
TRUEnever evaluated
FALSEnever evaluated
cell == d->grid[gridIndex]Description
TRUEnever evaluated
FALSEnever evaluated
0
796 ++gridIndex;-
797 }
never executed: end of block
0
798 if (gridIndex == gridEnd)
gridIndex == gridEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
799 cell = d->fragment_end;
never executed: cell = d->fragment_end;
0
800 else-
801 cell = d->grid[gridIndex];
never executed: cell = d->grid[gridIndex];
0
802 }-
803 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);-
804 QTextCharFormat fmt = c->charFormat(it->format);-
805 fmt.setTableCellRowSpan(1);-
806 fmt.setTableCellColumnSpan(1);-
807 Q_ASSERT(fmt.objectIndex() == objectIndex());-
808 int position = it.position();-
809 int cfmt = p->formatCollection()->indexForFormat(fmt);-
810 int bfmt = p->formatCollection()->indexForFormat(QTextBlockFormat());-
811 for (int i = 0; i < num; ++i)
i < numDescription
TRUEnever evaluated
FALSEnever evaluated
0
812 p->insertBlock(QTextBeginningOfFrame, position, bfmt, cfmt, QTextUndoCommand::MoveCursor);
never executed: p->insertBlock(QChar(0xfdd0), position, bfmt, cfmt, QTextUndoCommand::MoveCursor);
0
813 }
never executed: end of block
0
814 }-
815-
816 QTextTableFormat tfmt = format();-
817 tfmt.setColumns(tfmt.columns()+num);-
818 QVector<QTextLength> columnWidths = tfmt.columnWidthConstraints();-
819 if (! columnWidths.isEmpty()) {
! columnWidths.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
820 for (int i = num; i > 0; --i)
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
821 columnWidths.insert(pos, columnWidths[qMax(0, pos-1)]);
never executed: columnWidths.insert(pos, columnWidths[qMax(0, pos-1)]);
0
822 }
never executed: end of block
0
823 tfmt.setColumnWidthConstraints (columnWidths);-
824 QTextObject::setFormat(tfmt);-
825-
826// qDebug() << "-------- end insertCols" << pos << num;-
827 p->endEditBlock();-
828}
never executed: end of block
0
829-
830/*!-
831 \since 4.5-
832 Appends \a count rows at the bottom of the table.-
833-
834 \sa insertColumns(), insertRows(), resize(), removeRows(), removeColumns(), appendColumns()-
835*/-
836void QTextTable::appendRows(int count)-
837{-
838 insertRows(rows(), count);-
839}
never executed: end of block
0
840-
841/*!-
842 \since 4.5-
843 Appends \a count columns at the right side of the table.-
844-
845 \sa insertColumns(), insertRows(), resize(), removeRows(), removeColumns(), appendRows()-
846*/-
847void QTextTable::appendColumns(int count)-
848{-
849 insertColumns(columns(), count);-
850}
never executed: end of block
0
851-
852/*!-
853 \fn void QTextTable::removeRows(int index, int rows)-
854-
855 Removes a number of \a rows starting with the row at the specified \a index.-
856-
857 \sa insertRows(), insertColumns(), resize(), removeColumns(), appendRows(), appendColumns()-
858*/-
859void QTextTable::removeRows(int pos, int num)-
860{-
861 Q_D(QTextTable);-
862// qDebug() << "-------- removeRows" << pos << num;-
863-
864 if (num <= 0 || pos < 0)
num <= 0Description
TRUEnever evaluated
FALSEnever evaluated
pos < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
865 return;
never executed: return;
0
866 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
867 d->update();
never executed: d->update();
0
868 if (pos >= d->nRows)
pos >= d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
869 return;
never executed: return;
0
870 if (pos+num > d->nRows)
pos+num > d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
871 num = d->nRows - pos;
never executed: num = d->nRows - pos;
0
872-
873 QTextDocumentPrivate *p = d->pieceTable;-
874 QTextFormatCollection *collection = p->formatCollection();-
875 p->beginEditBlock();-
876-
877 // delete whole table?-
878 if (pos == 0 && num == d->nRows) {
pos == 0Description
TRUEnever evaluated
FALSEnever evaluated
num == d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
879 const int pos = p->fragmentMap().position(d->fragment_start);-
880 p->remove(pos, p->fragmentMap().position(d->fragment_end) - pos + 1);-
881 p->endEditBlock();-
882 return;
never executed: return;
0
883 }-
884-
885 p->aboutToRemoveCell(cellAt(pos, 0).firstPosition(), cellAt(pos + num - 1, d->nCols - 1).lastPosition());-
886-
887 QList<int> touchedCells;-
888 for (int r = pos; r < pos + num; ++r) {
r < pos + numDescription
TRUEnever evaluated
FALSEnever evaluated
0
889 for (int c = 0; c < d->nCols; ++c) {
c < d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
890 int cell = d->grid[r*d->nCols + c];-
891 if (touchedCells.contains(cell))
touchedCells.contains(cell)Description
TRUEnever evaluated
FALSEnever evaluated
0
892 continue;
never executed: continue;
0
893 touchedCells << cell;-
894 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);-
895 QTextCharFormat fmt = collection->charFormat(it->format);-
896 int span = fmt.tableCellRowSpan();-
897 if (span > 1) {
span > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
898 fmt.setTableCellRowSpan(span - 1);-
899 p->setCharFormat(it.position(), 1, fmt);-
900 } else {
never executed: end of block
0
901 // remove cell-
902 int index = d->cells.indexOf(cell) + 1;-
903 int f_end = index < d->cells.size() ? d->cells.at(index) : d->fragment_end;
index < d->cells.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
904 p->remove(it.position(), p->fragmentMap().position(f_end) - it.position());-
905 }
never executed: end of block
0
906 }-
907 }
never executed: end of block
0
908-
909 p->endEditBlock();-
910// qDebug() << "-------- end removeRows" << pos << num;-
911}
never executed: end of block
0
912-
913/*!-
914 \fn void QTextTable::removeColumns(int index, int columns)-
915-
916 Removes a number of \a columns starting with the column at the specified-
917 \a index.-
918-
919 \sa insertRows(), insertColumns(), removeRows(), resize(), appendRows(), appendColumns()-
920*/-
921void QTextTable::removeColumns(int pos, int num)-
922{-
923 Q_D(QTextTable);-
924// qDebug() << "-------- removeCols" << pos << num;-
925-
926 if (num <= 0 || pos < 0)
num <= 0Description
TRUEnever evaluated
FALSEnever evaluated
pos < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
927 return;
never executed: return;
0
928 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
929 d->update();
never executed: d->update();
0
930 if (pos >= d->nCols)
pos >= d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
931 return;
never executed: return;
0
932 if (pos + num > d->nCols)
pos + num > d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
933 pos = d->nCols - num;
never executed: pos = d->nCols - num;
0
934-
935 QTextDocumentPrivate *p = d->pieceTable;-
936 QTextFormatCollection *collection = p->formatCollection();-
937 p->beginEditBlock();-
938-
939 // delete whole table?-
940 if (pos == 0 && num == d->nCols) {
pos == 0Description
TRUEnever evaluated
FALSEnever evaluated
num == d->nColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
941 const int pos = p->fragmentMap().position(d->fragment_start);-
942 p->remove(pos, p->fragmentMap().position(d->fragment_end) - pos + 1);-
943 p->endEditBlock();-
944 return;
never executed: return;
0
945 }-
946-
947 p->aboutToRemoveCell(cellAt(0, pos).firstPosition(), cellAt(d->nRows - 1, pos + num - 1).lastPosition());-
948-
949 QList<int> touchedCells;-
950 for (int r = 0; r < d->nRows; ++r) {
r < d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
951 for (int c = pos; c < pos + num; ++c) {
c < pos + numDescription
TRUEnever evaluated
FALSEnever evaluated
0
952 int cell = d->grid[r*d->nCols + c];-
953 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);-
954 QTextCharFormat fmt = collection->charFormat(it->format);-
955 int span = fmt.tableCellColumnSpan();-
956 if (touchedCells.contains(cell) && span <= 1)
touchedCells.contains(cell)Description
TRUEnever evaluated
FALSEnever evaluated
span <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
957 continue;
never executed: continue;
0
958 touchedCells << cell;-
959-
960 if (span > 1) {
span > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
961 fmt.setTableCellColumnSpan(span - 1);-
962 p->setCharFormat(it.position(), 1, fmt);-
963 } else {
never executed: end of block
0
964 // remove cell-
965 int index = d->cells.indexOf(cell) + 1;-
966 int f_end = index < d->cells.size() ? d->cells.at(index) : d->fragment_end;
index < d->cells.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
967 p->remove(it.position(), p->fragmentMap().position(f_end) - it.position());-
968 }
never executed: end of block
0
969 }-
970 }
never executed: end of block
0
971-
972 QTextTableFormat tfmt = format();-
973 tfmt.setColumns(tfmt.columns()-num);-
974 QVector<QTextLength> columnWidths = tfmt.columnWidthConstraints();-
975 if (columnWidths.count() > pos) {
columnWidths.count() > posDescription
TRUEnever evaluated
FALSEnever evaluated
0
976 columnWidths.remove(pos, num);-
977 tfmt.setColumnWidthConstraints (columnWidths);-
978 }
never executed: end of block
0
979 QTextObject::setFormat(tfmt);-
980-
981 p->endEditBlock();-
982// qDebug() << "-------- end removeCols" << pos << num;-
983}
never executed: end of block
0
984-
985/*!-
986 \since 4.1-
987-
988 Merges the cell at the specified \a row and \a column with the adjacent cells-
989 into one cell. The new cell will span \a numRows rows and \a numCols columns.-
990 This method does nothing if \a numRows or \a numCols is less than the current-
991 number of rows or columns spanned by the cell.-
992-
993 \sa splitCell()-
994*/-
995void QTextTable::mergeCells(int row, int column, int numRows, int numCols)-
996{-
997 Q_D(QTextTable);-
998-
999 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1000 d->update();
never executed: d->update();
0
1001-
1002 QTextDocumentPrivate *p = d->pieceTable;-
1003 QTextFormatCollection *fc = p->formatCollection();-
1004-
1005 const QTextTableCell cell = cellAt(row, column);-
1006 if (!cell.isValid() || row != cell.row() || column != cell.column())
!cell.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
row != cell.row()Description
TRUEnever evaluated
FALSEnever evaluated
column != cell.column()Description
TRUEnever evaluated
FALSEnever evaluated
0
1007 return;
never executed: return;
0
1008-
1009 QTextCharFormat fmt = cell.format();-
1010 const int rowSpan = fmt.tableCellRowSpan();-
1011 const int colSpan = fmt.tableCellColumnSpan();-
1012-
1013 numRows = qMin(numRows, rows() - cell.row());-
1014 numCols = qMin(numCols, columns() - cell.column());-
1015-
1016 // nothing to merge?-
1017 if (numRows < rowSpan || numCols < colSpan)
numRows < rowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
numCols < colSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1018 return;
never executed: return;
0
1019-
1020 // check the edges of the merge rect to make sure no cell spans the edge-
1021 for (int r = row; r < row + numRows; ++r) {
r < row + numRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1022 if (cellAt(r, column) == cellAt(r, column - 1))
cellAt(r, colu...r, column - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1023 return;
never executed: return;
0
1024 if (cellAt(r, column + numCols) == cellAt(r, column + numCols - 1))
cellAt(r, colu...+ numCols - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1025 return;
never executed: return;
0
1026 }
never executed: end of block
0
1027-
1028 for (int c = column; c < column + numCols; ++c) {
c < column + numColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1029 if (cellAt(row, c) == cellAt(row - 1, c))
cellAt(row, c)...At(row - 1, c)Description
TRUEnever evaluated
FALSEnever evaluated
0
1030 return;
never executed: return;
0
1031 if (cellAt(row + numRows, c) == cellAt(row + numRows - 1, c))
cellAt(row + n...umRows - 1, c)Description
TRUEnever evaluated
FALSEnever evaluated
0
1032 return;
never executed: return;
0
1033 }
never executed: end of block
0
1034-
1035 p->beginEditBlock();-
1036-
1037 const int origCellPosition = cell.firstPosition() - 1;-
1038-
1039 const int cellFragment = d->grid[row * d->nCols + column];-
1040-
1041 // find the position at which to insert the contents of the merged cells-
1042 QFragmentFindHelper helper(origCellPosition, p->fragmentMap());-
1043 QList<int>::Iterator it = std::lower_bound(d->cells.begin(), d->cells.end(), helper);-
1044 Q_ASSERT(it != d->cells.end());-
1045 Q_ASSERT(!(helper < *it));-
1046 Q_ASSERT(*it == cellFragment);-
1047 const int insertCellIndex = it - d->cells.begin();-
1048 int insertFragment = d->cells.value(insertCellIndex + 1, d->fragment_end);-
1049 uint insertPos = p->fragmentMap().position(insertFragment);-
1050-
1051 d->blockFragmentUpdates = true;-
1052-
1053 bool rowHasText = cell.firstCursorPosition().block().length();-
1054 bool needsParagraph = rowHasText && colSpan == numCols;
rowHasTextDescription
TRUEnever evaluated
FALSEnever evaluated
colSpan == numColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1055-
1056 // find all cells that will be erased by the merge-
1057 for (int r = row; r < row + numRows; ++r) {
r < row + numRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1058 int firstColumn = r < row + rowSpan ? column + colSpan : column;
r < row + rowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1059-
1060 // don't recompute the cell index for the first row-
1061 int firstCellIndex = r == row ? insertCellIndex + 1 : -1;
r == rowDescription
TRUEnever evaluated
FALSEnever evaluated
0
1062 int cellIndex = firstCellIndex;-
1063-
1064 for (int c = firstColumn; c < column + numCols; ++c) {
c < column + numColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1065 const int fragment = d->grid[r * d->nCols + c];-
1066-
1067 // already handled?-
1068 if (fragment == cellFragment)
fragment == cellFragmentDescription
TRUEnever evaluated
FALSEnever evaluated
0
1069 continue;
never executed: continue;
0
1070-
1071 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), fragment);-
1072 uint pos = it.position();-
1073-
1074 if (firstCellIndex == -1) {
firstCellIndex == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1075 QFragmentFindHelper helper(pos, p->fragmentMap());-
1076 QList<int>::Iterator it = std::lower_bound(d->cells.begin(), d->cells.end(), helper);-
1077 Q_ASSERT(it != d->cells.end());-
1078 Q_ASSERT(!(helper < *it));-
1079 Q_ASSERT(*it == fragment);-
1080 firstCellIndex = cellIndex = it - d->cells.begin();-
1081 }
never executed: end of block
0
1082-
1083 ++cellIndex;-
1084-
1085 QTextCharFormat fmt = fc->charFormat(it->format);-
1086-
1087 const int cellRowSpan = fmt.tableCellRowSpan();-
1088 const int cellColSpan = fmt.tableCellColumnSpan();-
1089-
1090 // update the grid for this cell-
1091 for (int i = r; i < r + cellRowSpan; ++i)
i < r + cellRowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1092 for (int j = c; j < c + cellColSpan; ++j)
j < c + cellColSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1093 d->grid[i * d->nCols + j] = cellFragment;
never executed: d->grid[i * d->nCols + j] = cellFragment;
0
1094-
1095 // erase the cell marker-
1096 p->remove(pos, 1);-
1097-
1098 const int nextFragment = d->cells.value(cellIndex, d->fragment_end);-
1099 const uint nextPos = p->fragmentMap().position(nextFragment);-
1100-
1101 Q_ASSERT(nextPos >= pos);-
1102-
1103 // merge the contents of the cell (if not empty)-
1104 if (nextPos > pos) {
nextPos > posDescription
TRUEnever evaluated
FALSEnever evaluated
0
1105 if (needsParagraph) {
needsParagraphDescription
TRUEnever evaluated
FALSEnever evaluated
0
1106 needsParagraph = false;-
1107 QTextCursorPrivate::fromPosition(p, insertPos++).insertBlock();-
1108 p->move(pos + 1, insertPos, nextPos - pos);-
1109 } else if (rowHasText) {
never executed: end of block
rowHasTextDescription
TRUEnever evaluated
FALSEnever evaluated
0
1110 QTextCursorPrivate::fromPosition(p, insertPos++).insertText(QLatin1String(" "));-
1111 p->move(pos + 1, insertPos, nextPos - pos);-
1112 } else {
never executed: end of block
0
1113 p->move(pos, insertPos, nextPos - pos);-
1114 }
never executed: end of block
0
1115-
1116 insertPos += nextPos - pos;-
1117 rowHasText = true;-
1118 }
never executed: end of block
0
1119 }
never executed: end of block
0
1120-
1121 if (rowHasText) {
rowHasTextDescription
TRUEnever evaluated
FALSEnever evaluated
0
1122 needsParagraph = true;-
1123 rowHasText = false;-
1124 }
never executed: end of block
0
1125-
1126 // erase cells from last row-
1127 if (firstCellIndex >= 0) {
firstCellIndex >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1128 d->cellIndices.remove(firstCellIndex, cellIndex - firstCellIndex);-
1129 d->cells.erase(d->cells.begin() + firstCellIndex, d->cells.begin() + cellIndex);-
1130 }
never executed: end of block
0
1131 }
never executed: end of block
0
1132-
1133 d->fragment_start = d->cells.first();-
1134-
1135 fmt.setTableCellRowSpan(numRows);-
1136 fmt.setTableCellColumnSpan(numCols);-
1137 p->setCharFormat(origCellPosition, 1, fmt);-
1138-
1139 d->blockFragmentUpdates = false;-
1140 d->dirty = false;-
1141-
1142 p->endEditBlock();-
1143}
never executed: end of block
0
1144-
1145/*!-
1146 \overload-
1147 \since 4.1-
1148-
1149 Merges the cells selected by the provided \a cursor.-
1150-
1151 \sa splitCell()-
1152*/-
1153void QTextTable::mergeCells(const QTextCursor &cursor)-
1154{-
1155 if (!cursor.hasComplexSelection())
!cursor.hasComplexSelection()Description
TRUEnever evaluated
FALSEnever evaluated
0
1156 return;
never executed: return;
0
1157-
1158 int firstRow, numRows, firstColumn, numColumns;-
1159 cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);-
1160 mergeCells(firstRow, firstColumn, numRows, numColumns);-
1161}
never executed: end of block
0
1162-
1163/*!-
1164 \since 4.1-
1165-
1166 Splits the specified cell at \a row and \a column into an array of multiple-
1167 cells with dimensions specified by \a numRows and \a numCols.-
1168-
1169 \note It is only possible to split cells that span multiple rows or columns, such as rows-
1170 that have been merged using mergeCells().-
1171-
1172 \sa mergeCells()-
1173*/-
1174void QTextTable::splitCell(int row, int column, int numRows, int numCols)-
1175{-
1176 Q_D(QTextTable);-
1177-
1178 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1179 d->update();
never executed: d->update();
0
1180-
1181 QTextDocumentPrivate *p = d->pieceTable;-
1182 QTextFormatCollection *c = p->formatCollection();-
1183-
1184 const QTextTableCell cell = cellAt(row, column);-
1185 if (!cell.isValid())
!cell.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1186 return;
never executed: return;
0
1187 row = cell.row();-
1188 column = cell.column();-
1189-
1190 QTextCharFormat fmt = cell.format();-
1191 const int rowSpan = fmt.tableCellRowSpan();-
1192 const int colSpan = fmt.tableCellColumnSpan();-
1193-
1194 // nothing to split?-
1195 if (numRows > rowSpan || numCols > colSpan)
numRows > rowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
numCols > colSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1196 return;
never executed: return;
0
1197-
1198 p->beginEditBlock();-
1199-
1200 const int origCellPosition = cell.firstPosition() - 1;-
1201-
1202 QVarLengthArray<int> rowPositions(rowSpan);-
1203-
1204 rowPositions[0] = cell.lastPosition();-
1205-
1206 for (int r = row + 1; r < row + rowSpan; ++r) {
r < row + rowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1207 // find the cell before which to insert the new cell markers-
1208 int gridIndex = r * d->nCols + column;-
1209 QVector<int>::iterator it = std::upper_bound(d->cellIndices.begin(), d->cellIndices.end(), gridIndex);-
1210 int cellIndex = it - d->cellIndices.begin();-
1211 int fragment = d->cells.value(cellIndex, d->fragment_end);-
1212 rowPositions[r - row] = p->fragmentMap().position(fragment);-
1213 }
never executed: end of block
0
1214-
1215 fmt.setTableCellColumnSpan(1);-
1216 fmt.setTableCellRowSpan(1);-
1217 const int fmtIndex = c->indexForFormat(fmt);-
1218 const int blockIndex = p->blockMap().find(cell.lastPosition())->format;-
1219-
1220 int insertAdjustement = 0;-
1221 for (int i = 0; i < numRows; ++i) {
i < numRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1222 for (int c = 0; c < colSpan - numCols; ++c)
c < colSpan - numColsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1223 p->insertBlock(QTextBeginningOfFrame, rowPositions[i] + insertAdjustement + c, blockIndex, fmtIndex);
never executed: p->insertBlock(QChar(0xfdd0), rowPositions[i] + insertAdjustement + c, blockIndex, fmtIndex);
0
1224 insertAdjustement += colSpan - numCols;-
1225 }
never executed: end of block
0
1226-
1227 for (int i = numRows; i < rowSpan; ++i) {
i < rowSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1228 for (int c = 0; c < colSpan; ++c)
c < colSpanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1229 p->insertBlock(QTextBeginningOfFrame, rowPositions[i] + insertAdjustement + c, blockIndex, fmtIndex);
never executed: p->insertBlock(QChar(0xfdd0), rowPositions[i] + insertAdjustement + c, blockIndex, fmtIndex);
0
1230 insertAdjustement += colSpan;-
1231 }
never executed: end of block
0
1232-
1233 fmt.setTableCellRowSpan(numRows);-
1234 fmt.setTableCellColumnSpan(numCols);-
1235 p->setCharFormat(origCellPosition, 1, fmt);-
1236-
1237 p->endEditBlock();-
1238}
never executed: end of block
0
1239-
1240/*!-
1241 Returns the number of rows in the table.-
1242-
1243 \sa columns()-
1244*/-
1245int QTextTable::rows() const-
1246{-
1247 Q_D(const QTextTable);-
1248 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1249 d->update();
never executed: d->update();
0
1250-
1251 return d->nRows;
never executed: return d->nRows;
0
1252}-
1253-
1254/*!-
1255 Returns the number of columns in the table.-
1256-
1257 \sa rows()-
1258*/-
1259int QTextTable::columns() const-
1260{-
1261 Q_D(const QTextTable);-
1262 if (d->dirty)
d->dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1263 d->update();
never executed: d->update();
0
1264-
1265 return d->nCols;
never executed: return d->nCols;
0
1266}-
1267-
1268/*!-
1269 \fn QTextCursor QTextTable::rowStart(const QTextCursor &cursor) const-
1270-
1271 Returns a cursor pointing to the start of the row that contains the-
1272 given \a cursor.-
1273-
1274 \sa rowEnd()-
1275*/-
1276QTextCursor QTextTable::rowStart(const QTextCursor &c) const-
1277{-
1278 Q_D(const QTextTable);-
1279 QTextTableCell cell = cellAt(c);-
1280 if (!cell.isValid())
!cell.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1281 return QTextCursor();
never executed: return QTextCursor();
0
1282-
1283 int row = cell.row();-
1284 QTextDocumentPrivate *p = d->pieceTable;-
1285 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), d->grid[row*d->nCols]);-
1286 return QTextCursorPrivate::fromPosition(p, it.position());
never executed: return QTextCursorPrivate::fromPosition(p, it.position());
0
1287}-
1288-
1289/*!-
1290 \fn QTextCursor QTextTable::rowEnd(const QTextCursor &cursor) const-
1291-
1292 Returns a cursor pointing to the end of the row that contains the given-
1293 \a cursor.-
1294-
1295 \sa rowStart()-
1296*/-
1297QTextCursor QTextTable::rowEnd(const QTextCursor &c) const-
1298{-
1299 Q_D(const QTextTable);-
1300 QTextTableCell cell = cellAt(c);-
1301 if (!cell.isValid())
!cell.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1302 return QTextCursor();
never executed: return QTextCursor();
0
1303-
1304 int row = cell.row() + 1;-
1305 int fragment = row < d->nRows ? d->grid[row*d->nCols] : d->fragment_end;
row < d->nRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1306 QTextDocumentPrivate *p = d->pieceTable;-
1307 QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), fragment);-
1308 return QTextCursorPrivate::fromPosition(p, it.position() - 1);
never executed: return QTextCursorPrivate::fromPosition(p, it.position() - 1);
0
1309}-
1310-
1311/*!-
1312 \fn void QTextTable::setFormat(const QTextTableFormat &format)-
1313-
1314 Sets the table's \a format.-
1315-
1316 \sa format()-
1317*/-
1318void QTextTable::setFormat(const QTextTableFormat &format)-
1319{-
1320 QTextTableFormat fmt = format;-
1321 // don't try to change the number of table columns from here-
1322 fmt.setColumns(columns());-
1323 QTextObject::setFormat(fmt);-
1324}
never executed: end of block
0
1325-
1326/*!-
1327 \fn QTextTableFormat QTextTable::format() const-
1328-
1329 Returns the table's format.-
1330-
1331 \sa setFormat()-
1332*/-
1333-
1334QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9