1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textcmn.cpp
3 // Purpose: implementation of platform-independent functions of wxTextCtrl
4 // Author: Julian Smart
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // for compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 #include "wx/textctrl.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 // we don't have any objects of type wxTextCtrlBase in the program, only
43 // wxTextCtrl, so this cast is safe
44 #define TEXTCTRL(ptr) ((wxTextCtrl *)(ptr))
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 wxDEFINE_FLAGS( wxTextCtrlStyle
)
55 wxBEGIN_FLAGS( wxTextCtrlStyle
)
56 // new style border flags, we put them first to
57 // use them for streaming out
58 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
59 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
60 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
61 wxFLAGS_MEMBER(wxBORDER_RAISED
)
62 wxFLAGS_MEMBER(wxBORDER_STATIC
)
63 wxFLAGS_MEMBER(wxBORDER_NONE
)
65 // old style border flags
66 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
67 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
68 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
69 wxFLAGS_MEMBER(wxRAISED_BORDER
)
70 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
71 wxFLAGS_MEMBER(wxBORDER
)
73 // standard window styles
74 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
75 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
76 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
77 wxFLAGS_MEMBER(wxWANTS_CHARS
)
78 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
79 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
80 wxFLAGS_MEMBER(wxVSCROLL
)
81 wxFLAGS_MEMBER(wxHSCROLL
)
83 wxFLAGS_MEMBER(wxTE_PROCESS_ENTER
)
84 wxFLAGS_MEMBER(wxTE_PROCESS_TAB
)
85 wxFLAGS_MEMBER(wxTE_MULTILINE
)
86 wxFLAGS_MEMBER(wxTE_PASSWORD
)
87 wxFLAGS_MEMBER(wxTE_READONLY
)
88 wxFLAGS_MEMBER(wxHSCROLL
)
89 wxFLAGS_MEMBER(wxTE_RICH
)
90 wxFLAGS_MEMBER(wxTE_RICH2
)
91 wxFLAGS_MEMBER(wxTE_AUTO_URL
)
92 wxFLAGS_MEMBER(wxTE_NOHIDESEL
)
93 wxFLAGS_MEMBER(wxTE_LEFT
)
94 wxFLAGS_MEMBER(wxTE_CENTRE
)
95 wxFLAGS_MEMBER(wxTE_RIGHT
)
96 wxFLAGS_MEMBER(wxTE_DONTWRAP
)
97 wxFLAGS_MEMBER(wxTE_CHARWRAP
)
98 wxFLAGS_MEMBER(wxTE_WORDWRAP
)
99 wxEND_FLAGS( wxTextCtrlStyle
)
101 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTextCtrl
, wxControl
, "wx/textctrl.h")
103 wxBEGIN_PROPERTIES_TABLE(wxTextCtrl
)
104 wxEVENT_PROPERTY( TextUpdated
, wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
)
105 wxEVENT_PROPERTY( TextEnter
, wxEVT_COMMAND_TEXT_ENTER
, wxCommandEvent
)
107 wxPROPERTY( Font
, wxFont
, SetFont
, GetFont
, wxEMPTY_PARAMETER_VALUE
, \
108 0 /*flags*/, wxT("Helpstring"), wxT("group") )
109 wxPROPERTY( Value
, wxString
, SetValue
, GetValue
, wxString(), \
110 0 /*flags*/, wxT("Helpstring"), wxT("group"))
112 wxPROPERTY_FLAGS( WindowStyle
, wxTextCtrlStyle
, long, SetWindowStyleFlag
, \
113 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
114 wxT("Helpstring"), wxT("group")) // style
115 wxEND_PROPERTIES_TABLE()
117 wxEMPTY_HANDLERS_TABLE(wxTextCtrl
)
119 wxCONSTRUCTOR_6( wxTextCtrl
, wxWindow
*, Parent
, wxWindowID
, Id
, \
120 wxString
, Value
, wxPoint
, Position
, wxSize
, Size
, \
124 IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent
, wxCommandEvent
)
126 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
);
127 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_ENTER
, wxCommandEvent
);
128 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_URL
, wxTextUrlEvent
);
129 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_MAXLEN
, wxCommandEvent
);
131 IMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase
, wxControl
)
133 // ============================================================================
134 // wxTextAttr implementation
135 // ============================================================================
137 wxTextAttr::wxTextAttr(const wxColour
& colText
,
138 const wxColour
& colBack
,
140 wxTextAttrAlignment alignment
): m_textAlignment(alignment
), m_colText(colText
), m_colBack(colBack
)
144 if (m_colText
.Ok()) m_flags
|= wxTEXT_ATTR_TEXT_COLOUR
;
145 if (m_colBack
.Ok()) m_flags
|= wxTEXT_ATTR_BACKGROUND_COLOUR
;
146 if (alignment
!= wxTEXT_ALIGNMENT_DEFAULT
)
147 m_flags
|= wxTEXT_ATTR_ALIGNMENT
;
149 GetFontAttributes(font
);
153 void wxTextAttr::Init()
155 m_textAlignment
= wxTEXT_ALIGNMENT_DEFAULT
;
162 m_fontStyle
= wxFONTSTYLE_NORMAL
;
163 m_fontWeight
= wxFONTWEIGHT_NORMAL
;
164 m_fontUnderlined
= false;
165 m_fontEncoding
= wxFONTENCODING_DEFAULT
;
166 m_fontFamily
= wxFONTFAMILY_DEFAULT
;
168 m_paragraphSpacingAfter
= 0;
169 m_paragraphSpacingBefore
= 0;
171 m_bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_NONE
;
172 m_textEffects
= wxTEXT_ATTR_EFFECT_NONE
;
173 m_textEffectFlags
= wxTEXT_ATTR_EFFECT_NONE
;
179 void wxTextAttr::Copy(const wxTextAttr
& attr
)
181 m_colText
= attr
.m_colText
;
182 m_colBack
= attr
.m_colBack
;
183 m_textAlignment
= attr
.m_textAlignment
;
184 m_leftIndent
= attr
.m_leftIndent
;
185 m_leftSubIndent
= attr
.m_leftSubIndent
;
186 m_rightIndent
= attr
.m_rightIndent
;
187 m_tabs
= attr
.m_tabs
;
188 m_flags
= attr
.m_flags
;
190 m_fontSize
= attr
.m_fontSize
;
191 m_fontStyle
= attr
.m_fontStyle
;
192 m_fontWeight
= attr
.m_fontWeight
;
193 m_fontUnderlined
= attr
.m_fontUnderlined
;
194 m_fontFaceName
= attr
.m_fontFaceName
;
195 m_fontEncoding
= attr
.m_fontEncoding
;
196 m_fontFamily
= attr
.m_fontFamily
;
197 m_textEffects
= attr
.m_textEffects
;
198 m_textEffectFlags
= attr
.m_textEffectFlags
;
200 m_paragraphSpacingAfter
= attr
.m_paragraphSpacingAfter
;
201 m_paragraphSpacingBefore
= attr
.m_paragraphSpacingBefore
;
202 m_lineSpacing
= attr
.m_lineSpacing
;
203 m_characterStyleName
= attr
.m_characterStyleName
;
204 m_paragraphStyleName
= attr
.m_paragraphStyleName
;
205 m_listStyleName
= attr
.m_listStyleName
;
206 m_bulletStyle
= attr
.m_bulletStyle
;
207 m_bulletNumber
= attr
.m_bulletNumber
;
208 m_bulletText
= attr
.m_bulletText
;
209 m_bulletFont
= attr
.m_bulletFont
;
210 m_bulletName
= attr
.m_bulletName
;
211 m_outlineLevel
= attr
.m_outlineLevel
;
213 m_urlTarget
= attr
.m_urlTarget
;
217 void wxTextAttr::operator= (const wxTextAttr
& attr
)
223 bool wxTextAttr::operator== (const wxTextAttr
& attr
) const
225 return GetFlags() == attr
.GetFlags() &&
227 GetTextColour() == attr
.GetTextColour() &&
228 GetBackgroundColour() == attr
.GetBackgroundColour() &&
230 GetAlignment() == attr
.GetAlignment() &&
231 GetLeftIndent() == attr
.GetLeftIndent() &&
232 GetLeftSubIndent() == attr
.GetLeftSubIndent() &&
233 GetRightIndent() == attr
.GetRightIndent() &&
234 TabsEq(GetTabs(), attr
.GetTabs()) &&
236 GetParagraphSpacingAfter() == attr
.GetParagraphSpacingAfter() &&
237 GetParagraphSpacingBefore() == attr
.GetParagraphSpacingBefore() &&
238 GetLineSpacing() == attr
.GetLineSpacing() &&
239 GetCharacterStyleName() == attr
.GetCharacterStyleName() &&
240 GetParagraphStyleName() == attr
.GetParagraphStyleName() &&
241 GetListStyleName() == attr
.GetListStyleName() &&
243 GetBulletStyle() == attr
.GetBulletStyle() &&
244 GetBulletText() == attr
.GetBulletText() &&
245 GetBulletNumber() == attr
.GetBulletNumber() &&
246 GetBulletFont() == attr
.GetBulletFont() &&
247 GetBulletName() == attr
.GetBulletName() &&
249 GetTextEffects() == attr
.GetTextEffects() &&
250 GetTextEffectFlags() == attr
.GetTextEffectFlags() &&
252 GetOutlineLevel() == attr
.GetOutlineLevel() &&
254 GetFontSize() == attr
.GetFontSize() &&
255 GetFontStyle() == attr
.GetFontStyle() &&
256 GetFontWeight() == attr
.GetFontWeight() &&
257 GetFontUnderlined() == attr
.GetFontUnderlined() &&
258 GetFontFaceName() == attr
.GetFontFaceName() &&
259 GetFontEncoding() == attr
.GetFontEncoding() &&
260 GetFontFamily() == attr
.GetFontFamily() &&
262 GetURL() == attr
.GetURL();
265 // Partial equality test. Only returns false if an attribute doesn't match.
266 bool wxTextAttr::EqPartial(const wxTextAttr
& attr
) const
268 int flags
= attr
.GetFlags();
270 if ((flags
& wxTEXT_ATTR_TEXT_COLOUR
) && GetTextColour() != attr
.GetTextColour())
273 if ((flags
& wxTEXT_ATTR_BACKGROUND_COLOUR
) && GetBackgroundColour() != attr
.GetBackgroundColour())
276 if ((flags
& wxTEXT_ATTR_FONT_FACE
) &&
277 GetFontFaceName() != attr
.GetFontFaceName())
280 if ((flags
& wxTEXT_ATTR_FONT_SIZE
) &&
281 GetFontSize() != attr
.GetFontSize())
284 if ((flags
& wxTEXT_ATTR_FONT_WEIGHT
) &&
285 GetFontWeight() != attr
.GetFontWeight())
288 if ((flags
& wxTEXT_ATTR_FONT_ITALIC
) &&
289 GetFontStyle() != attr
.GetFontStyle())
292 if ((flags
& wxTEXT_ATTR_FONT_UNDERLINE
) &&
293 GetFontUnderlined() != attr
.GetFontUnderlined())
296 if ((flags
& wxTEXT_ATTR_FONT_ENCODING
) &&
297 GetFontEncoding() != attr
.GetFontEncoding())
300 if ((flags
& wxTEXT_ATTR_FONT_FAMILY
) &&
301 GetFontFamily() != attr
.GetFontFamily())
304 if ((flags
& wxTEXT_ATTR_URL
) && GetURL() != attr
.GetURL())
307 if ((flags
& wxTEXT_ATTR_ALIGNMENT
) && GetAlignment() != attr
.GetAlignment())
310 if ((flags
& wxTEXT_ATTR_LEFT_INDENT
) &&
311 ((GetLeftIndent() != attr
.GetLeftIndent()) || (GetLeftSubIndent() != attr
.GetLeftSubIndent())))
314 if ((flags
& wxTEXT_ATTR_RIGHT_INDENT
) &&
315 (GetRightIndent() != attr
.GetRightIndent()))
318 if ((flags
& wxTEXT_ATTR_PARA_SPACING_AFTER
) &&
319 (GetParagraphSpacingAfter() != attr
.GetParagraphSpacingAfter()))
322 if ((flags
& wxTEXT_ATTR_PARA_SPACING_BEFORE
) &&
323 (GetParagraphSpacingBefore() != attr
.GetParagraphSpacingBefore()))
326 if ((flags
& wxTEXT_ATTR_LINE_SPACING
) &&
327 (GetLineSpacing() != attr
.GetLineSpacing()))
330 if ((flags
& wxTEXT_ATTR_CHARACTER_STYLE_NAME
) &&
331 (GetCharacterStyleName() != attr
.GetCharacterStyleName()))
334 if ((flags
& wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
) &&
335 (GetParagraphStyleName() != attr
.GetParagraphStyleName()))
338 if ((flags
& wxTEXT_ATTR_LIST_STYLE_NAME
) &&
339 (GetListStyleName() != attr
.GetListStyleName()))
342 if ((flags
& wxTEXT_ATTR_BULLET_STYLE
) &&
343 (GetBulletStyle() != attr
.GetBulletStyle()))
346 if ((flags
& wxTEXT_ATTR_BULLET_NUMBER
) &&
347 (GetBulletNumber() != attr
.GetBulletNumber()))
350 if ((flags
& wxTEXT_ATTR_BULLET_TEXT
) &&
351 (GetBulletText() != attr
.GetBulletText()) &&
352 (GetBulletFont() != attr
.GetBulletFont()))
355 if ((flags
& wxTEXT_ATTR_BULLET_NAME
) &&
356 (GetBulletName() != attr
.GetBulletName()))
359 if ((flags
& wxTEXT_ATTR_TABS
) &&
360 !TabsEq(GetTabs(), attr
.GetTabs()))
363 if ((flags
& wxTEXT_ATTR_PAGE_BREAK
) &&
364 (HasPageBreak() != attr
.HasPageBreak()))
367 if (flags
& wxTEXT_ATTR_EFFECTS
)
369 if (HasTextEffects() != attr
.HasTextEffects())
371 if (!BitlistsEqPartial(GetTextEffects(), attr
.GetTextEffects(), attr
.GetTextEffectFlags()))
375 if ((flags
& wxTEXT_ATTR_OUTLINE_LEVEL
) &&
376 (GetOutlineLevel() != attr
.GetOutlineLevel()))
382 // Create font from font attributes.
383 wxFont
wxTextAttr::GetFont() const
390 fontSize
= GetFontSize();
392 int fontStyle
= wxNORMAL
;
394 fontStyle
= GetFontStyle();
396 int fontWeight
= wxNORMAL
;
398 fontWeight
= GetFontWeight();
400 bool underlined
= false;
401 if (HasFontUnderlined())
402 underlined
= GetFontUnderlined();
404 wxString fontFaceName
;
405 if (HasFontFaceName())
406 fontFaceName
= GetFontFaceName();
408 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
;
409 if (HasFontEncoding())
410 encoding
= GetFontEncoding();
412 wxFontFamily fontFamily
= wxFONTFAMILY_DEFAULT
;
414 fontFamily
= GetFontFamily();
416 wxFont
font(fontSize
, fontFamily
, fontStyle
, fontWeight
, underlined
, fontFaceName
, encoding
);
420 // Get attributes from font.
421 bool wxTextAttr::GetFontAttributes(const wxFont
& font
, int flags
)
426 if (flags
& wxTEXT_ATTR_FONT_SIZE
)
427 m_fontSize
= font
.GetPointSize();
429 if (flags
& wxTEXT_ATTR_FONT_ITALIC
)
430 m_fontStyle
= font
.GetStyle();
432 if (flags
& wxTEXT_ATTR_FONT_WEIGHT
)
433 m_fontWeight
= font
.GetWeight();
435 if (flags
& wxTEXT_ATTR_FONT_UNDERLINE
)
436 m_fontUnderlined
= font
.GetUnderlined();
438 if (flags
& wxTEXT_ATTR_FONT_FACE
)
439 m_fontFaceName
= font
.GetFaceName();
441 if (flags
& wxTEXT_ATTR_FONT_ENCODING
)
442 m_fontEncoding
= font
.GetEncoding();
444 if (flags
& wxTEXT_ATTR_FONT_FAMILY
)
446 // wxFont might not know its family, avoid setting m_fontFamily to an
447 // invalid value and rather pretend that we don't have any font family
448 // information at all in this case
449 const wxFontFamily fontFamily
= font
.GetFamily();
450 if ( fontFamily
== wxFONTFAMILY_UNKNOWN
)
451 flags
&= ~wxTEXT_ATTR_FONT_FAMILY
;
453 m_fontFamily
= fontFamily
;
461 // Resets bits in destination so new attributes aren't merged with mutually exclusive ones
462 static bool wxResetIncompatibleBits(const int mask
, const int srcFlags
, int& destFlags
, int& destBits
)
464 if ((srcFlags
& mask
) && (destFlags
& mask
))
473 bool wxTextAttr::Apply(const wxTextAttr
& style
, const wxTextAttr
* compareWith
)
475 wxTextAttr
& destStyle
= (*this);
477 if (style
.HasFontWeight())
479 if (!(compareWith
&& compareWith
->HasFontWeight() && compareWith
->GetFontWeight() == style
.GetFontWeight()))
480 destStyle
.SetFontWeight(style
.GetFontWeight());
483 if (style
.HasFontSize())
485 if (!(compareWith
&& compareWith
->HasFontSize() && compareWith
->GetFontSize() == style
.GetFontSize()))
486 destStyle
.SetFontSize(style
.GetFontSize());
489 if (style
.HasFontItalic())
491 if (!(compareWith
&& compareWith
->HasFontItalic() && compareWith
->GetFontStyle() == style
.GetFontStyle()))
492 destStyle
.SetFontStyle(style
.GetFontStyle());
495 if (style
.HasFontUnderlined())
497 if (!(compareWith
&& compareWith
->HasFontUnderlined() && compareWith
->GetFontUnderlined() == style
.GetFontUnderlined()))
498 destStyle
.SetFontUnderlined(style
.GetFontUnderlined());
501 if (style
.HasFontFaceName())
503 if (!(compareWith
&& compareWith
->HasFontFaceName() && compareWith
->GetFontFaceName() == style
.GetFontFaceName()))
504 destStyle
.SetFontFaceName(style
.GetFontFaceName());
507 if (style
.HasFontEncoding())
509 if (!(compareWith
&& compareWith
->HasFontEncoding() && compareWith
->GetFontEncoding() == style
.GetFontEncoding()))
510 destStyle
.SetFontEncoding(style
.GetFontEncoding());
513 if (style
.HasFontFamily())
515 if (!(compareWith
&& compareWith
->HasFontFamily() && compareWith
->GetFontFamily() == style
.GetFontFamily()))
516 destStyle
.SetFontFamily(style
.GetFontFamily());
519 if (style
.GetTextColour().Ok() && style
.HasTextColour())
521 if (!(compareWith
&& compareWith
->HasTextColour() && compareWith
->GetTextColour() == style
.GetTextColour()))
522 destStyle
.SetTextColour(style
.GetTextColour());
525 if (style
.GetBackgroundColour().Ok() && style
.HasBackgroundColour())
527 if (!(compareWith
&& compareWith
->HasBackgroundColour() && compareWith
->GetBackgroundColour() == style
.GetBackgroundColour()))
528 destStyle
.SetBackgroundColour(style
.GetBackgroundColour());
531 if (style
.HasAlignment())
533 if (!(compareWith
&& compareWith
->HasAlignment() && compareWith
->GetAlignment() == style
.GetAlignment()))
534 destStyle
.SetAlignment(style
.GetAlignment());
539 if (!(compareWith
&& compareWith
->HasTabs() && TabsEq(compareWith
->GetTabs(), style
.GetTabs())))
540 destStyle
.SetTabs(style
.GetTabs());
543 if (style
.HasLeftIndent())
545 if (!(compareWith
&& compareWith
->HasLeftIndent() && compareWith
->GetLeftIndent() == style
.GetLeftIndent()
546 && compareWith
->GetLeftSubIndent() == style
.GetLeftSubIndent()))
547 destStyle
.SetLeftIndent(style
.GetLeftIndent(), style
.GetLeftSubIndent());
550 if (style
.HasRightIndent())
552 if (!(compareWith
&& compareWith
->HasRightIndent() && compareWith
->GetRightIndent() == style
.GetRightIndent()))
553 destStyle
.SetRightIndent(style
.GetRightIndent());
556 if (style
.HasParagraphSpacingAfter())
558 if (!(compareWith
&& compareWith
->HasParagraphSpacingAfter() && compareWith
->GetParagraphSpacingAfter() == style
.GetParagraphSpacingAfter()))
559 destStyle
.SetParagraphSpacingAfter(style
.GetParagraphSpacingAfter());
562 if (style
.HasParagraphSpacingBefore())
564 if (!(compareWith
&& compareWith
->HasParagraphSpacingBefore() && compareWith
->GetParagraphSpacingBefore() == style
.GetParagraphSpacingBefore()))
565 destStyle
.SetParagraphSpacingBefore(style
.GetParagraphSpacingBefore());
568 if (style
.HasLineSpacing())
570 if (!(compareWith
&& compareWith
->HasLineSpacing() && compareWith
->GetLineSpacing() == style
.GetLineSpacing()))
571 destStyle
.SetLineSpacing(style
.GetLineSpacing());
574 if (style
.HasCharacterStyleName())
576 if (!(compareWith
&& compareWith
->HasCharacterStyleName() && compareWith
->GetCharacterStyleName() == style
.GetCharacterStyleName()))
577 destStyle
.SetCharacterStyleName(style
.GetCharacterStyleName());
580 if (style
.HasParagraphStyleName())
582 if (!(compareWith
&& compareWith
->HasParagraphStyleName() && compareWith
->GetParagraphStyleName() == style
.GetParagraphStyleName()))
583 destStyle
.SetParagraphStyleName(style
.GetParagraphStyleName());
586 if (style
.HasListStyleName())
588 if (!(compareWith
&& compareWith
->HasListStyleName() && compareWith
->GetListStyleName() == style
.GetListStyleName()))
589 destStyle
.SetListStyleName(style
.GetListStyleName());
592 if (style
.HasBulletStyle())
594 if (!(compareWith
&& compareWith
->HasBulletStyle() && compareWith
->GetBulletStyle() == style
.GetBulletStyle()))
595 destStyle
.SetBulletStyle(style
.GetBulletStyle());
598 if (style
.HasBulletText())
600 if (!(compareWith
&& compareWith
->HasBulletText() && compareWith
->GetBulletText() == style
.GetBulletText()))
602 destStyle
.SetBulletText(style
.GetBulletText());
603 destStyle
.SetBulletFont(style
.GetBulletFont());
607 if (style
.HasBulletNumber())
609 if (!(compareWith
&& compareWith
->HasBulletNumber() && compareWith
->GetBulletNumber() == style
.GetBulletNumber()))
610 destStyle
.SetBulletNumber(style
.GetBulletNumber());
613 if (style
.HasBulletName())
615 if (!(compareWith
&& compareWith
->HasBulletName() && compareWith
->GetBulletName() == style
.GetBulletName()))
616 destStyle
.SetBulletName(style
.GetBulletName());
621 if (!(compareWith
&& compareWith
->HasURL() && compareWith
->GetURL() == style
.GetURL()))
622 destStyle
.SetURL(style
.GetURL());
625 if (style
.HasPageBreak())
627 if (!(compareWith
&& compareWith
->HasPageBreak()))
628 destStyle
.SetPageBreak();
631 if (style
.HasTextEffects())
633 if (!(compareWith
&& compareWith
->HasTextEffects() && compareWith
->GetTextEffects() == style
.GetTextEffects()))
635 int destBits
= destStyle
.GetTextEffects();
636 int destFlags
= destStyle
.GetTextEffectFlags();
638 int srcBits
= style
.GetTextEffects();
639 int srcFlags
= style
.GetTextEffectFlags();
641 // Reset incompatible bits in the destination
642 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_SUPERSCRIPT
|wxTEXT_ATTR_EFFECT_SUBSCRIPT
), srcFlags
, destFlags
, destBits
);
643 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_CAPITALS
|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS
), srcFlags
, destFlags
, destBits
);
644 wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_STRIKETHROUGH
|wxTEXT_ATTR_EFFECT_DOUBLE_STRIKETHROUGH
), srcFlags
, destFlags
, destBits
);
646 CombineBitlists(destBits
, srcBits
, destFlags
, srcFlags
);
648 destStyle
.SetTextEffects(destBits
);
649 destStyle
.SetTextEffectFlags(destFlags
);
653 if (style
.HasOutlineLevel())
655 if (!(compareWith
&& compareWith
->HasOutlineLevel() && compareWith
->GetOutlineLevel() == style
.GetOutlineLevel()))
656 destStyle
.SetOutlineLevel(style
.GetOutlineLevel());
663 wxTextAttr
wxTextAttr::Combine(const wxTextAttr
& attr
,
664 const wxTextAttr
& attrDef
,
665 const wxTextCtrlBase
*text
)
669 font
= attr
.GetFont();
673 if (attrDef
.HasFont())
674 font
= attrDef
.GetFont();
676 if ( text
&& !font
.Ok() )
677 font
= text
->GetFont();
680 wxColour colFg
= attr
.GetTextColour();
683 colFg
= attrDef
.GetTextColour();
685 if ( text
&& !colFg
.Ok() )
686 colFg
= text
->GetForegroundColour();
689 wxColour colBg
= attr
.GetBackgroundColour();
692 colBg
= attrDef
.GetBackgroundColour();
694 if ( text
&& !colBg
.Ok() )
695 colBg
= text
->GetBackgroundColour();
698 wxTextAttr
newAttr(colFg
, colBg
, font
);
700 if (attr
.HasAlignment())
701 newAttr
.SetAlignment(attr
.GetAlignment());
702 else if (attrDef
.HasAlignment())
703 newAttr
.SetAlignment(attrDef
.GetAlignment());
706 newAttr
.SetTabs(attr
.GetTabs());
707 else if (attrDef
.HasTabs())
708 newAttr
.SetTabs(attrDef
.GetTabs());
710 if (attr
.HasLeftIndent())
711 newAttr
.SetLeftIndent(attr
.GetLeftIndent(), attr
.GetLeftSubIndent());
712 else if (attrDef
.HasLeftIndent())
713 newAttr
.SetLeftIndent(attrDef
.GetLeftIndent(), attr
.GetLeftSubIndent());
715 if (attr
.HasRightIndent())
716 newAttr
.SetRightIndent(attr
.GetRightIndent());
717 else if (attrDef
.HasRightIndent())
718 newAttr
.SetRightIndent(attrDef
.GetRightIndent());
724 bool wxTextAttr::TabsEq(const wxArrayInt
& tabs1
, const wxArrayInt
& tabs2
)
726 if (tabs1
.GetCount() != tabs2
.GetCount())
730 for (i
= 0; i
< tabs1
.GetCount(); i
++)
732 if (tabs1
[i
] != tabs2
[i
])
739 bool wxTextAttr::RemoveStyle(wxTextAttr
& destStyle
, const wxTextAttr
& style
)
741 int flags
= style
.GetFlags();
742 int destFlags
= destStyle
.GetFlags();
744 destStyle
.SetFlags(destFlags
& ~flags
);
749 /// Combine two bitlists, specifying the bits of interest with separate flags.
750 bool wxTextAttr::CombineBitlists(int& valueA
, int valueB
, int& flagsA
, int flagsB
)
752 // We want to apply B's bits to A, taking into account each's flags which indicate which bits
753 // are to be taken into account. A zero in B's bits should reset that bit in A but only if B's flags
756 // First, reset the 0 bits from B. We make a mask so we're only dealing with B's zero
757 // bits at this point, ignoring any 1 bits in B or 0 bits in B that are not relevant.
758 int valueA2
= ~(~valueB
& flagsB
) & valueA
;
760 // Now combine the 1 bits.
761 int valueA3
= (valueB
& flagsB
) | valueA2
;
764 flagsA
= (flagsA
| flagsB
);
769 /// Compare two bitlists
770 bool wxTextAttr::BitlistsEqPartial(int valueA
, int valueB
, int flags
)
772 int relevantBitsA
= valueA
& flags
;
773 int relevantBitsB
= valueB
& flags
;
774 return (relevantBitsA
!= relevantBitsB
);
777 /// Split into paragraph and character styles
778 bool wxTextAttr::SplitParaCharStyles(const wxTextAttr
& style
, wxTextAttr
& parStyle
, wxTextAttr
& charStyle
)
780 wxTextAttr
defaultCharStyle1(style
);
781 wxTextAttr
defaultParaStyle1(style
);
782 defaultCharStyle1
.SetFlags(defaultCharStyle1
.GetFlags()&wxTEXT_ATTR_CHARACTER
);
783 defaultParaStyle1
.SetFlags(defaultParaStyle1
.GetFlags()&wxTEXT_ATTR_PARAGRAPH
);
785 charStyle
.Apply(defaultCharStyle1
);
786 parStyle
.Apply(defaultParaStyle1
);
791 // apply styling to text range
792 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start
), long WXUNUSED(end
),
793 const wxTextAttr
& WXUNUSED(style
))
795 // to be implemented in derived classes
799 // get the styling at the given position
800 bool wxTextCtrlBase::GetStyle(long WXUNUSED(position
), wxTextAttr
& WXUNUSED(style
))
802 // to be implemented in derived classes
806 // change default text attributes
807 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr
& style
)
809 // keep the old attributes if the new style doesn't specify them unless the
810 // new style is empty - then reset m_defaultStyle (as there is no other way
812 if ( style
.IsDefault() )
813 m_defaultStyle
= style
;
815 m_defaultStyle
= wxTextAttr::Combine(style
, m_defaultStyle
, this);
820 // ----------------------------------------------------------------------------
822 // ----------------------------------------------------------------------------
824 bool wxTextAreaBase::DoLoadFile(const wxString
& filename
, int WXUNUSED(fileType
))
827 wxFFile
file(filename
);
828 if ( file
.IsOpened() )
831 if ( file
.ReadAll(&text
) )
838 #endif // wxUSE_FFILE
843 bool wxTextCtrlBase::DoLoadFile(const wxString
& filename
, int fileType
)
845 if ( wxTextAreaBase::DoLoadFile(filename
, fileType
) )
848 m_filename
= filename
;
851 wxLogError(_("File couldn't be loaded."));
855 bool wxTextAreaBase::DoSaveFile(const wxString
& filename
, int WXUNUSED(fileType
))
858 wxFFile
file(filename
, wxT("w"));
859 return file
.IsOpened() && file
.Write(GetValue(), *wxConvCurrent
);
862 #endif // wxUSE_FFILE
865 bool wxTextAreaBase::SaveFile(const wxString
& filename
, int fileType
)
867 wxString filenameToUse
= filename
.empty() ? m_filename
: filename
;
868 if ( filenameToUse
.empty() )
870 // what kind of message to give? is it an error or a program bug?
871 wxLogDebug(wxT("Can't save textctrl to file without filename."));
876 return DoSaveFile(filenameToUse
, fileType
);
879 bool wxTextCtrlBase::DoSaveFile(const wxString
& filename
, int fileType
)
881 if ( wxTextAreaBase::DoSaveFile(filename
, fileType
) )
883 // if it worked, save for future calls
884 m_filename
= filename
;
886 // it's not modified any longer
894 // ----------------------------------------------------------------------------
895 // stream-like insertion operator
896 // ----------------------------------------------------------------------------
898 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxString
& s
)
901 return *TEXTCTRL(this);
904 wxTextCtrl
& wxTextCtrlBase::operator<<(double d
)
906 return *this << wxString::Format("%.2f", d
);
909 wxTextCtrl
& wxTextCtrlBase::operator<<(int i
)
911 return *this << wxString::Format("%d", i
);
914 wxTextCtrl
& wxTextCtrlBase::operator<<(long l
)
916 return *this << wxString::Format("%ld", l
);
919 // ----------------------------------------------------------------------------
920 // streambuf methods implementation
921 // ----------------------------------------------------------------------------
923 #if wxHAS_TEXT_WINDOW_STREAM
925 int wxTextCtrlBase::overflow(int c
)
927 AppendText((wxChar
)c
);
929 // return something different from EOF
933 #endif // wxHAS_TEXT_WINDOW_STREAM
935 // ----------------------------------------------------------------------------
936 // emulating key presses
937 // ----------------------------------------------------------------------------
939 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& event
)
941 // we have a native implementation for Win32 and so don't need this one
944 int keycode
= event
.GetKeyCode();
957 ch
= (wxChar
)(wxT('0') + keycode
- WXK_NUMPAD0
);
961 case WXK_NUMPAD_MULTIPLY
:
971 case WXK_NUMPAD_SUBTRACT
:
976 case WXK_NUMPAD_DECIMAL
:
981 case WXK_NUMPAD_DIVIDE
:
986 case WXK_NUMPAD_DELETE
:
987 // delete the character at cursor
989 const long pos
= GetInsertionPoint();
990 if ( pos
< GetLastPosition() )
991 Remove(pos
, pos
+ 1);
996 // delete the character before the cursor
998 const long pos
= GetInsertionPoint();
1000 Remove(pos
- 1, pos
);
1006 if ( event
.GetUnicodeKey() )
1008 ch
= event
.GetUnicodeKey();
1012 if ( keycode
< 256 && keycode
>= 0 && wxIsprint(keycode
) )
1014 // FIXME this is not going to work for non letters...
1015 if ( !event
.ShiftDown() )
1017 keycode
= wxTolower(keycode
);
1020 ch
= (wxChar
)keycode
;
1036 #endif // !__WIN32__/__WIN32__
1041 // do the window-specific processing after processing the update event
1042 void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent
& event
)
1044 // call inherited, but skip the wxControl's version, and call directly the
1045 // wxWindow's one instead, because the only reason why we are overriding this
1046 // function is that we want to use SetValue() instead of wxControl::SetLabel()
1047 wxWindowBase::DoUpdateWindowUI(event
);
1050 if ( event
.GetSetText() )
1052 if ( event
.GetText() != GetValue() )
1053 SetValue(event
.GetText());
1057 // ----------------------------------------------------------------------------
1059 // ----------------------------------------------------------------------------
1061 wxTextCtrlHitTestResult
1062 wxTextAreaBase::HitTest(const wxPoint
& pt
, wxTextCoord
*x
, wxTextCoord
*y
) const
1064 // implement in terms of the other overload as the native ports typically
1065 // can get the position and not (x, y) pair directly (although wxUniv
1066 // directly gets x and y -- and so overrides this method as well)
1068 wxTextCtrlHitTestResult rc
= HitTest(pt
, &pos
);
1070 if ( rc
!= wxTE_HT_UNKNOWN
)
1072 PositionToXY(pos
, x
, y
);
1078 wxTextCtrlHitTestResult
1079 wxTextAreaBase::HitTest(const wxPoint
& WXUNUSED(pt
), long * WXUNUSED(pos
)) const
1082 return wxTE_HT_UNKNOWN
;
1085 #else // !wxUSE_TEXTCTRL
1087 // define this one even if !wxUSE_TEXTCTRL because it is also used by other
1088 // controls (wxComboBox and wxSpinCtrl)
1090 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
);
1092 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL