X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/19cf1ef3a7077dd99a90f141847b8a9b67b318c9..63a65070911908802c27b52173c3306e93dd63bf:/src/common/stattextcmn.cpp diff --git a/src/common/stattextcmn.cpp b/src/common/stattextcmn.cpp index b4b6acee00..66cfd3ba96 100644 --- a/src/common/stattextcmn.cpp +++ b/src/common/stattextcmn.cpp @@ -24,28 +24,78 @@ #pragma hdrstop #endif -#include "wx/private/stattext.h" +#if wxUSE_STATTEXT #ifndef WX_PRECOMP + #include "wx/stattext.h" #include "wx/button.h" #include "wx/dcclient.h" #include "wx/intl.h" #include "wx/log.h" #include "wx/settings.h" - #include "wx/stattext.h" #include "wx/sizer.h" #include "wx/containr.h" #endif -#if wxUSE_STATTEXT +#include "wx/textwrapper.h" -const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] = -{ - // the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string +#include "wx/private/markupparser.h" - { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT(""") }, - { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") } -}; +extern WXDLLEXPORT_DATA(const char) wxStaticTextNameStr[] = "staticText"; + +// ---------------------------------------------------------------------------- +// XTI +// ---------------------------------------------------------------------------- + +wxDEFINE_FLAGS( wxStaticTextStyle ) +wxBEGIN_FLAGS( wxStaticTextStyle ) +// new style border flags, we put them first to +// use them for streaming out +wxFLAGS_MEMBER(wxBORDER_SIMPLE) +wxFLAGS_MEMBER(wxBORDER_SUNKEN) +wxFLAGS_MEMBER(wxBORDER_DOUBLE) +wxFLAGS_MEMBER(wxBORDER_RAISED) +wxFLAGS_MEMBER(wxBORDER_STATIC) +wxFLAGS_MEMBER(wxBORDER_NONE) + +// old style border flags +wxFLAGS_MEMBER(wxSIMPLE_BORDER) +wxFLAGS_MEMBER(wxSUNKEN_BORDER) +wxFLAGS_MEMBER(wxDOUBLE_BORDER) +wxFLAGS_MEMBER(wxRAISED_BORDER) +wxFLAGS_MEMBER(wxSTATIC_BORDER) +wxFLAGS_MEMBER(wxBORDER) + +// standard window styles +wxFLAGS_MEMBER(wxTAB_TRAVERSAL) +wxFLAGS_MEMBER(wxCLIP_CHILDREN) +wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW) +wxFLAGS_MEMBER(wxWANTS_CHARS) +wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE) +wxFLAGS_MEMBER(wxALWAYS_SHOW_SB ) +wxFLAGS_MEMBER(wxVSCROLL) +wxFLAGS_MEMBER(wxHSCROLL) + +wxFLAGS_MEMBER(wxST_NO_AUTORESIZE) +wxFLAGS_MEMBER(wxALIGN_LEFT) +wxFLAGS_MEMBER(wxALIGN_RIGHT) +wxFLAGS_MEMBER(wxALIGN_CENTRE) +wxEND_FLAGS( wxStaticTextStyle ) + +wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxStaticText, wxControl, "wx/stattext.h") + +wxBEGIN_PROPERTIES_TABLE(wxStaticText) +wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxString(), 0 /*flags*/, \ + wxT("Helpstring"), wxT("group")) +wxPROPERTY_FLAGS( WindowStyle, wxStaticTextStyle, long, SetWindowStyleFlag, \ + GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \ + wxT("Helpstring"), wxT("group")) // style +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxStaticText) + +wxCONSTRUCTOR_6( wxStaticText, wxWindow*, Parent, wxWindowID, Id, \ + wxString, Label, wxPoint, Position, wxSize, Size, long, WindowStyle ) // ---------------------------------------------------------------------------- @@ -69,7 +119,7 @@ void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax) lineStart = p; } - if ( p == text.end() || *p == _T('\n') ) + if ( p == text.end() || *p == wxT('\n') ) { DoOutputLine(line); @@ -78,7 +128,7 @@ void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax) } else // not EOL { - if ( *p == _T(' ') ) + if ( *p == wxT(' ') ) lastSpace = p; line += *p; @@ -127,7 +177,7 @@ protected: virtual void OnNewLine() { - m_text += _T('\n'); + m_text += wxT('\n'); } private: @@ -145,133 +195,6 @@ void wxStaticTextBase::Wrap(int width) wrapper.WrapLabel(this, width); } -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; -} - - - // ---------------------------------------------------------------------------- // wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support // ---------------------------------------------------------------------------- @@ -281,12 +204,12 @@ void wxStaticTextBase::UpdateLabel() if (!IsEllipsized()) return; - wxString newlabel = GetEllipsizedLabelWithoutMarkup(); + wxString newlabel = GetEllipsizedLabel(); // we need to touch the "real" label (i.e. the text set inside the control, // using port-specific functions) instead of the string returned by GetLabel(). // - // In fact, we must be careful not to touch the original label passed to + // In fact, we must be careful not to touch the original label passed to // SetLabel() otherwise GetLabel() will behave in a strange way to the user // (e.g. returning a "Ver...ing" instead of "Very long string") ! if (newlabel == DoGetLabel()) @@ -294,7 +217,7 @@ void wxStaticTextBase::UpdateLabel() DoSetLabel(newlabel); } -wxString wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const +wxString wxStaticTextBase::GetEllipsizedLabel() const { // this function should be used only by ports which do not support // ellipsis in static texts: we first remove markup (which cannot @@ -302,19 +225,12 @@ wxString wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const wxString ret(m_labelOrig); - // the order of the following two blocks is important! - - if (HasFlag(wxST_MARKUP)) - ret = RemoveMarkup(ret); - if (IsEllipsized()) ret = Ellipsize(ret); return ret; } -#define wxELLIPSE_REPLACEMENT wxT("...") - wxString wxStaticTextBase::Ellipsize(const wxString& label) const { wxSize sz(GetSize()); @@ -324,169 +240,24 @@ wxString wxStaticTextBase::Ellipsize(const wxString& label) const return label; } - wxClientDC dc(wx_const_cast(wxStaticTextBase*, this)); + wxClientDC dc(const_cast(this)); dc.SetFont(GetFont()); - 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; - - // handle correctly labels with newlines - wxString curLine; - wxSize reqsize; - size_t len; - for ( wxString::const_iterator pc = label.begin(); ; ++pc ) + wxEllipsizeMode mode; + if ( HasFlag(wxST_ELLIPSIZE_START) ) + mode = wxELLIPSIZE_START; + else if ( HasFlag(wxST_ELLIPSIZE_MIDDLE) ) + mode = wxELLIPSIZE_MIDDLE; + else if ( HasFlag(wxST_ELLIPSIZE_END) ) + mode = wxELLIPSIZE_END; + else { - 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)sz.GetWidth() ) - { - // we need to ellipsize this row - int excessPixels = totalWidth - sz.GetWidth() + - 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 (HasFlag(wxST_ELLIPSIZE_START)) - { - initialChar = 0; - for (nChars=0; - nChars < len && charOffsets[nChars] < excessPixels; - nChars++) - ; - } - else if (HasFlag(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(HasFlag(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 (sz.GetWidth() > replacementWidth) - curLine.insert(initialChar, wxELLIPSE_REPLACEMENT); - } - - // if everything was ok, we should have shortened this line - // enough to make it fit in sz.GetWidth(): - wxASSERT(dc.GetTextExtent(curLine).GetWidth() < sz.GetWidth()); - } - } + wxFAIL_MSG( "should only be called if have one of wxST_ELLIPSIZE_XXX" ); - // 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 label; } - //return ret; + return wxControl::Ellipsize(label, dc, mode, sz.GetWidth()); } #endif // wxUSE_STATTEXT