-wxString wxStaticTextBase::GetLabelText() const
-{
- wxString ret(GetLabel());
-
- if (HasFlag(wxST_MARKUP))
- ret = RemoveMarkup(ret);
- return RemoveMnemonics(ret);
-}
-
-/*static*/
-wxString wxStaticTextBase::GetLabelText(const wxString& label)
-{
- // remove markup
- wxString ret = RemoveMarkup(label);
- return RemoveMnemonics(ret);
-}
-
-/*static*/
-wxString wxStaticTextBase::RemoveMarkup(const wxString& text)
-{
- // strip out of "text" the markup for platforms which don't support it natively
- bool inside_tag = false;
-
- wxString label;
- for ( wxString::const_iterator source = text.begin();
- source != text.end(); ++source )
- {
- switch ( (*source).GetValue() )
- {
- case wxT('<'):
- if (inside_tag)
- {
- wxLogDebug(wxT("Invalid markup !"));
- return wxEmptyString;
- }
- inside_tag = true;
- break;
-
- case wxT('>'):
- if (!inside_tag)
- {
- wxLogDebug(wxT("Invalid markup !"));
- return wxEmptyString;
- }
- inside_tag = false;
- break;
-
- case wxT('&'):
- {
- if ( source+1 == text.end() )
- {
- wxLogDebug(wxT("Cannot use & as last character of the string '%s'"),
- text.c_str());
- return wxEmptyString;
- }
-
- // is this ampersand introducing a mnemonic or rather an entity?
- bool isMnemonic = true;
- size_t distanceFromEnd = text.end() - source;
- for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++)
- {
- const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j];
- size_t entityLen = wxStrlen(entity);
-
- if (distanceFromEnd >= entityLen &&
- wxString(source, source + entityLen) == entity)
- {
- // replace the &entity; string with the entity reference
- label << wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j];
- // little exception: when the entity reference is
- // "&" (i.e. when entity is "&"), substitute it
- // with && instead of a single ampersand:
- if (*wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j] == wxT('&'))
- label << wxT('&');
- // the -1 is because main for() loop already
- // increments i:
- source += entityLen - 1;
- isMnemonic = false;
- break;
- }
- }
-
- if (isMnemonic)
- label << *source;
- }
- break;
-
-
- default:
- if (!inside_tag)
- label << *source;
- }
- }
-
- return label;
-}
-
-/* static */
-wxString wxStaticTextBase::EscapeMarkup(const wxString& text)
-{
- wxString ret;
-
- for (wxString::const_iterator source = text.begin();
- source != text.end(); ++source)
- {
- bool isEntity = false;
-
- // search in the list of the entities and eventually escape this character
- for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++)
- {
- if (*source == *wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j])
- {
- ret << wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j];
- isEntity = true;
- break;
- }
- }
-
- if (!isEntity)
- ret << *source; // this character does not need to be escaped
- }
-
- return ret;
-}
-
-#define wxELLIPSE_REPLACEMENT wxT("...")
-
-/* static */
-wxString wxStaticTextBase::Ellipsize(const wxString& label, const wxDC& dc,
- wxEllipsizeMode mode, int maxFinalWidth)
-{
- wxArrayInt charOffsets;
- wxString ret;
-
- // these cannot be cached as they can change because of e.g. a font change
- int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth();
- int marginWidth = dc.GetCharWidth()*2;
-
- // NB: we must handle correctly labels with newlines:
- wxString curLine;
- wxSize reqsize;
- size_t len;
- for ( wxString::const_iterator pc = label.begin(); ; ++pc )
- {
- if ( pc == label.end() || *pc == _T('\n') )
- {
- len = curLine.length();
- if (len > 0 &&
- dc.GetPartialTextExtents(curLine, charOffsets))
- {
- wxASSERT(charOffsets.GetCount() == len);
-
- size_t totalWidth = charOffsets.Last();
- if ( totalWidth > (size_t)maxFinalWidth )
- {
- // we need to ellipsize this row
- int excessPixels = totalWidth - maxFinalWidth +
- replacementWidth +
- marginWidth; // security margin (NEEDED!)
-
- // remove characters in excess
- size_t initialChar, // index of first char to erase
- nChars; // how many chars do we need to erase?
- if (mode == wxST_ELLIPSIZE_START)
- {
- initialChar = 0;
- for (nChars=0;
- nChars < len && charOffsets[nChars] < excessPixels;
- nChars++)
- ;
- }
- else if (mode == wxST_ELLIPSIZE_MIDDLE)
- {
- // the start & end of the removed span of chars
- initialChar = len/2;
- size_t endChar = len/2;
-
- int removed = 0;
- for ( ; removed < excessPixels; )
- {
- if (initialChar > 0)
- {
- // width of the initialChar-th character
- int width = charOffsets[initialChar] -
- charOffsets[initialChar-1];
-
- // remove the initialChar-th character
- removed += width;
- initialChar--;
- }
-
- if (endChar < len - 1 &&
- removed < excessPixels)
- {
- // width of the (endChar+1)-th character
- int width = charOffsets[endChar+1] -
- charOffsets[endChar];
-
- // remove the endChar-th character
- removed += width;
- endChar++;
- }
-
- if (initialChar == 0 && endChar == len-1)
- {
- nChars = len+1;
- break;
- }
- }
-
- initialChar++;
- nChars = endChar - initialChar + 1;
- }
- else
- {
- wxASSERT(mode == wxST_ELLIPSIZE_END);
- wxASSERT(len > 0);
-
- int maxWidth = totalWidth - excessPixels;
- for (initialChar=0;
- initialChar < len &&
- charOffsets[initialChar] < maxWidth;
- initialChar++)
- ;
-
- if (initialChar == 0)
- {
- nChars = len;
- }
- else
- {
- initialChar--; // go back one character
- nChars = len - initialChar;
- }
- }
-
- if (nChars > len)
- {
- // need to remove the entire row!
- curLine.clear();
- }
- else
- {
- // erase nChars characters after initialChar (included):
- curLine.erase(initialChar, nChars+1);
-
- // if there is space for the replacement dots, add them
- if (maxFinalWidth > replacementWidth)
- curLine.insert(initialChar, wxELLIPSE_REPLACEMENT);
- }
-
- // if everything was ok, we should have shortened this line
- // enough to make it fit in sz.maxFinalWidth:
- wxASSERT(dc.GetTextExtent(curLine).GetWidth() < maxFinalWidth);
- }
- }
-
- // add this (ellipsized) row to the rest of the label
- ret << curLine;
- if ( pc == label.end() )
- {
- return ret;
- }
- else
- {
- ret << *pc;
- curLine.clear();
- }
- }
- // we need to remove mnemonics from the label for correct calculations
- else if ( *pc == _T('&') )
- {
- // pc+1 is safe: at worst we'll be at end()
- wxString::const_iterator next = pc + 1;
- if ( next != label.end() && *next == _T('&') )
- curLine += _T('&'); // && becomes &
- //else: remove this ampersand
- }
- // we need also to expand tabs to properly calc their size
- else if ( *pc == _T('\t') )
- {
- // Windows natively expands the TABs to 6 spaces. Do the same:
- curLine += wxT(" ");
- }
- else
- {
- curLine += *pc;
- }
- }
-
- return ret;
-}
-
-
-