1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textcmn.cpp
3 // Purpose: implementation of platform-independent functions of wxTextCtrl
4 // Author: Julian Smart
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // for compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
28 #include "wx/textctrl.h"
37 extern WXDLLEXPORT_DATA(const char) wxTextCtrlNameStr
[] = "text";
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
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))
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 wxDEFINE_FLAGS( wxTextCtrlStyle
)
56 wxBEGIN_FLAGS( wxTextCtrlStyle
)
57 // new style border flags, we put them first to
58 // use them for streaming out
59 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
60 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
61 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
62 wxFLAGS_MEMBER(wxBORDER_RAISED
)
63 wxFLAGS_MEMBER(wxBORDER_STATIC
)
64 wxFLAGS_MEMBER(wxBORDER_NONE
)
66 // old style border flags
67 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
68 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
69 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
70 wxFLAGS_MEMBER(wxRAISED_BORDER
)
71 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
72 wxFLAGS_MEMBER(wxBORDER
)
74 // standard window styles
75 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
76 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
77 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
78 wxFLAGS_MEMBER(wxWANTS_CHARS
)
79 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
80 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
81 wxFLAGS_MEMBER(wxVSCROLL
)
82 wxFLAGS_MEMBER(wxHSCROLL
)
84 wxFLAGS_MEMBER(wxTE_PROCESS_ENTER
)
85 wxFLAGS_MEMBER(wxTE_PROCESS_TAB
)
86 wxFLAGS_MEMBER(wxTE_MULTILINE
)
87 wxFLAGS_MEMBER(wxTE_PASSWORD
)
88 wxFLAGS_MEMBER(wxTE_READONLY
)
89 wxFLAGS_MEMBER(wxHSCROLL
)
90 wxFLAGS_MEMBER(wxTE_RICH
)
91 wxFLAGS_MEMBER(wxTE_RICH2
)
92 wxFLAGS_MEMBER(wxTE_AUTO_URL
)
93 wxFLAGS_MEMBER(wxTE_NOHIDESEL
)
94 wxFLAGS_MEMBER(wxTE_LEFT
)
95 wxFLAGS_MEMBER(wxTE_CENTRE
)
96 wxFLAGS_MEMBER(wxTE_RIGHT
)
97 wxFLAGS_MEMBER(wxTE_DONTWRAP
)
98 wxFLAGS_MEMBER(wxTE_CHARWRAP
)
99 wxFLAGS_MEMBER(wxTE_WORDWRAP
)
100 wxEND_FLAGS( wxTextCtrlStyle
)
102 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTextCtrl
, wxControl
, "wx/textctrl.h")
104 wxBEGIN_PROPERTIES_TABLE(wxTextCtrl
)
105 wxEVENT_PROPERTY( TextUpdated
, wxEVT_TEXT
, wxCommandEvent
)
106 wxEVENT_PROPERTY( TextEnter
, wxEVT_TEXT_ENTER
, wxCommandEvent
)
108 wxPROPERTY( Font
, wxFont
, SetFont
, GetFont
, wxEMPTY_PARAMETER_VALUE
, \
109 0 /*flags*/, wxT("Helpstring"), wxT("group") )
110 wxPROPERTY( Value
, wxString
, SetValue
, GetValue
, wxString(), \
111 0 /*flags*/, wxT("Helpstring"), wxT("group"))
113 wxPROPERTY_FLAGS( WindowStyle
, wxTextCtrlStyle
, long, SetWindowStyleFlag
, \
114 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
115 wxT("Helpstring"), wxT("group")) // style
116 wxEND_PROPERTIES_TABLE()
118 wxEMPTY_HANDLERS_TABLE(wxTextCtrl
)
120 wxCONSTRUCTOR_6( wxTextCtrl
, wxWindow
*, Parent
, wxWindowID
, Id
, \
121 wxString
, Value
, wxPoint
, Position
, wxSize
, Size
, \
125 IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent
, wxCommandEvent
)
127 wxDEFINE_EVENT( wxEVT_TEXT
, wxCommandEvent
);
128 wxDEFINE_EVENT( wxEVT_TEXT_ENTER
, wxCommandEvent
);
129 wxDEFINE_EVENT( wxEVT_TEXT_URL
, wxTextUrlEvent
);
130 wxDEFINE_EVENT( wxEVT_TEXT_MAXLEN
, wxCommandEvent
);
132 IMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase
, wxControl
)
134 // ============================================================================
135 // wxTextAttr implementation
136 // ============================================================================
138 wxTextAttr::wxTextAttr(const wxColour
& colText
,
139 const wxColour
& colBack
,
141 wxTextAttrAlignment alignment
): m_textAlignment(alignment
), m_colText(colText
), m_colBack(colBack
)
145 if (m_colText
.IsOk()) m_flags
|= wxTEXT_ATTR_TEXT_COLOUR
;
146 if (m_colBack
.IsOk()) m_flags
|= wxTEXT_ATTR_BACKGROUND_COLOUR
;
147 if (alignment
!= wxTEXT_ALIGNMENT_DEFAULT
)
148 m_flags
|= wxTEXT_ATTR_ALIGNMENT
;
150 GetFontAttributes(font
);
154 void wxTextAttr::Init()
156 m_textAlignment
= wxTEXT_ALIGNMENT_DEFAULT
;
163 m_fontStyle
= wxFONTSTYLE_NORMAL
;
164 m_fontWeight
= wxFONTWEIGHT_NORMAL
;
165 m_fontUnderlined
= false;
166 m_fontStrikethrough
= false;
167 m_fontEncoding
= wxFONTENCODING_DEFAULT
;
168 m_fontFamily
= wxFONTFAMILY_DEFAULT
;
170 m_paragraphSpacingAfter
= 0;
171 m_paragraphSpacingBefore
= 0;
173 m_bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_NONE
;
174 m_textEffects
= wxTEXT_ATTR_EFFECT_NONE
;
175 m_textEffectFlags
= wxTEXT_ATTR_EFFECT_NONE
;
181 void wxTextAttr::Copy(const wxTextAttr
& attr
)
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
;
192 m_fontSize
= attr
.m_fontSize
;
193 m_fontStyle
= attr
.m_fontStyle
;
194 m_fontWeight
= attr
.m_fontWeight
;
195 m_fontUnderlined
= attr
.m_fontUnderlined
;
196 m_fontStrikethrough
= attr
.m_fontStrikethrough
;
197 m_fontFaceName
= attr
.m_fontFaceName
;
198 m_fontEncoding
= attr
.m_fontEncoding
;
199 m_fontFamily
= attr
.m_fontFamily
;
200 m_textEffects
= attr
.m_textEffects
;
201 m_textEffectFlags
= attr
.m_textEffectFlags
;
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
;
216 m_urlTarget
= attr
.m_urlTarget
;
220 void wxTextAttr::operator= (const wxTextAttr
& attr
)
226 bool wxTextAttr::operator== (const wxTextAttr
& attr
) const
228 return GetFlags() == attr
.GetFlags() &&
230 GetTextColour() == attr
.GetTextColour() &&
231 GetBackgroundColour() == attr
.GetBackgroundColour() &&
233 GetAlignment() == attr
.GetAlignment() &&
234 GetLeftIndent() == attr
.GetLeftIndent() &&
235 GetLeftSubIndent() == attr
.GetLeftSubIndent() &&
236 GetRightIndent() == attr
.GetRightIndent() &&
237 TabsEq(GetTabs(), attr
.GetTabs()) &&
239 GetParagraphSpacingAfter() == attr
.GetParagraphSpacingAfter() &&
240 GetParagraphSpacingBefore() == attr
.GetParagraphSpacingBefore() &&
241 GetLineSpacing() == attr
.GetLineSpacing() &&
242 GetCharacterStyleName() == attr
.GetCharacterStyleName() &&
243 GetParagraphStyleName() == attr
.GetParagraphStyleName() &&
244 GetListStyleName() == attr
.GetListStyleName() &&
246 GetBulletStyle() == attr
.GetBulletStyle() &&
247 GetBulletText() == attr
.GetBulletText() &&
248 GetBulletNumber() == attr
.GetBulletNumber() &&
249 GetBulletFont() == attr
.GetBulletFont() &&
250 GetBulletName() == attr
.GetBulletName() &&
252 GetTextEffects() == attr
.GetTextEffects() &&
253 GetTextEffectFlags() == attr
.GetTextEffectFlags() &&
255 GetOutlineLevel() == attr
.GetOutlineLevel() &&
257 GetFontSize() == attr
.GetFontSize() &&
258 GetFontStyle() == attr
.GetFontStyle() &&
259 GetFontWeight() == attr
.GetFontWeight() &&
260 GetFontUnderlined() == attr
.GetFontUnderlined() &&
261 GetFontFaceName() == attr
.GetFontFaceName() &&
262 GetFontEncoding() == attr
.GetFontEncoding() &&
263 GetFontFamily() == attr
.GetFontFamily() &&
265 GetURL() == attr
.GetURL();
268 // Partial equality test. Only returns false if an attribute doesn't match.
269 bool wxTextAttr::EqPartial(const wxTextAttr
& attr
, bool weakTest
) const
271 int flags
= attr
.GetFlags();
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())))
304 if (HasTextColour() && attr
.HasTextColour() && GetTextColour() != attr
.GetTextColour())
307 if (HasBackgroundColour() && attr
.HasBackgroundColour() && GetBackgroundColour() != attr
.GetBackgroundColour())
310 if (HasFontFaceName() && attr
.HasFontFaceName() && GetFontFaceName() != attr
.GetFontFaceName())
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
))
317 if (HasFontPointSize() && attr
.HasFontPointSize() && GetFontSize() != attr
.GetFontSize())
320 if (HasFontPixelSize() && attr
.HasFontPixelSize() && GetFontSize() != attr
.GetFontSize())
323 if (HasFontWeight() && attr
.HasFontWeight() && GetFontWeight() != attr
.GetFontWeight())
326 if (HasFontItalic() && attr
.HasFontItalic() && GetFontStyle() != attr
.GetFontStyle())
329 if (HasFontUnderlined() && attr
.HasFontUnderlined() && GetFontUnderlined() != attr
.GetFontUnderlined())
332 if (HasFontStrikethrough() && attr
.HasFontStrikethrough() && GetFontStrikethrough() != attr
.GetFontStrikethrough())
335 if (HasFontEncoding() && attr
.HasFontEncoding() && GetFontEncoding() != attr
.GetFontEncoding())
338 if (HasFontFamily() && attr
.HasFontFamily() && GetFontFamily() != attr
.GetFontFamily())
341 if (HasURL() && attr
.HasURL() && GetURL() != attr
.GetURL())
344 if (HasAlignment() && attr
.HasAlignment() && GetAlignment() != attr
.GetAlignment())
347 if (HasLeftIndent() && attr
.HasLeftIndent() &&
348 ((GetLeftIndent() != attr
.GetLeftIndent()) || (GetLeftSubIndent() != attr
.GetLeftSubIndent())))
351 if (HasRightIndent() && attr
.HasRightIndent() && (GetRightIndent() != attr
.GetRightIndent()))
354 if (HasParagraphSpacingAfter() && attr
.HasParagraphSpacingAfter() &&
355 (GetParagraphSpacingAfter() != attr
.GetParagraphSpacingAfter()))
358 if (HasParagraphSpacingBefore() && attr
.HasParagraphSpacingBefore() &&
359 (GetParagraphSpacingBefore() != attr
.GetParagraphSpacingBefore()))
362 if (HasLineSpacing() && attr
.HasLineSpacing() && (GetLineSpacing() != attr
.GetLineSpacing()))
365 if (HasCharacterStyleName() && attr
.HasCharacterStyleName() && (GetCharacterStyleName() != attr
.GetCharacterStyleName()))
368 if (HasParagraphStyleName() && attr
.HasParagraphStyleName() && (GetParagraphStyleName() != attr
.GetParagraphStyleName()))
371 if (HasListStyleName() && attr
.HasListStyleName() && (GetListStyleName() != attr
.GetListStyleName()))
374 if (HasBulletStyle() && attr
.HasBulletStyle() && (GetBulletStyle() != attr
.GetBulletStyle()))
377 if (HasBulletNumber() && attr
.HasBulletNumber() && (GetBulletNumber() != attr
.GetBulletNumber()))
380 if (HasBulletText() && attr
.HasBulletText() &&
381 (GetBulletText() != attr
.GetBulletText()) &&
382 (GetBulletFont() != attr
.GetBulletFont()))
385 if (HasBulletName() && attr
.HasBulletName() && (GetBulletName() != attr
.GetBulletName()))
388 if (HasTabs() && attr
.HasTabs() && !TabsEq(GetTabs(), attr
.GetTabs()))
391 if ((HasPageBreak() != attr
.HasPageBreak()))
394 if (HasTextEffects() && attr
.HasTextEffects())
396 if (!BitlistsEqPartial(GetTextEffects(), attr
.GetTextEffects(), attr
.GetTextEffectFlags()))
400 if (HasOutlineLevel() && attr
.HasOutlineLevel() && (GetOutlineLevel() != attr
.GetOutlineLevel()))
406 // Create font from font attributes.
407 wxFont
wxTextAttr::GetFont() const
414 fontSize
= GetFontSize();
416 wxFontStyle fontStyle
= wxFONTSTYLE_NORMAL
;
418 fontStyle
= GetFontStyle();
420 wxFontWeight fontWeight
= wxFONTWEIGHT_NORMAL
;
422 fontWeight
= GetFontWeight();
424 bool underlined
= false;
425 if (HasFontUnderlined())
426 underlined
= GetFontUnderlined();
428 bool strikethrough
= false;
429 if (HasFontStrikethrough())
430 strikethrough
= GetFontStrikethrough();
432 wxString fontFaceName
;
433 if (HasFontFaceName())
434 fontFaceName
= GetFontFaceName();
436 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
;
437 if (HasFontEncoding())
438 encoding
= GetFontEncoding();
440 wxFontFamily fontFamily
= wxFONTFAMILY_DEFAULT
;
442 fontFamily
= GetFontFamily();
444 if (HasFontPixelSize())
446 wxFont
font(wxSize(0, fontSize
), fontFamily
, fontStyle
, fontWeight
, underlined
, fontFaceName
, encoding
);
448 font
.SetStrikethrough(true);
453 wxFont
font(fontSize
, fontFamily
, fontStyle
, fontWeight
, underlined
, fontFaceName
, encoding
);
455 font
.SetStrikethrough(true);
460 // Get attributes from font.
461 bool wxTextAttr::GetFontAttributes(const wxFont
& font
, int flags
)
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
)
470 if (font
.IsUsingSizeInPixels())
472 m_fontSize
= font
.GetPixelSize().y
;
473 flags
&= ~wxTEXT_ATTR_FONT_POINT_SIZE
;
477 m_fontSize
= font
.GetPointSize();
478 flags
&= ~wxTEXT_ATTR_FONT_PIXEL_SIZE
;
481 else if (flags
& wxTEXT_ATTR_FONT_POINT_SIZE
)
483 m_fontSize
= font
.GetPointSize();
484 flags
&= ~wxTEXT_ATTR_FONT_PIXEL_SIZE
;
486 else if (flags
& wxTEXT_ATTR_FONT_PIXEL_SIZE
)
488 m_fontSize
= font
.GetPixelSize().y
;
491 if (flags
& wxTEXT_ATTR_FONT_ITALIC
)
492 m_fontStyle
= font
.GetStyle();
494 if (flags
& wxTEXT_ATTR_FONT_WEIGHT
)
495 m_fontWeight
= font
.GetWeight();
497 if (flags
& wxTEXT_ATTR_FONT_UNDERLINE
)
498 m_fontUnderlined
= font
.GetUnderlined();
500 if (flags
& wxTEXT_ATTR_FONT_STRIKETHROUGH
)
501 m_fontStrikethrough
= font
.GetStrikethrough();
503 if (flags
& wxTEXT_ATTR_FONT_FACE
)
504 m_fontFaceName
= font
.GetFaceName();
506 if (flags
& wxTEXT_ATTR_FONT_ENCODING
)
507 m_fontEncoding
= font
.GetEncoding();
509 if (flags
& wxTEXT_ATTR_FONT_FAMILY
)
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
;
518 m_fontFamily
= fontFamily
;
526 // Resets bits in destination so new attributes aren't merged with mutually exclusive ones
527 static bool wxResetIncompatibleBits(const int mask
, const int srcFlags
, int& destFlags
, int& destBits
)
529 if ((srcFlags
& mask
) && (destFlags
& mask
))
538 bool wxTextAttr::Apply(const wxTextAttr
& style
, const wxTextAttr
* compareWith
)
540 wxTextAttr
& destStyle
= (*this);
542 if (style
.HasFontWeight())
544 if (!(compareWith
&& compareWith
->HasFontWeight() && compareWith
->GetFontWeight() == style
.GetFontWeight()))
545 destStyle
.SetFontWeight(style
.GetFontWeight());
548 if (style
.HasFontPointSize())
550 if (!(compareWith
&& compareWith
->HasFontPointSize() && compareWith
->GetFontSize() == style
.GetFontSize()))
551 destStyle
.SetFontPointSize(style
.GetFontSize());
553 else if (style
.HasFontPixelSize())
555 if (!(compareWith
&& compareWith
->HasFontPixelSize() && compareWith
->GetFontSize() == style
.GetFontSize()))
556 destStyle
.SetFontPixelSize(style
.GetFontSize());
559 if (style
.HasFontItalic())
561 if (!(compareWith
&& compareWith
->HasFontItalic() && compareWith
->GetFontStyle() == style
.GetFontStyle()))
562 destStyle
.SetFontStyle(style
.GetFontStyle());
565 if (style
.HasFontUnderlined())
567 if (!(compareWith
&& compareWith
->HasFontUnderlined() && compareWith
->GetFontUnderlined() == style
.GetFontUnderlined()))
568 destStyle
.SetFontUnderlined(style
.GetFontUnderlined());
571 if (style
.HasFontStrikethrough())
573 if (!(compareWith
&& compareWith
->HasFontStrikethrough() && compareWith
->GetFontStrikethrough() == style
.GetFontStrikethrough()))
574 destStyle
.SetFontStrikethrough(style
.GetFontStrikethrough());
577 if (style
.HasFontFaceName())
579 if (!(compareWith
&& compareWith
->HasFontFaceName() && compareWith
->GetFontFaceName() == style
.GetFontFaceName()))
580 destStyle
.SetFontFaceName(style
.GetFontFaceName());
583 if (style
.HasFontEncoding())
585 if (!(compareWith
&& compareWith
->HasFontEncoding() && compareWith
->GetFontEncoding() == style
.GetFontEncoding()))
586 destStyle
.SetFontEncoding(style
.GetFontEncoding());
589 if (style
.HasFontFamily())
591 if (!(compareWith
&& compareWith
->HasFontFamily() && compareWith
->GetFontFamily() == style
.GetFontFamily()))
592 destStyle
.SetFontFamily(style
.GetFontFamily());
595 if (style
.GetTextColour().IsOk() && style
.HasTextColour())
597 if (!(compareWith
&& compareWith
->HasTextColour() && compareWith
->GetTextColour() == style
.GetTextColour()))
598 destStyle
.SetTextColour(style
.GetTextColour());
601 if (style
.GetBackgroundColour().IsOk() && style
.HasBackgroundColour())
603 if (!(compareWith
&& compareWith
->HasBackgroundColour() && compareWith
->GetBackgroundColour() == style
.GetBackgroundColour()))
604 destStyle
.SetBackgroundColour(style
.GetBackgroundColour());
607 if (style
.HasAlignment())
609 if (!(compareWith
&& compareWith
->HasAlignment() && compareWith
->GetAlignment() == style
.GetAlignment()))
610 destStyle
.SetAlignment(style
.GetAlignment());
615 if (!(compareWith
&& compareWith
->HasTabs() && TabsEq(compareWith
->GetTabs(), style
.GetTabs())))
616 destStyle
.SetTabs(style
.GetTabs());
619 if (style
.HasLeftIndent())
621 if (!(compareWith
&& compareWith
->HasLeftIndent() && compareWith
->GetLeftIndent() == style
.GetLeftIndent()
622 && compareWith
->GetLeftSubIndent() == style
.GetLeftSubIndent()))
623 destStyle
.SetLeftIndent(style
.GetLeftIndent(), style
.GetLeftSubIndent());
626 if (style
.HasRightIndent())
628 if (!(compareWith
&& compareWith
->HasRightIndent() && compareWith
->GetRightIndent() == style
.GetRightIndent()))
629 destStyle
.SetRightIndent(style
.GetRightIndent());
632 if (style
.HasParagraphSpacingAfter())
634 if (!(compareWith
&& compareWith
->HasParagraphSpacingAfter() && compareWith
->GetParagraphSpacingAfter() == style
.GetParagraphSpacingAfter()))
635 destStyle
.SetParagraphSpacingAfter(style
.GetParagraphSpacingAfter());
638 if (style
.HasParagraphSpacingBefore())
640 if (!(compareWith
&& compareWith
->HasParagraphSpacingBefore() && compareWith
->GetParagraphSpacingBefore() == style
.GetParagraphSpacingBefore()))
641 destStyle
.SetParagraphSpacingBefore(style
.GetParagraphSpacingBefore());
644 if (style
.HasLineSpacing())
646 if (!(compareWith
&& compareWith
->HasLineSpacing() && compareWith
->GetLineSpacing() == style
.GetLineSpacing()))
647 destStyle
.SetLineSpacing(style
.GetLineSpacing());
650 if (style
.HasCharacterStyleName())
652 if (!(compareWith
&& compareWith
->HasCharacterStyleName() && compareWith
->GetCharacterStyleName() == style
.GetCharacterStyleName()))
653 destStyle
.SetCharacterStyleName(style
.GetCharacterStyleName());
656 if (style
.HasParagraphStyleName())
658 if (!(compareWith
&& compareWith
->HasParagraphStyleName() && compareWith
->GetParagraphStyleName() == style
.GetParagraphStyleName()))
659 destStyle
.SetParagraphStyleName(style
.GetParagraphStyleName());
662 if (style
.HasListStyleName())
664 if (!(compareWith
&& compareWith
->HasListStyleName() && compareWith
->GetListStyleName() == style
.GetListStyleName()))
665 destStyle
.SetListStyleName(style
.GetListStyleName());
668 if (style
.HasBulletStyle())
670 if (!(compareWith
&& compareWith
->HasBulletStyle() && compareWith
->GetBulletStyle() == style
.GetBulletStyle()))
671 destStyle
.SetBulletStyle(style
.GetBulletStyle());
674 if (style
.HasBulletText())
676 if (!(compareWith
&& compareWith
->HasBulletText() && compareWith
->GetBulletText() == style
.GetBulletText()))
678 destStyle
.SetBulletText(style
.GetBulletText());
679 destStyle
.SetBulletFont(style
.GetBulletFont());
683 if (style
.HasBulletNumber())
685 if (!(compareWith
&& compareWith
->HasBulletNumber() && compareWith
->GetBulletNumber() == style
.GetBulletNumber()))
686 destStyle
.SetBulletNumber(style
.GetBulletNumber());
689 if (style
.HasBulletName())
691 if (!(compareWith
&& compareWith
->HasBulletName() && compareWith
->GetBulletName() == style
.GetBulletName()))
692 destStyle
.SetBulletName(style
.GetBulletName());
697 if (!(compareWith
&& compareWith
->HasURL() && compareWith
->GetURL() == style
.GetURL()))
698 destStyle
.SetURL(style
.GetURL());
701 if (style
.HasPageBreak())
703 if (!(compareWith
&& compareWith
->HasPageBreak()))
704 destStyle
.SetPageBreak();
707 if (style
.HasTextEffects())
709 if (!(compareWith
&& compareWith
->HasTextEffects() && compareWith
->GetTextEffects() == style
.GetTextEffects()))
711 int destBits
= destStyle
.GetTextEffects();
712 int destFlags
= destStyle
.GetTextEffectFlags();
714 int srcBits
= style
.GetTextEffects();
715 int srcFlags
= style
.GetTextEffectFlags();
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
);
722 CombineBitlists(destBits
, srcBits
, destFlags
, srcFlags
);
724 destStyle
.SetTextEffects(destBits
);
725 destStyle
.SetTextEffectFlags(destFlags
);
729 if (style
.HasOutlineLevel())
731 if (!(compareWith
&& compareWith
->HasOutlineLevel() && compareWith
->GetOutlineLevel() == style
.GetOutlineLevel()))
732 destStyle
.SetOutlineLevel(style
.GetOutlineLevel());
739 wxTextAttr
wxTextAttr::Combine(const wxTextAttr
& attr
,
740 const wxTextAttr
& attrDef
,
741 const wxTextCtrlBase
*text
)
745 font
= attr
.GetFont();
749 if (attrDef
.HasFont())
750 font
= attrDef
.GetFont();
752 if ( text
&& !font
.IsOk() )
753 font
= text
->GetFont();
756 wxColour colFg
= attr
.GetTextColour();
759 colFg
= attrDef
.GetTextColour();
761 if ( text
&& !colFg
.IsOk() )
762 colFg
= text
->GetForegroundColour();
765 wxColour colBg
= attr
.GetBackgroundColour();
768 colBg
= attrDef
.GetBackgroundColour();
770 if ( text
&& !colBg
.IsOk() )
771 colBg
= text
->GetBackgroundColour();
774 wxTextAttr
newAttr(colFg
, colBg
, font
);
776 if (attr
.HasAlignment())
777 newAttr
.SetAlignment(attr
.GetAlignment());
778 else if (attrDef
.HasAlignment())
779 newAttr
.SetAlignment(attrDef
.GetAlignment());
782 newAttr
.SetTabs(attr
.GetTabs());
783 else if (attrDef
.HasTabs())
784 newAttr
.SetTabs(attrDef
.GetTabs());
786 if (attr
.HasLeftIndent())
787 newAttr
.SetLeftIndent(attr
.GetLeftIndent(), attr
.GetLeftSubIndent());
788 else if (attrDef
.HasLeftIndent())
789 newAttr
.SetLeftIndent(attrDef
.GetLeftIndent(), attr
.GetLeftSubIndent());
791 if (attr
.HasRightIndent())
792 newAttr
.SetRightIndent(attr
.GetRightIndent());
793 else if (attrDef
.HasRightIndent())
794 newAttr
.SetRightIndent(attrDef
.GetRightIndent());
800 bool wxTextAttr::TabsEq(const wxArrayInt
& tabs1
, const wxArrayInt
& tabs2
)
802 if (tabs1
.GetCount() != tabs2
.GetCount())
806 for (i
= 0; i
< tabs1
.GetCount(); i
++)
808 if (tabs1
[i
] != tabs2
[i
])
815 bool wxTextAttr::RemoveStyle(wxTextAttr
& destStyle
, const wxTextAttr
& style
)
817 int flags
= style
.GetFlags();
818 int destFlags
= destStyle
.GetFlags();
820 destStyle
.SetFlags(destFlags
& ~flags
);
825 /// Combine two bitlists, specifying the bits of interest with separate flags.
826 bool wxTextAttr::CombineBitlists(int& valueA
, int valueB
, int& flagsA
, int flagsB
)
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
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
;
836 // Now combine the 1 bits.
837 int valueA3
= (valueB
& flagsB
) | valueA2
;
840 flagsA
= (flagsA
| flagsB
);
845 /// Compare two bitlists
846 bool wxTextAttr::BitlistsEqPartial(int valueA
, int valueB
, int flags
)
848 int relevantBitsA
= valueA
& flags
;
849 int relevantBitsB
= valueB
& flags
;
850 return relevantBitsA
== relevantBitsB
;
853 /// Split into paragraph and character styles
854 bool wxTextAttr::SplitParaCharStyles(const wxTextAttr
& style
, wxTextAttr
& parStyle
, wxTextAttr
& charStyle
)
856 wxTextAttr
defaultCharStyle1(style
);
857 wxTextAttr
defaultParaStyle1(style
);
858 defaultCharStyle1
.SetFlags(defaultCharStyle1
.GetFlags()&wxTEXT_ATTR_CHARACTER
);
859 defaultParaStyle1
.SetFlags(defaultParaStyle1
.GetFlags()&wxTEXT_ATTR_PARAGRAPH
);
861 charStyle
.Apply(defaultCharStyle1
);
862 parStyle
.Apply(defaultParaStyle1
);
867 // apply styling to text range
868 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start
), long WXUNUSED(end
),
869 const wxTextAttr
& WXUNUSED(style
))
871 // to be implemented in derived classes
875 // get the styling at the given position
876 bool wxTextCtrlBase::GetStyle(long WXUNUSED(position
), wxTextAttr
& WXUNUSED(style
))
878 // to be implemented in derived classes
882 // change default text attributes
883 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr
& style
)
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
888 if ( style
.IsDefault() )
889 m_defaultStyle
= style
;
891 m_defaultStyle
= wxTextAttr::Combine(style
, m_defaultStyle
, this);
896 // ----------------------------------------------------------------------------
898 // ----------------------------------------------------------------------------
900 bool wxTextAreaBase::DoLoadFile(const wxString
& filename
, int WXUNUSED(fileType
))
903 wxFFile
file(filename
);
904 if ( file
.IsOpened() )
907 if ( file
.ReadAll(&text
) )
912 m_filename
= filename
;
918 (void)filename
; // avoid compiler warning about unreferenced parameter
919 #endif // wxUSE_FFILE
921 wxLogError(_("File couldn't be loaded."));
926 bool wxTextAreaBase::DoSaveFile(const wxString
& filename
, int WXUNUSED(fileType
))
929 wxFFile
file(filename
, wxT("w"));
930 if ( file
.IsOpened() && file
.Write(GetValue(), *wxConvCurrent
) )
932 // if it worked, save for future calls
933 m_filename
= filename
;
935 // it's not modified any longer
941 (void)filename
; // avoid compiler warning about unreferenced parameter
942 #endif // wxUSE_FFILE
947 bool wxTextAreaBase::SaveFile(const wxString
& filename
, int fileType
)
949 wxString filenameToUse
= filename
.empty() ? m_filename
: filename
;
950 if ( filenameToUse
.empty() )
952 // what kind of message to give? is it an error or a program bug?
953 wxLogDebug(wxT("Can't save textctrl to file without filename."));
958 return DoSaveFile(filenameToUse
, fileType
);
961 // ----------------------------------------------------------------------------
962 // stream-like insertion operator
963 // ----------------------------------------------------------------------------
965 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxString
& s
)
968 return *TEXTCTRL(this);
971 wxTextCtrl
& wxTextCtrlBase::operator<<(double d
)
973 return *this << wxString::Format("%.2f", d
);
976 wxTextCtrl
& wxTextCtrlBase::operator<<(int i
)
978 return *this << wxString::Format("%d", i
);
981 wxTextCtrl
& wxTextCtrlBase::operator<<(long l
)
983 return *this << wxString::Format("%ld", l
);
986 // ----------------------------------------------------------------------------
987 // streambuf methods implementation
988 // ----------------------------------------------------------------------------
990 #if wxHAS_TEXT_WINDOW_STREAM
992 int wxTextCtrlBase::overflow(int c
)
994 AppendText((wxChar
)c
);
996 // return something different from EOF
1000 #endif // wxHAS_TEXT_WINDOW_STREAM
1002 // ----------------------------------------------------------------------------
1003 // emulating key presses
1004 // ----------------------------------------------------------------------------
1006 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& event
)
1008 bool handled
= false;
1009 // we have a native implementation for Win32 and so don't need this one
1012 int keycode
= event
.GetKeyCode();
1015 GetSelection(&from
,&to
);
1016 long insert
= GetInsertionPoint();
1017 long last
= GetLastPosition();
1019 // catch arrow left and right
1024 if ( event
.ShiftDown() )
1025 SetSelection( (from
> 0 ? from
- 1 : 0) , to
);
1030 else if ( insert
> 0 )
1032 SetInsertionPoint( insert
);
1037 if ( event
.ShiftDown() )
1038 SetSelection( from
, (to
< last
? to
+ 1 : last
) );
1043 else if ( insert
< last
)
1045 SetInsertionPoint( insert
);
1059 ch
= (wxChar
)(wxT('0') + keycode
- WXK_NUMPAD0
);
1063 case WXK_NUMPAD_MULTIPLY
:
1068 case WXK_NUMPAD_ADD
:
1073 case WXK_NUMPAD_SUBTRACT
:
1078 case WXK_NUMPAD_DECIMAL
:
1083 case WXK_NUMPAD_DIVIDE
:
1088 case WXK_NUMPAD_DELETE
:
1089 // delete the character at cursor
1091 const long pos
= GetInsertionPoint();
1092 if ( pos
< GetLastPosition() )
1093 Remove(pos
, pos
+ 1);
1099 // delete the character before the cursor
1101 const long pos
= GetInsertionPoint();
1103 Remove(pos
- 1, pos
);
1110 if ( event
.GetUnicodeKey() )
1112 ch
= event
.GetUnicodeKey();
1116 if ( keycode
< 256 && keycode
>= 0 && wxIsprint(keycode
) )
1118 // FIXME this is not going to work for non letters...
1119 if ( !event
.ShiftDown() )
1121 keycode
= wxTolower(keycode
);
1124 ch
= (wxChar
)keycode
;
1140 #endif // !__WIN32__/__WIN32__
1145 // ----------------------------------------------------------------------------
1146 // Other miscellaneous stuff
1147 // ----------------------------------------------------------------------------
1149 bool wxTextCtrlBase::SetHint(const wxString
& hint
)
1151 wxCHECK_MSG( IsSingleLine(), false,
1152 wxS("Hints can only be set for single line text controls") );
1154 return wxTextEntry::SetHint(hint
);
1157 // do the window-specific processing after processing the update event
1158 void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent
& event
)
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
);
1166 if ( event
.GetSetText() )
1168 if ( event
.GetText() != GetValue() )
1169 SetValue(event
.GetText());
1173 // ----------------------------------------------------------------------------
1175 // ----------------------------------------------------------------------------
1177 wxTextCtrlHitTestResult
1178 wxTextAreaBase::HitTest(const wxPoint
& pt
, wxTextCoord
*x
, wxTextCoord
*y
) const
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)
1184 wxTextCtrlHitTestResult rc
= HitTest(pt
, &pos
);
1186 if ( rc
!= wxTE_HT_UNKNOWN
)
1188 PositionToXY(pos
, x
, y
);
1194 wxTextCtrlHitTestResult
1195 wxTextAreaBase::HitTest(const wxPoint
& WXUNUSED(pt
), long * WXUNUSED(pos
)) const
1198 return wxTE_HT_UNKNOWN
;
1201 wxPoint
wxTextAreaBase::PositionToCoords(long pos
) const
1203 wxCHECK_MSG( IsValidPosition(pos
), wxDefaultPosition
,
1204 wxS("Position argument out of range.") );
1206 return DoPositionToCoords(pos
);
1209 wxPoint
wxTextAreaBase::DoPositionToCoords(long WXUNUSED(pos
)) const
1211 return wxDefaultPosition
;
1214 #else // !wxUSE_TEXTCTRL
1216 // define this one even if !wxUSE_TEXTCTRL because it is also used by other
1217 // controls (wxComboBox and wxSpinCtrl)
1219 wxDEFINE_EVENT( wxEVT_TEXT
, wxCommandEvent
);
1221 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL