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