|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 |
|
45 |
|
46 #include <qtextdocument.h> |
|
47 #include <qdebug.h> |
|
48 |
|
49 #include <qtextcursor.h> |
|
50 #include <qtextdocumentfragment.h> |
|
51 #include <qtextformat.h> |
|
52 #include <qtextobject.h> |
|
53 #include <qtexttable.h> |
|
54 #include <qabstracttextdocumentlayout.h> |
|
55 #include <qtextlist.h> |
|
56 #include <qtextcodec.h> |
|
57 #include <qurl.h> |
|
58 #include <qpainter.h> |
|
59 #include <qfontmetrics.h> |
|
60 #include <qimage.h> |
|
61 #include <qtextlayout.h> |
|
62 #include "common.h" |
|
63 |
|
64 |
|
65 QT_FORWARD_DECLARE_CLASS(QTextDocument) |
|
66 |
|
67 //TESTED_CLASS= |
|
68 //TESTED_FILES= |
|
69 |
|
70 class tst_QTextDocument : public QObject |
|
71 { |
|
72 Q_OBJECT |
|
73 |
|
74 public: |
|
75 tst_QTextDocument(); |
|
76 virtual ~tst_QTextDocument(); |
|
77 |
|
78 public slots: |
|
79 void init(); |
|
80 void cleanup(); |
|
81 private slots: |
|
82 void getSetCheck(); |
|
83 void isEmpty(); |
|
84 void find_data(); |
|
85 void find(); |
|
86 void find2(); |
|
87 void findWithRegExp_data(); |
|
88 void findWithRegExp(); |
|
89 void findMultiple(); |
|
90 void basicIsModifiedChecks(); |
|
91 void moreIsModified(); |
|
92 void isModified2(); |
|
93 void isModified3(); |
|
94 void isModified4(); |
|
95 void noundo_basicIsModifiedChecks(); |
|
96 void noundo_moreIsModified(); |
|
97 void noundo_isModified2(); |
|
98 void noundo_isModified3(); |
|
99 void mightBeRichText(); |
|
100 |
|
101 void task240325(); |
|
102 |
|
103 void stylesheetFont_data(); |
|
104 void stylesheetFont(); |
|
105 |
|
106 void toHtml_data(); |
|
107 void toHtml(); |
|
108 void toHtml2(); |
|
109 |
|
110 void setFragmentMarkersInHtmlExport(); |
|
111 |
|
112 void toHtmlBodyBgColor(); |
|
113 void toHtmlRootFrameProperties(); |
|
114 void capitalizationHtmlInExport(); |
|
115 void wordspacingHtmlExport(); |
|
116 |
|
117 void cursorPositionChanged(); |
|
118 void cursorPositionChangedOnSetText(); |
|
119 |
|
120 void textFrameIterator(); |
|
121 |
|
122 void codecForHtml(); |
|
123 |
|
124 void markContentsDirty(); |
|
125 |
|
126 void clonePreservesMetaInformation(); |
|
127 void clonePreservesPageSize(); |
|
128 void clonePreservesPageBreakPolicies(); |
|
129 void clonePreservesDefaultFont(); |
|
130 void clonePreservesRootFrameFormat(); |
|
131 void clonePreservesResources(); |
|
132 void clonePreservesUserStates(); |
|
133 void clonePreservesIndentWidth(); |
|
134 void blockCount(); |
|
135 void defaultStyleSheet(); |
|
136 |
|
137 void resolvedFontInEmptyFormat(); |
|
138 |
|
139 void defaultRootFrameMargin(); |
|
140 |
|
141 void clearResources(); |
|
142 |
|
143 void setPlainText(); |
|
144 void toPlainText(); |
|
145 |
|
146 void deleteTextObjectsOnClear(); |
|
147 |
|
148 void maximumBlockCount(); |
|
149 void adjustSize(); |
|
150 void initialUserData(); |
|
151 |
|
152 void html_defaultFont(); |
|
153 |
|
154 void blockCountChanged(); |
|
155 |
|
156 void nonZeroDocumentLengthOnClear(); |
|
157 |
|
158 void setTextPreservesUndoRedoEnabled(); |
|
159 |
|
160 void firstLast(); |
|
161 |
|
162 void backgroundImage_toHtml(); |
|
163 void backgroundImage_toHtml2(); |
|
164 void backgroundImage_clone(); |
|
165 void backgroundImage_copy(); |
|
166 |
|
167 void documentCleanup(); |
|
168 |
|
169 void characterAt(); |
|
170 void revisions(); |
|
171 void revisionWithUndoCompressionAndUndo(); |
|
172 |
|
173 void testUndoCommandAdded(); |
|
174 |
|
175 void testUndoBlocks(); |
|
176 |
|
177 void receiveCursorPositionChangedAfterContentsChange(); |
|
178 |
|
179 private: |
|
180 void backgroundImage_checkExpectedHtml(const QTextDocument &doc); |
|
181 |
|
182 QTextDocument *doc; |
|
183 QTextCursor cursor; |
|
184 QFont defaultFont; |
|
185 QString htmlHead; |
|
186 QString htmlTail; |
|
187 }; |
|
188 |
|
189 class MyAbstractTextDocumentLayout : public QAbstractTextDocumentLayout |
|
190 { |
|
191 public: |
|
192 MyAbstractTextDocumentLayout(QTextDocument *doc) : QAbstractTextDocumentLayout(doc) {} |
|
193 void draw(QPainter *, const PaintContext &) {} |
|
194 int hitTest(const QPointF &, Qt::HitTestAccuracy) const { return 0; } |
|
195 int pageCount() const { return 0; } |
|
196 QSizeF documentSize() const { return QSizeF(); } |
|
197 QRectF frameBoundingRect(QTextFrame *) const { return QRectF(); } |
|
198 QRectF blockBoundingRect(const QTextBlock &) const { return QRectF(); } |
|
199 void documentChanged(int, int, int) {} |
|
200 }; |
|
201 |
|
202 // Testing get/set functions |
|
203 void tst_QTextDocument::getSetCheck() |
|
204 { |
|
205 QTextDocument obj1; |
|
206 // QAbstractTextDocumentLayout * QTextDocument::documentLayout() |
|
207 // void QTextDocument::setDocumentLayout(QAbstractTextDocumentLayout *) |
|
208 QPointer<MyAbstractTextDocumentLayout> var1 = new MyAbstractTextDocumentLayout(0); |
|
209 obj1.setDocumentLayout(var1); |
|
210 QCOMPARE(static_cast<QAbstractTextDocumentLayout *>(var1), obj1.documentLayout()); |
|
211 obj1.setDocumentLayout((QAbstractTextDocumentLayout *)0); |
|
212 QVERIFY(var1.isNull()); |
|
213 QVERIFY(obj1.documentLayout()); |
|
214 |
|
215 // bool QTextDocument::useDesignMetrics() |
|
216 // void QTextDocument::setUseDesignMetrics(bool) |
|
217 obj1.setUseDesignMetrics(false); |
|
218 QCOMPARE(false, obj1.useDesignMetrics()); |
|
219 obj1.setUseDesignMetrics(true); |
|
220 QCOMPARE(true, obj1.useDesignMetrics()); |
|
221 } |
|
222 |
|
223 tst_QTextDocument::tst_QTextDocument() |
|
224 { |
|
225 QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); |
|
226 img.save("foo.png"); |
|
227 } |
|
228 |
|
229 tst_QTextDocument::~tst_QTextDocument() |
|
230 { |
|
231 QFile::remove(QLatin1String("foo.png")); |
|
232 } |
|
233 |
|
234 void tst_QTextDocument::init() |
|
235 { |
|
236 doc = new QTextDocument; |
|
237 cursor = QTextCursor(doc); |
|
238 defaultFont = QFont(); |
|
239 |
|
240 htmlHead = QString("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " |
|
241 "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" |
|
242 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" |
|
243 "p, li { white-space: pre-wrap; }\n" |
|
244 "</style></head>" |
|
245 "<body style=\" font-family:'%1'; font-size:%2pt; font-weight:%3; font-style:%4;\">\n"); |
|
246 htmlHead = htmlHead.arg(defaultFont.family()).arg(defaultFont.pointSizeF()).arg(defaultFont.weight() * 8).arg((defaultFont.italic() ? "italic" : "normal")); |
|
247 |
|
248 htmlTail = QString("</body></html>"); |
|
249 } |
|
250 |
|
251 void tst_QTextDocument::cleanup() |
|
252 { |
|
253 cursor = QTextCursor(); |
|
254 delete doc; |
|
255 doc = 0; |
|
256 } |
|
257 |
|
258 void tst_QTextDocument::isEmpty() |
|
259 { |
|
260 QVERIFY(doc->isEmpty()); |
|
261 } |
|
262 |
|
263 void tst_QTextDocument::find_data() |
|
264 { |
|
265 QTest::addColumn<QString>("haystack"); |
|
266 QTest::addColumn<QString>("needle"); |
|
267 QTest::addColumn<int>("flags"); |
|
268 QTest::addColumn<int>("from"); |
|
269 QTest::addColumn<int>("anchor"); |
|
270 QTest::addColumn<int>("position"); |
|
271 |
|
272 QTest::newRow("1") << "Hello World" << "World" << int(QTextDocument::FindCaseSensitively) << 0 << 6 << 11; |
|
273 |
|
274 QTest::newRow("2") << QString::fromAscii("Hello") + QString(QChar::ParagraphSeparator) + QString::fromAscii("World") |
|
275 << "World" << int(QTextDocument::FindCaseSensitively) << 1 << 6 << 11; |
|
276 |
|
277 QTest::newRow("3") << QString::fromAscii("Hello") + QString(QChar::ParagraphSeparator) + QString::fromAscii("World") |
|
278 << "Hello" << int(QTextDocument::FindCaseSensitively | QTextDocument::FindBackward) << 10 << 0 << 5; |
|
279 QTest::newRow("4wholewords") << QString::fromAscii("Hello Blah World") |
|
280 << "Blah" << int(QTextDocument::FindWholeWords) << 0 << 6 << 10; |
|
281 QTest::newRow("5wholewords") << QString::fromAscii("HelloBlahWorld") |
|
282 << "Blah" << int(QTextDocument::FindWholeWords) << 0 << -1 << -1; |
|
283 QTest::newRow("6wholewords") << QString::fromAscii("HelloBlahWorld Blah Hah") |
|
284 << "Blah" << int(QTextDocument::FindWholeWords) << 0 << 15 << 19; |
|
285 QTest::newRow("7wholewords") << QString::fromAscii("HelloBlahWorld Blah Hah") |
|
286 << "Blah" << int(QTextDocument::FindWholeWords | QTextDocument::FindBackward) << 23 << 15 << 19; |
|
287 QTest::newRow("8wholewords") << QString::fromAscii("Hello: World\n") |
|
288 << "orld" << int(QTextDocument::FindWholeWords) << 0 << -1 << -1; |
|
289 |
|
290 QTest::newRow("across-paragraphs") << QString::fromAscii("First Parag\nSecond Parag with a lot more text") |
|
291 << "Parag" << int(QTextDocument::FindBackward) |
|
292 << 15 << 6 << 11; |
|
293 |
|
294 QTest::newRow("nbsp") << "Hello" + QString(QChar(QChar::Nbsp)) +"World" << " " << int(QTextDocument::FindCaseSensitively) << 0 << 5 << 6; |
|
295 } |
|
296 |
|
297 void tst_QTextDocument::find() |
|
298 { |
|
299 QFETCH(QString, haystack); |
|
300 QFETCH(QString, needle); |
|
301 QFETCH(int, flags); |
|
302 QFETCH(int, from); |
|
303 QFETCH(int, anchor); |
|
304 QFETCH(int, position); |
|
305 |
|
306 cursor.insertText(haystack); |
|
307 cursor = doc->find(needle, from, QTextDocument::FindFlags(flags)); |
|
308 |
|
309 if (anchor != -1) { |
|
310 QCOMPARE(cursor.anchor(), anchor); |
|
311 QCOMPARE(cursor.position(), position); |
|
312 } else { |
|
313 QVERIFY(cursor.isNull()); |
|
314 } |
|
315 |
|
316 //search using a regular expression |
|
317 QRegExp expr(needle); |
|
318 expr.setPatternSyntax(QRegExp::FixedString); |
|
319 QTextDocument::FindFlags flg(flags); |
|
320 expr.setCaseSensitivity((flg & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive); |
|
321 cursor = doc->find(expr, from, flg); |
|
322 |
|
323 if (anchor != -1) { |
|
324 QCOMPARE(cursor.anchor(), anchor); |
|
325 QCOMPARE(cursor.position(), position); |
|
326 } else { |
|
327 QVERIFY(cursor.isNull()); |
|
328 } |
|
329 } |
|
330 |
|
331 void tst_QTextDocument::findWithRegExp_data() |
|
332 { |
|
333 QTest::addColumn<QString>("haystack"); |
|
334 QTest::addColumn<QString>("needle"); |
|
335 QTest::addColumn<int>("flags"); |
|
336 QTest::addColumn<int>("from"); |
|
337 QTest::addColumn<int>("anchor"); |
|
338 QTest::addColumn<int>("position"); |
|
339 |
|
340 // match integers 0 to 99 |
|
341 QTest::newRow("1") << "23" << "^\\d\\d?$" << int(QTextDocument::FindCaseSensitively) << 0 << 0 << 2; |
|
342 // match ampersands but not & |
|
343 QTest::newRow("2") << "His & hers & theirs" << "&(?!amp;)"<< int(QTextDocument::FindCaseSensitively) << 0 << 15 << 16; |
|
344 //backward search |
|
345 QTest::newRow("3") << QString::fromAscii("HelloBlahWorld Blah Hah") |
|
346 << "h" << int(QTextDocument::FindBackward) << 18 << 8 << 9; |
|
347 |
|
348 } |
|
349 |
|
350 void tst_QTextDocument::findWithRegExp() |
|
351 { |
|
352 QFETCH(QString, haystack); |
|
353 QFETCH(QString, needle); |
|
354 QFETCH(int, flags); |
|
355 QFETCH(int, from); |
|
356 QFETCH(int, anchor); |
|
357 QFETCH(int, position); |
|
358 |
|
359 cursor.insertText(haystack); |
|
360 //search using a regular expression |
|
361 QRegExp expr(needle); |
|
362 QTextDocument::FindFlags flg(flags); |
|
363 expr.setCaseSensitivity((flg & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive); |
|
364 cursor = doc->find(expr, from, flg); |
|
365 |
|
366 if (anchor != -1) { |
|
367 QCOMPARE(cursor.anchor(), anchor); |
|
368 QCOMPARE(cursor.position(), position); |
|
369 } else { |
|
370 QVERIFY(cursor.isNull()); |
|
371 } |
|
372 } |
|
373 |
|
374 void tst_QTextDocument::find2() |
|
375 { |
|
376 doc->setPlainText("aaa"); |
|
377 cursor.movePosition(QTextCursor::Start); |
|
378 cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); |
|
379 QTextCursor hit = doc->find("a", cursor); |
|
380 QCOMPARE(hit.position(), 2); |
|
381 QCOMPARE(hit.anchor(), 1); |
|
382 } |
|
383 |
|
384 void tst_QTextDocument::findMultiple() |
|
385 { |
|
386 const QString text("foo bar baz foo bar baz"); |
|
387 doc->setPlainText(text); |
|
388 |
|
389 cursor.movePosition(QTextCursor::Start); |
|
390 cursor = doc->find("bar", cursor); |
|
391 QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); |
|
392 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
393 cursor = doc->find("bar", cursor); |
|
394 QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); |
|
395 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
396 |
|
397 cursor.movePosition(QTextCursor::End); |
|
398 cursor = doc->find("bar", cursor, QTextDocument::FindBackward); |
|
399 QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); |
|
400 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
401 cursor = doc->find("bar", cursor, QTextDocument::FindBackward); |
|
402 QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); |
|
403 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
404 |
|
405 |
|
406 QRegExp expr("bar"); |
|
407 expr.setPatternSyntax(QRegExp::FixedString); |
|
408 |
|
409 cursor.movePosition(QTextCursor::End); |
|
410 cursor = doc->find(expr, cursor, QTextDocument::FindBackward); |
|
411 QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); |
|
412 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
413 cursor = doc->find(expr, cursor, QTextDocument::FindBackward); |
|
414 QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); |
|
415 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
416 |
|
417 cursor.movePosition(QTextCursor::Start); |
|
418 cursor = doc->find(expr, cursor); |
|
419 QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); |
|
420 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
421 cursor = doc->find(expr, cursor); |
|
422 QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); |
|
423 QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); |
|
424 } |
|
425 |
|
426 void tst_QTextDocument::basicIsModifiedChecks() |
|
427 { |
|
428 QSignalSpy spy(doc, SIGNAL(modificationChanged(bool))); |
|
429 |
|
430 QVERIFY(!doc->isModified()); |
|
431 cursor.insertText("Hello World"); |
|
432 QVERIFY(doc->isModified()); |
|
433 QCOMPARE(spy.count(), 1); |
|
434 QVERIFY(spy.takeFirst().at(0).toBool()); |
|
435 |
|
436 doc->undo(); |
|
437 QVERIFY(!doc->isModified()); |
|
438 QCOMPARE(spy.count(), 1); |
|
439 QVERIFY(!spy.takeFirst().at(0).toBool()); |
|
440 |
|
441 doc->redo(); |
|
442 QVERIFY(doc->isModified()); |
|
443 QCOMPARE(spy.count(), 1); |
|
444 QVERIFY(spy.takeFirst().at(0).toBool()); |
|
445 } |
|
446 |
|
447 void tst_QTextDocument::moreIsModified() |
|
448 { |
|
449 QVERIFY(!doc->isModified()); |
|
450 |
|
451 cursor.insertText("Hello"); |
|
452 QVERIFY(doc->isModified()); |
|
453 |
|
454 doc->undo(); |
|
455 QVERIFY(!doc->isModified()); |
|
456 |
|
457 cursor.insertText("Hello"); |
|
458 |
|
459 doc->undo(); |
|
460 QVERIFY(!doc->isModified()); |
|
461 } |
|
462 |
|
463 void tst_QTextDocument::isModified2() |
|
464 { |
|
465 // reported on qt4-preview-feedback |
|
466 QVERIFY(!doc->isModified()); |
|
467 |
|
468 cursor.insertText("Hello"); |
|
469 QVERIFY(doc->isModified()); |
|
470 |
|
471 doc->setModified(false); |
|
472 QVERIFY(!doc->isModified()); |
|
473 |
|
474 cursor.insertText("Hello"); |
|
475 QVERIFY(doc->isModified()); |
|
476 } |
|
477 |
|
478 void tst_QTextDocument::isModified3() |
|
479 { |
|
480 QVERIFY(!doc->isModified()); |
|
481 |
|
482 doc->setUndoRedoEnabled(false); |
|
483 doc->setUndoRedoEnabled(true); |
|
484 |
|
485 cursor.insertText("Hello"); |
|
486 |
|
487 QVERIFY(doc->isModified()); |
|
488 doc->undo(); |
|
489 QVERIFY(!doc->isModified()); |
|
490 } |
|
491 |
|
492 void tst_QTextDocument::isModified4() |
|
493 { |
|
494 QVERIFY(!doc->isModified()); |
|
495 |
|
496 cursor.insertText("Hello"); |
|
497 cursor.insertText("World"); |
|
498 |
|
499 doc->setModified(false); |
|
500 |
|
501 QVERIFY(!doc->isModified()); |
|
502 |
|
503 cursor.insertText("Again"); |
|
504 QVERIFY(doc->isModified()); |
|
505 |
|
506 doc->undo(); |
|
507 QVERIFY(!doc->isModified()); |
|
508 doc->undo(); |
|
509 QVERIFY(doc->isModified()); |
|
510 |
|
511 doc->redo(); |
|
512 QVERIFY(!doc->isModified()); |
|
513 doc->redo(); |
|
514 QVERIFY(doc->isModified()); |
|
515 |
|
516 doc->undo(); |
|
517 QVERIFY(!doc->isModified()); |
|
518 doc->undo(); |
|
519 QVERIFY(doc->isModified()); |
|
520 |
|
521 //task 197769 |
|
522 cursor.insertText("Hello"); |
|
523 QVERIFY(doc->isModified()); |
|
524 } |
|
525 |
|
526 void tst_QTextDocument::noundo_basicIsModifiedChecks() |
|
527 { |
|
528 doc->setUndoRedoEnabled(false); |
|
529 QSignalSpy spy(doc, SIGNAL(modificationChanged(bool))); |
|
530 |
|
531 QVERIFY(!doc->isModified()); |
|
532 cursor.insertText("Hello World"); |
|
533 QVERIFY(doc->isModified()); |
|
534 QCOMPARE(spy.count(), 1); |
|
535 QVERIFY(spy.takeFirst().at(0).toBool()); |
|
536 |
|
537 doc->undo(); |
|
538 QVERIFY(doc->isModified()); |
|
539 QCOMPARE(spy.count(), 0); |
|
540 |
|
541 doc->redo(); |
|
542 QVERIFY(doc->isModified()); |
|
543 QCOMPARE(spy.count(), 0); |
|
544 } |
|
545 |
|
546 void tst_QTextDocument::task240325() |
|
547 { |
|
548 doc->setHtml("<html><img width=\"100\" height=\"100\" align=\"right\"/>Foobar Foobar Foobar Foobar</html>"); |
|
549 |
|
550 QImage img(1000, 7000, QImage::Format_ARGB32_Premultiplied); |
|
551 QPainter p(&img); |
|
552 QFontMetrics fm(p.font()); |
|
553 |
|
554 // Set page size to contain image and one "Foobar" |
|
555 doc->setPageSize(QSize(100 + fm.width("Foobar")*2, 1000)); |
|
556 |
|
557 // Force layout |
|
558 doc->drawContents(&p); |
|
559 |
|
560 QCOMPARE(doc->blockCount(), 1); |
|
561 for (QTextBlock block = doc->begin() ; block!=doc->end() ; block = block.next()) { |
|
562 QTextLayout *layout = block.layout(); |
|
563 QCOMPARE(layout->lineCount(), 4); |
|
564 for (int lineIdx=0;lineIdx<layout->lineCount();++lineIdx) { |
|
565 QTextLine line = layout->lineAt(lineIdx); |
|
566 |
|
567 QString text = block.text().mid(line.textStart(), line.textLength()).trimmed(); |
|
568 |
|
569 // Remove start token |
|
570 if (lineIdx == 0) |
|
571 text = text.mid(1); |
|
572 |
|
573 QCOMPARE(text, QString::fromLatin1("Foobar")); |
|
574 } |
|
575 } |
|
576 } |
|
577 |
|
578 void tst_QTextDocument::stylesheetFont_data() |
|
579 { |
|
580 QTest::addColumn<QString>("stylesheet"); |
|
581 QTest::addColumn<QFont>("font"); |
|
582 |
|
583 { |
|
584 QFont font; |
|
585 font.setBold(true); |
|
586 font.setPixelSize(64); |
|
587 |
|
588 QTest::newRow("Regular font specification") |
|
589 << "font-size: 64px; font-weight: bold;" |
|
590 << font; |
|
591 } |
|
592 |
|
593 |
|
594 { |
|
595 QFont font; |
|
596 font.setBold(true); |
|
597 font.setPixelSize(64); |
|
598 |
|
599 QTest::newRow("Shorthand font specification") |
|
600 << "font: normal bold 64px Arial;" |
|
601 << font; |
|
602 } |
|
603 |
|
604 } |
|
605 |
|
606 void tst_QTextDocument::stylesheetFont() |
|
607 { |
|
608 QFETCH(QString, stylesheet); |
|
609 QFETCH(QFont, font); |
|
610 |
|
611 QString html = QString::fromLatin1("<html>" |
|
612 "<body>" |
|
613 "<div style=\"%1\" >" |
|
614 "Foobar" |
|
615 "</div>" |
|
616 "</body>" |
|
617 "</html>").arg(stylesheet); |
|
618 |
|
619 qDebug() << html; |
|
620 doc->setHtml(html); |
|
621 QCOMPARE(doc->blockCount(), 1); |
|
622 |
|
623 // First and only block |
|
624 QTextBlock block = doc->firstBlock(); |
|
625 |
|
626 QString text = block.text(); |
|
627 QCOMPARE(text, QString::fromLatin1("Foobar")); |
|
628 |
|
629 QFont actualFont = block.charFormat().font(); |
|
630 |
|
631 QCOMPARE(actualFont.bold(), font.bold()); |
|
632 QCOMPARE(actualFont.pixelSize(), font.pixelSize()); |
|
633 } |
|
634 |
|
635 void tst_QTextDocument::noundo_moreIsModified() |
|
636 { |
|
637 doc->setUndoRedoEnabled(false); |
|
638 QVERIFY(!doc->isModified()); |
|
639 |
|
640 cursor.insertText("Hello"); |
|
641 QVERIFY(doc->isModified()); |
|
642 |
|
643 doc->undo(); |
|
644 QVERIFY(doc->isModified()); |
|
645 |
|
646 cursor.insertText("Hello"); |
|
647 |
|
648 doc->undo(); |
|
649 QVERIFY(doc->isModified()); |
|
650 } |
|
651 |
|
652 void tst_QTextDocument::noundo_isModified2() |
|
653 { |
|
654 // reported on qt4-preview-feedback |
|
655 QVERIFY(!doc->isModified()); |
|
656 |
|
657 cursor.insertText("Hello"); |
|
658 QVERIFY(doc->isModified()); |
|
659 |
|
660 doc->setModified(false); |
|
661 QVERIFY(!doc->isModified()); |
|
662 |
|
663 cursor.insertText("Hello"); |
|
664 QVERIFY(doc->isModified()); |
|
665 } |
|
666 |
|
667 void tst_QTextDocument::noundo_isModified3() |
|
668 { |
|
669 doc->setUndoRedoEnabled(false); |
|
670 QVERIFY(!doc->isModified()); |
|
671 |
|
672 cursor.insertText("Hello"); |
|
673 |
|
674 QVERIFY(doc->isModified()); |
|
675 doc->undo(); |
|
676 QVERIFY(doc->isModified()); |
|
677 } |
|
678 |
|
679 void tst_QTextDocument::mightBeRichText() |
|
680 { |
|
681 const char qtDocuHeader[] = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" |
|
682 "<!DOCTYPE html\n" |
|
683 " PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" |
|
684 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; |
|
685 QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader))); |
|
686 } |
|
687 |
|
688 Q_DECLARE_METATYPE(QTextDocumentFragment) |
|
689 |
|
690 #define CREATE_DOC_AND_CURSOR() \ |
|
691 QTextDocument doc; \ |
|
692 doc.setDefaultFont(defaultFont); \ |
|
693 QTextCursor cursor(&doc); |
|
694 |
|
695 void tst_QTextDocument::toHtml_data() |
|
696 { |
|
697 QTest::addColumn<QTextDocumentFragment>("input"); |
|
698 QTest::addColumn<QString>("expectedOutput"); |
|
699 |
|
700 { |
|
701 CREATE_DOC_AND_CURSOR(); |
|
702 |
|
703 cursor.insertText("Blah"); |
|
704 |
|
705 QTest::newRow("simple") << QTextDocumentFragment(&doc) << QString("<p DEFAULTBLOCKSTYLE>Blah</p>"); |
|
706 } |
|
707 |
|
708 { |
|
709 CREATE_DOC_AND_CURSOR(); |
|
710 |
|
711 cursor.insertText("&<>"); |
|
712 |
|
713 QTest::newRow("entities") << QTextDocumentFragment(&doc) << QString("<p DEFAULTBLOCKSTYLE>&<></p>"); |
|
714 } |
|
715 |
|
716 { |
|
717 CREATE_DOC_AND_CURSOR(); |
|
718 |
|
719 QTextCharFormat fmt; |
|
720 fmt.setFontFamily("Times"); |
|
721 cursor.insertText("Blah", fmt); |
|
722 |
|
723 QTest::newRow("font-family") << QTextDocumentFragment(&doc) |
|
724 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:'Times';\">Blah</span></p>"); |
|
725 } |
|
726 |
|
727 { |
|
728 CREATE_DOC_AND_CURSOR(); |
|
729 |
|
730 QTextCharFormat fmt; |
|
731 fmt.setFontFamily("Foo's Family"); |
|
732 cursor.insertText("Blah", fmt); |
|
733 |
|
734 QTest::newRow("font-family-with-quotes1") << QTextDocumentFragment(&doc) |
|
735 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:\"Foo's Family\";\">Blah</span></p>"); |
|
736 } |
|
737 |
|
738 { |
|
739 CREATE_DOC_AND_CURSOR(); |
|
740 |
|
741 QTextCharFormat fmt; |
|
742 fmt.setFontFamily("Foo\"s Family"); |
|
743 cursor.insertText("Blah", fmt); |
|
744 |
|
745 QTest::newRow("font-family-with-quotes2") << QTextDocumentFragment(&doc) |
|
746 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:'Foo\"s Family';\">Blah</span></p>"); |
|
747 } |
|
748 |
|
749 { |
|
750 CREATE_DOC_AND_CURSOR(); |
|
751 |
|
752 QTextBlockFormat fmt; |
|
753 fmt.setNonBreakableLines(true); |
|
754 cursor.insertBlock(fmt); |
|
755 cursor.insertText("Blah"); |
|
756 |
|
757 QTest::newRow("pre") << QTextDocumentFragment(&doc) |
|
758 << |
|
759 QString("EMPTYBLOCK") + |
|
760 QString("<pre DEFAULTBLOCKSTYLE>Blah</pre>"); |
|
761 } |
|
762 |
|
763 { |
|
764 CREATE_DOC_AND_CURSOR(); |
|
765 |
|
766 QTextCharFormat fmt; |
|
767 fmt.setFontPointSize(40); |
|
768 cursor.insertText("Blah", fmt); |
|
769 |
|
770 QTest::newRow("font-size") << QTextDocumentFragment(&doc) |
|
771 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-size:40pt;\">Blah</span></p>"); |
|
772 } |
|
773 |
|
774 { |
|
775 CREATE_DOC_AND_CURSOR(); |
|
776 |
|
777 QTextCharFormat fmt; |
|
778 fmt.setProperty(QTextFormat::FontSizeIncrement, 2); |
|
779 cursor.insertText("Blah", fmt); |
|
780 |
|
781 QTest::newRow("logical-font-size") << QTextDocumentFragment(&doc) |
|
782 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-size:x-large;\">Blah</span></p>"); |
|
783 } |
|
784 |
|
785 { |
|
786 CREATE_DOC_AND_CURSOR(); |
|
787 |
|
788 cursor.insertText("Foo"); |
|
789 |
|
790 QTextCharFormat fmt; |
|
791 fmt.setFontPointSize(40); |
|
792 cursor.insertBlock(QTextBlockFormat(), fmt); |
|
793 |
|
794 fmt.clearProperty(QTextFormat::FontPointSize); |
|
795 cursor.insertText("Blub", fmt); |
|
796 |
|
797 QTest::newRow("no-font-size") << QTextDocumentFragment(&doc) |
|
798 << QString("<p DEFAULTBLOCKSTYLE>Foo</p>\n<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blub</p>"); |
|
799 } |
|
800 |
|
801 { |
|
802 CREATE_DOC_AND_CURSOR(); |
|
803 |
|
804 QTextBlockFormat fmt; |
|
805 fmt.setLayoutDirection(Qt::RightToLeft); |
|
806 cursor.insertBlock(fmt); |
|
807 cursor.insertText("Blah"); |
|
808 |
|
809 QTest::newRow("rtl") << QTextDocumentFragment(&doc) |
|
810 << |
|
811 QString("EMPTYBLOCK") + |
|
812 QString("<p dir='rtl' DEFAULTBLOCKSTYLE>Blah</p>"); |
|
813 } |
|
814 |
|
815 { |
|
816 CREATE_DOC_AND_CURSOR(); |
|
817 |
|
818 QTextBlockFormat fmt; |
|
819 fmt.setAlignment(Qt::AlignJustify); |
|
820 cursor.insertBlock(fmt); |
|
821 cursor.insertText("Blah"); |
|
822 |
|
823 QTest::newRow("blockalign") << QTextDocumentFragment(&doc) |
|
824 << |
|
825 QString("EMPTYBLOCK") + |
|
826 QString("<p align=\"justify\" DEFAULTBLOCKSTYLE>Blah</p>"); |
|
827 } |
|
828 |
|
829 { |
|
830 CREATE_DOC_AND_CURSOR(); |
|
831 |
|
832 QTextBlockFormat fmt; |
|
833 fmt.setAlignment(Qt::AlignCenter); |
|
834 cursor.insertBlock(fmt); |
|
835 cursor.insertText("Blah"); |
|
836 |
|
837 QTest::newRow("blockalign2") << QTextDocumentFragment(&doc) |
|
838 << |
|
839 QString("EMPTYBLOCK") + |
|
840 QString("<p align=\"center\" DEFAULTBLOCKSTYLE>Blah</p>"); |
|
841 } |
|
842 |
|
843 { |
|
844 CREATE_DOC_AND_CURSOR(); |
|
845 |
|
846 QTextBlockFormat fmt; |
|
847 fmt.setAlignment(Qt::AlignRight | Qt::AlignAbsolute); |
|
848 cursor.insertBlock(fmt); |
|
849 cursor.insertText("Blah"); |
|
850 |
|
851 QTest::newRow("blockalign3") << QTextDocumentFragment(&doc) |
|
852 << |
|
853 QString("EMPTYBLOCK") + |
|
854 QString("<p align=\"right\" DEFAULTBLOCKSTYLE>Blah</p>"); |
|
855 } |
|
856 |
|
857 { |
|
858 CREATE_DOC_AND_CURSOR(); |
|
859 |
|
860 QTextBlockFormat fmt; |
|
861 fmt.setBackground(QColor("#0000ff")); |
|
862 cursor.insertBlock(fmt); |
|
863 cursor.insertText("Blah"); |
|
864 |
|
865 QTest::newRow("bgcolor") << QTextDocumentFragment(&doc) |
|
866 << QString("EMPTYBLOCK") + |
|
867 QString("<p OPENDEFAULTBLOCKSTYLE background-color:#0000ff;\">Blah</p>"); |
|
868 } |
|
869 |
|
870 { |
|
871 CREATE_DOC_AND_CURSOR(); |
|
872 |
|
873 QTextCharFormat fmt; |
|
874 fmt.setFontWeight(40); |
|
875 cursor.insertText("Blah", fmt); |
|
876 |
|
877 QTest::newRow("font-weight") << QTextDocumentFragment(&doc) |
|
878 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-weight:320;\">Blah</span></p>"); |
|
879 } |
|
880 |
|
881 { |
|
882 CREATE_DOC_AND_CURSOR(); |
|
883 |
|
884 QTextCharFormat fmt; |
|
885 fmt.setFontItalic(true); |
|
886 cursor.insertText("Blah", fmt); |
|
887 |
|
888 QTest::newRow("font-italic") << QTextDocumentFragment(&doc) |
|
889 << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-style:italic;\">Blah</span></p>"); |
|
890 } |
|
891 |
|
892 { |
|
893 CREATE_DOC_AND_CURSOR(); |
|
894 |
|
895 QTextCharFormat fmt; |
|
896 fmt.setFontUnderline(true); |
|
897 fmt.setFontOverline(false); |
|
898 cursor.insertText("Blah", fmt); |
|
899 |
|
900 QTest::newRow("text-decoration-1") << QTextDocumentFragment(&doc) |
|
901 << QString("<p DEFAULTBLOCKSTYLE><span style=\" text-decoration: underline;\">Blah</span></p>"); |
|
902 } |
|
903 |
|
904 { |
|
905 CREATE_DOC_AND_CURSOR(); |
|
906 |
|
907 QTextCharFormat fmt; |
|
908 fmt.setForeground(QColor("#00ff00")); |
|
909 cursor.insertText("Blah", fmt); |
|
910 |
|
911 QTest::newRow("color") << QTextDocumentFragment(&doc) |
|
912 << QString("<p DEFAULTBLOCKSTYLE><span style=\" color:#00ff00;\">Blah</span></p>"); |
|
913 } |
|
914 |
|
915 { |
|
916 CREATE_DOC_AND_CURSOR(); |
|
917 |
|
918 QTextCharFormat fmt; |
|
919 fmt.setBackground(QColor("#00ff00")); |
|
920 cursor.insertText("Blah", fmt); |
|
921 |
|
922 QTest::newRow("span-bgcolor") << QTextDocumentFragment(&doc) |
|
923 << QString("<p DEFAULTBLOCKSTYLE><span style=\" background-color:#00ff00;\">Blah</span></p>"); |
|
924 } |
|
925 |
|
926 { |
|
927 CREATE_DOC_AND_CURSOR(); |
|
928 |
|
929 QTextCharFormat fmt; |
|
930 fmt.setVerticalAlignment(QTextCharFormat::AlignSubScript); |
|
931 cursor.insertText("Blah", fmt); |
|
932 |
|
933 QTest::newRow("valign-sub") << QTextDocumentFragment(&doc) |
|
934 << QString("<p DEFAULTBLOCKSTYLE><span style=\" vertical-align:sub;\">Blah</span></p>"); |
|
935 |
|
936 } |
|
937 |
|
938 { |
|
939 CREATE_DOC_AND_CURSOR(); |
|
940 |
|
941 QTextCharFormat fmt; |
|
942 fmt.setVerticalAlignment(QTextCharFormat::AlignSuperScript); |
|
943 cursor.insertText("Blah", fmt); |
|
944 |
|
945 QTest::newRow("valign-super") << QTextDocumentFragment(&doc) |
|
946 << QString("<p DEFAULTBLOCKSTYLE><span style=\" vertical-align:super;\">Blah</span></p>"); |
|
947 |
|
948 } |
|
949 |
|
950 { |
|
951 CREATE_DOC_AND_CURSOR(); |
|
952 |
|
953 QTextCharFormat fmt; |
|
954 fmt.setAnchor(true); |
|
955 fmt.setAnchorName("blub"); |
|
956 cursor.insertText("Blah", fmt); |
|
957 |
|
958 QTest::newRow("named anchor") << QTextDocumentFragment(&doc) |
|
959 << QString("<p DEFAULTBLOCKSTYLE><a name=\"blub\"></a>Blah</p>"); |
|
960 } |
|
961 |
|
962 { |
|
963 CREATE_DOC_AND_CURSOR(); |
|
964 |
|
965 QTextCharFormat fmt; |
|
966 fmt.setAnchor(true); |
|
967 fmt.setAnchorHref("http://www.kde.org/"); |
|
968 cursor.insertText("Blah", fmt); |
|
969 |
|
970 QTest::newRow("href anchor") << QTextDocumentFragment(&doc) |
|
971 << QString("<p DEFAULTBLOCKSTYLE><a href=\"http://www.kde.org/\">Blah</a></p>"); |
|
972 } |
|
973 |
|
974 { |
|
975 CREATE_DOC_AND_CURSOR(); |
|
976 |
|
977 cursor.insertTable(2, 2); |
|
978 |
|
979 QTest::newRow("simpletable") << QTextDocumentFragment(&doc) |
|
980 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
981 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
982 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
983 "</table>"); |
|
984 } |
|
985 |
|
986 { |
|
987 CREATE_DOC_AND_CURSOR(); |
|
988 |
|
989 QTextTable *table = cursor.insertTable(1, 4); |
|
990 table->mergeCells(0, 0, 1, 2); |
|
991 table->mergeCells(0, 2, 1, 2); |
|
992 |
|
993 QTest::newRow("tablespans") << QTextDocumentFragment(&doc) |
|
994 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
995 "\n<tr>\n<td colspan=\"2\"></td>\n<td colspan=\"2\"></td></tr>" |
|
996 "</table>"); |
|
997 } |
|
998 |
|
999 { |
|
1000 CREATE_DOC_AND_CURSOR(); |
|
1001 |
|
1002 QTextTableFormat fmt; |
|
1003 fmt.setBorder(1); |
|
1004 fmt.setCellSpacing(3); |
|
1005 fmt.setCellPadding(3); |
|
1006 fmt.setBackground(QColor("#ff00ff")); |
|
1007 fmt.setWidth(QTextLength(QTextLength::PercentageLength, 50)); |
|
1008 fmt.setAlignment(Qt::AlignHCenter); |
|
1009 fmt.setPosition(QTextFrameFormat::FloatRight); |
|
1010 cursor.insertTable(2, 2, fmt); |
|
1011 |
|
1012 QTest::newRow("tableattrs") << QTextDocumentFragment(&doc) |
|
1013 << QString("<table border=\"1\" style=\" float: right;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">" |
|
1014 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1015 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1016 "</table>"); |
|
1017 } |
|
1018 |
|
1019 { |
|
1020 CREATE_DOC_AND_CURSOR(); |
|
1021 |
|
1022 QTextTableFormat fmt; |
|
1023 fmt.setBorder(1); |
|
1024 fmt.setCellSpacing(3); |
|
1025 fmt.setCellPadding(3); |
|
1026 fmt.setBackground(QColor("#ff00ff")); |
|
1027 fmt.setWidth(QTextLength(QTextLength::PercentageLength, 50)); |
|
1028 fmt.setAlignment(Qt::AlignHCenter); |
|
1029 fmt.setPosition(QTextFrameFormat::FloatRight); |
|
1030 fmt.setLeftMargin(25); |
|
1031 fmt.setBottomMargin(35); |
|
1032 cursor.insertTable(2, 2, fmt); |
|
1033 |
|
1034 QTest::newRow("tableattrs2") << QTextDocumentFragment(&doc) |
|
1035 << QString("<table border=\"1\" style=\" float: right; margin-top:0px; margin-bottom:35px; margin-left:25px; margin-right:0px;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">" |
|
1036 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1037 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1038 "</table>"); |
|
1039 } |
|
1040 |
|
1041 { |
|
1042 CREATE_DOC_AND_CURSOR(); |
|
1043 |
|
1044 QTextTableFormat fmt; |
|
1045 fmt.setHeaderRowCount(2); |
|
1046 cursor.insertTable(4, 2, fmt); |
|
1047 |
|
1048 QTest::newRow("tableheader") << QTextDocumentFragment(&doc) |
|
1049 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1050 "<thead>\n<tr>\n<td></td>\n<td></td></tr>" |
|
1051 "\n<tr>\n<td></td>\n<td></td></tr></thead>" |
|
1052 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1053 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1054 "</table>"); |
|
1055 } |
|
1056 |
|
1057 { |
|
1058 CREATE_DOC_AND_CURSOR(); |
|
1059 |
|
1060 QTextTable *table = cursor.insertTable(2, 2); |
|
1061 QTextTable *subTable = table->cellAt(0, 1).firstCursorPosition().insertTable(1, 1); |
|
1062 subTable->cellAt(0, 0).firstCursorPosition().insertText("Hey"); |
|
1063 |
|
1064 QTest::newRow("nestedtable") << QTextDocumentFragment(&doc) |
|
1065 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1066 "\n<tr>\n<td></td>\n<td>\n<table border=\"1\" cellspacing=\"2\">\n<tr>\n<td>\n<p DEFAULTBLOCKSTYLE>Hey</p></td></tr></table></td></tr>" |
|
1067 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1068 "</table>"); |
|
1069 } |
|
1070 |
|
1071 { |
|
1072 CREATE_DOC_AND_CURSOR(); |
|
1073 |
|
1074 QTextTableFormat fmt; |
|
1075 QVector<QTextLength> widths; |
|
1076 widths.append(QTextLength()); |
|
1077 widths.append(QTextLength(QTextLength::PercentageLength, 30)); |
|
1078 widths.append(QTextLength(QTextLength::FixedLength, 40)); |
|
1079 fmt.setColumnWidthConstraints(widths); |
|
1080 cursor.insertTable(1, 3, fmt); |
|
1081 |
|
1082 QTest::newRow("colwidths") << QTextDocumentFragment(&doc) |
|
1083 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1084 "\n<tr>\n<td></td>\n<td width=\"30%\"></td>\n<td width=\"40\"></td></tr>" |
|
1085 "</table>"); |
|
1086 } |
|
1087 |
|
1088 // ### rowspan/colspan tests, once texttable api for that is back again |
|
1089 // |
|
1090 { |
|
1091 CREATE_DOC_AND_CURSOR(); |
|
1092 |
|
1093 QTextTable *table = cursor.insertTable(1, 1); |
|
1094 QTextCursor cellCurs = table->cellAt(0, 0).firstCursorPosition(); |
|
1095 QTextCharFormat fmt; |
|
1096 fmt.setBackground(QColor("#ffffff")); |
|
1097 cellCurs.mergeBlockCharFormat(fmt); |
|
1098 |
|
1099 QTest::newRow("cellproperties") << QTextDocumentFragment(&doc) |
|
1100 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1101 "\n<tr>\n<td bgcolor=\"#ffffff\"></td></tr>" |
|
1102 "</table>"); |
|
1103 } |
|
1104 |
|
1105 { |
|
1106 CREATE_DOC_AND_CURSOR(); |
|
1107 |
|
1108 // ### fixme: use programmatic api as soon as we can create floats through it |
|
1109 const char html[] = "<html><body>Blah<img src=\"image.png\" width=\"10\" height=\"20\" style=\"float: right;\" />Blubb</body></html>"; |
|
1110 |
|
1111 QTest::newRow("image") << QTextDocumentFragment::fromHtml(QString::fromLatin1(html)) |
|
1112 << QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah<img src=\"image.png\" width=\"10\" height=\"20\" style=\"float: right;\" />Blubb</p>"); |
|
1113 } |
|
1114 |
|
1115 { |
|
1116 CREATE_DOC_AND_CURSOR(); |
|
1117 |
|
1118 QTextImageFormat fmt; |
|
1119 fmt.setName("foo"); |
|
1120 fmt.setVerticalAlignment(QTextCharFormat::AlignMiddle); |
|
1121 cursor.insertImage(fmt); |
|
1122 |
|
1123 QTest::newRow("image-malign") << QTextDocumentFragment(&doc) |
|
1124 << QString("<p DEFAULTBLOCKSTYLE><img src=\"foo\" style=\"vertical-align: middle;\" /></p>"); |
|
1125 } |
|
1126 |
|
1127 { |
|
1128 CREATE_DOC_AND_CURSOR(); |
|
1129 |
|
1130 QTextImageFormat fmt; |
|
1131 fmt.setName("foo"); |
|
1132 fmt.setVerticalAlignment(QTextCharFormat::AlignTop); |
|
1133 cursor.insertImage(fmt); |
|
1134 |
|
1135 QTest::newRow("image-malign") << QTextDocumentFragment(&doc) |
|
1136 << QString("<p DEFAULTBLOCKSTYLE><img src=\"foo\" style=\"vertical-align: top;\" /></p>"); |
|
1137 } |
|
1138 |
|
1139 { |
|
1140 CREATE_DOC_AND_CURSOR(); |
|
1141 |
|
1142 QTextImageFormat fmt; |
|
1143 fmt.setName("foo"); |
|
1144 cursor.insertImage(fmt); |
|
1145 cursor.insertImage(fmt); |
|
1146 |
|
1147 QTest::newRow("2images") << QTextDocumentFragment(&doc) |
|
1148 << QString("<p DEFAULTBLOCKSTYLE><img src=\"foo\" /><img src=\"foo\" /></p>"); |
|
1149 } |
|
1150 |
|
1151 { |
|
1152 CREATE_DOC_AND_CURSOR(); |
|
1153 |
|
1154 QString txt = QLatin1String("Blah"); |
|
1155 txt += QChar::LineSeparator; |
|
1156 txt += QLatin1String("Bar"); |
|
1157 cursor.insertText(txt); |
|
1158 |
|
1159 QTest::newRow("linebreaks") << QTextDocumentFragment(&doc) |
|
1160 << QString("<p DEFAULTBLOCKSTYLE>Blah<br />Bar</p>"); |
|
1161 } |
|
1162 |
|
1163 { |
|
1164 CREATE_DOC_AND_CURSOR(); |
|
1165 |
|
1166 QTextBlockFormat fmt; |
|
1167 fmt.setTopMargin(10); |
|
1168 fmt.setBottomMargin(20); |
|
1169 fmt.setLeftMargin(30); |
|
1170 fmt.setRightMargin(40); |
|
1171 cursor.insertBlock(fmt); |
|
1172 cursor.insertText("Blah"); |
|
1173 |
|
1174 QTest::newRow("blockmargins") << QTextDocumentFragment(&doc) |
|
1175 << |
|
1176 QString("EMPTYBLOCK") + |
|
1177 QString("<p style=\" margin-top:10px; margin-bottom:20px; margin-left:30px; margin-right:40px; -qt-block-indent:0; text-indent:0px;\">Blah</p>"); |
|
1178 } |
|
1179 |
|
1180 { |
|
1181 CREATE_DOC_AND_CURSOR(); |
|
1182 |
|
1183 QTextList *list = cursor.insertList(QTextListFormat::ListDisc); |
|
1184 cursor.insertText("Blubb"); |
|
1185 cursor.insertBlock(); |
|
1186 cursor.insertText("Blah"); |
|
1187 QCOMPARE(list->count(), 2); |
|
1188 |
|
1189 QTest::newRow("lists") << QTextDocumentFragment(&doc) |
|
1190 << |
|
1191 QString("EMPTYBLOCK") + |
|
1192 QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blubb</li>\n<li DEFAULTBLOCKSTYLE>Blah</li></ul>"); |
|
1193 } |
|
1194 |
|
1195 { |
|
1196 CREATE_DOC_AND_CURSOR(); |
|
1197 |
|
1198 QTextList *list = cursor.insertList(QTextListFormat::ListDisc); |
|
1199 cursor.insertText("Blubb"); |
|
1200 |
|
1201 cursor.insertBlock(); |
|
1202 |
|
1203 QTextCharFormat blockCharFmt; |
|
1204 blockCharFmt.setForeground(QColor("#0000ff")); |
|
1205 cursor.mergeBlockCharFormat(blockCharFmt); |
|
1206 |
|
1207 QTextCharFormat fmt; |
|
1208 fmt.setForeground(QColor("#ff0000")); |
|
1209 cursor.insertText("Blah", fmt); |
|
1210 QCOMPARE(list->count(), 2); |
|
1211 |
|
1212 QTest::newRow("charfmt-for-list-item") << QTextDocumentFragment(&doc) |
|
1213 << |
|
1214 QString("EMPTYBLOCK") + |
|
1215 QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blubb</li>\n<li style=\" color:#0000ff;\" DEFAULTBLOCKSTYLE><span style=\" color:#ff0000;\">Blah</span></li></ul>"); |
|
1216 } |
|
1217 |
|
1218 { |
|
1219 CREATE_DOC_AND_CURSOR(); |
|
1220 |
|
1221 QTextBlockFormat fmt; |
|
1222 fmt.setIndent(3); |
|
1223 fmt.setTextIndent(30); |
|
1224 cursor.insertBlock(fmt); |
|
1225 cursor.insertText("Test"); |
|
1226 |
|
1227 QTest::newRow("block-indent") << QTextDocumentFragment(&doc) |
|
1228 << |
|
1229 QString("EMPTYBLOCK") + |
|
1230 QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:3; text-indent:30px;\">Test</p>"); |
|
1231 } |
|
1232 |
|
1233 { |
|
1234 CREATE_DOC_AND_CURSOR(); |
|
1235 |
|
1236 QTextListFormat fmt; |
|
1237 fmt.setStyle(QTextListFormat::ListDisc); |
|
1238 fmt.setIndent(4); |
|
1239 cursor.insertList(fmt); |
|
1240 cursor.insertText("Blah"); |
|
1241 |
|
1242 QTest::newRow("list-indent") << QTextDocumentFragment(&doc) |
|
1243 << |
|
1244 QString("EMPTYBLOCK") + |
|
1245 QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 4;\"><li DEFAULTBLOCKSTYLE>Blah</li></ul>"); |
|
1246 } |
|
1247 |
|
1248 { |
|
1249 CREATE_DOC_AND_CURSOR(); |
|
1250 |
|
1251 cursor.insertBlock(); |
|
1252 |
|
1253 |
|
1254 QTest::newRow("emptyblock") << QTextDocumentFragment(&doc) |
|
1255 // after insertBlock() we /do/ have two blocks in the document, so also expect |
|
1256 // these in the html output |
|
1257 << QString("EMPTYBLOCK") + QString("EMPTYBLOCK"); |
|
1258 } |
|
1259 |
|
1260 { |
|
1261 CREATE_DOC_AND_CURSOR(); |
|
1262 |
|
1263 // if you press enter twice in an empty textedit and then insert 'Test' |
|
1264 // you actually get three visible paragraphs, two empty leading ones and |
|
1265 // a third with the actual text. the corresponding html representation |
|
1266 // therefore should also contain three paragraphs. |
|
1267 |
|
1268 cursor.insertBlock(); |
|
1269 QTextCharFormat fmt; |
|
1270 fmt.setForeground(QColor("#00ff00")); |
|
1271 fmt.setProperty(QTextFormat::FontSizeIncrement, 1); |
|
1272 cursor.mergeBlockCharFormat(fmt); |
|
1273 |
|
1274 fmt.setProperty(QTextFormat::FontSizeIncrement, 2); |
|
1275 cursor.insertText("Test", fmt); |
|
1276 |
|
1277 QTest::newRow("blockcharfmt") << QTextDocumentFragment(&doc) |
|
1278 << QString("EMPTYBLOCK<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:x-large; color:#00ff00;\">Test</span></p>"); |
|
1279 } |
|
1280 |
|
1281 { |
|
1282 CREATE_DOC_AND_CURSOR(); |
|
1283 |
|
1284 QTextCharFormat fmt; |
|
1285 fmt.setForeground(QColor("#00ff00")); |
|
1286 cursor.setBlockCharFormat(fmt); |
|
1287 fmt.setForeground(QColor("#0000ff")); |
|
1288 cursor.insertText("Test", fmt); |
|
1289 |
|
1290 QTest::newRow("blockcharfmt2") << QTextDocumentFragment(&doc) |
|
1291 << QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" color:#0000ff;\">Test</span></p>"); |
|
1292 } |
|
1293 |
|
1294 { |
|
1295 QTest::newRow("horizontal-ruler") << QTextDocumentFragment::fromHtml("<hr />") |
|
1296 << |
|
1297 QString("EMPTYBLOCK") + |
|
1298 QString("<hr />"); |
|
1299 } |
|
1300 { |
|
1301 QTest::newRow("horizontal-ruler-with-width") << QTextDocumentFragment::fromHtml("<hr width=\"50%\"/>") |
|
1302 << |
|
1303 QString("EMPTYBLOCK") + |
|
1304 QString("<hr width=\"50%\"/>"); |
|
1305 } |
|
1306 { |
|
1307 CREATE_DOC_AND_CURSOR(); |
|
1308 |
|
1309 QTextFrame *mainFrame = cursor.currentFrame(); |
|
1310 |
|
1311 QTextFrameFormat ffmt; |
|
1312 ffmt.setBorder(1); |
|
1313 ffmt.setPosition(QTextFrameFormat::FloatRight); |
|
1314 ffmt.setMargin(2); |
|
1315 ffmt.setWidth(100); |
|
1316 ffmt.setHeight(50); |
|
1317 ffmt.setBackground(QColor("#00ff00")); |
|
1318 cursor.insertFrame(ffmt); |
|
1319 cursor.insertText("Hello World"); |
|
1320 cursor = mainFrame->lastCursorPosition(); |
|
1321 |
|
1322 QTest::newRow("frame") << QTextDocumentFragment(&doc) |
|
1323 << QString("<table border=\"1\" style=\"-qt-table-type: frame; float: right; margin-top:2px; margin-bottom:2px; margin-left:2px; margin-right:2px;\" width=\"100\" height=\"50\" bgcolor=\"#00ff00\">\n<tr>\n<td style=\"border: none;\">\n<p DEFAULTBLOCKSTYLE>Hello World</p></td></tr></table>"); |
|
1324 } |
|
1325 |
|
1326 { |
|
1327 CREATE_DOC_AND_CURSOR(); |
|
1328 |
|
1329 QTextCharFormat fmt; |
|
1330 fmt.setForeground(QColor("#00ff00")); |
|
1331 // fmt.setBackground(QColor("#0000ff")); |
|
1332 cursor.setBlockCharFormat(fmt); |
|
1333 |
|
1334 fmt.setForeground(QBrush()); |
|
1335 // fmt.setBackground(QBrush()); |
|
1336 cursor.insertText("Test", fmt); |
|
1337 |
|
1338 // QTest::newRow("nostylebrush") << QTextDocumentFragment(&doc) << QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#00ff00; -qt-blockcharfmt-background-color:#0000ff;\">Test</p>"); |
|
1339 QTest::newRow("nostylebrush") << QTextDocumentFragment(&doc) << QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Test</p>"); |
|
1340 } |
|
1341 |
|
1342 { |
|
1343 CREATE_DOC_AND_CURSOR(); |
|
1344 |
|
1345 QTextTable *table = cursor.insertTable(2, 2); |
|
1346 table->mergeCells(0, 0, 1, 2); |
|
1347 QTextTableFormat fmt = table->format(); |
|
1348 QVector<QTextLength> widths; |
|
1349 widths.append(QTextLength(QTextLength::FixedLength, 20)); |
|
1350 widths.append(QTextLength(QTextLength::FixedLength, 40)); |
|
1351 fmt.setColumnWidthConstraints(widths); |
|
1352 table->setFormat(fmt); |
|
1353 |
|
1354 QTest::newRow("mergedtablecolwidths") << QTextDocumentFragment(&doc) |
|
1355 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1356 "\n<tr>\n<td colspan=\"2\"></td></tr>" |
|
1357 "\n<tr>\n<td width=\"20\"></td>\n<td width=\"40\"></td></tr>" |
|
1358 "</table>"); |
|
1359 } |
|
1360 |
|
1361 { |
|
1362 CREATE_DOC_AND_CURSOR(); |
|
1363 |
|
1364 QTextCharFormat fmt; |
|
1365 |
|
1366 cursor.insertText("Blah\nGreen yellow green"); |
|
1367 cursor.setPosition(0); |
|
1368 cursor.setPosition(23, QTextCursor::KeepAnchor); |
|
1369 fmt.setBackground(Qt::green); |
|
1370 cursor.mergeCharFormat(fmt); |
|
1371 cursor.clearSelection(); |
|
1372 cursor.setPosition(11); |
|
1373 cursor.setPosition(17, QTextCursor::KeepAnchor); |
|
1374 fmt.setBackground(Qt::yellow); |
|
1375 cursor.mergeCharFormat(fmt); |
|
1376 cursor.clearSelection(); |
|
1377 |
|
1378 QTest::newRow("multiparagraph-bgcolor") << QTextDocumentFragment(&doc) |
|
1379 << QString("<p DEFAULTBLOCKSTYLE><span style=\" background-color:#00ff00;\">Blah</span></p>\n" |
|
1380 "<p DEFAULTBLOCKSTYLE><span style=\" background-color:#00ff00;\">Green </span>" |
|
1381 "<span style=\" background-color:#ffff00;\">yellow</span>" |
|
1382 "<span style=\" background-color:#00ff00;\"> green</span></p>"); |
|
1383 } |
|
1384 |
|
1385 { |
|
1386 CREATE_DOC_AND_CURSOR(); |
|
1387 |
|
1388 QTextBlockFormat fmt; |
|
1389 fmt.setBackground(QColor("#0000ff")); |
|
1390 cursor.insertBlock(fmt); |
|
1391 |
|
1392 QTextCharFormat charfmt; |
|
1393 charfmt.setBackground(QColor("#0000ff")); |
|
1394 cursor.insertText("Blah", charfmt); |
|
1395 |
|
1396 QTest::newRow("nospan-bgcolor") << QTextDocumentFragment(&doc) |
|
1397 << QString("EMPTYBLOCK") + |
|
1398 QString("<p OPENDEFAULTBLOCKSTYLE background-color:#0000ff;\"><span style=\" background-color:#0000ff;\">Blah</span></p>"); |
|
1399 } |
|
1400 |
|
1401 { |
|
1402 CREATE_DOC_AND_CURSOR(); |
|
1403 |
|
1404 QTextTable *table = cursor.insertTable(2, 2); |
|
1405 QTextCharFormat fmt = table->cellAt(0, 0).format(); |
|
1406 fmt.setVerticalAlignment(QTextCharFormat::AlignMiddle); |
|
1407 table->cellAt(0, 0).setFormat(fmt); |
|
1408 fmt = table->cellAt(0, 1).format(); |
|
1409 fmt.setVerticalAlignment(QTextCharFormat::AlignTop); |
|
1410 table->cellAt(0, 1).setFormat(fmt); |
|
1411 fmt = table->cellAt(1, 0).format(); |
|
1412 fmt.setVerticalAlignment(QTextCharFormat::AlignBottom); |
|
1413 table->cellAt(1, 0).setFormat(fmt); |
|
1414 |
|
1415 table->cellAt(0, 0).firstCursorPosition().insertText("Blah"); |
|
1416 |
|
1417 QTest::newRow("table-vertical-alignment") << QTextDocumentFragment(&doc) |
|
1418 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1419 "\n<tr>\n<td style=\" vertical-align:middle;\">\n" |
|
1420 "<p DEFAULTBLOCKSTYLE>Blah</p></td>" |
|
1421 "\n<td style=\" vertical-align:top;\"></td></tr>" |
|
1422 "\n<tr>\n<td style=\" vertical-align:bottom;\"></td>" |
|
1423 "\n<td></td></tr>" |
|
1424 "</table>"); |
|
1425 } |
|
1426 |
|
1427 { |
|
1428 CREATE_DOC_AND_CURSOR(); |
|
1429 |
|
1430 QTextTable *table = cursor.insertTable(2, 2); |
|
1431 QTextTableCellFormat fmt = table->cellAt(0, 0).format().toTableCellFormat(); |
|
1432 fmt.setLeftPadding(1); |
|
1433 table->cellAt(0, 0).setFormat(fmt); |
|
1434 fmt = table->cellAt(0, 1).format().toTableCellFormat(); |
|
1435 fmt.setRightPadding(1); |
|
1436 table->cellAt(0, 1).setFormat(fmt); |
|
1437 fmt = table->cellAt(1, 0).format().toTableCellFormat(); |
|
1438 fmt.setTopPadding(1); |
|
1439 table->cellAt(1, 0).setFormat(fmt); |
|
1440 fmt = table->cellAt(1, 1).format().toTableCellFormat(); |
|
1441 fmt.setBottomPadding(1); |
|
1442 table->cellAt(1, 1).setFormat(fmt); |
|
1443 |
|
1444 table->cellAt(0, 0).firstCursorPosition().insertText("Blah"); |
|
1445 |
|
1446 QTest::newRow("table-cell-paddings") << QTextDocumentFragment(&doc) |
|
1447 << QString("<table border=\"1\" cellspacing=\"2\">" |
|
1448 "\n<tr>\n<td style=\" padding-left:1;\">\n" |
|
1449 "<p DEFAULTBLOCKSTYLE>Blah</p></td>" |
|
1450 "\n<td style=\" padding-right:1;\"></td></tr>" |
|
1451 "\n<tr>\n<td style=\" padding-top:1;\"></td>" |
|
1452 "\n<td style=\" padding-bottom:1;\"></td></tr>" |
|
1453 "</table>"); |
|
1454 } |
|
1455 |
|
1456 { |
|
1457 CREATE_DOC_AND_CURSOR(); |
|
1458 |
|
1459 QTextTableFormat fmt; |
|
1460 fmt.setBorderBrush(QColor("#0000ff")); |
|
1461 fmt.setBorderStyle(QTextFrameFormat::BorderStyle_Solid); |
|
1462 cursor.insertTable(2, 2, fmt); |
|
1463 |
|
1464 QTest::newRow("tableborder") << QTextDocumentFragment(&doc) |
|
1465 << QString("<table border=\"1\" style=\" border-color:#0000ff; border-style:solid;\" cellspacing=\"2\">" |
|
1466 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1467 "\n<tr>\n<td></td>\n<td></td></tr>" |
|
1468 "</table>"); |
|
1469 } |
|
1470 |
|
1471 { |
|
1472 CREATE_DOC_AND_CURSOR(); |
|
1473 |
|
1474 cursor.insertBlock(); |
|
1475 cursor.insertText("Foo"); |
|
1476 |
|
1477 cursor.block().setUserState(42); |
|
1478 |
|
1479 QTest::newRow("userstate") << QTextDocumentFragment(&doc) |
|
1480 << QString("EMPTYBLOCK") + |
|
1481 QString("<p OPENDEFAULTBLOCKSTYLE -qt-user-state:42;\">Foo</p>"); |
|
1482 } |
|
1483 |
|
1484 { |
|
1485 CREATE_DOC_AND_CURSOR(); |
|
1486 |
|
1487 QTextBlockFormat blockFmt; |
|
1488 blockFmt.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore); |
|
1489 |
|
1490 cursor.insertBlock(blockFmt); |
|
1491 cursor.insertText("Foo"); |
|
1492 |
|
1493 blockFmt.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore | QTextFormat::PageBreak_AlwaysAfter); |
|
1494 |
|
1495 cursor.insertBlock(blockFmt); |
|
1496 cursor.insertText("Bar"); |
|
1497 |
|
1498 QTextTableFormat tableFmt; |
|
1499 tableFmt.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysAfter); |
|
1500 |
|
1501 cursor.insertTable(1, 1, tableFmt); |
|
1502 |
|
1503 QTest::newRow("pagebreak") << QTextDocumentFragment(&doc) |
|
1504 << QString("EMPTYBLOCK") + |
|
1505 QString("<p OPENDEFAULTBLOCKSTYLE page-break-before:always;\">Foo</p>" |
|
1506 "\n<p OPENDEFAULTBLOCKSTYLE page-break-before:always; page-break-after:always;\">Bar</p>" |
|
1507 "\n<table border=\"1\" style=\" page-break-after:always;\" cellspacing=\"2\">\n<tr>\n<td></td></tr></table>"); |
|
1508 } |
|
1509 |
|
1510 { |
|
1511 CREATE_DOC_AND_CURSOR(); |
|
1512 |
|
1513 QTextListFormat listFmt; |
|
1514 listFmt.setStyle(QTextListFormat::ListDisc); |
|
1515 |
|
1516 cursor.insertList(listFmt); |
|
1517 cursor.insertText("Blah"); |
|
1518 |
|
1519 QTest::newRow("list-ul-margin") << QTextDocumentFragment(&doc) |
|
1520 << QString("EMPTYBLOCK") + |
|
1521 QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blah</li></ul>"); |
|
1522 } |
|
1523 } |
|
1524 |
|
1525 void tst_QTextDocument::toHtml() |
|
1526 { |
|
1527 QFETCH(QTextDocumentFragment, input); |
|
1528 QFETCH(QString, expectedOutput); |
|
1529 |
|
1530 cursor.insertFragment(input); |
|
1531 |
|
1532 expectedOutput.prepend(htmlHead); |
|
1533 |
|
1534 expectedOutput.replace("OPENDEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"); |
|
1535 expectedOutput.replace("DEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\""); |
|
1536 expectedOutput.replace("EMPTYBLOCK", "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"); |
|
1537 if (expectedOutput.endsWith(QLatin1Char('\n'))) |
|
1538 expectedOutput.chop(1); |
|
1539 expectedOutput.append(htmlTail); |
|
1540 |
|
1541 QString output = doc->toHtml(); |
|
1542 |
|
1543 QCOMPARE(output, expectedOutput); |
|
1544 } |
|
1545 |
|
1546 void tst_QTextDocument::toHtml2() |
|
1547 { |
|
1548 QTextDocument doc; |
|
1549 doc.setHtml("<p>text <img src=\"\"> text</p>"); // 4 spaces before the second 'text' |
|
1550 QTextBlock block = doc.firstBlock(); |
|
1551 QTextBlock::Iterator iter = block.begin(); |
|
1552 QTextFragment f = iter.fragment(); |
|
1553 QVERIFY(f.isValid()); |
|
1554 QCOMPARE(f.position(), 0); |
|
1555 QCOMPARE(f.length(), 5); |
|
1556 //qDebug() << block.text().mid(f.position(), f.length()); |
|
1557 |
|
1558 iter++; |
|
1559 f = iter.fragment(); |
|
1560 QVERIFY(f.isValid()); |
|
1561 QCOMPARE(f.position(), 5); |
|
1562 QCOMPARE(f.length(), 1); |
|
1563 //qDebug() << block.text().mid(f.position(), f.length()); |
|
1564 |
|
1565 iter++; |
|
1566 f = iter.fragment(); |
|
1567 //qDebug() << block.text().mid(f.position(), f.length()); |
|
1568 QVERIFY(f.isValid()); |
|
1569 QCOMPARE(f.position(), 6); |
|
1570 QCOMPARE(f.length(), 5); // 1 space should be preserved. |
|
1571 QCOMPARE(block.text().mid(f.position(), f.length()), QString(" text")); |
|
1572 |
|
1573 doc.setHtml("<table><tr><td> foo</td></tr></table> text"); // 4 spaces before the second 'text' |
|
1574 block = doc.firstBlock().next(); |
|
1575 //qDebug() << block.text(); |
|
1576 QCOMPARE(block.text(), QString("foo")); |
|
1577 |
|
1578 block = block.next(); |
|
1579 //qDebug() << block.text(); |
|
1580 QCOMPARE(block.text(), QString("text")); |
|
1581 } |
|
1582 |
|
1583 void tst_QTextDocument::setFragmentMarkersInHtmlExport() |
|
1584 { |
|
1585 { |
|
1586 CREATE_DOC_AND_CURSOR(); |
|
1587 |
|
1588 cursor.insertText("Leadin"); |
|
1589 const int startPos = cursor.position(); |
|
1590 |
|
1591 cursor.insertText("Test"); |
|
1592 QTextCharFormat fmt; |
|
1593 fmt.setForeground(QColor("#00ff00")); |
|
1594 cursor.insertText("Blah", fmt); |
|
1595 |
|
1596 const int endPos = cursor.position(); |
|
1597 cursor.insertText("Leadout", QTextCharFormat()); |
|
1598 |
|
1599 cursor.setPosition(startPos); |
|
1600 cursor.setPosition(endPos, QTextCursor::KeepAnchor); |
|
1601 QTextDocumentFragment fragment(cursor); |
|
1602 |
|
1603 QString expected = htmlHead; |
|
1604 expected.replace(QRegExp("<body.*>"), QString("<body>")); |
|
1605 expected += QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><!--StartFragment-->Test<span style=\" color:#00ff00;\">Blah</span><!--EndFragment--></p>") + htmlTail; |
|
1606 QCOMPARE(fragment.toHtml(), expected); |
|
1607 } |
|
1608 { |
|
1609 CREATE_DOC_AND_CURSOR(); |
|
1610 |
|
1611 cursor.insertText("Leadin"); |
|
1612 const int startPos = cursor.position(); |
|
1613 |
|
1614 cursor.insertText("Test"); |
|
1615 |
|
1616 const int endPos = cursor.position(); |
|
1617 cursor.insertText("Leadout", QTextCharFormat()); |
|
1618 |
|
1619 cursor.setPosition(startPos); |
|
1620 cursor.setPosition(endPos, QTextCursor::KeepAnchor); |
|
1621 QTextDocumentFragment fragment(cursor); |
|
1622 |
|
1623 QString expected = htmlHead; |
|
1624 expected.replace(QRegExp("<body.*>"), QString("<body>")); |
|
1625 expected += QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><!--StartFragment-->Test<!--EndFragment--></p>") + htmlTail; |
|
1626 QCOMPARE(fragment.toHtml(), expected); |
|
1627 } |
|
1628 } |
|
1629 |
|
1630 void tst_QTextDocument::toHtmlBodyBgColor() |
|
1631 { |
|
1632 CREATE_DOC_AND_CURSOR(); |
|
1633 |
|
1634 cursor.insertText("Blah"); |
|
1635 |
|
1636 QTextFrameFormat fmt = doc.rootFrame()->frameFormat(); |
|
1637 fmt.setBackground(QColor("#0000ff")); |
|
1638 doc.rootFrame()->setFrameFormat(fmt); |
|
1639 |
|
1640 QString expectedHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " |
|
1641 "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" |
|
1642 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" |
|
1643 "p, li { white-space: pre-wrap; }\n" |
|
1644 "</style></head>" |
|
1645 "<body style=\" font-family:'%1'; font-size:%2pt; font-weight:%3; font-style:%4;\"" |
|
1646 " bgcolor=\"#0000ff\">\n" |
|
1647 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" |
|
1648 "</body></html>"); |
|
1649 |
|
1650 expectedHtml = expectedHtml.arg(defaultFont.family()).arg(defaultFont.pointSizeF()).arg(defaultFont.weight() * 8).arg((defaultFont.italic() ? "italic" : "normal")); |
|
1651 |
|
1652 QCOMPARE(doc.toHtml(), expectedHtml); |
|
1653 } |
|
1654 |
|
1655 void tst_QTextDocument::toHtmlRootFrameProperties() |
|
1656 { |
|
1657 CREATE_DOC_AND_CURSOR(); |
|
1658 |
|
1659 QTextFrameFormat fmt = doc.rootFrame()->frameFormat(); |
|
1660 fmt.setTopMargin(10); |
|
1661 fmt.setLeftMargin(10); |
|
1662 fmt.setBorder(2); |
|
1663 doc.rootFrame()->setFrameFormat(fmt); |
|
1664 |
|
1665 cursor.insertText("Blah"); |
|
1666 |
|
1667 QString expectedOutput("<table border=\"2\" style=\"-qt-table-type: root; margin-top:10px; " |
|
1668 "margin-bottom:4px; margin-left:10px; margin-right:4px;\">\n" |
|
1669 "<tr>\n<td style=\"border: none;\">\n" |
|
1670 "<p DEFAULTBLOCKSTYLE>Blah</p></td></tr></table>"); |
|
1671 |
|
1672 expectedOutput.prepend(htmlHead); |
|
1673 expectedOutput.replace("DEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\""); |
|
1674 expectedOutput.append(htmlTail); |
|
1675 |
|
1676 QCOMPARE(doc.toHtml(), expectedOutput); |
|
1677 } |
|
1678 |
|
1679 void tst_QTextDocument::capitalizationHtmlInExport() |
|
1680 { |
|
1681 doc->setPlainText("Test"); |
|
1682 |
|
1683 QRegExp re(".*span style=\"(.*)\">Test.*"); |
|
1684 QVERIFY(re.exactMatch(doc->toHtml()) == false); // no span |
|
1685 |
|
1686 QTextCursor cursor(doc); |
|
1687 cursor.setPosition(4, QTextCursor::KeepAnchor); |
|
1688 QTextCharFormat cf; |
|
1689 cf.setFontCapitalization(QFont::SmallCaps); |
|
1690 cursor.mergeCharFormat(cf); |
|
1691 |
|
1692 const QString smallcaps = doc->toHtml(); |
|
1693 QVERIFY(re.exactMatch(doc->toHtml())); |
|
1694 QCOMPARE(re.numCaptures(), 1); |
|
1695 QCOMPARE(re.cap(1).trimmed(), QString("font-variant:small-caps;")); |
|
1696 |
|
1697 cf.setFontCapitalization(QFont::AllUppercase); |
|
1698 cursor.mergeCharFormat(cf); |
|
1699 const QString uppercase = doc->toHtml(); |
|
1700 QVERIFY(re.exactMatch(doc->toHtml())); |
|
1701 QCOMPARE(re.numCaptures(), 1); |
|
1702 QCOMPARE(re.cap(1).trimmed(), QString("text-transform:uppercase;")); |
|
1703 |
|
1704 cf.setFontCapitalization(QFont::AllLowercase); |
|
1705 cursor.mergeCharFormat(cf); |
|
1706 const QString lowercase = doc->toHtml(); |
|
1707 QVERIFY(re.exactMatch(doc->toHtml())); |
|
1708 QCOMPARE(re.numCaptures(), 1); |
|
1709 QCOMPARE(re.cap(1).trimmed(), QString("text-transform:lowercase;")); |
|
1710 |
|
1711 doc->setHtml(smallcaps); |
|
1712 cursor.setPosition(1); |
|
1713 QCOMPARE(cursor.charFormat().fontCapitalization(), QFont::SmallCaps); |
|
1714 doc->setHtml(uppercase); |
|
1715 QCOMPARE(cursor.charFormat().fontCapitalization(), QFont::AllUppercase); |
|
1716 doc->setHtml(lowercase); |
|
1717 QCOMPARE(cursor.charFormat().fontCapitalization(), QFont::AllLowercase); |
|
1718 } |
|
1719 |
|
1720 void tst_QTextDocument::wordspacingHtmlExport() |
|
1721 { |
|
1722 doc->setPlainText("Test"); |
|
1723 |
|
1724 QRegExp re(".*span style=\"(.*)\">Test.*"); |
|
1725 QVERIFY(re.exactMatch(doc->toHtml()) == false); // no span |
|
1726 |
|
1727 QTextCursor cursor(doc); |
|
1728 cursor.setPosition(4, QTextCursor::KeepAnchor); |
|
1729 QTextCharFormat cf; |
|
1730 cf.setFontWordSpacing(4); |
|
1731 cursor.mergeCharFormat(cf); |
|
1732 |
|
1733 QVERIFY(re.exactMatch(doc->toHtml())); |
|
1734 QCOMPARE(re.numCaptures(), 1); |
|
1735 QCOMPARE(re.cap(1).trimmed(), QString("word-spacing:4px;")); |
|
1736 |
|
1737 cf.setFontWordSpacing(-8.5); |
|
1738 cursor.mergeCharFormat(cf); |
|
1739 |
|
1740 QVERIFY(re.exactMatch(doc->toHtml())); |
|
1741 QCOMPARE(re.numCaptures(), 1); |
|
1742 QCOMPARE(re.cap(1).trimmed(), QString("word-spacing:-8.5px;")); |
|
1743 } |
|
1744 |
|
1745 class CursorPosSignalSpy : public QObject |
|
1746 { |
|
1747 Q_OBJECT |
|
1748 public: |
|
1749 CursorPosSignalSpy(QTextDocument *doc) |
|
1750 { |
|
1751 calls = 0; |
|
1752 connect(doc, SIGNAL(cursorPositionChanged(const QTextCursor &)), |
|
1753 this, SLOT(cursorPositionChanged(const QTextCursor &))); |
|
1754 } |
|
1755 |
|
1756 int calls; |
|
1757 |
|
1758 private slots: |
|
1759 void cursorPositionChanged(const QTextCursor &) |
|
1760 { |
|
1761 ++calls; |
|
1762 } |
|
1763 }; |
|
1764 |
|
1765 void tst_QTextDocument::cursorPositionChanged() |
|
1766 { |
|
1767 CursorPosSignalSpy spy(doc); |
|
1768 |
|
1769 cursor.insertText("Test"); |
|
1770 QCOMPARE(spy.calls, 1); |
|
1771 |
|
1772 spy.calls = 0; |
|
1773 QTextCursor unrelatedCursor(doc); |
|
1774 unrelatedCursor.insertText("Blah"); |
|
1775 QCOMPARE(spy.calls, 2); |
|
1776 |
|
1777 spy.calls = 0; |
|
1778 cursor.insertText("Blah"); |
|
1779 QCOMPARE(spy.calls, 1); |
|
1780 |
|
1781 spy.calls = 0; |
|
1782 cursor.movePosition(QTextCursor::PreviousCharacter); |
|
1783 QCOMPARE(spy.calls, 0); |
|
1784 } |
|
1785 |
|
1786 void tst_QTextDocument::cursorPositionChangedOnSetText() |
|
1787 { |
|
1788 CursorPosSignalSpy spy(doc); |
|
1789 |
|
1790 // doc has one QTextCursor stored in the |
|
1791 // cursor member variable, thus the signal |
|
1792 // gets emitted once. |
|
1793 |
|
1794 doc->setPlainText("Foo\nBar\nBaz\nBlub\nBlah"); |
|
1795 |
|
1796 QCOMPARE(spy.calls, 1); |
|
1797 |
|
1798 spy.calls = 0; |
|
1799 doc->setHtml("<p>Foo<p>Bar<p>Baz<p>Blah"); |
|
1800 |
|
1801 QCOMPARE(spy.calls, 1); |
|
1802 } |
|
1803 |
|
1804 void tst_QTextDocument::textFrameIterator() |
|
1805 { |
|
1806 cursor.insertTable(1, 1); |
|
1807 |
|
1808 int blockCount = 0; |
|
1809 int frameCount = 0; |
|
1810 |
|
1811 for (QTextFrame::Iterator frameIt = doc->rootFrame()->begin(); |
|
1812 !frameIt.atEnd(); ++frameIt) { |
|
1813 if (frameIt.currentFrame()) |
|
1814 ++frameCount; |
|
1815 else if (frameIt.currentBlock().isValid()) |
|
1816 ++blockCount; |
|
1817 |
|
1818 } |
|
1819 |
|
1820 QEXPECT_FAIL("", "This is currently worked around in the html export but needs fixing!", Continue); |
|
1821 QCOMPARE(blockCount, 0); |
|
1822 QCOMPARE(frameCount, 1); |
|
1823 } |
|
1824 |
|
1825 void tst_QTextDocument::codecForHtml() |
|
1826 { |
|
1827 const QByteArray header("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html;charset=utf-16\">"); |
|
1828 QTextCodec *c = Qt::codecForHtml(header); |
|
1829 QVERIFY(c); |
|
1830 QCOMPARE(c->name(), QByteArray("UTF-16")); |
|
1831 } |
|
1832 |
|
1833 class TestSyntaxHighlighter : public QObject |
|
1834 { |
|
1835 Q_OBJECT |
|
1836 public: |
|
1837 inline TestSyntaxHighlighter(QTextDocument *doc) : QObject(doc), ok(false) {} |
|
1838 |
|
1839 bool ok; |
|
1840 |
|
1841 private slots: |
|
1842 inline void markBlockDirty(int from, int charsRemoved, int charsAdded) |
|
1843 { |
|
1844 Q_UNUSED(charsRemoved); |
|
1845 Q_UNUSED(charsAdded); |
|
1846 QTextDocument *doc = static_cast<QTextDocument *>(parent()); |
|
1847 QTextBlock block = doc->findBlock(from); |
|
1848 |
|
1849 QTestDocumentLayout *lout = qobject_cast<QTestDocumentLayout *>(doc->documentLayout()); |
|
1850 lout->called = false; |
|
1851 |
|
1852 doc->markContentsDirty(block.position(), block.length()); |
|
1853 |
|
1854 ok = (lout->called == false); |
|
1855 } |
|
1856 |
|
1857 inline void modifyBlockAgain(int from, int charsRemoved, int charsAdded) |
|
1858 { |
|
1859 Q_UNUSED(charsRemoved); |
|
1860 Q_UNUSED(charsAdded); |
|
1861 QTextDocument *doc = static_cast<QTextDocument *>(parent()); |
|
1862 QTextBlock block = doc->findBlock(from); |
|
1863 QTextCursor cursor(block); |
|
1864 |
|
1865 QTestDocumentLayout *lout = qobject_cast<QTestDocumentLayout *>(doc->documentLayout()); |
|
1866 lout->called = false; |
|
1867 |
|
1868 cursor.insertText("Foo"); |
|
1869 |
|
1870 ok = (lout->called == true); |
|
1871 } |
|
1872 }; |
|
1873 |
|
1874 void tst_QTextDocument::markContentsDirty() |
|
1875 { |
|
1876 QTestDocumentLayout *lout = new QTestDocumentLayout(doc); |
|
1877 doc->setDocumentLayout(lout); |
|
1878 TestSyntaxHighlighter *highlighter = new TestSyntaxHighlighter(doc); |
|
1879 connect(doc, SIGNAL(contentsChange(int, int, int)), |
|
1880 highlighter, SLOT(markBlockDirty(int, int, int))); |
|
1881 |
|
1882 highlighter->ok = false; |
|
1883 cursor.insertText("Some dummy text blah blah"); |
|
1884 QVERIFY(highlighter->ok); |
|
1885 |
|
1886 disconnect(doc, SIGNAL(contentsChange(int, int, int)), |
|
1887 highlighter, SLOT(markBlockDirty(int, int, int))); |
|
1888 connect(doc, SIGNAL(contentsChange(int, int, int)), |
|
1889 highlighter, SLOT(modifyBlockAgain(int, int, int))); |
|
1890 highlighter->ok = false; |
|
1891 cursor.insertText("FooBar"); |
|
1892 QVERIFY(highlighter->ok); |
|
1893 |
|
1894 lout->called = false; |
|
1895 |
|
1896 doc->markContentsDirty(1, 4); |
|
1897 |
|
1898 QVERIFY(lout->called); |
|
1899 } |
|
1900 |
|
1901 void tst_QTextDocument::clonePreservesMetaInformation() |
|
1902 { |
|
1903 const QString title("Foobar"); |
|
1904 const QString url("about:blank"); |
|
1905 doc->setHtml("<html><head><title>" + title + "</title></head><body>Hrm</body></html>"); |
|
1906 doc->setMetaInformation(QTextDocument::DocumentUrl, url); |
|
1907 QCOMPARE(doc->metaInformation(QTextDocument::DocumentTitle), title); |
|
1908 QCOMPARE(doc->metaInformation(QTextDocument::DocumentUrl), url); |
|
1909 |
|
1910 QTextDocument *clone = doc->clone(); |
|
1911 QCOMPARE(clone->metaInformation(QTextDocument::DocumentTitle), title); |
|
1912 QCOMPARE(clone->metaInformation(QTextDocument::DocumentUrl), url); |
|
1913 delete clone; |
|
1914 } |
|
1915 |
|
1916 void tst_QTextDocument::clonePreservesPageSize() |
|
1917 { |
|
1918 QSizeF sz(100., 100.); |
|
1919 doc->setPageSize(sz); |
|
1920 QTextDocument *clone = doc->clone(); |
|
1921 QCOMPARE(clone->pageSize(), sz); |
|
1922 delete clone; |
|
1923 } |
|
1924 |
|
1925 void tst_QTextDocument::clonePreservesPageBreakPolicies() |
|
1926 { |
|
1927 QTextTableFormat tableFmt; |
|
1928 tableFmt.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysAfter); |
|
1929 |
|
1930 QTextBlockFormat blockFmt; |
|
1931 blockFmt.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore); |
|
1932 |
|
1933 QTextCursor cursor(doc); |
|
1934 |
|
1935 cursor.setBlockFormat(blockFmt); |
|
1936 cursor.insertText("foo"); |
|
1937 cursor.insertTable(2, 2, tableFmt); |
|
1938 |
|
1939 QTextDocument *clone = doc->clone(); |
|
1940 QCOMPARE(clone->begin().blockFormat().pageBreakPolicy(), QTextFormat::PageBreak_AlwaysBefore); |
|
1941 QVERIFY(!clone->rootFrame()->childFrames().isEmpty()); |
|
1942 QCOMPARE(clone->rootFrame()->childFrames().first()->frameFormat().pageBreakPolicy(), QTextFormat::PageBreak_AlwaysAfter); |
|
1943 delete clone; |
|
1944 } |
|
1945 |
|
1946 void tst_QTextDocument::clonePreservesDefaultFont() |
|
1947 { |
|
1948 QFont f = doc->defaultFont(); |
|
1949 QVERIFY(f.pointSize() != 100); |
|
1950 f.setPointSize(100); |
|
1951 doc->setDefaultFont(f); |
|
1952 QTextDocument *clone = doc->clone(); |
|
1953 QCOMPARE(clone->defaultFont(), f); |
|
1954 delete clone; |
|
1955 } |
|
1956 |
|
1957 void tst_QTextDocument::clonePreservesResources() |
|
1958 { |
|
1959 QUrl testUrl(":/foobar"); |
|
1960 QVariant testResource("hello world"); |
|
1961 |
|
1962 doc->addResource(QTextDocument::ImageResource, testUrl, testResource); |
|
1963 QTextDocument *clone = doc->clone(); |
|
1964 QVERIFY(clone->resource(QTextDocument::ImageResource, testUrl) == testResource); |
|
1965 delete clone; |
|
1966 } |
|
1967 |
|
1968 void tst_QTextDocument::clonePreservesUserStates() |
|
1969 { |
|
1970 QTextCursor cursor(doc); |
|
1971 cursor.insertText("bla bla bla"); |
|
1972 cursor.block().setUserState(1); |
|
1973 cursor.insertBlock(); |
|
1974 cursor.insertText("foo bar"); |
|
1975 cursor.block().setUserState(2); |
|
1976 cursor.insertBlock(); |
|
1977 cursor.insertText("no user state"); |
|
1978 |
|
1979 QTextDocument *clone = doc->clone(); |
|
1980 QTextBlock b1 = doc->begin(), b2 = clone->begin(); |
|
1981 while (b1 != doc->end()) { |
|
1982 b1 = b1.next(); |
|
1983 b2 = b2.next(); |
|
1984 QCOMPARE(b1.userState(), b2.userState()); |
|
1985 } |
|
1986 QVERIFY(b2 == clone->end()); |
|
1987 delete clone; |
|
1988 } |
|
1989 |
|
1990 void tst_QTextDocument::clonePreservesRootFrameFormat() |
|
1991 { |
|
1992 doc->setPlainText("Hello"); |
|
1993 QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); |
|
1994 fmt.setMargin(200); |
|
1995 doc->rootFrame()->setFrameFormat(fmt); |
|
1996 QCOMPARE(doc->rootFrame()->frameFormat().margin(), qreal(200)); |
|
1997 QTextDocument *copy = doc->clone(); |
|
1998 QCOMPARE(copy->rootFrame()->frameFormat().margin(), qreal(200)); |
|
1999 delete copy; |
|
2000 } |
|
2001 |
|
2002 void tst_QTextDocument::clonePreservesIndentWidth() |
|
2003 { |
|
2004 doc->setIndentWidth(42); |
|
2005 QTextDocument *clone = doc->clone(); |
|
2006 QCOMPARE(clone->indentWidth(), qreal(42)); |
|
2007 } |
|
2008 |
|
2009 void tst_QTextDocument::blockCount() |
|
2010 { |
|
2011 QCOMPARE(doc->blockCount(), 1); |
|
2012 cursor.insertBlock(); |
|
2013 QCOMPARE(doc->blockCount(), 2); |
|
2014 cursor.insertBlock(); |
|
2015 QCOMPARE(doc->blockCount(), 3); |
|
2016 cursor.insertText("blah blah"); |
|
2017 QCOMPARE(doc->blockCount(), 3); |
|
2018 doc->undo(); |
|
2019 doc->undo(); |
|
2020 QCOMPARE(doc->blockCount(), 2); |
|
2021 doc->undo(); |
|
2022 QCOMPARE(doc->blockCount(), 1); |
|
2023 } |
|
2024 |
|
2025 void tst_QTextDocument::resolvedFontInEmptyFormat() |
|
2026 { |
|
2027 QFont font; |
|
2028 font.setPointSize(42); |
|
2029 doc->setDefaultFont(font); |
|
2030 QTextCharFormat fmt = doc->begin().charFormat(); |
|
2031 QVERIFY(fmt.properties().isEmpty()); |
|
2032 QVERIFY(fmt.font() == font); |
|
2033 } |
|
2034 |
|
2035 void tst_QTextDocument::defaultRootFrameMargin() |
|
2036 { |
|
2037 QCOMPARE(doc->rootFrame()->frameFormat().margin(), 4.0); |
|
2038 } |
|
2039 |
|
2040 class TestDocument : public QTextDocument |
|
2041 { |
|
2042 public: |
|
2043 inline TestDocument(const QUrl &testUrl, const QString &testString) |
|
2044 : url(testUrl), string(testString), resourceLoaded(false) {} |
|
2045 |
|
2046 bool hasResourceCached(); |
|
2047 |
|
2048 protected: |
|
2049 virtual QVariant loadResource(int type, const QUrl &name); |
|
2050 |
|
2051 private: |
|
2052 QUrl url; |
|
2053 QString string; |
|
2054 bool resourceLoaded; |
|
2055 }; |
|
2056 |
|
2057 bool TestDocument::hasResourceCached() |
|
2058 { |
|
2059 resourceLoaded = false; |
|
2060 resource(QTextDocument::ImageResource, url); |
|
2061 return !resourceLoaded; |
|
2062 } |
|
2063 |
|
2064 QVariant TestDocument::loadResource(int type, const QUrl &name) |
|
2065 { |
|
2066 if (type == QTextDocument::ImageResource |
|
2067 && name == url) { |
|
2068 resourceLoaded = true; |
|
2069 return string; |
|
2070 } |
|
2071 return QTextDocument::loadResource(type, name); |
|
2072 } |
|
2073 |
|
2074 void tst_QTextDocument::clearResources() |
|
2075 { |
|
2076 // regular resource for QTextDocument |
|
2077 QUrl testUrl(":/foobar"); |
|
2078 QVariant testResource("hello world"); |
|
2079 |
|
2080 // implicitly cached resource, initially loaded through TestDocument::loadResource() |
|
2081 QUrl cacheUrl(":/blub"); |
|
2082 QString cacheResource("mah"); |
|
2083 |
|
2084 TestDocument doc(cacheUrl, cacheResource); |
|
2085 doc.addResource(QTextDocument::ImageResource, testUrl, testResource); |
|
2086 |
|
2087 QVERIFY(doc.resource(QTextDocument::ImageResource, testUrl) == testResource); |
|
2088 |
|
2089 doc.setPlainText("Hah"); |
|
2090 QVERIFY(doc.resource(QTextDocument::ImageResource, testUrl) == testResource); |
|
2091 |
|
2092 doc.setHtml("<b>Mooo</b><img src=\":/blub\"/>"); |
|
2093 QVERIFY(doc.resource(QTextDocument::ImageResource, testUrl) == testResource); |
|
2094 QVERIFY(doc.resource(QTextDocument::ImageResource, cacheUrl) == cacheResource); |
|
2095 |
|
2096 doc.clear(); |
|
2097 QVERIFY(!doc.resource(QTextDocument::ImageResource, testUrl).isValid()); |
|
2098 QVERIFY(!doc.hasResourceCached()); |
|
2099 doc.clear(); |
|
2100 |
|
2101 doc.setHtml("<b>Mooo</b><img src=\":/blub\"/>"); |
|
2102 QVERIFY(doc.resource(QTextDocument::ImageResource, cacheUrl) == cacheResource); |
|
2103 |
|
2104 doc.setPlainText("Foob"); |
|
2105 QVERIFY(!doc.hasResourceCached()); |
|
2106 } |
|
2107 |
|
2108 void tst_QTextDocument::setPlainText() |
|
2109 { |
|
2110 doc->setPlainText("Hello World"); |
|
2111 QString s(""); |
|
2112 doc->setPlainText(s); |
|
2113 QCOMPARE(doc->toPlainText(), s); |
|
2114 } |
|
2115 |
|
2116 void tst_QTextDocument::toPlainText() |
|
2117 { |
|
2118 doc->setHtml("Hello World"); |
|
2119 QCOMPARE(doc->toPlainText(), QLatin1String("Hello World")); |
|
2120 } |
|
2121 |
|
2122 void tst_QTextDocument::deleteTextObjectsOnClear() |
|
2123 { |
|
2124 QPointer<QTextTable> table = cursor.insertTable(2, 2); |
|
2125 QVERIFY(!table.isNull()); |
|
2126 doc->clear(); |
|
2127 QVERIFY(table.isNull()); |
|
2128 } |
|
2129 |
|
2130 void tst_QTextDocument::defaultStyleSheet() |
|
2131 { |
|
2132 const QString sheet("p { background-color: green; }"); |
|
2133 QVERIFY(doc->defaultStyleSheet().isEmpty()); |
|
2134 doc->setDefaultStyleSheet(sheet); |
|
2135 QCOMPARE(doc->defaultStyleSheet(), sheet); |
|
2136 |
|
2137 cursor.insertHtml("<p>test"); |
|
2138 QTextBlockFormat fmt = doc->begin().blockFormat(); |
|
2139 QVERIFY(fmt.background().color() == QColor("green")); |
|
2140 |
|
2141 doc->clear(); |
|
2142 cursor.insertHtml("<p>test"); |
|
2143 fmt = doc->begin().blockFormat(); |
|
2144 QVERIFY(fmt.background().color() == QColor("green")); |
|
2145 |
|
2146 QTextDocument *clone = doc->clone(); |
|
2147 QCOMPARE(clone->defaultStyleSheet(), sheet); |
|
2148 cursor = QTextCursor(clone); |
|
2149 cursor.insertHtml("<p>test"); |
|
2150 fmt = clone->begin().blockFormat(); |
|
2151 QVERIFY(fmt.background().color() == QColor("green")); |
|
2152 delete clone; |
|
2153 |
|
2154 cursor = QTextCursor(doc); |
|
2155 cursor.insertHtml("<p>test"); |
|
2156 fmt = doc->begin().blockFormat(); |
|
2157 QVERIFY(fmt.background().color() == QColor("green")); |
|
2158 |
|
2159 doc->clear(); |
|
2160 cursor.insertHtml("<style>p { background-color: red; }</style><p>test"); |
|
2161 fmt = doc->begin().blockFormat(); |
|
2162 QVERIFY(fmt.background().color() == QColor("red")); |
|
2163 |
|
2164 doc->clear(); |
|
2165 doc->setDefaultStyleSheet("invalid style sheet...."); |
|
2166 cursor.insertHtml("<p>test"); |
|
2167 fmt = doc->begin().blockFormat(); |
|
2168 QVERIFY(fmt.background().color() != QColor("green")); |
|
2169 } |
|
2170 |
|
2171 void tst_QTextDocument::maximumBlockCount() |
|
2172 { |
|
2173 QCOMPARE(doc->maximumBlockCount(), 0); |
|
2174 QVERIFY(doc->isUndoRedoEnabled()); |
|
2175 |
|
2176 cursor.insertBlock(); |
|
2177 cursor.insertText("Blah"); |
|
2178 cursor.insertBlock(); |
|
2179 cursor.insertText("Foo"); |
|
2180 QCOMPARE(doc->blockCount(), 3); |
|
2181 QCOMPARE(doc->toPlainText(), QString("\nBlah\nFoo")); |
|
2182 |
|
2183 doc->setMaximumBlockCount(1); |
|
2184 QVERIFY(!doc->isUndoRedoEnabled()); |
|
2185 |
|
2186 QCOMPARE(doc->blockCount(), 1); |
|
2187 QCOMPARE(doc->toPlainText(), QString("Foo")); |
|
2188 |
|
2189 cursor.insertBlock(); |
|
2190 cursor.insertText("Hello"); |
|
2191 doc->setMaximumBlockCount(1); |
|
2192 QCOMPARE(doc->blockCount(), 1); |
|
2193 QCOMPARE(doc->toPlainText(), QString("Hello")); |
|
2194 |
|
2195 doc->setMaximumBlockCount(100); |
|
2196 for (int i = 0; i < 1000; ++i) { |
|
2197 cursor.insertBlock(); |
|
2198 cursor.insertText("Blah)"); |
|
2199 QVERIFY(doc->blockCount() <= 100); |
|
2200 } |
|
2201 |
|
2202 cursor.movePosition(QTextCursor::End); |
|
2203 QCOMPARE(cursor.blockNumber(), 99); |
|
2204 QTextCharFormat fmt; |
|
2205 fmt.setFontItalic(true); |
|
2206 cursor.setBlockCharFormat(fmt); |
|
2207 cursor.movePosition(QTextCursor::Start); |
|
2208 QVERIFY(!cursor.blockCharFormat().fontItalic()); |
|
2209 |
|
2210 doc->setMaximumBlockCount(1); |
|
2211 QVERIFY(cursor.blockCharFormat().fontItalic()); |
|
2212 |
|
2213 cursor.insertTable(2, 2); |
|
2214 QCOMPARE(doc->blockCount(), 6); |
|
2215 cursor.insertBlock(); |
|
2216 QCOMPARE(doc->blockCount(), 1); |
|
2217 } |
|
2218 |
|
2219 void tst_QTextDocument::adjustSize() |
|
2220 { |
|
2221 // avoid ugly tooltips like in task 125583 |
|
2222 QString text("Test Text"); |
|
2223 doc->setPlainText(text); |
|
2224 doc->rootFrame()->setFrameFormat(QTextFrameFormat()); |
|
2225 doc->adjustSize(); |
|
2226 QCOMPARE(doc->size().width(), doc->idealWidth()); |
|
2227 } |
|
2228 |
|
2229 void tst_QTextDocument::initialUserData() |
|
2230 { |
|
2231 doc->setPlainText("Hello"); |
|
2232 QTextBlock block = doc->begin(); |
|
2233 block.setUserData(new QTextBlockUserData); |
|
2234 QVERIFY(block.userData()); |
|
2235 doc->documentLayout(); |
|
2236 QVERIFY(block.userData()); |
|
2237 doc->setDocumentLayout(new QTestDocumentLayout(doc)); |
|
2238 QVERIFY(!block.userData()); |
|
2239 } |
|
2240 |
|
2241 void tst_QTextDocument::html_defaultFont() |
|
2242 { |
|
2243 QFont f; |
|
2244 f.setItalic(true); |
|
2245 f.setWeight(QFont::Bold); |
|
2246 doc->setDefaultFont(f); |
|
2247 doc->setPlainText("Test"); |
|
2248 |
|
2249 QString bodyPart = QString::fromLatin1("<body style=\" font-family:'%1'; font-size:%2pt; font-weight:%3; font-style:italic;\">") |
|
2250 .arg(f.family()).arg(f.pointSizeF()).arg(f.weight() * 8); |
|
2251 |
|
2252 QString html = doc->toHtml(); |
|
2253 if (!html.contains(bodyPart)) { |
|
2254 qDebug() << "html:" << html; |
|
2255 qDebug() << "expected body:" << bodyPart; |
|
2256 QVERIFY(html.contains(bodyPart)); |
|
2257 } |
|
2258 |
|
2259 if (html.contains("span")) |
|
2260 qDebug() << "html:" << html; |
|
2261 QVERIFY(!html.contains("<span style")); |
|
2262 } |
|
2263 |
|
2264 void tst_QTextDocument::blockCountChanged() |
|
2265 { |
|
2266 QSignalSpy spy(doc, SIGNAL(blockCountChanged(int))); |
|
2267 |
|
2268 doc->setPlainText("Foo"); |
|
2269 |
|
2270 QCOMPARE(doc->blockCount(), 1); |
|
2271 QCOMPARE(spy.count(), 0); |
|
2272 |
|
2273 spy.clear(); |
|
2274 |
|
2275 doc->setPlainText("Foo\nBar"); |
|
2276 QCOMPARE(doc->blockCount(), 2); |
|
2277 QCOMPARE(spy.count(), 1); |
|
2278 QCOMPARE(spy.at(0).value(0).toInt(), 2); |
|
2279 |
|
2280 spy.clear(); |
|
2281 |
|
2282 cursor.movePosition(QTextCursor::End); |
|
2283 cursor.insertText("Blahblah"); |
|
2284 |
|
2285 QCOMPARE(spy.count(), 0); |
|
2286 |
|
2287 cursor.insertBlock(); |
|
2288 QCOMPARE(spy.count(), 1); |
|
2289 QCOMPARE(spy.at(0).value(0).toInt(), 3); |
|
2290 |
|
2291 spy.clear(); |
|
2292 doc->undo(); |
|
2293 |
|
2294 QCOMPARE(spy.count(), 1); |
|
2295 QCOMPARE(spy.at(0).value(0).toInt(), 2); |
|
2296 } |
|
2297 |
|
2298 void tst_QTextDocument::nonZeroDocumentLengthOnClear() |
|
2299 { |
|
2300 QTestDocumentLayout *lout = new QTestDocumentLayout(doc); |
|
2301 doc->setDocumentLayout(lout); |
|
2302 |
|
2303 doc->clear(); |
|
2304 QVERIFY(lout->called); |
|
2305 QVERIFY(!lout->lastDocumentLengths.contains(0)); |
|
2306 } |
|
2307 |
|
2308 void tst_QTextDocument::setTextPreservesUndoRedoEnabled() |
|
2309 { |
|
2310 QVERIFY(doc->isUndoRedoEnabled()); |
|
2311 |
|
2312 doc->setPlainText("Test"); |
|
2313 |
|
2314 QVERIFY(doc->isUndoRedoEnabled()); |
|
2315 |
|
2316 doc->setUndoRedoEnabled(false); |
|
2317 QVERIFY(!doc->isUndoRedoEnabled()); |
|
2318 doc->setPlainText("Test2"); |
|
2319 QVERIFY(!doc->isUndoRedoEnabled()); |
|
2320 |
|
2321 doc->setHtml("<p>hello"); |
|
2322 QVERIFY(!doc->isUndoRedoEnabled()); |
|
2323 } |
|
2324 |
|
2325 void tst_QTextDocument::firstLast() |
|
2326 { |
|
2327 QCOMPARE(doc->blockCount(), 1); |
|
2328 QVERIFY(doc->firstBlock() == doc->lastBlock()); |
|
2329 |
|
2330 doc->setPlainText("Hello\nTest\nWorld"); |
|
2331 |
|
2332 QCOMPARE(doc->blockCount(), 3); |
|
2333 QVERIFY(doc->firstBlock() != doc->lastBlock()); |
|
2334 |
|
2335 QCOMPARE(doc->firstBlock().text(), QString("Hello")); |
|
2336 QCOMPARE(doc->lastBlock().text(), QString("World")); |
|
2337 |
|
2338 // manual forward loop |
|
2339 QTextBlock block = doc->firstBlock(); |
|
2340 |
|
2341 QVERIFY(block.isValid()); |
|
2342 QCOMPARE(block.text(), QString("Hello")); |
|
2343 |
|
2344 block = block.next(); |
|
2345 |
|
2346 QVERIFY(block.isValid()); |
|
2347 QCOMPARE(block.text(), QString("Test")); |
|
2348 |
|
2349 block = block.next(); |
|
2350 |
|
2351 QVERIFY(block.isValid()); |
|
2352 QCOMPARE(block.text(), QString("World")); |
|
2353 |
|
2354 block = block.next(); |
|
2355 QVERIFY(!block.isValid()); |
|
2356 |
|
2357 // manual backward loop |
|
2358 block = doc->lastBlock(); |
|
2359 |
|
2360 QVERIFY(block.isValid()); |
|
2361 QCOMPARE(block.text(), QString("World")); |
|
2362 |
|
2363 block = block.previous(); |
|
2364 |
|
2365 QVERIFY(block.isValid()); |
|
2366 QCOMPARE(block.text(), QString("Test")); |
|
2367 |
|
2368 block = block.previous(); |
|
2369 |
|
2370 QVERIFY(block.isValid()); |
|
2371 QCOMPARE(block.text(), QString("Hello")); |
|
2372 |
|
2373 block = block.previous(); |
|
2374 QVERIFY(!block.isValid()); |
|
2375 } |
|
2376 |
|
2377 const QString backgroundImage_html("<body><table><tr><td background=\"foo.png\">Blah</td></tr></table></body>"); |
|
2378 |
|
2379 void tst_QTextDocument::backgroundImage_checkExpectedHtml(const QTextDocument &doc) |
|
2380 { |
|
2381 QString expectedHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " |
|
2382 "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" |
|
2383 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" |
|
2384 "p, li { white-space: pre-wrap; }\n" |
|
2385 "</style></head>" |
|
2386 "<body style=\" font-family:'%1'; font-size:%2pt; font-weight:%3; font-style:%4;\">\n" |
|
2387 "<table border=\"0\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\" cellspacing=\"2\" cellpadding=\"0\">" |
|
2388 "\n<tr>\n<td background=\"foo.png\">" |
|
2389 "\n<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" |
|
2390 "</td></tr></table></body></html>"); |
|
2391 |
|
2392 expectedHtml = expectedHtml.arg(defaultFont.family()).arg(defaultFont.pointSizeF()).arg(defaultFont.weight() * 8).arg((defaultFont.italic() ? "italic" : "normal")); |
|
2393 |
|
2394 QCOMPARE(doc.toHtml(), expectedHtml); |
|
2395 } |
|
2396 |
|
2397 void tst_QTextDocument::backgroundImage_toHtml() |
|
2398 { |
|
2399 CREATE_DOC_AND_CURSOR(); |
|
2400 |
|
2401 doc.setHtml(backgroundImage_html); |
|
2402 backgroundImage_checkExpectedHtml(doc); |
|
2403 } |
|
2404 |
|
2405 void tst_QTextDocument::backgroundImage_toHtml2() |
|
2406 { |
|
2407 CREATE_DOC_AND_CURSOR(); |
|
2408 |
|
2409 cursor.insertHtml(backgroundImage_html); |
|
2410 backgroundImage_checkExpectedHtml(doc); |
|
2411 } |
|
2412 |
|
2413 void tst_QTextDocument::backgroundImage_clone() |
|
2414 { |
|
2415 CREATE_DOC_AND_CURSOR(); |
|
2416 |
|
2417 doc.setHtml(backgroundImage_html); |
|
2418 QTextDocument *clone = doc.clone(); |
|
2419 backgroundImage_checkExpectedHtml(*clone); |
|
2420 delete clone; |
|
2421 } |
|
2422 |
|
2423 void tst_QTextDocument::backgroundImage_copy() |
|
2424 { |
|
2425 CREATE_DOC_AND_CURSOR(); |
|
2426 |
|
2427 doc.setHtml(backgroundImage_html); |
|
2428 QTextDocumentFragment fragment(&doc); |
|
2429 |
|
2430 { |
|
2431 CREATE_DOC_AND_CURSOR(); |
|
2432 |
|
2433 cursor.insertFragment(fragment); |
|
2434 backgroundImage_checkExpectedHtml(doc); |
|
2435 } |
|
2436 } |
|
2437 |
|
2438 void tst_QTextDocument::documentCleanup() |
|
2439 { |
|
2440 QTextDocument doc; |
|
2441 QTextCursor cursor(&doc); |
|
2442 cursor.insertText("d\nfoo\nbar\n"); |
|
2443 doc.documentLayout(); // forces relayout |
|
2444 |
|
2445 // remove char 1 |
|
2446 cursor.setPosition(0); |
|
2447 QSizeF size = doc.documentLayout()->documentSize(); |
|
2448 cursor.deleteChar(); |
|
2449 // the size should be unchanged. |
|
2450 QCOMPARE(doc.documentLayout()->documentSize(), size); |
|
2451 } |
|
2452 |
|
2453 void tst_QTextDocument::characterAt() |
|
2454 { |
|
2455 QTextDocument doc; |
|
2456 QTextCursor cursor(&doc); |
|
2457 QString text("12345\n67890"); |
|
2458 cursor.insertText(text); |
|
2459 int length = doc.characterCount(); |
|
2460 QCOMPARE(length, text.length() + 1); |
|
2461 QCOMPARE(doc.characterAt(length-1), QChar(QChar::ParagraphSeparator)); |
|
2462 QCOMPARE(doc.characterAt(-1), QChar()); |
|
2463 QCOMPARE(doc.characterAt(length), QChar()); |
|
2464 QCOMPARE(doc.characterAt(length + 1), QChar()); |
|
2465 for (int i = 0; i < text.length(); ++i) { |
|
2466 QChar c = text.at(i); |
|
2467 if (c == QLatin1Char('\n')) |
|
2468 c = QChar(QChar::ParagraphSeparator); |
|
2469 QCOMPARE(doc.characterAt(i), c); |
|
2470 } |
|
2471 } |
|
2472 |
|
2473 void tst_QTextDocument::revisions() |
|
2474 { |
|
2475 QTextDocument doc; |
|
2476 QTextCursor cursor(&doc); |
|
2477 QString text("Hello World"); |
|
2478 QCOMPARE(doc.firstBlock().revision(), 0); |
|
2479 cursor.insertText(text); |
|
2480 QCOMPARE(doc.firstBlock().revision(), 1); |
|
2481 cursor.setPosition(6); |
|
2482 cursor.insertBlock(); |
|
2483 QCOMPARE(cursor.block().previous().revision(), 2); |
|
2484 QCOMPARE(cursor.block().revision(), 2); |
|
2485 cursor.insertText("candle"); |
|
2486 QCOMPARE(cursor.block().revision(), 3); |
|
2487 cursor.movePosition(QTextCursor::EndOfBlock); |
|
2488 cursor.insertBlock(); // we are at the block end |
|
2489 QCOMPARE(cursor.block().previous().revision(), 3); |
|
2490 QCOMPARE(cursor.block().revision(), 4); |
|
2491 cursor.insertText("lightbulb"); |
|
2492 QCOMPARE(cursor.block().revision(), 5); |
|
2493 cursor.movePosition(QTextCursor::StartOfBlock); |
|
2494 cursor.insertBlock(); // we are the block start |
|
2495 QCOMPARE(cursor.block().previous().revision(), 6); |
|
2496 QCOMPARE(cursor.block().revision(), 5); |
|
2497 } |
|
2498 |
|
2499 void tst_QTextDocument::revisionWithUndoCompressionAndUndo() |
|
2500 { |
|
2501 QTextDocument doc; |
|
2502 QTextCursor cursor(&doc); |
|
2503 cursor.insertText("This is the beginning of it all."); |
|
2504 QCOMPARE(doc.firstBlock().revision(), 1); |
|
2505 QCOMPARE(doc.revision(), 1); |
|
2506 cursor.insertBlock(); |
|
2507 QCOMPARE(doc.revision(), 2); |
|
2508 cursor.insertText("this"); |
|
2509 QCOMPARE(doc.revision(), 3); |
|
2510 cursor.insertText("is"); |
|
2511 QCOMPARE(doc.revision(), 4); |
|
2512 cursor.insertText("compressed"); |
|
2513 QCOMPARE(doc.revision(), 5); |
|
2514 doc.undo(); |
|
2515 QCOMPARE(doc.revision(), 6); |
|
2516 QCOMPARE(doc.toPlainText(), QString("This is the beginning of it all.\n")) ; |
|
2517 cursor.setPosition(0); |
|
2518 QCOMPARE(doc.firstBlock().revision(), 1); |
|
2519 cursor.insertText("Very beginnig"); |
|
2520 QCOMPARE(doc.firstBlock().revision(), 7); |
|
2521 doc.undo(); |
|
2522 QCOMPARE(doc.revision(), 8); |
|
2523 QCOMPARE(doc.firstBlock().revision(), 1); |
|
2524 |
|
2525 cursor.beginEditBlock(); |
|
2526 cursor.insertText("Hello"); |
|
2527 cursor.insertBlock(); |
|
2528 cursor.insertText("world"); |
|
2529 cursor.endEditBlock(); |
|
2530 QCOMPARE(doc.revision(), 9); |
|
2531 doc.undo(); |
|
2532 QCOMPARE(doc.revision(), 10); |
|
2533 |
|
2534 |
|
2535 } |
|
2536 |
|
2537 void tst_QTextDocument::testUndoCommandAdded() |
|
2538 { |
|
2539 QVERIFY(doc); |
|
2540 QSignalSpy spy(doc, SIGNAL(undoCommandAdded())); |
|
2541 QVERIFY(spy.isValid()); |
|
2542 QVERIFY(spy.isEmpty()); |
|
2543 |
|
2544 cursor.insertText("a"); |
|
2545 QCOMPARE(spy.count(), 1); |
|
2546 cursor.insertText("b"); // should be merged |
|
2547 QCOMPARE(spy.count(), 1); |
|
2548 cursor.insertText("c"); // should be merged |
|
2549 QCOMPARE(spy.count(), 1); |
|
2550 QCOMPARE(doc->toPlainText(), QString("abc")); |
|
2551 doc->undo(); |
|
2552 QCOMPARE(doc->toPlainText(), QString("")); |
|
2553 |
|
2554 doc->clear(); |
|
2555 spy.clear(); |
|
2556 cursor.insertText("aaa"); |
|
2557 QCOMPARE(spy.count(), 1); |
|
2558 |
|
2559 spy.clear(); |
|
2560 cursor.insertText("aaaa\nbcd"); |
|
2561 QCOMPARE(spy.count(), 1); |
|
2562 |
|
2563 spy.clear(); |
|
2564 cursor.beginEditBlock(); |
|
2565 cursor.insertText("aa"); |
|
2566 cursor.insertText("bbb\n"); |
|
2567 cursor.setCharFormat(QTextCharFormat()); |
|
2568 cursor.insertText("\nccc"); |
|
2569 QVERIFY(spy.isEmpty()); |
|
2570 cursor.endEditBlock(); |
|
2571 QCOMPARE(spy.count(), 1); |
|
2572 |
|
2573 spy.clear(); |
|
2574 cursor.insertBlock(); |
|
2575 QCOMPARE(spy.count(), 1); |
|
2576 |
|
2577 spy.clear(); |
|
2578 cursor.setPosition(5); |
|
2579 QVERIFY(spy.isEmpty()); |
|
2580 cursor.setCharFormat(QTextCharFormat()); |
|
2581 QVERIFY(spy.isEmpty()); |
|
2582 cursor.setPosition(10, QTextCursor::KeepAnchor); |
|
2583 QVERIFY(spy.isEmpty()); |
|
2584 QTextCharFormat cf; |
|
2585 cf.setFontItalic(true); |
|
2586 cursor.mergeCharFormat(cf); |
|
2587 QCOMPARE(spy.count(), 1); |
|
2588 } |
|
2589 |
|
2590 void tst_QTextDocument::testUndoBlocks() |
|
2591 { |
|
2592 QVERIFY(doc); |
|
2593 cursor.insertText("Hello World"); |
|
2594 cursor.insertText("period"); |
|
2595 doc->undo(); |
|
2596 QCOMPARE(doc->toPlainText(), QString("")); |
|
2597 cursor.insertText("Hello World"); |
|
2598 cursor.insertText("One\nTwo\nThree"); |
|
2599 QCOMPARE(doc->toPlainText(), QString("Hello WorldOne\nTwo\nThree")); |
|
2600 doc->undo(); |
|
2601 QCOMPARE(doc->toPlainText(), QString("Hello World")); |
|
2602 cursor.insertText("One\nTwo\nThree"); |
|
2603 cursor.insertText("Trailing text"); |
|
2604 doc->undo(); |
|
2605 QCOMPARE(doc->toPlainText(), QString("Hello WorldOne\nTwo\nThree")); |
|
2606 doc->undo(); |
|
2607 QCOMPARE(doc->toPlainText(), QString("Hello World")); |
|
2608 doc->undo(); |
|
2609 QCOMPARE(doc->toPlainText(), QString("")); |
|
2610 |
|
2611 cursor.insertText("quod"); |
|
2612 cursor.beginEditBlock(); |
|
2613 cursor.insertText(" erat"); |
|
2614 cursor.endEditBlock(); |
|
2615 cursor.insertText(" demonstrandum"); |
|
2616 QCOMPARE(doc->toPlainText(), QString("quod erat demonstrandum")); |
|
2617 doc->undo(); |
|
2618 QCOMPARE(doc->toPlainText(), QString("quod erat")); |
|
2619 doc->undo(); |
|
2620 QCOMPARE(doc->toPlainText(), QString("quod")); |
|
2621 doc->undo(); |
|
2622 QCOMPARE(doc->toPlainText(), QString("")); |
|
2623 } |
|
2624 |
|
2625 class Receiver : public QObject |
|
2626 { |
|
2627 Q_OBJECT |
|
2628 public: |
|
2629 QString first; |
|
2630 public slots: |
|
2631 void cursorPositionChanged() { |
|
2632 if (first.isEmpty()) |
|
2633 first = QLatin1String("cursorPositionChanged"); |
|
2634 } |
|
2635 |
|
2636 void contentsChange() { |
|
2637 if (first.isEmpty()) |
|
2638 first = QLatin1String("contentsChanged"); |
|
2639 } |
|
2640 }; |
|
2641 |
|
2642 void tst_QTextDocument::receiveCursorPositionChangedAfterContentsChange() |
|
2643 { |
|
2644 QVERIFY(doc); |
|
2645 doc->setDocumentLayout(new MyAbstractTextDocumentLayout(doc)); |
|
2646 Receiver rec; |
|
2647 connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), |
|
2648 &rec, SLOT(cursorPositionChanged())); |
|
2649 connect(doc, SIGNAL(contentsChange(int,int,int)), |
|
2650 &rec, SLOT(contentsChange())); |
|
2651 cursor.insertText("Hello World"); |
|
2652 QCOMPARE(rec.first, QString("contentsChanged")); |
|
2653 } |
|
2654 |
|
2655 QTEST_MAIN(tst_QTextDocument) |
|
2656 #include "tst_qtextdocument.moc" |