]>
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/textwrapper.h"
28 #include "wx/private/stattext.h"
31 #include "wx/button.h"
32 #include "wx/dcclient.h"
35 #include "wx/settings.h"
36 #include "wx/stattext.h"
38 #include "wx/containr.h"
41 const wxChar
*wxMarkupEntities
[][wxMARKUP_ENTITY_MAX
] =
43 // the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string
45 { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT(""") },
46 { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") }
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 void wxTextWrapper::Wrap(wxWindow
*win
, const wxString
& text
, int widthMax
)
59 wxString::const_iterator lastSpace
= text
.end();
60 wxString::const_iterator lineStart
= text
.begin();
61 for ( wxString::const_iterator p
= lineStart
; ; ++p
)
63 if ( IsStartOfNewLine() )
67 lastSpace
= text
.end();
72 if ( p
== text
.end() || *p
== wxT('\n') )
76 if ( p
== text
.end() )
86 if ( widthMax
>= 0 && lastSpace
!= text
.end() )
89 win
->GetTextExtent(line
, &width
, NULL
);
91 if ( width
> widthMax
)
93 // remove the last word from this line
94 line
.erase(lastSpace
- lineStart
, p
+ 1 - lineStart
);
97 // go back to the last word of this line which we didn't
102 //else: no wrapping at all or impossible to wrap
108 // ----------------------------------------------------------------------------
109 // wxLabelWrapper: helper class for wxStaticTextBase::Wrap()
110 // ----------------------------------------------------------------------------
112 class wxLabelWrapper
: public wxTextWrapper
115 void WrapLabel(wxWindow
*text
, int widthMax
)
118 Wrap(text
, text
->GetLabel(), widthMax
);
119 text
->SetLabel(m_text
);
123 virtual void OnOutputLine(const wxString
& line
)
128 virtual void OnNewLine()
138 // ----------------------------------------------------------------------------
140 // ----------------------------------------------------------------------------
142 void wxStaticTextBase::Wrap(int width
)
144 wxLabelWrapper wrapper
;
145 wrapper
.WrapLabel(this, width
);
148 wxString
wxStaticTextBase::GetLabelText() const
150 wxString
ret(GetLabel());
152 if (HasFlag(wxST_MARKUP
))
153 ret
= RemoveMarkup(ret
);
154 return RemoveMnemonics(ret
);
157 void wxStaticTextBase::SetLabelText(const wxString
& text
)
161 if (HasFlag(wxST_MARKUP
))
162 str
= EscapeMarkup(str
); // escapes markup and the & characters (which are also mnemonics)
164 str
= EscapeMnemonics(text
); // escape only the mnemonics
169 wxString
wxStaticTextBase::GetLabelText(const wxString
& label
)
171 wxString ret
= RemoveMarkup(label
);
172 // always remove the markup (this function is static
173 // and cannot check for wxST_MARKUP presence/absence)
175 return RemoveMnemonics(ret
);
179 wxString
wxStaticTextBase::RemoveMarkup(const wxString
& text
)
181 // strip out of "text" the markup for platforms which don't support it natively
182 bool inside_tag
= false;
185 for ( wxString::const_iterator source
= text
.begin();
186 source
!= text
.end(); ++source
)
188 switch ( (*source
).GetValue() )
193 wxLogDebug(wxT("Invalid markup !"));
194 return wxEmptyString
;
202 wxLogDebug(wxT("Invalid markup !"));
203 return wxEmptyString
;
210 if ( source
+1 == text
.end() )
212 wxLogDebug(wxT("Cannot use & as last character of the string '%s'"),
214 return wxEmptyString
;
217 // is this ampersand introducing a mnemonic or rather an entity?
218 bool isMnemonic
= true;
219 size_t distanceFromEnd
= text
.end() - source
;
220 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
222 const wxChar
*entity
= wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
223 size_t entityLen
= wxStrlen(entity
);
225 if (distanceFromEnd
>= entityLen
&&
226 wxString(source
, source
+ entityLen
) == entity
)
228 // replace the &entity; string with the entity reference
229 label
<< wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
];
230 // little exception: when the entity reference is
231 // "&" (i.e. when entity is "&"), substitute it
232 // with && instead of a single ampersand:
233 if (*wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
] == wxT('&'))
235 // the -1 is because main for() loop already
237 source
+= entityLen
- 1;
259 wxString
wxStaticTextBase::EscapeMarkup(const wxString
& text
)
263 for (wxString::const_iterator source
= text
.begin();
264 source
!= text
.end(); ++source
)
266 bool isEntity
= false;
268 // search in the list of the entities and eventually escape this character
269 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
271 if (*source
== *wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
])
273 ret
<< wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
280 ret
<< *source
; // this character does not need to be escaped
287 // ----------------------------------------------------------------------------
288 // wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
289 // ----------------------------------------------------------------------------
291 void wxStaticTextBase::UpdateLabel()
296 wxString newlabel
= GetEllipsizedLabelWithoutMarkup();
298 // we need to touch the "real" label (i.e. the text set inside the control,
299 // using port-specific functions) instead of the string returned by GetLabel().
301 // In fact, we must be careful not to touch the original label passed to
302 // SetLabel() otherwise GetLabel() will behave in a strange way to the user
303 // (e.g. returning a "Ver...ing" instead of "Very long string") !
304 if (newlabel
== DoGetLabel())
306 DoSetLabel(newlabel
);
309 wxString
wxStaticTextBase::GetLabelWithoutMarkup() const
311 wxString
ret(m_labelOrig
);
313 if (HasFlag(wxST_MARKUP
))
314 ret
= RemoveMarkup(ret
);
316 // unlike GetLabelText() we don't remove the mnemonics here!
320 wxString
wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const
322 // this function should be used only by ports which do not support
323 // ellipsis in static texts: we first remove markup (which cannot
324 // be handled safely by Ellipsize()) and then ellipsize the result.
326 wxString
ret(m_labelOrig
);
328 // the order of the following two blocks is important!
330 if (HasFlag(wxST_MARKUP
))
331 ret
= RemoveMarkup(ret
);
334 ret
= Ellipsize(ret
);
339 wxString
wxStaticTextBase::Ellipsize(const wxString
& label
) const
341 wxSize
sz(GetSize());
342 if (sz
.GetWidth() < 2 || sz
.GetHeight() < 2)
344 // the size of this window is not valid (yet)
348 wxClientDC
dc(const_cast<wxStaticTextBase
*>(this));
349 dc
.SetFont(GetFont());
351 wxEllipsizeMode mode
;
352 if ( HasFlag(wxST_ELLIPSIZE_START
) )
353 mode
= wxELLIPSIZE_START
;
354 else if ( HasFlag(wxST_ELLIPSIZE_MIDDLE
) )
355 mode
= wxELLIPSIZE_MIDDLE
;
356 else if ( HasFlag(wxST_ELLIPSIZE_END
) )
357 mode
= wxELLIPSIZE_END
;
360 wxFAIL_MSG( "should only be called if have one of wxST_ELLIPSIZE_XXX" );
365 return wxControl::Ellipsize(label
, dc
, mode
, sz
.GetWidth());
368 #endif // wxUSE_STATTEXT