]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stattextcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/stattextcmn.cpp
3 // Purpose: common (to all ports) wxStaticText functions
4 // Author: Vadim Zeitlin, Francesco Montorsi
5 // Created: 2007-01-07 (extracted from dlgcmn.cpp)
7 // Copyright: (c) 1999-2006 Vadim Zeitlin
8 // (c) 2007 Francesco Montorsi
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/private/stattext.h"
29 const wxChar
*const wxMarkupEntities
[][wxMARKUP_ENTITY_MAX
] =
31 // the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string
33 { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT(""") },
34 { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") }
40 #include "wx/stattext.h"
41 #include "wx/button.h"
42 #include "wx/dcclient.h"
45 #include "wx/settings.h"
47 #include "wx/containr.h"
50 #include "wx/textwrapper.h"
52 extern WXDLLEXPORT_DATA(const char) wxStaticTextNameStr
[] = "staticText";
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 wxDEFINE_FLAGS( wxStaticTextStyle
)
59 wxBEGIN_FLAGS( wxStaticTextStyle
)
60 // new style border flags, we put them first to
61 // use them for streaming out
62 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
63 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
64 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
65 wxFLAGS_MEMBER(wxBORDER_RAISED
)
66 wxFLAGS_MEMBER(wxBORDER_STATIC
)
67 wxFLAGS_MEMBER(wxBORDER_NONE
)
69 // old style border flags
70 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
71 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
72 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
73 wxFLAGS_MEMBER(wxRAISED_BORDER
)
74 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
75 wxFLAGS_MEMBER(wxBORDER
)
77 // standard window styles
78 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
79 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
80 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
81 wxFLAGS_MEMBER(wxWANTS_CHARS
)
82 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
83 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
84 wxFLAGS_MEMBER(wxVSCROLL
)
85 wxFLAGS_MEMBER(wxHSCROLL
)
87 wxFLAGS_MEMBER(wxST_NO_AUTORESIZE
)
88 wxFLAGS_MEMBER(wxALIGN_LEFT
)
89 wxFLAGS_MEMBER(wxALIGN_RIGHT
)
90 wxFLAGS_MEMBER(wxALIGN_CENTRE
)
91 wxEND_FLAGS( wxStaticTextStyle
)
93 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxStaticText
, wxControl
, "wx/stattext.h")
95 wxBEGIN_PROPERTIES_TABLE(wxStaticText
)
96 wxPROPERTY( Label
,wxString
, SetLabel
, GetLabel
, wxString(), 0 /*flags*/, \
97 wxT("Helpstring"), wxT("group"))
98 wxPROPERTY_FLAGS( WindowStyle
, wxStaticTextStyle
, long, SetWindowStyleFlag
, \
99 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
100 wxT("Helpstring"), wxT("group")) // style
101 wxEND_PROPERTIES_TABLE()
103 wxEMPTY_HANDLERS_TABLE(wxStaticText
)
105 wxCONSTRUCTOR_6( wxStaticText
, wxWindow
*, Parent
, wxWindowID
, Id
, \
106 wxString
, Label
, wxPoint
, Position
, wxSize
, Size
, long, WindowStyle
)
109 // ----------------------------------------------------------------------------
111 // ----------------------------------------------------------------------------
113 void wxTextWrapper::Wrap(wxWindow
*win
, const wxString
& text
, int widthMax
)
117 wxString::const_iterator lastSpace
= text
.end();
118 wxString::const_iterator lineStart
= text
.begin();
119 for ( wxString::const_iterator p
= lineStart
; ; ++p
)
121 if ( IsStartOfNewLine() )
125 lastSpace
= text
.end();
130 if ( p
== text
.end() || *p
== wxT('\n') )
134 if ( p
== text
.end() )
139 if ( *p
== wxT(' ') )
144 if ( widthMax
>= 0 && lastSpace
!= text
.end() )
147 win
->GetTextExtent(line
, &width
, NULL
);
149 if ( width
> widthMax
)
151 // remove the last word from this line
152 line
.erase(lastSpace
- lineStart
, p
+ 1 - lineStart
);
155 // go back to the last word of this line which we didn't
160 //else: no wrapping at all or impossible to wrap
166 // ----------------------------------------------------------------------------
167 // wxLabelWrapper: helper class for wxStaticTextBase::Wrap()
168 // ----------------------------------------------------------------------------
170 class wxLabelWrapper
: public wxTextWrapper
173 void WrapLabel(wxWindow
*text
, int widthMax
)
176 Wrap(text
, text
->GetLabel(), widthMax
);
177 text
->SetLabel(m_text
);
181 virtual void OnOutputLine(const wxString
& line
)
186 virtual void OnNewLine()
196 // ----------------------------------------------------------------------------
198 // ----------------------------------------------------------------------------
200 void wxStaticTextBase::Wrap(int width
)
202 wxLabelWrapper wrapper
;
203 wrapper
.WrapLabel(this, width
);
206 wxString
wxStaticTextBase::GetLabelText() const
208 wxString
ret(GetLabel());
210 if (HasFlag(wxST_MARKUP
))
211 ret
= RemoveMarkup(ret
);
212 return RemoveMnemonics(ret
);
215 void wxStaticTextBase::SetLabelText(const wxString
& text
)
219 if (HasFlag(wxST_MARKUP
))
220 str
= EscapeMarkup(str
); // escapes markup and the & characters (which are also mnemonics)
222 str
= EscapeMnemonics(text
); // escape only the mnemonics
227 wxString
wxStaticTextBase::GetLabelText(const wxString
& label
)
229 wxString ret
= RemoveMarkup(label
);
230 // always remove the markup (this function is static
231 // and cannot check for wxST_MARKUP presence/absence)
233 return RemoveMnemonics(ret
);
237 wxString
wxStaticTextBase::RemoveMarkup(const wxString
& text
)
239 // strip out of "text" the markup for platforms which don't support it natively
240 bool inside_tag
= false;
243 for ( wxString::const_iterator source
= text
.begin();
244 source
!= text
.end(); ++source
)
246 switch ( (*source
).GetValue() )
251 wxLogDebug(wxT("Invalid markup !"));
252 return wxEmptyString
;
260 wxLogDebug(wxT("Invalid markup !"));
261 return wxEmptyString
;
268 if ( source
+1 == text
.end() )
270 wxLogDebug(wxT("Cannot use & as last character of the string '%s'"),
272 return wxEmptyString
;
275 // is this ampersand introducing a mnemonic or rather an entity?
276 bool isMnemonic
= true;
277 size_t distanceFromEnd
= text
.end() - source
;
278 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
280 const wxChar
*entity
= wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
281 size_t entityLen
= wxStrlen(entity
);
283 if (distanceFromEnd
>= entityLen
&&
284 wxString(source
, source
+ entityLen
) == entity
)
286 // replace the &entity; string with the entity reference
287 label
<< wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
];
288 // little exception: when the entity reference is
289 // "&" (i.e. when entity is "&"), substitute it
290 // with && instead of a single ampersand:
291 if (*wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
] == wxT('&'))
293 // the -1 is because main for() loop already
295 source
+= entityLen
- 1;
317 wxString
wxStaticTextBase::EscapeMarkup(const wxString
& text
)
321 for (wxString::const_iterator source
= text
.begin();
322 source
!= text
.end(); ++source
)
324 bool isEntity
= false;
326 // search in the list of the entities and eventually escape this character
327 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
329 if (*source
== *wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
])
331 ret
<< wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
338 ret
<< *source
; // this character does not need to be escaped
345 // ----------------------------------------------------------------------------
346 // wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
347 // ----------------------------------------------------------------------------
349 void wxStaticTextBase::UpdateLabel()
354 wxString newlabel
= GetEllipsizedLabelWithoutMarkup();
356 // we need to touch the "real" label (i.e. the text set inside the control,
357 // using port-specific functions) instead of the string returned by GetLabel().
359 // In fact, we must be careful not to touch the original label passed to
360 // SetLabel() otherwise GetLabel() will behave in a strange way to the user
361 // (e.g. returning a "Ver...ing" instead of "Very long string") !
362 if (newlabel
== DoGetLabel())
364 DoSetLabel(newlabel
);
367 wxString
wxStaticTextBase::GetLabelWithoutMarkup() const
369 wxString
ret(m_labelOrig
);
371 if (HasFlag(wxST_MARKUP
))
372 ret
= RemoveMarkup(ret
);
374 // unlike GetLabelText() we don't remove the mnemonics here!
378 wxString
wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const
380 // this function should be used only by ports which do not support
381 // ellipsis in static texts: we first remove markup (which cannot
382 // be handled safely by Ellipsize()) and then ellipsize the result.
384 wxString
ret(m_labelOrig
);
386 // the order of the following two blocks is important!
388 if (HasFlag(wxST_MARKUP
))
389 ret
= RemoveMarkup(ret
);
392 ret
= Ellipsize(ret
);
397 wxString
wxStaticTextBase::Ellipsize(const wxString
& label
) const
399 wxSize
sz(GetSize());
400 if (sz
.GetWidth() < 2 || sz
.GetHeight() < 2)
402 // the size of this window is not valid (yet)
406 wxClientDC
dc(const_cast<wxStaticTextBase
*>(this));
407 dc
.SetFont(GetFont());
409 wxEllipsizeMode mode
;
410 if ( HasFlag(wxST_ELLIPSIZE_START
) )
411 mode
= wxELLIPSIZE_START
;
412 else if ( HasFlag(wxST_ELLIPSIZE_MIDDLE
) )
413 mode
= wxELLIPSIZE_MIDDLE
;
414 else if ( HasFlag(wxST_ELLIPSIZE_END
) )
415 mode
= wxELLIPSIZE_END
;
418 wxFAIL_MSG( "should only be called if have one of wxST_ELLIPSIZE_XXX" );
423 return wxControl::Ellipsize(label
, dc
, mode
, sz
.GetWidth());
426 #endif // wxUSE_STATTEXT