]>
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 wxDEFINE_FLAGS( wxStaticTextStyle
)
56 wxBEGIN_FLAGS( wxStaticTextStyle
)
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(wxST_NO_AUTORESIZE
)
85 wxFLAGS_MEMBER(wxALIGN_LEFT
)
86 wxFLAGS_MEMBER(wxALIGN_RIGHT
)
87 wxFLAGS_MEMBER(wxALIGN_CENTRE
)
88 wxEND_FLAGS( wxStaticTextStyle
)
90 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxStaticText
, wxControl
, "wx/stattext.h")
92 wxBEGIN_PROPERTIES_TABLE(wxStaticText
)
93 wxPROPERTY( Label
,wxString
, SetLabel
, GetLabel
, wxString(), 0 /*flags*/, \
94 wxT("Helpstring"), wxT("group"))
95 wxPROPERTY_FLAGS( WindowStyle
, wxStaticTextStyle
, long, SetWindowStyleFlag
, \
96 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
97 wxT("Helpstring"), wxT("group")) // style
98 wxEND_PROPERTIES_TABLE()
100 wxEMPTY_HANDLERS_TABLE(wxStaticText
)
102 wxCONSTRUCTOR_6( wxStaticText
, wxWindow
*, Parent
, wxWindowID
, Id
, \
103 wxString
, Label
, wxPoint
, Position
, wxSize
, Size
, long, WindowStyle
)
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 void wxTextWrapper::Wrap(wxWindow
*win
, const wxString
& text
, int widthMax
)
114 wxString::const_iterator lastSpace
= text
.end();
115 wxString::const_iterator lineStart
= text
.begin();
116 for ( wxString::const_iterator p
= lineStart
; ; ++p
)
118 if ( IsStartOfNewLine() )
122 lastSpace
= text
.end();
127 if ( p
== text
.end() || *p
== wxT('\n') )
131 if ( p
== text
.end() )
136 if ( *p
== wxT(' ') )
141 if ( widthMax
>= 0 && lastSpace
!= text
.end() )
144 win
->GetTextExtent(line
, &width
, NULL
);
146 if ( width
> widthMax
)
148 // remove the last word from this line
149 line
.erase(lastSpace
- lineStart
, p
+ 1 - lineStart
);
152 // go back to the last word of this line which we didn't
157 //else: no wrapping at all or impossible to wrap
163 // ----------------------------------------------------------------------------
164 // wxLabelWrapper: helper class for wxStaticTextBase::Wrap()
165 // ----------------------------------------------------------------------------
167 class wxLabelWrapper
: public wxTextWrapper
170 void WrapLabel(wxWindow
*text
, int widthMax
)
173 Wrap(text
, text
->GetLabel(), widthMax
);
174 text
->SetLabel(m_text
);
178 virtual void OnOutputLine(const wxString
& line
)
183 virtual void OnNewLine()
193 // ----------------------------------------------------------------------------
195 // ----------------------------------------------------------------------------
197 void wxStaticTextBase::Wrap(int width
)
199 wxLabelWrapper wrapper
;
200 wrapper
.WrapLabel(this, width
);
203 wxString
wxStaticTextBase::GetLabelText() const
205 wxString
ret(GetLabel());
207 if (HasFlag(wxST_MARKUP
))
208 ret
= RemoveMarkup(ret
);
209 return RemoveMnemonics(ret
);
212 void wxStaticTextBase::SetLabelText(const wxString
& text
)
216 if (HasFlag(wxST_MARKUP
))
217 str
= EscapeMarkup(str
); // escapes markup and the & characters (which are also mnemonics)
219 str
= EscapeMnemonics(text
); // escape only the mnemonics
224 wxString
wxStaticTextBase::GetLabelText(const wxString
& label
)
226 wxString ret
= RemoveMarkup(label
);
227 // always remove the markup (this function is static
228 // and cannot check for wxST_MARKUP presence/absence)
230 return RemoveMnemonics(ret
);
234 wxString
wxStaticTextBase::RemoveMarkup(const wxString
& text
)
236 // strip out of "text" the markup for platforms which don't support it natively
237 bool inside_tag
= false;
240 for ( wxString::const_iterator source
= text
.begin();
241 source
!= text
.end(); ++source
)
243 switch ( (*source
).GetValue() )
248 wxLogDebug(wxT("Invalid markup !"));
249 return wxEmptyString
;
257 wxLogDebug(wxT("Invalid markup !"));
258 return wxEmptyString
;
265 if ( source
+1 == text
.end() )
267 wxLogDebug(wxT("Cannot use & as last character of the string '%s'"),
269 return wxEmptyString
;
272 // is this ampersand introducing a mnemonic or rather an entity?
273 bool isMnemonic
= true;
274 size_t distanceFromEnd
= text
.end() - source
;
275 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
277 const wxChar
*entity
= wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
278 size_t entityLen
= wxStrlen(entity
);
280 if (distanceFromEnd
>= entityLen
&&
281 wxString(source
, source
+ entityLen
) == entity
)
283 // replace the &entity; string with the entity reference
284 label
<< wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
];
285 // little exception: when the entity reference is
286 // "&" (i.e. when entity is "&"), substitute it
287 // with && instead of a single ampersand:
288 if (*wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
] == wxT('&'))
290 // the -1 is because main for() loop already
292 source
+= entityLen
- 1;
314 wxString
wxStaticTextBase::EscapeMarkup(const wxString
& text
)
318 for (wxString::const_iterator source
= text
.begin();
319 source
!= text
.end(); ++source
)
321 bool isEntity
= false;
323 // search in the list of the entities and eventually escape this character
324 for (size_t j
=0; j
< wxMARKUP_ENTITY_MAX
; j
++)
326 if (*source
== *wxMarkupEntities
[wxMARKUP_ELEMENT_VALUE
][j
])
328 ret
<< wxMarkupEntities
[wxMARKUP_ELEMENT_NAME
][j
];
335 ret
<< *source
; // this character does not need to be escaped
342 // ----------------------------------------------------------------------------
343 // wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support
344 // ----------------------------------------------------------------------------
346 void wxStaticTextBase::UpdateLabel()
351 wxString newlabel
= GetEllipsizedLabelWithoutMarkup();
353 // we need to touch the "real" label (i.e. the text set inside the control,
354 // using port-specific functions) instead of the string returned by GetLabel().
356 // In fact, we must be careful not to touch the original label passed to
357 // SetLabel() otherwise GetLabel() will behave in a strange way to the user
358 // (e.g. returning a "Ver...ing" instead of "Very long string") !
359 if (newlabel
== DoGetLabel())
361 DoSetLabel(newlabel
);
364 wxString
wxStaticTextBase::GetLabelWithoutMarkup() const
366 wxString
ret(m_labelOrig
);
368 if (HasFlag(wxST_MARKUP
))
369 ret
= RemoveMarkup(ret
);
371 // unlike GetLabelText() we don't remove the mnemonics here!
375 wxString
wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const
377 // this function should be used only by ports which do not support
378 // ellipsis in static texts: we first remove markup (which cannot
379 // be handled safely by Ellipsize()) and then ellipsize the result.
381 wxString
ret(m_labelOrig
);
383 // the order of the following two blocks is important!
385 if (HasFlag(wxST_MARKUP
))
386 ret
= RemoveMarkup(ret
);
389 ret
= Ellipsize(ret
);
394 wxString
wxStaticTextBase::Ellipsize(const wxString
& label
) const
396 wxSize
sz(GetSize());
397 if (sz
.GetWidth() < 2 || sz
.GetHeight() < 2)
399 // the size of this window is not valid (yet)
403 wxClientDC
dc(const_cast<wxStaticTextBase
*>(this));
404 dc
.SetFont(GetFont());
406 wxEllipsizeMode mode
;
407 if ( HasFlag(wxST_ELLIPSIZE_START
) )
408 mode
= wxELLIPSIZE_START
;
409 else if ( HasFlag(wxST_ELLIPSIZE_MIDDLE
) )
410 mode
= wxELLIPSIZE_MIDDLE
;
411 else if ( HasFlag(wxST_ELLIPSIZE_END
) )
412 mode
= wxELLIPSIZE_END
;
415 wxFAIL_MSG( "should only be called if have one of wxST_ELLIPSIZE_XXX" );
420 return wxControl::Ellipsize(label
, dc
, mode
, sz
.GetWidth());
423 #endif // wxUSE_STATTEXT