]>
Commit | Line | Data |
---|---|---|
c0d9b217 | 1 | /////////////////////////////////////////////////////////////////////////////// |
f0f6a32d | 2 | // Name: tests/controls/textctrltest.cpp |
c0d9b217 VZ |
3 | // Purpose: wxTextCtrl unit test |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2007-09-25 | |
c0d9b217 VZ |
6 | // Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwidgets.org> |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | ||
9 | // ---------------------------------------------------------------------------- | |
10 | // headers | |
11 | // ---------------------------------------------------------------------------- | |
12 | ||
13 | #include "testprec.h" | |
14 | ||
232fdc63 VZ |
15 | #if wxUSE_TEXTCTRL |
16 | ||
c0d9b217 VZ |
17 | #ifdef __BORLANDC__ |
18 | #pragma hdrstop | |
19 | #endif | |
20 | ||
21 | #ifndef WX_PRECOMP | |
22 | #include "wx/app.h" | |
23 | #include "wx/textctrl.h" | |
24 | #endif // WX_PRECOMP | |
25 | ||
8859c729 VZ |
26 | #include "wx/scopeguard.h" |
27 | ||
f0f6a32d | 28 | #include "textentrytest.h" |
232fdc63 VZ |
29 | #include "testableframe.h" |
30 | #include "asserthelper.h" | |
31 | #include "wx/uiaction.h" | |
f0f6a32d | 32 | |
358fb6ad VZ |
33 | static const int TEXT_HEIGHT = 200; |
34 | ||
c0d9b217 VZ |
35 | // ---------------------------------------------------------------------------- |
36 | // test class | |
37 | // ---------------------------------------------------------------------------- | |
38 | ||
232fdc63 | 39 | class TextCtrlTestCase : public TextEntryTestCase, public CppUnit::TestCase |
c0d9b217 VZ |
40 | { |
41 | public: | |
42 | TextCtrlTestCase() { } | |
43 | ||
44 | virtual void setUp(); | |
45 | virtual void tearDown(); | |
46 | ||
47 | private: | |
f0f6a32d VZ |
48 | virtual wxTextEntry *GetTestEntry() const { return m_text; } |
49 | virtual wxWindow *GetTestWindow() const { return m_text; } | |
50 | ||
d9abe7f2 VZ |
51 | #define SINGLE_AND_MULTI_TESTS() \ |
52 | WXUISIM_TEST( ReadOnly ); \ | |
53 | CPPUNIT_TEST( StreamInput ); \ | |
54 | CPPUNIT_TEST( Redirector ) | |
55 | ||
c0d9b217 | 56 | CPPUNIT_TEST_SUITE( TextCtrlTestCase ); |
d9abe7f2 | 57 | // These tests run for single line text controls. |
f0f6a32d | 58 | wxTEXT_ENTRY_TESTS(); |
232fdc63 | 59 | WXUISIM_TEST( MaxLength ); |
d9abe7f2 VZ |
60 | SINGLE_AND_MULTI_TESTS(); |
61 | ||
62 | // Now switch to the multi-line text controls. | |
358fb6ad | 63 | CPPUNIT_TEST( PseudoTestSwitchToMultiLineStyle ); |
d9abe7f2 VZ |
64 | |
65 | // Rerun some of the tests above. Notice that not all of them pass, so | |
66 | // we can't just use wxTEXT_ENTRY_TESTS() here. For some of them it's | |
67 | // normal, e.g. Hint() test isn't supposed to work for multi-line | |
68 | // controls. Others, such as InsertionPoint() and TextChangeEvents() | |
69 | // don't pass neither but this could be a bug. | |
70 | CPPUNIT_TEST( SetValue ); | |
71 | CPPUNIT_TEST( Selection ); | |
72 | CPPUNIT_TEST( Replace ); | |
73 | WXUISIM_TEST( Editable ); | |
74 | CPPUNIT_TEST( CopyPaste ); | |
75 | CPPUNIT_TEST( UndoRedo ); | |
76 | ||
77 | SINGLE_AND_MULTI_TESTS(); | |
78 | ||
79 | ||
80 | // All tests from now on are for multi-line controls only. | |
358fb6ad | 81 | CPPUNIT_TEST( MultiLineReplace ); |
232fdc63 VZ |
82 | //WXUISIM_TEST( ProcessEnter ); |
83 | WXUISIM_TEST( Url ); | |
84 | CPPUNIT_TEST( Style ); | |
be74a2a2 | 85 | CPPUNIT_TEST( FontStyle ); |
232fdc63 VZ |
86 | CPPUNIT_TEST( Lines ); |
87 | CPPUNIT_TEST( LogTextCtrl ); | |
6ce83213 VZ |
88 | CPPUNIT_TEST( PositionToCoords ); |
89 | CPPUNIT_TEST( PositionToCoordsRich ); | |
90 | CPPUNIT_TEST( PositionToCoordsRich2 ); | |
c0d9b217 VZ |
91 | CPPUNIT_TEST_SUITE_END(); |
92 | ||
358fb6ad VZ |
93 | void PseudoTestSwitchToMultiLineStyle() |
94 | { | |
95 | ms_style = wxTE_MULTILINE; | |
96 | } | |
97 | ||
d911dc04 | 98 | void MultiLineReplace(); |
232fdc63 VZ |
99 | void ReadOnly(); |
100 | void MaxLength(); | |
101 | void StreamInput(); | |
102 | void Redirector(); | |
103 | //void ProcessEnter(); | |
104 | void Url(); | |
105 | void Style(); | |
be74a2a2 | 106 | void FontStyle(); |
232fdc63 VZ |
107 | void Lines(); |
108 | void LogTextCtrl(); | |
6ce83213 VZ |
109 | void PositionToCoords(); |
110 | void PositionToCoordsRich(); | |
111 | void PositionToCoordsRich2(); | |
112 | ||
113 | void DoPositionToCoordsTestWithStyle(long style); | |
d911dc04 | 114 | |
358fb6ad VZ |
115 | // Create the control with the following styles added to ms_style which may |
116 | // (or not) already contain wxTE_MULTILINE. | |
117 | void CreateText(long extraStyles); | |
118 | ||
c0d9b217 | 119 | wxTextCtrl *m_text; |
c0d9b217 | 120 | |
358fb6ad VZ |
121 | static long ms_style; |
122 | ||
c0d9b217 VZ |
123 | DECLARE_NO_COPY_CLASS(TextCtrlTestCase) |
124 | }; | |
125 | ||
126 | // register in the unnamed registry so that these tests are run by default | |
127 | CPPUNIT_TEST_SUITE_REGISTRATION( TextCtrlTestCase ); | |
128 | ||
e3778b4d | 129 | // also include in its own registry so that these tests can be run alone |
c0d9b217 VZ |
130 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TextCtrlTestCase, "TextCtrlTestCase" ); |
131 | ||
132 | // ---------------------------------------------------------------------------- | |
133 | // test initialization | |
134 | // ---------------------------------------------------------------------------- | |
135 | ||
358fb6ad VZ |
136 | // This is 0 initially and set to wxTE_MULTILINE later to allow running the |
137 | // same tests for both single and multi line controls. | |
138 | long TextCtrlTestCase::ms_style = 0; | |
139 | ||
140 | void TextCtrlTestCase::CreateText(long extraStyles) | |
141 | { | |
142 | wxSize size; | |
143 | if ( ms_style == wxTE_MULTILINE ) | |
144 | size = wxSize(400, TEXT_HEIGHT); | |
145 | ||
146 | m_text = new wxTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY, "", | |
147 | wxDefaultPosition, size, | |
148 | ms_style | extraStyles); | |
149 | } | |
150 | ||
c0d9b217 VZ |
151 | void TextCtrlTestCase::setUp() |
152 | { | |
358fb6ad | 153 | CreateText(ms_style); |
c0d9b217 VZ |
154 | } |
155 | ||
156 | void TextCtrlTestCase::tearDown() | |
157 | { | |
232fdc63 | 158 | wxDELETE(m_text); |
c0d9b217 VZ |
159 | } |
160 | ||
161 | // ---------------------------------------------------------------------------- | |
162 | // tests themselves | |
163 | // ---------------------------------------------------------------------------- | |
164 | ||
d911dc04 VZ |
165 | void TextCtrlTestCase::MultiLineReplace() |
166 | { | |
d911dc04 VZ |
167 | m_text->SetValue("Hello replace\n" |
168 | "0123456789012"); | |
169 | m_text->SetInsertionPoint(0); | |
170 | ||
171 | m_text->Replace(6, 13, "changed"); | |
172 | ||
173 | CPPUNIT_ASSERT_EQUAL("Hello changed\n" | |
174 | "0123456789012", | |
175 | m_text->GetValue()); | |
176 | CPPUNIT_ASSERT_EQUAL(13, m_text->GetInsertionPoint()); | |
177 | ||
178 | m_text->Replace(13, -1, ""); | |
179 | CPPUNIT_ASSERT_EQUAL("Hello changed", m_text->GetValue()); | |
180 | CPPUNIT_ASSERT_EQUAL(13, m_text->GetInsertionPoint()); | |
232fdc63 VZ |
181 | } |
182 | ||
183 | void TextCtrlTestCase::ReadOnly() | |
184 | { | |
185 | #if wxUSE_UIACTIONSIMULATOR | |
186 | // we need a read only control for this test so recreate it | |
187 | delete m_text; | |
358fb6ad | 188 | CreateText(wxTE_READONLY); |
232fdc63 | 189 | |
ce7fe42e | 190 | EventCounter updated(m_text, wxEVT_TEXT); |
232fdc63 VZ |
191 | |
192 | m_text->SetFocus(); | |
193 | ||
194 | wxUIActionSimulator sim; | |
195 | sim.Text("abcdef"); | |
196 | wxYield(); | |
197 | ||
198 | CPPUNIT_ASSERT_EQUAL("", m_text->GetValue()); | |
744d91d4 | 199 | CPPUNIT_ASSERT_EQUAL(0, updated.GetCount()); |
232fdc63 VZ |
200 | |
201 | // SetEditable() is supposed to override wxTE_READONLY | |
202 | m_text->SetEditable(true); | |
64fd19db SC |
203 | |
204 | #ifdef __WXOSX__ | |
205 | // a ready only text field might not have been focusable at all | |
206 | m_text->SetFocus(); | |
207 | #endif | |
232fdc63 VZ |
208 | |
209 | sim.Text("abcdef"); | |
210 | wxYield(); | |
211 | ||
212 | CPPUNIT_ASSERT_EQUAL("abcdef", m_text->GetValue()); | |
744d91d4 | 213 | CPPUNIT_ASSERT_EQUAL(6, updated.GetCount()); |
232fdc63 VZ |
214 | #endif |
215 | } | |
216 | ||
217 | void TextCtrlTestCase::MaxLength() | |
218 | { | |
219 | #if wxUSE_UIACTIONSIMULATOR | |
ce7fe42e VZ |
220 | EventCounter updated(m_text, wxEVT_TEXT); |
221 | EventCounter maxlen(m_text, wxEVT_TEXT_MAXLEN); | |
232fdc63 VZ |
222 | |
223 | m_text->SetFocus(); | |
224 | m_text->SetMaxLength(10); | |
225 | ||
226 | wxUIActionSimulator sim; | |
227 | sim.Text("abcdef"); | |
228 | wxYield(); | |
229 | ||
744d91d4 | 230 | CPPUNIT_ASSERT_EQUAL(0, maxlen.GetCount()); |
232fdc63 VZ |
231 | |
232 | sim.Text("ghij"); | |
233 | wxYield(); | |
234 | ||
744d91d4 SL |
235 | CPPUNIT_ASSERT_EQUAL(0, maxlen.GetCount()); |
236 | CPPUNIT_ASSERT_EQUAL(10, updated.GetCount()); | |
237 | ||
238 | maxlen.Clear(); | |
239 | updated.Clear(); | |
232fdc63 VZ |
240 | |
241 | sim.Text("k"); | |
242 | wxYield(); | |
243 | ||
744d91d4 SL |
244 | CPPUNIT_ASSERT_EQUAL(1, maxlen.GetCount()); |
245 | CPPUNIT_ASSERT_EQUAL(0, updated.GetCount()); | |
246 | ||
247 | maxlen.Clear(); | |
248 | updated.Clear(); | |
232fdc63 VZ |
249 | |
250 | m_text->SetMaxLength(0); | |
251 | ||
252 | sim.Text("k"); | |
253 | wxYield(); | |
254 | ||
744d91d4 SL |
255 | CPPUNIT_ASSERT_EQUAL(0, maxlen.GetCount()); |
256 | CPPUNIT_ASSERT_EQUAL(1, updated.GetCount()); | |
232fdc63 VZ |
257 | #endif |
258 | } | |
259 | ||
260 | void TextCtrlTestCase::StreamInput() | |
261 | { | |
262 | #ifndef __WXOSX__ | |
8859c729 VZ |
263 | { |
264 | // Ensure we use decimal point and not a comma. | |
265 | char * const locOld = setlocale(LC_NUMERIC, "C"); | |
266 | wxON_BLOCK_EXIT2( setlocale, (int)LC_NUMERIC, locOld ); | |
267 | ||
268 | *m_text << "stringinput" | |
269 | << 10 | |
270 | << 1000L | |
271 | << 3.14f | |
272 | << 2.71 | |
273 | << 'a' | |
274 | << L'b'; | |
275 | } | |
232fdc63 VZ |
276 | |
277 | CPPUNIT_ASSERT_EQUAL("stringinput1010003.142.71ab", m_text->GetValue()); | |
278 | ||
279 | m_text->SetValue(""); | |
280 | ||
281 | #if wxHAS_TEXT_WINDOW_STREAM | |
282 | ||
283 | std::ostream stream(m_text); | |
284 | ||
285 | // We don't test a wide character as this is not a wide stream | |
286 | stream << "stringinput" | |
287 | << 10 | |
288 | << 1000L | |
289 | << 3.14f | |
290 | << 2.71 | |
291 | << 'a'; | |
292 | ||
293 | stream.flush(); | |
294 | ||
295 | CPPUNIT_ASSERT_EQUAL("stringinput1010003.142.71a", m_text->GetValue()); | |
296 | ||
8859c729 VZ |
297 | #endif // wxHAS_TEXT_WINDOW_STREAM |
298 | #endif // !__WXOSX__ | |
232fdc63 VZ |
299 | } |
300 | ||
301 | void TextCtrlTestCase::Redirector() | |
302 | { | |
303 | #if wxHAS_TEXT_WINDOW_STREAM && wxUSE_STD_IOSTREAM | |
304 | ||
305 | wxStreamToTextRedirector redirect(m_text); | |
306 | ||
307 | std::cout << "stringinput" | |
308 | << 10 | |
309 | << 1000L | |
310 | << 3.14f | |
311 | << 2.71 | |
312 | << 'a'; | |
313 | ||
314 | CPPUNIT_ASSERT_EQUAL("stringinput1010003.142.71a", m_text->GetValue()); | |
315 | ||
316 | #endif | |
317 | } | |
318 | ||
319 | #if 0 | |
320 | void TextCtrlTestCase::ProcessEnter() | |
321 | { | |
322 | #if wxUSE_UIACTIONSIMULATOR | |
323 | wxTestableFrame* frame = wxStaticCast(wxTheApp->GetTopWindow(), | |
324 | wxTestableFrame); | |
325 | ||
ce7fe42e | 326 | EventCounter count(m_text, wxEVT_TEXT_ENTER); |
232fdc63 VZ |
327 | |
328 | m_text->SetFocus(); | |
329 | ||
330 | wxUIActionSimulator sim; | |
331 | sim.Char(WXK_RETURN); | |
332 | wxYield(); | |
333 | ||
ce7fe42e | 334 | CPPUNIT_ASSERT_EQUAL(0, frame->GetEventCount(wxEVT_TEXT_ENTER)); |
232fdc63 VZ |
335 | |
336 | // we need a text control with wxTE_PROCESS_ENTER for this test | |
337 | delete m_text; | |
358fb6ad | 338 | CreateText(wxTE_PROCESS_ENTER); |
232fdc63 VZ |
339 | |
340 | m_text->SetFocus(); | |
341 | ||
342 | sim.Char(WXK_RETURN); | |
343 | wxYield(); | |
344 | ||
ce7fe42e | 345 | CPPUNIT_ASSERT_EQUAL(1, frame->GetEventCount(wxEVT_TEXT_ENTER)); |
232fdc63 VZ |
346 | #endif |
347 | } | |
348 | #endif | |
349 | ||
350 | void TextCtrlTestCase::Url() | |
351 | { | |
352 | #if wxUSE_UIACTIONSIMULATOR && defined(__WXMSW__) | |
353 | delete m_text; | |
358fb6ad | 354 | CreateText(wxTE_RICH | wxTE_AUTO_URL); |
232fdc63 | 355 | |
ce7fe42e | 356 | EventCounter url(m_text, wxEVT_TEXT_URL); |
232fdc63 VZ |
357 | |
358 | m_text->AppendText("http://www.wxwidgets.org"); | |
359 | ||
360 | wxUIActionSimulator sim; | |
361 | sim.MouseMove(m_text->ClientToScreen(wxPoint(5, 5))); | |
362 | sim.MouseClick(); | |
363 | wxYield(); | |
364 | ||
744d91d4 | 365 | CPPUNIT_ASSERT_EQUAL(1, url.GetCount()); |
232fdc63 VZ |
366 | #endif |
367 | } | |
368 | ||
369 | void TextCtrlTestCase::Style() | |
370 | { | |
371 | #ifndef __WXOSX__ | |
372 | delete m_text; | |
373 | // We need wxTE_RICH under windows for style support | |
358fb6ad | 374 | CreateText(wxTE_RICH); |
232fdc63 VZ |
375 | |
376 | // Red text on a white background | |
377 | m_text->SetDefaultStyle(wxTextAttr(*wxRED, *wxWHITE)); | |
378 | ||
379 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetTextColour(), *wxRED); | |
380 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetBackgroundColour(), | |
381 | *wxWHITE); | |
382 | ||
383 | m_text->AppendText("red on white "); | |
384 | ||
385 | // Red text on a grey background | |
386 | m_text->SetDefaultStyle(wxTextAttr(wxNullColour, *wxLIGHT_GREY)); | |
387 | ||
388 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetTextColour(), *wxRED); | |
389 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetBackgroundColour(), | |
390 | *wxLIGHT_GREY); | |
391 | ||
392 | m_text->AppendText("red on grey "); | |
393 | ||
394 | // Blue text on a grey background | |
395 | m_text->SetDefaultStyle(wxTextAttr(*wxBLUE)); | |
396 | ||
397 | ||
398 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetTextColour(), *wxBLUE); | |
399 | CPPUNIT_ASSERT_EQUAL(m_text->GetDefaultStyle().GetBackgroundColour(), | |
400 | *wxLIGHT_GREY); | |
401 | ||
402 | m_text->AppendText("blue on grey"); | |
403 | ||
404 | // Get getting the style at a specific location | |
405 | wxTextAttr style; | |
406 | ||
407 | // We have to check that styles are supported | |
408 | if(m_text->GetStyle(3, style)) | |
409 | { | |
410 | CPPUNIT_ASSERT_EQUAL(style.GetTextColour(), *wxRED); | |
411 | CPPUNIT_ASSERT_EQUAL(style.GetBackgroundColour(), *wxWHITE); | |
412 | } | |
413 | ||
414 | // And then setting the style | |
415 | if(m_text->SetStyle(15, 18, style)) | |
416 | { | |
417 | m_text->GetStyle(17, style); | |
418 | ||
419 | CPPUNIT_ASSERT_EQUAL(style.GetTextColour(), *wxRED); | |
420 | CPPUNIT_ASSERT_EQUAL(style.GetBackgroundColour(), *wxWHITE); | |
421 | } | |
422 | #endif | |
423 | } | |
424 | ||
be74a2a2 VZ |
425 | void TextCtrlTestCase::FontStyle() |
426 | { | |
427 | // We need wxTE_RICH under MSW and wxTE_MULTILINE under GTK for style | |
428 | // support so recreate the control with these styles. | |
429 | delete m_text; | |
358fb6ad | 430 | CreateText(wxTE_RICH); |
be74a2a2 VZ |
431 | |
432 | // Check that we get back the same font from GetStyle() after setting it | |
433 | // with SetDefaultStyle(). | |
434 | wxFont fontIn(14, | |
435 | wxFONTFAMILY_DEFAULT, | |
436 | wxFONTSTYLE_NORMAL, | |
437 | wxFONTWEIGHT_NORMAL); | |
438 | wxTextAttr attrIn; | |
439 | attrIn.SetFont(fontIn); | |
440 | if ( !m_text->SetDefaultStyle(attrIn) ) | |
441 | { | |
442 | // Skip the test if the styles are not supported. | |
443 | return; | |
444 | } | |
445 | ||
446 | m_text->AppendText("Default font size 14"); | |
447 | ||
448 | wxTextAttr attrOut; | |
449 | m_text->GetStyle(5, attrOut); | |
450 | ||
451 | CPPUNIT_ASSERT( attrOut.HasFont() ); | |
452 | ||
453 | wxFont fontOut = attrOut.GetFont(); | |
454 | #ifdef __WXMSW__ | |
455 | // Under MSW we get back an encoding in the font even though we hadn't | |
456 | // specified it originally. It's not really a problem but we need this hack | |
457 | // to prevent the assert below from failing because of it. | |
458 | fontOut.SetEncoding(fontIn.GetEncoding()); | |
459 | #endif | |
460 | CPPUNIT_ASSERT_EQUAL( fontIn, fontOut ); | |
461 | ||
462 | ||
463 | // Also check the same for SetStyle(). | |
464 | fontIn.SetPointSize(10); | |
465 | fontIn.SetWeight(wxFONTWEIGHT_BOLD); | |
466 | attrIn.SetFont(fontIn); | |
467 | m_text->SetStyle(0, 6, attrIn); | |
468 | ||
469 | m_text->GetStyle(4, attrOut); | |
470 | CPPUNIT_ASSERT( attrOut.HasFont() ); | |
471 | ||
472 | fontOut = attrOut.GetFont(); | |
473 | #ifdef __WXMSW__ | |
474 | fontOut.SetEncoding(fontIn.GetEncoding()); | |
475 | #endif | |
476 | CPPUNIT_ASSERT_EQUAL( fontIn, fontOut ); | |
477 | } | |
478 | ||
232fdc63 VZ |
479 | void TextCtrlTestCase::Lines() |
480 | { | |
232fdc63 VZ |
481 | m_text->SetValue("line1\nline2\nlong long line 3"); |
482 | m_text->Refresh(); | |
483 | m_text->Update(); | |
484 | ||
485 | CPPUNIT_ASSERT_EQUAL(3, m_text->GetNumberOfLines()); | |
486 | CPPUNIT_ASSERT_EQUAL(5, m_text->GetLineLength(0)); | |
487 | CPPUNIT_ASSERT_EQUAL("line2", m_text->GetLineText(1)); | |
488 | CPPUNIT_ASSERT_EQUAL(16, m_text->GetLineLength(2)); | |
489 | ||
490 | m_text->AppendText("\n\nMore text on line 5"); | |
491 | ||
492 | CPPUNIT_ASSERT_EQUAL(5, m_text->GetNumberOfLines()); | |
493 | CPPUNIT_ASSERT_EQUAL(0, m_text->GetLineLength(3)); | |
494 | CPPUNIT_ASSERT_EQUAL("", m_text->GetLineText(3)); | |
567e5e47 VZ |
495 | |
496 | // Verify that wrapped lines count as 2 lines. | |
497 | // | |
498 | // This currently doesn't work neither in wxGTK nor wxOSX/Cocoa, see | |
499 | // #12366, where GetNumberOfLines() always returns the number of logical, | |
500 | // not physical, lines. | |
501 | m_text->AppendText("\n" + wxString(50, '1') + ' ' + wxString(50, '2')); | |
502 | #if defined(__WXGTK__) || defined(__WXOSX_COCOA__) | |
503 | CPPUNIT_ASSERT_EQUAL(6, m_text->GetNumberOfLines()); | |
504 | #else | |
505 | CPPUNIT_ASSERT_EQUAL(7, m_text->GetNumberOfLines()); | |
232fdc63 VZ |
506 | #endif |
507 | } | |
508 | ||
509 | void TextCtrlTestCase::LogTextCtrl() | |
510 | { | |
232fdc63 VZ |
511 | CPPUNIT_ASSERT(m_text->IsEmpty()); |
512 | ||
513 | wxLogTextCtrl* logtext = new wxLogTextCtrl(m_text); | |
514 | ||
515 | wxLog* old = wxLog::SetActiveTarget(logtext); | |
516 | ||
517 | logtext->LogText("text"); | |
518 | ||
519 | delete wxLog::SetActiveTarget(old); | |
520 | ||
521 | CPPUNIT_ASSERT(!m_text->IsEmpty()); | |
d911dc04 VZ |
522 | } |
523 | ||
6ce83213 VZ |
524 | void TextCtrlTestCase::PositionToCoords() |
525 | { | |
526 | DoPositionToCoordsTestWithStyle(0); | |
527 | } | |
528 | ||
529 | void TextCtrlTestCase::PositionToCoordsRich() | |
530 | { | |
531 | DoPositionToCoordsTestWithStyle(wxTE_RICH); | |
532 | } | |
533 | ||
534 | void TextCtrlTestCase::PositionToCoordsRich2() | |
535 | { | |
536 | DoPositionToCoordsTestWithStyle(wxTE_RICH2); | |
537 | } | |
538 | ||
539 | void TextCtrlTestCase::DoPositionToCoordsTestWithStyle(long style) | |
540 | { | |
6ce83213 | 541 | delete m_text; |
358fb6ad | 542 | CreateText(style); |
6ce83213 VZ |
543 | |
544 | // Asking for invalid index should fail. | |
545 | WX_ASSERT_FAILS_WITH_ASSERT( m_text->PositionToCoords(1) ); | |
546 | ||
547 | // Getting position shouldn't return wxDefaultPosition except if the method | |
548 | // is not implemented at all in the current port. | |
549 | const wxPoint pos0 = m_text->PositionToCoords(0); | |
550 | if ( pos0 == wxDefaultPosition ) | |
551 | { | |
552 | #if defined(__WXMSW__) || defined(__WXGTK20__) | |
553 | CPPUNIT_FAIL( "PositionToCoords() unexpectedly failed." ); | |
554 | #endif | |
555 | return; | |
556 | } | |
557 | ||
558 | CPPUNIT_ASSERT(pos0.x >= 0); | |
559 | CPPUNIT_ASSERT(pos0.y >= 0); | |
560 | ||
561 | ||
562 | m_text->SetValue("Hello"); | |
563 | wxYield(); // Let GTK layout the control correctly. | |
564 | ||
565 | // Position of non-first character should be positive. | |
566 | const long posHello4 = m_text->PositionToCoords(4).x; | |
567 | CPPUNIT_ASSERT( posHello4 > 0 ); | |
568 | ||
569 | // Asking for position beyond the last character should succeed and return | |
570 | // reasonable result. | |
571 | CPPUNIT_ASSERT( m_text->PositionToCoords(5).x > posHello4 ); | |
572 | ||
573 | // But asking for the next position should fail. | |
574 | WX_ASSERT_FAILS_WITH_ASSERT( m_text->PositionToCoords(6) ); | |
575 | ||
576 | // Test getting the coordinates of the last character when it is in the | |
577 | // beginning of a new line to exercise MSW code which has specific logic | |
578 | // for it. | |
579 | m_text->AppendText("\n"); | |
580 | const wxPoint posLast = m_text->PositionToCoords(m_text->GetLastPosition()); | |
581 | CPPUNIT_ASSERT_EQUAL( pos0.x, posLast.x ); | |
582 | CPPUNIT_ASSERT( posLast.y > 0 ); | |
583 | ||
584 | ||
585 | // Add enough contents to the control to make sure it has a scrollbar. | |
586 | m_text->SetValue("First line" + wxString(50, '\n') + "Last line"); | |
587 | m_text->SetInsertionPoint(0); | |
588 | wxYield(); // Let GTK layout the control correctly. | |
589 | ||
590 | // This shouldn't change anything for the first position coordinates. | |
591 | CPPUNIT_ASSERT_EQUAL( pos0, m_text->PositionToCoords(0) ); | |
592 | ||
593 | // And the last one must be beyond the window boundary and so not be | |
594 | // visible -- but getting its coordinate should still work. | |
595 | CPPUNIT_ASSERT | |
596 | ( | |
597 | m_text->PositionToCoords(m_text->GetLastPosition()).y > TEXT_HEIGHT | |
598 | ); | |
599 | ||
600 | ||
601 | // Now make it scroll to the end and check that the first position now has | |
602 | // negative offset as its above the visible part of the window while the | |
603 | // last position is in its bounds. | |
604 | m_text->SetInsertionPointEnd(); | |
605 | ||
606 | CPPUNIT_ASSERT( m_text->PositionToCoords(0).y < 0 ); | |
607 | CPPUNIT_ASSERT | |
608 | ( | |
609 | m_text->PositionToCoords(m_text->GetInsertionPoint()).y <= TEXT_HEIGHT | |
610 | ); | |
611 | } | |
612 | ||
613 | ||
232fdc63 | 614 | #endif //wxUSE_TEXTCTRL |