]> git.saurik.com Git - wxWidgets.git/blame - src/common/textcmn.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / common / textcmn.cpp
CommitLineData
a1b82138 1///////////////////////////////////////////////////////////////////////////////
d5da0ce7 2// Name: src/common/textcmn.cpp
a1b82138
VZ
3// Purpose: implementation of platform-independent functions of wxTextCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 13.07.99
77ffb593 7// Copyright: (c) wxWidgets team
65571936 8// Licence: wxWindows licence
a1b82138
VZ
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
1e6feb95 14
a1b82138
VZ
15// for compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
d5da0ce7
WS
22#ifndef WX_PRECOMP
23 #include "wx/event.h"
24#endif // WX_PRECOMP
25
1e6feb95
VZ
26#if wxUSE_TEXTCTRL
27
d5da0ce7
WS
28#include "wx/textctrl.h"
29
a1b82138 30#ifndef WX_PRECOMP
0efe5ba7
VZ
31 #include "wx/intl.h"
32 #include "wx/log.h"
a1b82138
VZ
33#endif // WX_PRECOMP
34
35#include "wx/ffile.h"
36
f313deaa
PC
37extern WXDLLEXPORT_DATA(const char) wxTextCtrlNameStr[] = "text";
38
a1b82138
VZ
39// ----------------------------------------------------------------------------
40// macros
41// ----------------------------------------------------------------------------
42
43// we don't have any objects of type wxTextCtrlBase in the program, only
44// wxTextCtrl, so this cast is safe
45#define TEXTCTRL(ptr) ((wxTextCtrl *)(ptr))
46
47// ============================================================================
48// implementation
49// ============================================================================
50
28953245
SC
51// ----------------------------------------------------------------------------
52// XTI
53// ----------------------------------------------------------------------------
54
55wxDEFINE_FLAGS( wxTextCtrlStyle )
56wxBEGIN_FLAGS( wxTextCtrlStyle )
57// new style border flags, we put them first to
58// use them for streaming out
59wxFLAGS_MEMBER(wxBORDER_SIMPLE)
60wxFLAGS_MEMBER(wxBORDER_SUNKEN)
61wxFLAGS_MEMBER(wxBORDER_DOUBLE)
62wxFLAGS_MEMBER(wxBORDER_RAISED)
63wxFLAGS_MEMBER(wxBORDER_STATIC)
64wxFLAGS_MEMBER(wxBORDER_NONE)
65
66// old style border flags
67wxFLAGS_MEMBER(wxSIMPLE_BORDER)
68wxFLAGS_MEMBER(wxSUNKEN_BORDER)
69wxFLAGS_MEMBER(wxDOUBLE_BORDER)
70wxFLAGS_MEMBER(wxRAISED_BORDER)
71wxFLAGS_MEMBER(wxSTATIC_BORDER)
72wxFLAGS_MEMBER(wxBORDER)
73
74// standard window styles
75wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
76wxFLAGS_MEMBER(wxCLIP_CHILDREN)
77wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
78wxFLAGS_MEMBER(wxWANTS_CHARS)
79wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
80wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
81wxFLAGS_MEMBER(wxVSCROLL)
82wxFLAGS_MEMBER(wxHSCROLL)
83
84wxFLAGS_MEMBER(wxTE_PROCESS_ENTER)
85wxFLAGS_MEMBER(wxTE_PROCESS_TAB)
86wxFLAGS_MEMBER(wxTE_MULTILINE)
87wxFLAGS_MEMBER(wxTE_PASSWORD)
88wxFLAGS_MEMBER(wxTE_READONLY)
89wxFLAGS_MEMBER(wxHSCROLL)
90wxFLAGS_MEMBER(wxTE_RICH)
91wxFLAGS_MEMBER(wxTE_RICH2)
92wxFLAGS_MEMBER(wxTE_AUTO_URL)
93wxFLAGS_MEMBER(wxTE_NOHIDESEL)
94wxFLAGS_MEMBER(wxTE_LEFT)
95wxFLAGS_MEMBER(wxTE_CENTRE)
96wxFLAGS_MEMBER(wxTE_RIGHT)
97wxFLAGS_MEMBER(wxTE_DONTWRAP)
98wxFLAGS_MEMBER(wxTE_CHARWRAP)
99wxFLAGS_MEMBER(wxTE_WORDWRAP)
100wxEND_FLAGS( wxTextCtrlStyle )
101
102wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTextCtrl, wxControl, "wx/textctrl.h")
103
104wxBEGIN_PROPERTIES_TABLE(wxTextCtrl)
ce7fe42e
VZ
105wxEVENT_PROPERTY( TextUpdated, wxEVT_TEXT, wxCommandEvent )
106wxEVENT_PROPERTY( TextEnter, wxEVT_TEXT_ENTER, wxCommandEvent )
28953245
SC
107
108wxPROPERTY( Font, wxFont, SetFont, GetFont , wxEMPTY_PARAMETER_VALUE, \
109 0 /*flags*/, wxT("Helpstring"), wxT("group") )
110wxPROPERTY( Value, wxString, SetValue, GetValue, wxString(), \
111 0 /*flags*/, wxT("Helpstring"), wxT("group"))
112
113wxPROPERTY_FLAGS( WindowStyle, wxTextCtrlStyle, long, SetWindowStyleFlag, \
114 GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \
115 wxT("Helpstring"), wxT("group")) // style
116wxEND_PROPERTIES_TABLE()
117
118wxEMPTY_HANDLERS_TABLE(wxTextCtrl)
119
120wxCONSTRUCTOR_6( wxTextCtrl, wxWindow*, Parent, wxWindowID, Id, \
121 wxString, Value, wxPoint, Position, wxSize, Size, \
122 long, WindowStyle)
123
124
c57e3339
VZ
125IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent)
126
ce7fe42e
VZ
127wxDEFINE_EVENT( wxEVT_TEXT, wxCommandEvent );
128wxDEFINE_EVENT( wxEVT_TEXT_ENTER, wxCommandEvent );
129wxDEFINE_EVENT( wxEVT_TEXT_URL, wxTextUrlEvent );
130wxDEFINE_EVENT( wxEVT_TEXT_MAXLEN, wxCommandEvent );
c57e3339 131
9d112688
JS
132IMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase, wxControl)
133
44cc96a8
JS
134// ============================================================================
135// wxTextAttr implementation
136// ============================================================================
4bc1afd5 137
e00a5d3c
JS
138wxTextAttr::wxTextAttr(const wxColour& colText,
139 const wxColour& colBack,
140 const wxFont& font,
44cc96a8 141 wxTextAttrAlignment alignment): m_textAlignment(alignment), m_colText(colText), m_colBack(colBack)
e00a5d3c 142{
44cc96a8
JS
143 Init();
144
a1b806b9
DS
145 if (m_colText.IsOk()) m_flags |= wxTEXT_ATTR_TEXT_COLOUR;
146 if (m_colBack.IsOk()) m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR;
e00a5d3c
JS
147 if (alignment != wxTEXT_ALIGNMENT_DEFAULT)
148 m_flags |= wxTEXT_ATTR_ALIGNMENT;
44cc96a8
JS
149
150 GetFontAttributes(font);
e00a5d3c
JS
151}
152
44cc96a8 153// Initialisation
e00a5d3c
JS
154void wxTextAttr::Init()
155{
156 m_textAlignment = wxTEXT_ALIGNMENT_DEFAULT;
157 m_flags = 0;
158 m_leftIndent = 0;
89b67477 159 m_leftSubIndent = 0;
e00a5d3c 160 m_rightIndent = 0;
44cc96a8
JS
161
162 m_fontSize = 12;
7d76fbd5
FM
163 m_fontStyle = wxFONTSTYLE_NORMAL;
164 m_fontWeight = wxFONTWEIGHT_NORMAL;
44cc96a8 165 m_fontUnderlined = false;
6e43a69f 166 m_fontStrikethrough = false;
44cc96a8 167 m_fontEncoding = wxFONTENCODING_DEFAULT;
9c4cb611 168 m_fontFamily = wxFONTFAMILY_DEFAULT;
44cc96a8
JS
169
170 m_paragraphSpacingAfter = 0;
171 m_paragraphSpacingBefore = 0;
172 m_lineSpacing = 0;
173 m_bulletStyle = wxTEXT_ATTR_BULLET_STYLE_NONE;
174 m_textEffects = wxTEXT_ATTR_EFFECT_NONE;
175 m_textEffectFlags = wxTEXT_ATTR_EFFECT_NONE;
176 m_outlineLevel = 0;
177 m_bulletNumber = 0;
178}
179
180// Copy
181void wxTextAttr::Copy(const wxTextAttr& attr)
182{
183 m_colText = attr.m_colText;
184 m_colBack = attr.m_colBack;
185 m_textAlignment = attr.m_textAlignment;
186 m_leftIndent = attr.m_leftIndent;
187 m_leftSubIndent = attr.m_leftSubIndent;
188 m_rightIndent = attr.m_rightIndent;
189 m_tabs = attr.m_tabs;
190 m_flags = attr.m_flags;
191
192 m_fontSize = attr.m_fontSize;
193 m_fontStyle = attr.m_fontStyle;
194 m_fontWeight = attr.m_fontWeight;
195 m_fontUnderlined = attr.m_fontUnderlined;
6e43a69f 196 m_fontStrikethrough = attr.m_fontStrikethrough;
44cc96a8
JS
197 m_fontFaceName = attr.m_fontFaceName;
198 m_fontEncoding = attr.m_fontEncoding;
9c4cb611 199 m_fontFamily = attr.m_fontFamily;
44cc96a8
JS
200 m_textEffects = attr.m_textEffects;
201 m_textEffectFlags = attr.m_textEffectFlags;
202
203 m_paragraphSpacingAfter = attr.m_paragraphSpacingAfter;
204 m_paragraphSpacingBefore = attr.m_paragraphSpacingBefore;
205 m_lineSpacing = attr.m_lineSpacing;
206 m_characterStyleName = attr.m_characterStyleName;
207 m_paragraphStyleName = attr.m_paragraphStyleName;
208 m_listStyleName = attr.m_listStyleName;
209 m_bulletStyle = attr.m_bulletStyle;
210 m_bulletNumber = attr.m_bulletNumber;
211 m_bulletText = attr.m_bulletText;
212 m_bulletFont = attr.m_bulletFont;
213 m_bulletName = attr.m_bulletName;
214 m_outlineLevel = attr.m_outlineLevel;
215
216 m_urlTarget = attr.m_urlTarget;
217}
218
219// operators
220void wxTextAttr::operator= (const wxTextAttr& attr)
221{
222 Copy(attr);
223}
224
225// Equality test
226bool wxTextAttr::operator== (const wxTextAttr& attr) const
227{
228 return GetFlags() == attr.GetFlags() &&
229
230 GetTextColour() == attr.GetTextColour() &&
231 GetBackgroundColour() == attr.GetBackgroundColour() &&
232
233 GetAlignment() == attr.GetAlignment() &&
234 GetLeftIndent() == attr.GetLeftIndent() &&
235 GetLeftSubIndent() == attr.GetLeftSubIndent() &&
236 GetRightIndent() == attr.GetRightIndent() &&
237 TabsEq(GetTabs(), attr.GetTabs()) &&
238
239 GetParagraphSpacingAfter() == attr.GetParagraphSpacingAfter() &&
240 GetParagraphSpacingBefore() == attr.GetParagraphSpacingBefore() &&
241 GetLineSpacing() == attr.GetLineSpacing() &&
242 GetCharacterStyleName() == attr.GetCharacterStyleName() &&
243 GetParagraphStyleName() == attr.GetParagraphStyleName() &&
244 GetListStyleName() == attr.GetListStyleName() &&
245
246 GetBulletStyle() == attr.GetBulletStyle() &&
247 GetBulletText() == attr.GetBulletText() &&
248 GetBulletNumber() == attr.GetBulletNumber() &&
249 GetBulletFont() == attr.GetBulletFont() &&
250 GetBulletName() == attr.GetBulletName() &&
251
252 GetTextEffects() == attr.GetTextEffects() &&
253 GetTextEffectFlags() == attr.GetTextEffectFlags() &&
254
255 GetOutlineLevel() == attr.GetOutlineLevel() &&
256
257 GetFontSize() == attr.GetFontSize() &&
258 GetFontStyle() == attr.GetFontStyle() &&
259 GetFontWeight() == attr.GetFontWeight() &&
260 GetFontUnderlined() == attr.GetFontUnderlined() &&
261 GetFontFaceName() == attr.GetFontFaceName() &&
262 GetFontEncoding() == attr.GetFontEncoding() &&
9c4cb611 263 GetFontFamily() == attr.GetFontFamily() &&
44cc96a8
JS
264
265 GetURL() == attr.GetURL();
266}
267
24777478 268// Partial equality test. Only returns false if an attribute doesn't match.
32423dd8 269bool wxTextAttr::EqPartial(const wxTextAttr& attr, bool weakTest) const
44cc96a8 270{
24777478 271 int flags = attr.GetFlags();
32423dd8
JS
272
273 if (!weakTest &&
274 ((!HasTextColour() && attr.HasTextColour()) ||
275 (!HasBackgroundColour() && attr.HasBackgroundColour()) ||
276 (!HasFontFaceName() && attr.HasFontFaceName()) ||
277 (!HasFontSize() && attr.HasFontSize()) ||
278 (!HasFontWeight() && attr.HasFontWeight()) ||
279 (!HasFontItalic() && attr.HasFontItalic()) ||
280 (!HasFontUnderlined() && attr.HasFontUnderlined()) ||
281 (!HasFontStrikethrough() && attr.HasFontStrikethrough()) ||
282 (!HasFontEncoding() && attr.HasFontEncoding()) ||
283 (!HasFontFamily() && attr.HasFontFamily()) ||
284 (!HasURL() && attr.HasURL()) ||
285 (!HasAlignment() && attr.HasAlignment()) ||
286 (!HasLeftIndent() && attr.HasLeftIndent()) ||
287 (!HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter()) ||
288 (!HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore()) ||
289 (!HasLineSpacing() && attr.HasLineSpacing()) ||
290 (!HasCharacterStyleName() && attr.HasCharacterStyleName()) ||
291 (!HasParagraphStyleName() && attr.HasParagraphStyleName()) ||
292 (!HasListStyleName() && attr.HasListStyleName()) ||
293 (!HasBulletStyle() && attr.HasBulletStyle()) ||
294 (!HasBulletNumber() && attr.HasBulletNumber()) ||
295 (!HasBulletText() && attr.HasBulletText()) ||
296 (!HasBulletName() && attr.HasBulletName()) ||
297 (!HasTabs() && attr.HasTabs()) ||
298 (!HasTextEffects() && attr.HasTextEffects()) ||
299 (!HasOutlineLevel() && attr.HasOutlineLevel())))
300 {
301 return false;
302 }
303
304 if (HasTextColour() && attr.HasTextColour() && GetTextColour() != attr.GetTextColour())
305 return false;
306
307 if (HasBackgroundColour() && attr.HasBackgroundColour() && GetBackgroundColour() != attr.GetBackgroundColour())
308 return false;
309
310 if (HasFontFaceName() && attr.HasFontFaceName() && GetFontFaceName() != attr.GetFontFaceName())
44cc96a8
JS
311 return false;
312
32423dd8
JS
313 // This checks whether the two objects have the same font size dimension (px versus pt)
314 if (HasFontSize() && attr.HasFontSize() && (flags & wxTEXT_ATTR_FONT) != (GetFlags() & wxTEXT_ATTR_FONT))
44cc96a8
JS
315 return false;
316
32423dd8 317 if (HasFontPointSize() && attr.HasFontPointSize() && GetFontSize() != attr.GetFontSize())
44cc96a8
JS
318 return false;
319
32423dd8 320 if (HasFontPixelSize() && attr.HasFontPixelSize() && GetFontSize() != attr.GetFontSize())
44cc96a8
JS
321 return false;
322
32423dd8 323 if (HasFontWeight() && attr.HasFontWeight() && GetFontWeight() != attr.GetFontWeight())
44cc96a8
JS
324 return false;
325
32423dd8 326 if (HasFontItalic() && attr.HasFontItalic() && GetFontStyle() != attr.GetFontStyle())
44cc96a8
JS
327 return false;
328
32423dd8 329 if (HasFontUnderlined() && attr.HasFontUnderlined() && GetFontUnderlined() != attr.GetFontUnderlined())
44cc96a8
JS
330 return false;
331
32423dd8 332 if (HasFontStrikethrough() && attr.HasFontStrikethrough() && GetFontStrikethrough() != attr.GetFontStrikethrough())
44cc96a8
JS
333 return false;
334
32423dd8 335 if (HasFontEncoding() && attr.HasFontEncoding() && GetFontEncoding() != attr.GetFontEncoding())
9c4cb611
JS
336 return false;
337
32423dd8 338 if (HasFontFamily() && attr.HasFontFamily() && GetFontFamily() != attr.GetFontFamily())
44cc96a8
JS
339 return false;
340
32423dd8 341 if (HasURL() && attr.HasURL() && GetURL() != attr.GetURL())
44cc96a8
JS
342 return false;
343
32423dd8
JS
344 if (HasAlignment() && attr.HasAlignment() && GetAlignment() != attr.GetAlignment())
345 return false;
346
347 if (HasLeftIndent() && attr.HasLeftIndent() &&
44cc96a8
JS
348 ((GetLeftIndent() != attr.GetLeftIndent()) || (GetLeftSubIndent() != attr.GetLeftSubIndent())))
349 return false;
350
32423dd8 351 if (HasRightIndent() && attr.HasRightIndent() && (GetRightIndent() != attr.GetRightIndent()))
44cc96a8
JS
352 return false;
353
32423dd8 354 if (HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter() &&
44cc96a8
JS
355 (GetParagraphSpacingAfter() != attr.GetParagraphSpacingAfter()))
356 return false;
357
32423dd8 358 if (HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore() &&
44cc96a8
JS
359 (GetParagraphSpacingBefore() != attr.GetParagraphSpacingBefore()))
360 return false;
361
32423dd8 362 if (HasLineSpacing() && attr.HasLineSpacing() && (GetLineSpacing() != attr.GetLineSpacing()))
44cc96a8
JS
363 return false;
364
32423dd8 365 if (HasCharacterStyleName() && attr.HasCharacterStyleName() && (GetCharacterStyleName() != attr.GetCharacterStyleName()))
44cc96a8
JS
366 return false;
367
32423dd8 368 if (HasParagraphStyleName() && attr.HasParagraphStyleName() && (GetParagraphStyleName() != attr.GetParagraphStyleName()))
44cc96a8
JS
369 return false;
370
32423dd8 371 if (HasListStyleName() && attr.HasListStyleName() && (GetListStyleName() != attr.GetListStyleName()))
44cc96a8
JS
372 return false;
373
32423dd8 374 if (HasBulletStyle() && attr.HasBulletStyle() && (GetBulletStyle() != attr.GetBulletStyle()))
44cc96a8
JS
375 return false;
376
32423dd8 377 if (HasBulletNumber() && attr.HasBulletNumber() && (GetBulletNumber() != attr.GetBulletNumber()))
44cc96a8
JS
378 return false;
379
32423dd8 380 if (HasBulletText() && attr.HasBulletText() &&
44cc96a8
JS
381 (GetBulletText() != attr.GetBulletText()) &&
382 (GetBulletFont() != attr.GetBulletFont()))
383 return false;
384
32423dd8 385 if (HasBulletName() && attr.HasBulletName() && (GetBulletName() != attr.GetBulletName()))
44cc96a8
JS
386 return false;
387
32423dd8 388 if (HasTabs() && attr.HasTabs() && !TabsEq(GetTabs(), attr.GetTabs()))
44cc96a8
JS
389 return false;
390
32423dd8 391 if ((HasPageBreak() != attr.HasPageBreak()))
44cc96a8
JS
392 return false;
393
32423dd8 394 if (HasTextEffects() && attr.HasTextEffects())
44cc96a8 395 {
44cc96a8
JS
396 if (!BitlistsEqPartial(GetTextEffects(), attr.GetTextEffects(), attr.GetTextEffectFlags()))
397 return false;
398 }
399
32423dd8 400 if (HasOutlineLevel() && attr.HasOutlineLevel() && (GetOutlineLevel() != attr.GetOutlineLevel()))
44cc96a8
JS
401 return false;
402
403 return true;
404}
405
406// Create font from font attributes.
1fee6e25 407wxFont wxTextAttr::GetFont() const
44cc96a8 408{
1fee6e25
VZ
409 if ( !HasFont() )
410 return wxNullFont;
411
44cc96a8
JS
412 int fontSize = 10;
413 if (HasFontSize())
414 fontSize = GetFontSize();
415
32423dd8 416 wxFontStyle fontStyle = wxFONTSTYLE_NORMAL;
44cc96a8
JS
417 if (HasFontItalic())
418 fontStyle = GetFontStyle();
419
32423dd8 420 wxFontWeight fontWeight = wxFONTWEIGHT_NORMAL;
44cc96a8
JS
421 if (HasFontWeight())
422 fontWeight = GetFontWeight();
423
424 bool underlined = false;
425 if (HasFontUnderlined())
426 underlined = GetFontUnderlined();
427
c7a49742 428 bool strikethrough = false;
32423dd8 429 if (HasFontStrikethrough())
c7a49742
VZ
430 strikethrough = GetFontStrikethrough();
431
44cc96a8
JS
432 wxString fontFaceName;
433 if (HasFontFaceName())
434 fontFaceName = GetFontFaceName();
435
436 wxFontEncoding encoding = wxFONTENCODING_DEFAULT;
437 if (HasFontEncoding())
438 encoding = GetFontEncoding();
439
aa926768 440 wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT;
9c4cb611
JS
441 if (HasFontFamily())
442 fontFamily = GetFontFamily();
443
32423dd8
JS
444 if (HasFontPixelSize())
445 {
446 wxFont font(wxSize(0, fontSize), fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding);
447 if (strikethrough)
448 font.SetStrikethrough(true);
449 return font;
450 }
451 else
452 {
453 wxFont font(fontSize, fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding);
454 if (strikethrough)
455 font.SetStrikethrough(true);
456 return font;
457 }
44cc96a8
JS
458}
459
460// Get attributes from font.
461bool wxTextAttr::GetFontAttributes(const wxFont& font, int flags)
462{
a1b806b9 463 if (!font.IsOk())
44cc96a8
JS
464 return false;
465
32423dd8
JS
466 // If we pass both pixel and point size attributes, this is an indication
467 // to choose the most appropriate units.
468 if ((flags & wxTEXT_ATTR_FONT) == wxTEXT_ATTR_FONT)
469 {
470 if (font.IsUsingSizeInPixels())
471 {
472 m_fontSize = font.GetPixelSize().y;
473 flags &= ~wxTEXT_ATTR_FONT_POINT_SIZE;
474 }
475 else
476 {
477 m_fontSize = font.GetPointSize();
478 flags &= ~wxTEXT_ATTR_FONT_PIXEL_SIZE;
479 }
480 }
481 else if (flags & wxTEXT_ATTR_FONT_POINT_SIZE)
482 {
44cc96a8 483 m_fontSize = font.GetPointSize();
32423dd8
JS
484 flags &= ~wxTEXT_ATTR_FONT_PIXEL_SIZE;
485 }
486 else if (flags & wxTEXT_ATTR_FONT_PIXEL_SIZE)
487 {
488 m_fontSize = font.GetPixelSize().y;
489 }
44cc96a8
JS
490
491 if (flags & wxTEXT_ATTR_FONT_ITALIC)
492 m_fontStyle = font.GetStyle();
493
494 if (flags & wxTEXT_ATTR_FONT_WEIGHT)
495 m_fontWeight = font.GetWeight();
496
497 if (flags & wxTEXT_ATTR_FONT_UNDERLINE)
498 m_fontUnderlined = font.GetUnderlined();
499
c7a49742
VZ
500 if (flags & wxTEXT_ATTR_FONT_STRIKETHROUGH)
501 m_fontStrikethrough = font.GetStrikethrough();
502
44cc96a8
JS
503 if (flags & wxTEXT_ATTR_FONT_FACE)
504 m_fontFaceName = font.GetFaceName();
505
506 if (flags & wxTEXT_ATTR_FONT_ENCODING)
507 m_fontEncoding = font.GetEncoding();
508
9c4cb611 509 if (flags & wxTEXT_ATTR_FONT_FAMILY)
aa926768
VZ
510 {
511 // wxFont might not know its family, avoid setting m_fontFamily to an
512 // invalid value and rather pretend that we don't have any font family
513 // information at all in this case
514 const wxFontFamily fontFamily = font.GetFamily();
515 if ( fontFamily == wxFONTFAMILY_UNKNOWN )
516 flags &= ~wxTEXT_ATTR_FONT_FAMILY;
517 else
518 m_fontFamily = fontFamily;
519 }
9c4cb611 520
c4076626
JS
521 m_flags |= flags;
522
44cc96a8
JS
523 return true;
524}
525
d1e5be0e
JS
526// Resets bits in destination so new attributes aren't merged with mutually exclusive ones
527static bool wxResetIncompatibleBits(const int mask, const int srcFlags, int& destFlags, int& destBits)
528{
529 if ((srcFlags & mask) && (destFlags & mask))
530 {
531 destBits &= ~mask;
532 destFlags &= ~mask;
533 }
534
535 return true;
536}
537
44cc96a8
JS
538bool wxTextAttr::Apply(const wxTextAttr& style, const wxTextAttr* compareWith)
539{
540 wxTextAttr& destStyle = (*this);
541
542 if (style.HasFontWeight())
543 {
544 if (!(compareWith && compareWith->HasFontWeight() && compareWith->GetFontWeight() == style.GetFontWeight()))
545 destStyle.SetFontWeight(style.GetFontWeight());
546 }
547
32423dd8
JS
548 if (style.HasFontPointSize())
549 {
550 if (!(compareWith && compareWith->HasFontPointSize() && compareWith->GetFontSize() == style.GetFontSize()))
551 destStyle.SetFontPointSize(style.GetFontSize());
552 }
553 else if (style.HasFontPixelSize())
44cc96a8 554 {
32423dd8
JS
555 if (!(compareWith && compareWith->HasFontPixelSize() && compareWith->GetFontSize() == style.GetFontSize()))
556 destStyle.SetFontPixelSize(style.GetFontSize());
44cc96a8
JS
557 }
558
559 if (style.HasFontItalic())
560 {
561 if (!(compareWith && compareWith->HasFontItalic() && compareWith->GetFontStyle() == style.GetFontStyle()))
562 destStyle.SetFontStyle(style.GetFontStyle());
563 }
564
565 if (style.HasFontUnderlined())
566 {
567 if (!(compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined()))
568 destStyle.SetFontUnderlined(style.GetFontUnderlined());
569 }
570
c7a49742
VZ
571 if (style.HasFontStrikethrough())
572 {
573 if (!(compareWith && compareWith->HasFontStrikethrough() && compareWith->GetFontStrikethrough() == style.GetFontStrikethrough()))
574 destStyle.SetFontStrikethrough(style.GetFontStrikethrough());
575 }
576
44cc96a8
JS
577 if (style.HasFontFaceName())
578 {
579 if (!(compareWith && compareWith->HasFontFaceName() && compareWith->GetFontFaceName() == style.GetFontFaceName()))
580 destStyle.SetFontFaceName(style.GetFontFaceName());
581 }
582
583 if (style.HasFontEncoding())
584 {
585 if (!(compareWith && compareWith->HasFontEncoding() && compareWith->GetFontEncoding() == style.GetFontEncoding()))
586 destStyle.SetFontEncoding(style.GetFontEncoding());
587 }
588
9c4cb611
JS
589 if (style.HasFontFamily())
590 {
591 if (!(compareWith && compareWith->HasFontFamily() && compareWith->GetFontFamily() == style.GetFontFamily()))
592 destStyle.SetFontFamily(style.GetFontFamily());
593 }
594
a1b806b9 595 if (style.GetTextColour().IsOk() && style.HasTextColour())
44cc96a8
JS
596 {
597 if (!(compareWith && compareWith->HasTextColour() && compareWith->GetTextColour() == style.GetTextColour()))
598 destStyle.SetTextColour(style.GetTextColour());
599 }
600
a1b806b9 601 if (style.GetBackgroundColour().IsOk() && style.HasBackgroundColour())
44cc96a8
JS
602 {
603 if (!(compareWith && compareWith->HasBackgroundColour() && compareWith->GetBackgroundColour() == style.GetBackgroundColour()))
604 destStyle.SetBackgroundColour(style.GetBackgroundColour());
605 }
606
607 if (style.HasAlignment())
608 {
609 if (!(compareWith && compareWith->HasAlignment() && compareWith->GetAlignment() == style.GetAlignment()))
610 destStyle.SetAlignment(style.GetAlignment());
611 }
612
613 if (style.HasTabs())
614 {
615 if (!(compareWith && compareWith->HasTabs() && TabsEq(compareWith->GetTabs(), style.GetTabs())))
616 destStyle.SetTabs(style.GetTabs());
617 }
618
619 if (style.HasLeftIndent())
620 {
621 if (!(compareWith && compareWith->HasLeftIndent() && compareWith->GetLeftIndent() == style.GetLeftIndent()
622 && compareWith->GetLeftSubIndent() == style.GetLeftSubIndent()))
623 destStyle.SetLeftIndent(style.GetLeftIndent(), style.GetLeftSubIndent());
624 }
625
626 if (style.HasRightIndent())
627 {
628 if (!(compareWith && compareWith->HasRightIndent() && compareWith->GetRightIndent() == style.GetRightIndent()))
629 destStyle.SetRightIndent(style.GetRightIndent());
630 }
631
632 if (style.HasParagraphSpacingAfter())
633 {
634 if (!(compareWith && compareWith->HasParagraphSpacingAfter() && compareWith->GetParagraphSpacingAfter() == style.GetParagraphSpacingAfter()))
635 destStyle.SetParagraphSpacingAfter(style.GetParagraphSpacingAfter());
636 }
637
638 if (style.HasParagraphSpacingBefore())
639 {
640 if (!(compareWith && compareWith->HasParagraphSpacingBefore() && compareWith->GetParagraphSpacingBefore() == style.GetParagraphSpacingBefore()))
641 destStyle.SetParagraphSpacingBefore(style.GetParagraphSpacingBefore());
642 }
643
644 if (style.HasLineSpacing())
645 {
646 if (!(compareWith && compareWith->HasLineSpacing() && compareWith->GetLineSpacing() == style.GetLineSpacing()))
647 destStyle.SetLineSpacing(style.GetLineSpacing());
648 }
649
650 if (style.HasCharacterStyleName())
651 {
652 if (!(compareWith && compareWith->HasCharacterStyleName() && compareWith->GetCharacterStyleName() == style.GetCharacterStyleName()))
653 destStyle.SetCharacterStyleName(style.GetCharacterStyleName());
654 }
655
656 if (style.HasParagraphStyleName())
657 {
658 if (!(compareWith && compareWith->HasParagraphStyleName() && compareWith->GetParagraphStyleName() == style.GetParagraphStyleName()))
659 destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
660 }
661
662 if (style.HasListStyleName())
663 {
664 if (!(compareWith && compareWith->HasListStyleName() && compareWith->GetListStyleName() == style.GetListStyleName()))
665 destStyle.SetListStyleName(style.GetListStyleName());
666 }
667
668 if (style.HasBulletStyle())
669 {
670 if (!(compareWith && compareWith->HasBulletStyle() && compareWith->GetBulletStyle() == style.GetBulletStyle()))
671 destStyle.SetBulletStyle(style.GetBulletStyle());
672 }
673
674 if (style.HasBulletText())
675 {
676 if (!(compareWith && compareWith->HasBulletText() && compareWith->GetBulletText() == style.GetBulletText()))
677 {
678 destStyle.SetBulletText(style.GetBulletText());
679 destStyle.SetBulletFont(style.GetBulletFont());
680 }
681 }
682
683 if (style.HasBulletNumber())
684 {
685 if (!(compareWith && compareWith->HasBulletNumber() && compareWith->GetBulletNumber() == style.GetBulletNumber()))
686 destStyle.SetBulletNumber(style.GetBulletNumber());
687 }
688
689 if (style.HasBulletName())
690 {
691 if (!(compareWith && compareWith->HasBulletName() && compareWith->GetBulletName() == style.GetBulletName()))
692 destStyle.SetBulletName(style.GetBulletName());
693 }
694
695 if (style.HasURL())
696 {
697 if (!(compareWith && compareWith->HasURL() && compareWith->GetURL() == style.GetURL()))
698 destStyle.SetURL(style.GetURL());
699 }
700
701 if (style.HasPageBreak())
702 {
703 if (!(compareWith && compareWith->HasPageBreak()))
704 destStyle.SetPageBreak();
705 }
706
707 if (style.HasTextEffects())
708 {
709 if (!(compareWith && compareWith->HasTextEffects() && compareWith->GetTextEffects() == style.GetTextEffects()))
710 {
711 int destBits = destStyle.GetTextEffects();
712 int destFlags = destStyle.GetTextEffectFlags();
713
714 int srcBits = style.GetTextEffects();
715 int srcFlags = style.GetTextEffectFlags();
716
d1e5be0e
JS
717 // Reset incompatible bits in the destination
718 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_SUPERSCRIPT|wxTEXT_ATTR_EFFECT_SUBSCRIPT), srcFlags, destFlags, destBits);
719 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS), srcFlags, destFlags, destBits);
720 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_STRIKETHROUGH|wxTEXT_ATTR_EFFECT_DOUBLE_STRIKETHROUGH), srcFlags, destFlags, destBits);
721
44cc96a8
JS
722 CombineBitlists(destBits, srcBits, destFlags, srcFlags);
723
724 destStyle.SetTextEffects(destBits);
725 destStyle.SetTextEffectFlags(destFlags);
726 }
727 }
728
729 if (style.HasOutlineLevel())
730 {
731 if (!(compareWith && compareWith->HasOutlineLevel() && compareWith->GetOutlineLevel() == style.GetOutlineLevel()))
732 destStyle.SetOutlineLevel(style.GetOutlineLevel());
733 }
734
735 return true;
e00a5d3c
JS
736}
737
eda40bfc
VZ
738/* static */
739wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr,
740 const wxTextAttr& attrDef,
741 const wxTextCtrlBase *text)
742{
7c3c990e
JS
743 wxFont font;
744 if (attr.HasFont())
745 font = attr.GetFont();
746
a1b806b9 747 if ( !font.IsOk() )
eda40bfc 748 {
7c3c990e
JS
749 if (attrDef.HasFont())
750 font = attrDef.GetFont();
eda40bfc 751
a1b806b9 752 if ( text && !font.IsOk() )
eda40bfc
VZ
753 font = text->GetFont();
754 }
755
756 wxColour colFg = attr.GetTextColour();
a1b806b9 757 if ( !colFg.IsOk() )
eda40bfc
VZ
758 {
759 colFg = attrDef.GetTextColour();
760
a1b806b9 761 if ( text && !colFg.IsOk() )
eda40bfc
VZ
762 colFg = text->GetForegroundColour();
763 }
764
765 wxColour colBg = attr.GetBackgroundColour();
a1b806b9 766 if ( !colBg.IsOk() )
eda40bfc
VZ
767 {
768 colBg = attrDef.GetBackgroundColour();
769
a1b806b9 770 if ( text && !colBg.IsOk() )
eda40bfc
VZ
771 colBg = text->GetBackgroundColour();
772 }
773
e00a5d3c 774 wxTextAttr newAttr(colFg, colBg, font);
cb719f2e 775
e00a5d3c
JS
776 if (attr.HasAlignment())
777 newAttr.SetAlignment(attr.GetAlignment());
778 else if (attrDef.HasAlignment())
779 newAttr.SetAlignment(attrDef.GetAlignment());
cb719f2e 780
e00a5d3c
JS
781 if (attr.HasTabs())
782 newAttr.SetTabs(attr.GetTabs());
783 else if (attrDef.HasTabs())
784 newAttr.SetTabs(attrDef.GetTabs());
cb719f2e 785
e00a5d3c 786 if (attr.HasLeftIndent())
89b67477 787 newAttr.SetLeftIndent(attr.GetLeftIndent(), attr.GetLeftSubIndent());
e00a5d3c 788 else if (attrDef.HasLeftIndent())
89b67477 789 newAttr.SetLeftIndent(attrDef.GetLeftIndent(), attr.GetLeftSubIndent());
cb719f2e 790
e00a5d3c
JS
791 if (attr.HasRightIndent())
792 newAttr.SetRightIndent(attr.GetRightIndent());
793 else if (attrDef.HasRightIndent())
cb719f2e
WS
794 newAttr.SetRightIndent(attrDef.GetRightIndent());
795
e00a5d3c 796 return newAttr;
eda40bfc
VZ
797}
798
44cc96a8
JS
799/// Compare tabs
800bool wxTextAttr::TabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2)
e00a5d3c 801{
44cc96a8
JS
802 if (tabs1.GetCount() != tabs2.GetCount())
803 return false;
804
805 size_t i;
806 for (i = 0; i < tabs1.GetCount(); i++)
807 {
808 if (tabs1[i] != tabs2[i])
809 return false;
810 }
811 return true;
812}
813
814// Remove attributes
815bool wxTextAttr::RemoveStyle(wxTextAttr& destStyle, const wxTextAttr& style)
816{
817 int flags = style.GetFlags();
818 int destFlags = destStyle.GetFlags();
819
820 destStyle.SetFlags(destFlags & ~flags);
821
822 return true;
823}
824
825/// Combine two bitlists, specifying the bits of interest with separate flags.
826bool wxTextAttr::CombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB)
827{
828 // We want to apply B's bits to A, taking into account each's flags which indicate which bits
829 // are to be taken into account. A zero in B's bits should reset that bit in A but only if B's flags
830 // indicate it.
831
832 // First, reset the 0 bits from B. We make a mask so we're only dealing with B's zero
833 // bits at this point, ignoring any 1 bits in B or 0 bits in B that are not relevant.
834 int valueA2 = ~(~valueB & flagsB) & valueA;
835
836 // Now combine the 1 bits.
837 int valueA3 = (valueB & flagsB) | valueA2;
838
839 valueA = valueA3;
840 flagsA = (flagsA | flagsB);
841
842 return true;
843}
844
845/// Compare two bitlists
846bool wxTextAttr::BitlistsEqPartial(int valueA, int valueB, int flags)
847{
848 int relevantBitsA = valueA & flags;
849 int relevantBitsB = valueB & flags;
54c730a9 850 return relevantBitsA == relevantBitsB;
e00a5d3c
JS
851}
852
44cc96a8
JS
853/// Split into paragraph and character styles
854bool wxTextAttr::SplitParaCharStyles(const wxTextAttr& style, wxTextAttr& parStyle, wxTextAttr& charStyle)
855{
856 wxTextAttr defaultCharStyle1(style);
857 wxTextAttr defaultParaStyle1(style);
858 defaultCharStyle1.SetFlags(defaultCharStyle1.GetFlags()&wxTEXT_ATTR_CHARACTER);
859 defaultParaStyle1.SetFlags(defaultParaStyle1.GetFlags()&wxTEXT_ATTR_PARAGRAPH);
860
861 charStyle.Apply(defaultCharStyle1);
862 parStyle.Apply(defaultParaStyle1);
863
864 return true;
865}
e00a5d3c 866
4bc1afd5
VZ
867// apply styling to text range
868bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end),
869 const wxTextAttr& WXUNUSED(style))
870{
0ec1179b 871 // to be implemented in derived classes
cb719f2e 872 return false;
4bc1afd5
VZ
873}
874
e00a5d3c
JS
875// get the styling at the given position
876bool wxTextCtrlBase::GetStyle(long WXUNUSED(position), wxTextAttr& WXUNUSED(style))
877{
0ec1179b 878 // to be implemented in derived classes
cb719f2e 879 return false;
e00a5d3c
JS
880}
881
4bc1afd5 882// change default text attributes
eda40bfc 883bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style)
4bc1afd5 884{
c598f225
VZ
885 // keep the old attributes if the new style doesn't specify them unless the
886 // new style is empty - then reset m_defaultStyle (as there is no other way
887 // to do it)
888 if ( style.IsDefault() )
889 m_defaultStyle = style;
890 else
891 m_defaultStyle = wxTextAttr::Combine(style, m_defaultStyle, this);
eda40bfc 892
cb719f2e 893 return true;
4bc1afd5
VZ
894}
895
a1b82138
VZ
896// ----------------------------------------------------------------------------
897// file IO functions
898// ----------------------------------------------------------------------------
899
3396739d 900bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType))
a1b82138 901{
1e6feb95 902#if wxUSE_FFILE
a1b82138
VZ
903 wxFFile file(filename);
904 if ( file.IsOpened() )
905 {
906 wxString text;
907 if ( file.ReadAll(&text) )
908 {
3396739d 909 SetValue(text);
a1b82138 910
90761420
VZ
911 DiscardEdits();
912 m_filename = filename;
913
cb719f2e 914 return true;
a1b82138
VZ
915 }
916 }
7e81e3a7
VZ
917#else
918 (void)filename; // avoid compiler warning about unreferenced parameter
3396739d
VZ
919#endif // wxUSE_FFILE
920
90761420
VZ
921 wxLogError(_("File couldn't be loaded."));
922
3396739d
VZ
923 return false;
924}
a1b82138 925
90761420 926bool wxTextAreaBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType))
3396739d 927{
90761420
VZ
928#if wxUSE_FFILE
929 wxFFile file(filename, wxT("w"));
930 if ( file.IsOpened() && file.Write(GetValue(), *wxConvCurrent) )
3396739d 931 {
90761420 932 // if it worked, save for future calls
3396739d 933 m_filename = filename;
90761420
VZ
934
935 // it's not modified any longer
936 DiscardEdits();
937
3396739d
VZ
938 return true;
939 }
7e81e3a7
VZ
940#else
941 (void)filename; // avoid compiler warning about unreferenced parameter
90761420 942#endif // wxUSE_FFILE
a1b82138 943
cb719f2e 944 return false;
a1b82138
VZ
945}
946
0ec1179b 947bool wxTextAreaBase::SaveFile(const wxString& filename, int fileType)
a1b82138 948{
7d8268a1 949 wxString filenameToUse = filename.empty() ? m_filename : filename;
64dcc269 950 if ( filenameToUse.empty() )
a1b82138
VZ
951 {
952 // what kind of message to give? is it an error or a program bug?
223d09f6 953 wxLogDebug(wxT("Can't save textctrl to file without filename."));
a1b82138 954
cb719f2e 955 return false;
a1b82138
VZ
956 }
957
3306aec1
JS
958 return DoSaveFile(filenameToUse, fileType);
959}
960
a1b82138
VZ
961// ----------------------------------------------------------------------------
962// stream-like insertion operator
963// ----------------------------------------------------------------------------
964
965wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s)
966{
967 AppendText(s);
968 return *TEXTCTRL(this);
969}
970
a1b82138
VZ
971wxTextCtrl& wxTextCtrlBase::operator<<(double d)
972{
9e50ed28 973 return *this << wxString::Format("%.2f", d);
a1b82138
VZ
974}
975
976wxTextCtrl& wxTextCtrlBase::operator<<(int i)
977{
9e50ed28 978 return *this << wxString::Format("%d", i);
a1b82138
VZ
979}
980
9e50ed28 981wxTextCtrl& wxTextCtrlBase::operator<<(long l)
a1b82138 982{
9e50ed28 983 return *this << wxString::Format("%ld", l);
a1b82138
VZ
984}
985
986// ----------------------------------------------------------------------------
987// streambuf methods implementation
988// ----------------------------------------------------------------------------
989
15cdc341 990#if wxHAS_TEXT_WINDOW_STREAM
a1b82138 991
d73e6791 992int wxTextCtrlBase::overflow(int c)
a1b82138 993{
d73e6791 994 AppendText((wxChar)c);
a1b82138 995
d73e6791 996 // return something different from EOF
a1b82138
VZ
997 return 0;
998}
999
15cdc341 1000#endif // wxHAS_TEXT_WINDOW_STREAM
a1b82138 1001
94af7d45
VZ
1002// ----------------------------------------------------------------------------
1003// emulating key presses
1004// ----------------------------------------------------------------------------
1005
1006bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event)
1007{
8680646d 1008 bool handled = false;
0ec1179b
VZ
1009 // we have a native implementation for Win32 and so don't need this one
1010#ifndef __WIN32__
02a48e3b 1011 wxChar ch = 0;
94af7d45 1012 int keycode = event.GetKeyCode();
32423dd8 1013
8680646d
SC
1014 long from, to;
1015 GetSelection(&from,&to);
1016 long insert = GetInsertionPoint();
1017 long last = GetLastPosition();
32423dd8
JS
1018
1019 // catch arrow left and right
1020
94af7d45
VZ
1021 switch ( keycode )
1022 {
8680646d
SC
1023 case WXK_LEFT:
1024 if ( event.ShiftDown() )
1025 SetSelection( (from > 0 ? from - 1 : 0) , to );
1026 else
1027 {
1028 if ( from != to )
1029 insert = from;
1030 else if ( insert > 0 )
1031 insert -= 1;
1032 SetInsertionPoint( insert );
1033 }
1034 handled = true;
1035 break;
1036 case WXK_RIGHT:
1037 if ( event.ShiftDown() )
1038 SetSelection( from, (to < last ? to + 1 : last) );
1039 else
1040 {
1041 if ( from != to )
1042 insert = to;
1043 else if ( insert < last )
1044 insert += 1;
1045 SetInsertionPoint( insert );
1046 }
1047 handled = true;
1048 break;
94af7d45
VZ
1049 case WXK_NUMPAD0:
1050 case WXK_NUMPAD1:
1051 case WXK_NUMPAD2:
1052 case WXK_NUMPAD3:
1053 case WXK_NUMPAD4:
1054 case WXK_NUMPAD5:
1055 case WXK_NUMPAD6:
1056 case WXK_NUMPAD7:
1057 case WXK_NUMPAD8:
1058 case WXK_NUMPAD9:
9a83f860 1059 ch = (wxChar)(wxT('0') + keycode - WXK_NUMPAD0);
94af7d45
VZ
1060 break;
1061
1062 case WXK_MULTIPLY:
1063 case WXK_NUMPAD_MULTIPLY:
9a83f860 1064 ch = wxT('*');
94af7d45
VZ
1065 break;
1066
1067 case WXK_ADD:
1068 case WXK_NUMPAD_ADD:
9a83f860 1069 ch = wxT('+');
94af7d45
VZ
1070 break;
1071
1072 case WXK_SUBTRACT:
1073 case WXK_NUMPAD_SUBTRACT:
9a83f860 1074 ch = wxT('-');
94af7d45
VZ
1075 break;
1076
1077 case WXK_DECIMAL:
1078 case WXK_NUMPAD_DECIMAL:
9a83f860 1079 ch = wxT('.');
94af7d45
VZ
1080 break;
1081
1082 case WXK_DIVIDE:
1083 case WXK_NUMPAD_DIVIDE:
9a83f860 1084 ch = wxT('/');
94af7d45
VZ
1085 break;
1086
cd916794
VZ
1087 case WXK_DELETE:
1088 case WXK_NUMPAD_DELETE:
1089 // delete the character at cursor
1090 {
7d8268a1
WS
1091 const long pos = GetInsertionPoint();
1092 if ( pos < GetLastPosition() )
cd916794 1093 Remove(pos, pos + 1);
8680646d 1094 handled = true;
cd916794
VZ
1095 }
1096 break;
1097
1098 case WXK_BACK:
1099 // delete the character before the cursor
1100 {
1101 const long pos = GetInsertionPoint();
1102 if ( pos > 0 )
1103 Remove(pos - 1, pos);
8680646d 1104 handled = true;
cd916794
VZ
1105 }
1106 break;
1107
94af7d45 1108 default:
c4d25c01
VS
1109#if wxUSE_UNICODE
1110 if ( event.GetUnicodeKey() )
1111 {
1112 ch = event.GetUnicodeKey();
1113 }
1114 else
1115#endif
401eb3de 1116 if ( keycode < 256 && keycode >= 0 && wxIsprint(keycode) )
94af7d45
VZ
1117 {
1118 // FIXME this is not going to work for non letters...
1119 if ( !event.ShiftDown() )
1120 {
401eb3de 1121 keycode = wxTolower(keycode);
94af7d45
VZ
1122 }
1123
1124 ch = (wxChar)keycode;
1125 }
1126 else
1127 {
9a83f860 1128 ch = wxT('\0');
94af7d45
VZ
1129 }
1130 }
1131
1132 if ( ch )
1133 {
1134 WriteText(ch);
1135
8680646d 1136 handled = true;
94af7d45 1137 }
c8fe7fda
VZ
1138#else // __WIN32__
1139 wxUnusedVar(event);
1140#endif // !__WIN32__/__WIN32__
94af7d45 1141
8680646d 1142 return handled;
18414479
VZ
1143}
1144
7dd65e5a
VZ
1145// ----------------------------------------------------------------------------
1146// Other miscellaneous stuff
1147// ----------------------------------------------------------------------------
1148
1149bool wxTextCtrlBase::SetHint(const wxString& hint)
1150{
1151 wxCHECK_MSG( IsSingleLine(), false,
1152 wxS("Hints can only be set for single line text controls") );
1153
1154 return wxTextEntry::SetHint(hint);
1155}
1156
e39af974
JS
1157// do the window-specific processing after processing the update event
1158void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
1159{
a3a4105d
VZ
1160 // call inherited, but skip the wxControl's version, and call directly the
1161 // wxWindow's one instead, because the only reason why we are overriding this
1162 // function is that we want to use SetValue() instead of wxControl::SetLabel()
1163 wxWindowBase::DoUpdateWindowUI(event);
cb719f2e 1164
a3a4105d 1165 // update text
e39af974
JS
1166 if ( event.GetSetText() )
1167 {
1168 if ( event.GetText() != GetValue() )
1169 SetValue(event.GetText());
cb719f2e 1170 }
e39af974
JS
1171}
1172
efe66bbc
VZ
1173// ----------------------------------------------------------------------------
1174// hit testing
1175// ----------------------------------------------------------------------------
1176
692c9b86 1177wxTextCtrlHitTestResult
0ec1179b 1178wxTextAreaBase::HitTest(const wxPoint& pt, wxTextCoord *x, wxTextCoord *y) const
692c9b86
VZ
1179{
1180 // implement in terms of the other overload as the native ports typically
1181 // can get the position and not (x, y) pair directly (although wxUniv
1182 // directly gets x and y -- and so overrides this method as well)
1183 long pos;
1184 wxTextCtrlHitTestResult rc = HitTest(pt, &pos);
1185
1186 if ( rc != wxTE_HT_UNKNOWN )
1187 {
1188 PositionToXY(pos, x, y);
1189 }
1190
1191 return rc;
1192}
1193
efe66bbc 1194wxTextCtrlHitTestResult
0ec1179b 1195wxTextAreaBase::HitTest(const wxPoint& WXUNUSED(pt), long * WXUNUSED(pos)) const
efe66bbc
VZ
1196{
1197 // not implemented
1198 return wxTE_HT_UNKNOWN;
1199}
e39af974 1200
6ce83213
VZ
1201wxPoint wxTextAreaBase::PositionToCoords(long pos) const
1202{
1203 wxCHECK_MSG( IsValidPosition(pos), wxDefaultPosition,
1204 wxS("Position argument out of range.") );
1205
1206 return DoPositionToCoords(pos);
1207}
1208
1209wxPoint wxTextAreaBase::DoPositionToCoords(long WXUNUSED(pos)) const
1210{
1211 return wxDefaultPosition;
1212}
1213
ad0bae85
VZ
1214#else // !wxUSE_TEXTCTRL
1215
1216// define this one even if !wxUSE_TEXTCTRL because it is also used by other
1217// controls (wxComboBox and wxSpinCtrl)
ad0bae85 1218
ce7fe42e 1219wxDEFINE_EVENT( wxEVT_TEXT, wxCommandEvent );
ad0bae85
VZ
1220
1221#endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL