Define _CRT_NONSTDC_NO_WARNINGS for zlib compilation with MSVC.
[wxWidgets.git] / tests / controls / richtextctrltest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/controls/richtextctrltest.cpp
3 // Purpose: wxRichTextCtrl unit test
4 // Author: Steven Lamerton
5 // Created: 2010-07-07
6 // Copyright: (c) 2010 Steven Lamerton
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #include "testprec.h"
10
11 #if wxUSE_RICHTEXT
12
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16
17 #ifndef WX_PRECOMP
18 #include "wx/app.h"
19 #endif // WX_PRECOMP
20
21 #include "wx/richtext/richtextctrl.h"
22 #include "wx/richtext/richtextstyles.h"
23 #include "testableframe.h"
24 #include "asserthelper.h"
25 #include "wx/uiaction.h"
26
27 class RichTextCtrlTestCase : public CppUnit::TestCase
28 {
29 public:
30 RichTextCtrlTestCase() { }
31
32 void setUp();
33 void tearDown();
34
35 private:
36 CPPUNIT_TEST_SUITE( RichTextCtrlTestCase );
37 WXUISIM_TEST( CharacterEvent );
38 WXUISIM_TEST( DeleteEvent );
39 WXUISIM_TEST( ReturnEvent );
40 CPPUNIT_TEST( StyleEvent );
41 CPPUNIT_TEST( BufferResetEvent );
42 WXUISIM_TEST( UrlEvent );
43 WXUISIM_TEST( TextEvent );
44 CPPUNIT_TEST( CutCopyPaste );
45 CPPUNIT_TEST( UndoRedo );
46 CPPUNIT_TEST( CaretPosition );
47 CPPUNIT_TEST( Selection );
48 WXUISIM_TEST( Editable );
49 CPPUNIT_TEST( Range );
50 CPPUNIT_TEST( Alignment );
51 CPPUNIT_TEST( Bold );
52 CPPUNIT_TEST( Italic );
53 CPPUNIT_TEST( Underline );
54 CPPUNIT_TEST( Indent );
55 CPPUNIT_TEST( LineSpacing );
56 CPPUNIT_TEST( ParagraphSpacing );
57 CPPUNIT_TEST( TextColour );
58 CPPUNIT_TEST( NumberedBullet );
59 CPPUNIT_TEST( SymbolBullet );
60 CPPUNIT_TEST( FontSize );
61 CPPUNIT_TEST( Font );
62 CPPUNIT_TEST( Delete );
63 CPPUNIT_TEST( Url );
64 CPPUNIT_TEST( Table );
65 CPPUNIT_TEST_SUITE_END();
66
67 void CharacterEvent();
68 void DeleteEvent();
69 void ReturnEvent();
70 void StyleEvent();
71 void BufferResetEvent();
72 void UrlEvent();
73 void TextEvent();
74 void CutCopyPaste();
75 void UndoRedo();
76 void CaretPosition();
77 void Selection();
78 void Editable();
79 void Range();
80 void Alignment();
81 void Bold();
82 void Italic();
83 void Underline();
84 void Indent();
85 void LineSpacing();
86 void ParagraphSpacing();
87 void TextColour();
88 void NumberedBullet();
89 void SymbolBullet();
90 void FontSize();
91 void Font();
92 void Delete();
93 void Url();
94 void Table();
95
96 wxRichTextCtrl* m_rich;
97
98 DECLARE_NO_COPY_CLASS(RichTextCtrlTestCase)
99 };
100
101 // register in the unnamed registry so that these tests are run by default
102 CPPUNIT_TEST_SUITE_REGISTRATION( RichTextCtrlTestCase );
103
104 // also include in its own registry so that these tests can be run alone
105 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( RichTextCtrlTestCase, "RichTextCtrlTestCase" );
106
107 void RichTextCtrlTestCase::setUp()
108 {
109 m_rich = new wxRichTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY, "",
110 wxDefaultPosition, wxSize(400, 200), wxWANTS_CHARS);
111 }
112
113 void RichTextCtrlTestCase::tearDown()
114 {
115 wxDELETE(m_rich);
116 }
117
118 void RichTextCtrlTestCase::CharacterEvent()
119 {
120 #if wxUSE_UIACTIONSIMULATOR
121
122 // There seems to be an event sequence problem on GTK+ that causes the events
123 // to be disconnected before they're processed, generating spurious errors.
124 #if !defined(__WXGTK__)
125 EventCounter character(m_rich, wxEVT_RICHTEXT_CHARACTER);
126 EventCounter content(m_rich, wxEVT_RICHTEXT_CONTENT_INSERTED);
127
128 m_rich->SetFocus();
129
130 wxUIActionSimulator sim;
131 sim.Text("abcdef");
132 wxYield();
133
134 CPPUNIT_ASSERT_EQUAL(6, character.GetCount());
135 CPPUNIT_ASSERT_EQUAL(6, content.GetCount());
136
137 character.Clear();
138 content.Clear();
139
140 //As these are not characters they shouldn't count
141 sim.Char(WXK_RETURN);
142 sim.Char(WXK_SHIFT);
143 wxYield();
144
145 CPPUNIT_ASSERT_EQUAL(0, character.GetCount());
146 CPPUNIT_ASSERT_EQUAL(1, content.GetCount());
147 #endif
148 #endif
149 }
150
151 void RichTextCtrlTestCase::DeleteEvent()
152 {
153 #if wxUSE_UIACTIONSIMULATOR
154 // There seems to be an event sequence problem on GTK+ that causes the events
155 // to be disconnected before they're processed, generating spurious errors.
156 #if !defined(__WXGTK__)
157 EventCounter deleteevent(m_rich, wxEVT_RICHTEXT_DELETE);
158 EventCounter contentdelete(m_rich, wxEVT_RICHTEXT_CONTENT_DELETED);
159
160 m_rich->SetFocus();
161
162 wxUIActionSimulator sim;
163 sim.Text("abcdef");
164 sim.Char(WXK_BACK);
165 sim.Char(WXK_DELETE);
166 wxYield();
167
168 CPPUNIT_ASSERT_EQUAL(2, deleteevent.GetCount());
169 //Only one as the delete doesn't delete anthing
170 CPPUNIT_ASSERT_EQUAL(1, contentdelete.GetCount());
171 #endif
172 #endif
173 }
174
175 void RichTextCtrlTestCase::ReturnEvent()
176 {
177 #if wxUSE_UIACTIONSIMULATOR
178 // There seems to be an event sequence problem on GTK+ that causes the events
179 // to be disconnected before they're processed, generating spurious errors.
180 #if !defined(__WXGTK__)
181 EventCounter returnevent(m_rich, wxEVT_RICHTEXT_RETURN);
182
183 m_rich->SetFocus();
184
185 wxUIActionSimulator sim;
186 sim.Char(WXK_RETURN);
187 wxYield();
188
189 CPPUNIT_ASSERT_EQUAL(1, returnevent.GetCount());
190 #endif
191 #endif
192 }
193
194 void RichTextCtrlTestCase::StyleEvent()
195 {
196 EventCounter stylechanged(m_rich, wxEVT_RICHTEXT_STYLE_CHANGED);
197
198 m_rich->SetValue("Sometext");
199 m_rich->SetStyle(0, 8, wxTextAttr(*wxRED, *wxWHITE));
200
201 CPPUNIT_ASSERT_EQUAL(1, stylechanged.GetCount());
202 }
203
204 void RichTextCtrlTestCase::BufferResetEvent()
205 {
206 EventCounter reset(m_rich, wxEVT_RICHTEXT_BUFFER_RESET);
207
208 m_rich->AppendText("more text!");
209 m_rich->SetValue("");
210
211 CPPUNIT_ASSERT_EQUAL(1, reset.GetCount());
212
213 reset.Clear();
214 m_rich->AppendText("more text!");
215 m_rich->Clear();
216
217 CPPUNIT_ASSERT_EQUAL(1, reset.GetCount());
218
219 reset.Clear();
220
221 //We expect a buffer reset here as setvalue clears the existing text
222 m_rich->SetValue("replace");
223 CPPUNIT_ASSERT_EQUAL(1, reset.GetCount());
224 }
225
226 void RichTextCtrlTestCase::UrlEvent()
227 {
228 #if wxUSE_UIACTIONSIMULATOR
229 // Mouse up event not being caught on GTK+
230 #if !defined(__WXGTK__)
231 EventCounter url(m_rich, wxEVT_TEXT_URL);
232
233 m_rich->BeginURL("http://www.wxwidgets.org");
234 m_rich->WriteText("http://www.wxwidgets.org");
235 m_rich->EndURL();
236
237 wxUIActionSimulator sim;
238 sim.MouseMove(m_rich->ClientToScreen(wxPoint(10, 10)));
239 wxYield();
240
241 sim.MouseClick();
242 wxYield();
243
244 CPPUNIT_ASSERT_EQUAL(1, url.GetCount());
245 #endif
246 #endif
247 }
248
249 void RichTextCtrlTestCase::TextEvent()
250 {
251 #if wxUSE_UIACTIONSIMULATOR
252 #if !defined(__WXGTK__)
253 EventCounter updated(m_rich, wxEVT_TEXT);
254
255 m_rich->SetFocus();
256
257 wxUIActionSimulator sim;
258 sim.Text("abcdef");
259 wxYield();
260
261 CPPUNIT_ASSERT_EQUAL("abcdef", m_rich->GetValue());
262 CPPUNIT_ASSERT_EQUAL(6, updated.GetCount());
263 #endif
264 #endif
265 }
266
267 void RichTextCtrlTestCase::CutCopyPaste()
268 {
269 #ifndef __WXOSX__
270 m_rich->AppendText("sometext");
271 m_rich->SelectAll();
272
273 if(m_rich->CanCut() && m_rich->CanPaste())
274 {
275 m_rich->Cut();
276 CPPUNIT_ASSERT(m_rich->IsEmpty());
277
278 wxYield();
279
280 m_rich->Paste();
281 CPPUNIT_ASSERT_EQUAL("sometext", m_rich->GetValue());
282 }
283
284 m_rich->SelectAll();
285
286 if(m_rich->CanCopy() && m_rich->CanPaste())
287 {
288 m_rich->Copy();
289 m_rich->Clear();
290 CPPUNIT_ASSERT(m_rich->IsEmpty());
291
292 wxYield();
293
294 m_rich->Paste();
295 CPPUNIT_ASSERT_EQUAL("sometext", m_rich->GetValue());
296 }
297 #endif
298 }
299
300 void RichTextCtrlTestCase::UndoRedo()
301 {
302 m_rich->AppendText("sometext");
303
304 CPPUNIT_ASSERT(m_rich->CanUndo());
305
306 m_rich->Undo();
307
308 CPPUNIT_ASSERT(m_rich->IsEmpty());
309 CPPUNIT_ASSERT(m_rich->CanRedo());
310
311 m_rich->Redo();
312
313 CPPUNIT_ASSERT_EQUAL("sometext", m_rich->GetValue());
314
315 m_rich->AppendText("Batch undo");
316 m_rich->SelectAll();
317
318 //Also test batch operations
319 m_rich->BeginBatchUndo("batchtest");
320
321 m_rich->ApplyBoldToSelection();
322 m_rich->ApplyItalicToSelection();
323
324 m_rich->EndBatchUndo();
325
326 CPPUNIT_ASSERT(m_rich->CanUndo());
327
328 m_rich->Undo();
329
330 CPPUNIT_ASSERT(!m_rich->IsSelectionBold());
331 CPPUNIT_ASSERT(!m_rich->IsSelectionItalics());
332 CPPUNIT_ASSERT(m_rich->CanRedo());
333
334 m_rich->Redo();
335
336 CPPUNIT_ASSERT(m_rich->IsSelectionBold());
337 CPPUNIT_ASSERT(m_rich->IsSelectionItalics());
338
339 //And surpressing undo
340 m_rich->BeginSuppressUndo();
341
342 m_rich->AppendText("Can't undo this");
343
344 CPPUNIT_ASSERT(m_rich->CanUndo());
345
346 m_rich->EndSuppressUndo();
347 }
348
349 void RichTextCtrlTestCase::CaretPosition()
350 {
351 m_rich->AddParagraph("This is paragraph one");
352 m_rich->AddParagraph("Paragraph two\n has \nlots of\n lines");
353
354 m_rich->SetInsertionPoint(2);
355
356 CPPUNIT_ASSERT_EQUAL(1, m_rich->GetCaretPosition());
357
358 m_rich->MoveToParagraphStart();
359
360 CPPUNIT_ASSERT_EQUAL(0, m_rich->GetCaretPosition());
361
362 m_rich->MoveRight();
363 m_rich->MoveRight(2);
364 m_rich->MoveLeft(1);
365 m_rich->MoveLeft(0);
366
367 CPPUNIT_ASSERT_EQUAL(2, m_rich->GetCaretPosition());
368
369 m_rich->MoveToParagraphEnd();
370
371 CPPUNIT_ASSERT_EQUAL(21, m_rich->GetCaretPosition());
372
373 m_rich->MoveToLineStart();
374
375 CPPUNIT_ASSERT_EQUAL(0, m_rich->GetCaretPosition());
376
377 m_rich->MoveToLineEnd();
378
379 CPPUNIT_ASSERT_EQUAL(21, m_rich->GetCaretPosition());
380 }
381
382 void RichTextCtrlTestCase::Selection()
383 {
384 m_rich->SetValue("some more text");
385
386 m_rich->SelectAll();
387
388 CPPUNIT_ASSERT_EQUAL("some more text", m_rich->GetStringSelection());
389
390 m_rich->SelectNone();
391
392 CPPUNIT_ASSERT_EQUAL("", m_rich->GetStringSelection());
393
394 m_rich->SelectWord(1);
395
396 CPPUNIT_ASSERT_EQUAL("some", m_rich->GetStringSelection());
397
398 m_rich->SetSelection(5, 14);
399
400 CPPUNIT_ASSERT_EQUAL("more text", m_rich->GetStringSelection());
401
402 wxRichTextRange range(5, 9);
403
404 m_rich->SetSelectionRange(range);
405
406 CPPUNIT_ASSERT_EQUAL("more", m_rich->GetStringSelection());
407 }
408
409 void RichTextCtrlTestCase::Editable()
410 {
411 #if wxUSE_UIACTIONSIMULATOR
412 #if !defined(__WXGTK__)
413 EventCounter updated(m_rich, wxEVT_TEXT);
414
415 m_rich->SetFocus();
416
417 wxUIActionSimulator sim;
418 sim.Text("abcdef");
419 wxYield();
420
421 CPPUNIT_ASSERT_EQUAL("abcdef", m_rich->GetValue());
422 CPPUNIT_ASSERT_EQUAL(6, updated.GetCount());
423 updated.Clear();
424
425 m_rich->SetEditable(false);
426 sim.Text("gh");
427 wxYield();
428
429 CPPUNIT_ASSERT_EQUAL("abcdef", m_rich->GetValue());
430 CPPUNIT_ASSERT_EQUAL(0, updated.GetCount());
431 #endif
432 #endif
433 }
434
435 void RichTextCtrlTestCase::Range()
436 {
437 wxRichTextRange range(0, 10);
438
439 CPPUNIT_ASSERT_EQUAL(0, range.GetStart());
440 CPPUNIT_ASSERT_EQUAL(10, range.GetEnd());
441 CPPUNIT_ASSERT_EQUAL(11, range.GetLength());
442 CPPUNIT_ASSERT(range.Contains(5));
443
444 wxRichTextRange outside(12, 14);
445
446 CPPUNIT_ASSERT(outside.IsOutside(range));
447
448 wxRichTextRange inside(6, 7);
449
450 CPPUNIT_ASSERT(inside.IsWithin(range));
451
452 range.LimitTo(inside);
453
454 CPPUNIT_ASSERT(inside == range);
455 CPPUNIT_ASSERT(inside + range == outside);
456 CPPUNIT_ASSERT(outside - range == inside);
457
458 range.SetStart(4);
459 range.SetEnd(6);
460
461 CPPUNIT_ASSERT_EQUAL(4, range.GetStart());
462 CPPUNIT_ASSERT_EQUAL(6, range.GetEnd());
463 CPPUNIT_ASSERT_EQUAL(3, range.GetLength());
464
465 inside.SetRange(6, 4);
466 inside.Swap();
467
468 CPPUNIT_ASSERT(inside == range);
469 }
470
471 void RichTextCtrlTestCase::Alignment()
472 {
473 m_rich->SetValue("text to align");
474 m_rich->SelectAll();
475
476 m_rich->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT);
477
478 CPPUNIT_ASSERT(m_rich->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT));
479
480 m_rich->BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
481 m_rich->AddParagraph("middle aligned");
482 m_rich->EndAlignment();
483
484 m_rich->SetSelection(20, 25);
485
486 CPPUNIT_ASSERT(m_rich->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE));
487 }
488
489 void RichTextCtrlTestCase::Bold()
490 {
491 m_rich->SetValue("text to bold");
492 m_rich->SelectAll();
493 m_rich->ApplyBoldToSelection();
494
495 CPPUNIT_ASSERT(m_rich->IsSelectionBold());
496
497 m_rich->BeginBold();
498 m_rich->AddParagraph("bold paragraph");
499 m_rich->EndBold();
500 m_rich->AddParagraph("not bold paragraph");
501
502 m_rich->SetSelection(15, 20);
503
504 CPPUNIT_ASSERT(m_rich->IsSelectionBold());
505
506 m_rich->SetSelection(30, 35);
507
508 CPPUNIT_ASSERT(!m_rich->IsSelectionBold());
509 }
510
511 void RichTextCtrlTestCase::Italic()
512 {
513 m_rich->SetValue("text to italic");
514 m_rich->SelectAll();
515 m_rich->ApplyItalicToSelection();
516
517 CPPUNIT_ASSERT(m_rich->IsSelectionItalics());
518
519 m_rich->BeginItalic();
520 m_rich->AddParagraph("italic paragraph");
521 m_rich->EndItalic();
522 m_rich->AddParagraph("not italic paragraph");
523
524 m_rich->SetSelection(20, 25);
525
526 CPPUNIT_ASSERT(m_rich->IsSelectionItalics());
527
528 m_rich->SetSelection(35, 40);
529
530 CPPUNIT_ASSERT(!m_rich->IsSelectionItalics());
531 }
532
533 void RichTextCtrlTestCase::Underline()
534 {
535 m_rich->SetValue("text to underline");
536 m_rich->SelectAll();
537 m_rich->ApplyUnderlineToSelection();
538
539 CPPUNIT_ASSERT(m_rich->IsSelectionUnderlined());
540
541 m_rich->BeginUnderline();
542 m_rich->AddParagraph("underline paragraph");
543 m_rich->EndUnderline();
544 m_rich->AddParagraph("not underline paragraph");
545
546 m_rich->SetSelection(20, 25);
547
548 CPPUNIT_ASSERT(m_rich->IsSelectionUnderlined());
549
550 m_rich->SetSelection(40, 45);
551
552 CPPUNIT_ASSERT(!m_rich->IsSelectionUnderlined());
553 }
554
555 void RichTextCtrlTestCase::Indent()
556 {
557 m_rich->BeginLeftIndent(12, -5);
558 m_rich->BeginRightIndent(14);
559 m_rich->AddParagraph("A paragraph with indents");
560 m_rich->EndLeftIndent();
561 m_rich->EndRightIndent();
562 m_rich->AddParagraph("No more indent");
563
564 wxTextAttr indent;
565 m_rich->GetStyle(5, indent);
566
567 CPPUNIT_ASSERT_EQUAL(12, indent.GetLeftIndent());
568 CPPUNIT_ASSERT_EQUAL(-5, indent.GetLeftSubIndent());
569 CPPUNIT_ASSERT_EQUAL(14, indent.GetRightIndent());
570
571 m_rich->GetStyle(35, indent);
572
573 CPPUNIT_ASSERT_EQUAL(0, indent.GetLeftIndent());
574 CPPUNIT_ASSERT_EQUAL(0, indent.GetLeftSubIndent());
575 CPPUNIT_ASSERT_EQUAL(0, indent.GetRightIndent());
576 }
577
578 void RichTextCtrlTestCase::LineSpacing()
579 {
580 m_rich->BeginLineSpacing(20);
581 m_rich->AddParagraph("double spaced");
582 m_rich->EndLineSpacing();
583 m_rich->BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF);
584 m_rich->AddParagraph("1.5 spaced");
585 m_rich->EndLineSpacing();
586 m_rich->AddParagraph("normally spaced");
587
588 wxTextAttr spacing;
589 m_rich->GetStyle(5, spacing);
590
591 CPPUNIT_ASSERT_EQUAL(20, spacing.GetLineSpacing());
592
593 m_rich->GetStyle(20, spacing);
594
595 CPPUNIT_ASSERT_EQUAL(15, spacing.GetLineSpacing());
596
597 m_rich->GetStyle(30, spacing);
598
599 CPPUNIT_ASSERT_EQUAL(10, spacing.GetLineSpacing());
600 }
601
602 void RichTextCtrlTestCase::ParagraphSpacing()
603 {
604 m_rich->BeginParagraphSpacing(15, 20);
605 m_rich->AddParagraph("spaced paragraph");
606 m_rich->EndParagraphSpacing();
607 m_rich->AddParagraph("non-spaced paragraph");
608
609 wxTextAttr spacing;
610 m_rich->GetStyle(5, spacing);
611
612 CPPUNIT_ASSERT_EQUAL(15, spacing.GetParagraphSpacingBefore());
613 CPPUNIT_ASSERT_EQUAL(20, spacing.GetParagraphSpacingAfter());
614
615 m_rich->GetStyle(25, spacing);
616
617 //Make sure we test against the defaults
618 CPPUNIT_ASSERT_EQUAL(m_rich->GetBasicStyle().GetParagraphSpacingBefore(),
619 spacing.GetParagraphSpacingBefore());
620 CPPUNIT_ASSERT_EQUAL(m_rich->GetBasicStyle().GetParagraphSpacingAfter(),
621 spacing.GetParagraphSpacingAfter());
622 }
623
624 void RichTextCtrlTestCase::TextColour()
625 {
626 m_rich->BeginTextColour(*wxRED);
627 m_rich->AddParagraph("red paragraph");
628 m_rich->EndTextColour();
629 m_rich->AddParagraph("default paragraph");
630
631 wxTextAttr colour;
632 m_rich->GetStyle(5, colour);
633
634 CPPUNIT_ASSERT_EQUAL(*wxRED, colour.GetTextColour());
635
636 m_rich->GetStyle(25, colour);
637
638 CPPUNIT_ASSERT_EQUAL(m_rich->GetBasicStyle().GetTextColour(),
639 colour.GetTextColour());
640 }
641
642 void RichTextCtrlTestCase::NumberedBullet()
643 {
644 m_rich->BeginNumberedBullet(1, 15, 20);
645 m_rich->AddParagraph("bullet one");
646 m_rich->EndNumberedBullet();
647 m_rich->BeginNumberedBullet(2, 25, -5);
648 m_rich->AddParagraph("bullet two");
649 m_rich->EndNumberedBullet();
650
651 wxTextAttr bullet;
652 m_rich->GetStyle(5, bullet);
653
654 CPPUNIT_ASSERT(bullet.HasBulletStyle());
655 CPPUNIT_ASSERT(bullet.HasBulletNumber());
656 CPPUNIT_ASSERT_EQUAL(1, bullet.GetBulletNumber());
657 CPPUNIT_ASSERT_EQUAL(15, bullet.GetLeftIndent());
658 CPPUNIT_ASSERT_EQUAL(20, bullet.GetLeftSubIndent());
659
660 m_rich->GetStyle(15, bullet);
661
662 CPPUNIT_ASSERT(bullet.HasBulletStyle());
663 CPPUNIT_ASSERT(bullet.HasBulletNumber());
664 CPPUNIT_ASSERT_EQUAL(2, bullet.GetBulletNumber());
665 CPPUNIT_ASSERT_EQUAL(25, bullet.GetLeftIndent());
666 CPPUNIT_ASSERT_EQUAL(-5, bullet.GetLeftSubIndent());
667 }
668
669 void RichTextCtrlTestCase::SymbolBullet()
670 {
671 m_rich->BeginSymbolBullet("*", 15, 20);
672 m_rich->AddParagraph("bullet one");
673 m_rich->EndSymbolBullet();
674 m_rich->BeginSymbolBullet("%", 25, -5);
675 m_rich->AddParagraph("bullet two");
676 m_rich->EndSymbolBullet();
677
678 wxTextAttr bullet;
679 m_rich->GetStyle(5, bullet);
680
681 CPPUNIT_ASSERT(bullet.HasBulletStyle());
682 CPPUNIT_ASSERT(bullet.HasBulletText());
683 CPPUNIT_ASSERT_EQUAL("*", bullet.GetBulletText());
684 CPPUNIT_ASSERT_EQUAL(15, bullet.GetLeftIndent());
685 CPPUNIT_ASSERT_EQUAL(20, bullet.GetLeftSubIndent());
686
687 m_rich->GetStyle(15, bullet);
688
689 CPPUNIT_ASSERT(bullet.HasBulletStyle());
690 CPPUNIT_ASSERT(bullet.HasBulletText());
691 CPPUNIT_ASSERT_EQUAL("%", bullet.GetBulletText());
692 CPPUNIT_ASSERT_EQUAL(25, bullet.GetLeftIndent());
693 CPPUNIT_ASSERT_EQUAL(-5, bullet.GetLeftSubIndent());
694 }
695
696 void RichTextCtrlTestCase::FontSize()
697 {
698 m_rich->BeginFontSize(24);
699 m_rich->AddParagraph("Large text");
700 m_rich->EndFontSize();
701
702 wxTextAttr size;
703 m_rich->GetStyle(5, size);
704
705 CPPUNIT_ASSERT(size.HasFontSize());
706 CPPUNIT_ASSERT_EQUAL(24, size.GetFontSize());
707 }
708
709 void RichTextCtrlTestCase::Font()
710 {
711 wxFont font(14, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
712 m_rich->BeginFont(font);
713 m_rich->AddParagraph("paragraph with font");
714 m_rich->EndFont();
715
716 wxTextAttr fontstyle;
717 m_rich->GetStyle(5, fontstyle);
718
719 CPPUNIT_ASSERT_EQUAL(font, fontstyle.GetFont());
720 }
721
722 void RichTextCtrlTestCase::Delete()
723 {
724 m_rich->AddParagraph("here is a long long line in a paragraph");
725 m_rich->SetSelection(0, 6);
726
727 CPPUNIT_ASSERT(m_rich->CanDeleteSelection());
728
729 m_rich->DeleteSelection();
730
731 CPPUNIT_ASSERT_EQUAL("is a long long line in a paragraph", m_rich->GetValue());
732
733 m_rich->SetSelection(0, 5);
734
735 CPPUNIT_ASSERT(m_rich->CanDeleteSelection());
736
737 m_rich->DeleteSelectedContent();
738
739 CPPUNIT_ASSERT_EQUAL("long long line in a paragraph", m_rich->GetValue());
740
741 m_rich->Delete(wxRichTextRange(14, 29));
742
743 CPPUNIT_ASSERT_EQUAL("long long line", m_rich->GetValue());
744 }
745
746 void RichTextCtrlTestCase::Url()
747 {
748 m_rich->BeginURL("http://www.wxwidgets.org");
749 m_rich->WriteText("http://www.wxwidgets.org");
750 m_rich->EndURL();
751
752 wxTextAttr url;
753 m_rich->GetStyle(5, url);
754
755 CPPUNIT_ASSERT(url.HasURL());
756 CPPUNIT_ASSERT_EQUAL("http://www.wxwidgets.org", url.GetURL());
757 }
758
759 // Helper function for ::Table()
760 wxRichTextTable* GetCurrentTableInstance(wxRichTextParagraph* para)
761 {
762 wxRichTextTable* table = wxDynamicCast(para->FindObjectAtPosition(0), wxRichTextTable);
763 CPPUNIT_ASSERT(table);
764 return table;
765 }
766
767 void RichTextCtrlTestCase::Table()
768 {
769 m_rich->BeginSuppressUndo();
770 wxRichTextTable* table = m_rich->WriteTable(1, 1);
771 m_rich->EndSuppressUndo();
772 CPPUNIT_ASSERT(table);
773 CPPUNIT_ASSERT(m_rich->CanUndo() == false);
774
775 // Run the tests twice: first for the original table, then for a contained one
776 for (int t = 0; t < 2; ++t)
777 {
778 size_t n; // FIXME-VC6: outside of the loops for VC6 only.
779
780 // Undo() and Redo() switch table instances, so invalidating 'table'
781 // The containing paragraph isn't altered, and so can be used to find the current object
782 wxRichTextParagraph* para = wxDynamicCast(table->GetParent(), wxRichTextParagraph);
783 CPPUNIT_ASSERT(para);
784
785 CPPUNIT_ASSERT(table->GetColumnCount() == 1);
786 CPPUNIT_ASSERT(table->GetRowCount() == 1);
787
788 // Test adding columns and rows
789 for (n = 0; n < 3; ++n)
790 {
791 m_rich->BeginBatchUndo("Add col and row");
792
793 table->AddColumns(0, 1);
794 table->AddRows(0, 1);
795
796 m_rich->EndBatchUndo();
797 }
798 CPPUNIT_ASSERT(table->GetColumnCount() == 4);
799 CPPUNIT_ASSERT(table->GetRowCount() == 4);
800
801 // Test deleting columns and rows
802 for (n = 0; n < 3; ++n)
803 {
804 m_rich->BeginBatchUndo("Delete col and row");
805
806 table->DeleteColumns(table->GetColumnCount() - 1, 1);
807 table->DeleteRows(table->GetRowCount() - 1, 1);
808
809 m_rich->EndBatchUndo();
810 }
811 CPPUNIT_ASSERT(table->GetColumnCount() == 1);
812 CPPUNIT_ASSERT(table->GetRowCount() == 1);
813
814 // Test undo, first of the deletions...
815 CPPUNIT_ASSERT(m_rich->CanUndo());
816 for (n = 0; n < 3; ++n)
817 {
818 m_rich->Undo();
819 }
820 table = GetCurrentTableInstance(para);
821 CPPUNIT_ASSERT(table->GetColumnCount() == 4);
822 CPPUNIT_ASSERT(table->GetRowCount() == 4);
823
824 // ...then the additions
825 for (n = 0; n < 3; ++n)
826 {
827 m_rich->Undo();
828 }
829 table = GetCurrentTableInstance(para);
830 CPPUNIT_ASSERT(table->GetColumnCount() == 1);
831 CPPUNIT_ASSERT(table->GetRowCount() == 1);
832 CPPUNIT_ASSERT(m_rich->CanUndo() == false);
833
834 // Similarly test redo. Additions:
835 CPPUNIT_ASSERT(m_rich->CanRedo());
836 for (n = 0; n < 3; ++n)
837 {
838 m_rich->Redo();
839 }
840 table = GetCurrentTableInstance(para);
841 CPPUNIT_ASSERT(table->GetColumnCount() == 4);
842 CPPUNIT_ASSERT(table->GetRowCount() == 4);
843
844 // Deletions:
845 for (n = 0; n < 3; ++n)
846 {
847 m_rich->Redo();
848 }
849 table = GetCurrentTableInstance(para);
850 CPPUNIT_ASSERT(table->GetColumnCount() == 1);
851 CPPUNIT_ASSERT(table->GetRowCount() == 1);
852 CPPUNIT_ASSERT(m_rich->CanRedo() == false);
853
854 // Now test multiple addition and deletion, and also suppression
855 m_rich->BeginSuppressUndo();
856 table->AddColumns(0, 3);
857 table->AddRows(0, 3);
858 CPPUNIT_ASSERT(table->GetColumnCount() == 4);
859 CPPUNIT_ASSERT(table->GetRowCount() == 4);
860
861 // Only delete 2 of these. This makes it easy to be sure we're dealing with the child table when we loop
862 table->DeleteColumns(0, 2);
863 table->DeleteRows(0, 2);
864 CPPUNIT_ASSERT(table->GetColumnCount() == 2);
865 CPPUNIT_ASSERT(table->GetRowCount() == 2);
866 m_rich->EndSuppressUndo();
867
868 m_rich->GetCommandProcessor()->ClearCommands(); // otherwise the command-history from this loop will cause CPPUNIT_ASSERT failures in the next one
869
870 if (t == 0)
871 {
872 // For round 2, re-run the tests on another table inside the last cell of the first one
873 wxRichTextCell* cell = table->GetCell(table->GetRowCount() - 1, table->GetColumnCount() - 1);
874 CPPUNIT_ASSERT(cell);
875 m_rich->SetFocusObject(cell);
876 m_rich->BeginSuppressUndo();
877 table = m_rich->WriteTable(1, 1);
878 m_rich->EndSuppressUndo();
879 CPPUNIT_ASSERT(table);
880 }
881 }
882
883 // Test ClearTable()
884 table->ClearTable();
885 CPPUNIT_ASSERT_EQUAL(0, table->GetCells().GetCount());
886 CPPUNIT_ASSERT_EQUAL(0, table->GetColumnCount());
887 CPPUNIT_ASSERT_EQUAL(0, table->GetRowCount());
888
889 m_rich->Clear();
890 m_rich->SetFocusObject(NULL);
891 }
892
893 #endif //wxUSE_RICHTEXT