Fix handling of ampersands in wxDataViewCtrl markup
Handle "&" in exactly the same way as "&" in wxMarkupParser, i.e. do not map the former to "&&" to prevent it from being interpreted as a mnemonic as this is incompatible with using markup for anything but the control labels, e.g. for wxDataViewCtrl items text, in which mnemonics are not recognized. And even when using markup for control labels, it was a questionable decision as it's really not clear at all why should the XML entity and the raw character itself be handled differently. Also split wxMarkupText into two classes, wxMarkupText that handles mnemonics in the markup (which is typically a label) and a very similar, but not derived, wxItemMarkupText that handles mnemonics-less markup for list etc. items, uses DrawItemText() and supports ellipsizing. Illustrate the use of ampersands in the dataview sample.
This commit is contained in:
parent
0e2f6f6ec0
commit
60bd6842e4
@ -83,7 +83,7 @@ protected:
|
||||
|
||||
private:
|
||||
#if wxUSE_MARKUP
|
||||
class wxMarkupText *m_markupText;
|
||||
class wxItemMarkupText *m_markupText;
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer);
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/generic/private/markuptext.h
|
||||
// Purpose: Generic wxMarkupText class for managing text with markup.
|
||||
// Purpose: Generic wx*MarkupText classes for managing text with markup.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2011-02-21
|
||||
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
@ -21,7 +21,36 @@ class wxMarkupParserOutput;
|
||||
// wxMarkupText: allows to measure and draw the text containing markup.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxMarkupText
|
||||
class WXDLLIMPEXP_CORE wxMarkupTextBase
|
||||
{
|
||||
public:
|
||||
// Update the markup string.
|
||||
void SetMarkup(const wxString& markup) { m_markup = markup; }
|
||||
|
||||
// Return the width and height required by the given string and optionally
|
||||
// the height of the visible part above the baseline (i.e. ascent minus
|
||||
// internal leading).
|
||||
//
|
||||
// The font currently selected into the DC is used for measuring (notice
|
||||
// that it is changed by this function but normally -- i.e. if markup is
|
||||
// valid -- restored to its original value when it returns).
|
||||
wxSize Measure(wxDC& dc, int *visibleHeight = NULL) const;
|
||||
|
||||
protected:
|
||||
wxMarkupTextBase(const wxString& markup)
|
||||
: m_markup(markup)
|
||||
{
|
||||
}
|
||||
|
||||
// Return m_markup suitable for measuring by Measure, i.e. stripped of
|
||||
// any mnenomics.
|
||||
virtual wxString GetMarkupForMeasuring() const = 0;
|
||||
|
||||
wxString m_markup;
|
||||
};
|
||||
|
||||
|
||||
class WXDLLIMPEXP_CORE wxMarkupText : public wxMarkupTextBase
|
||||
{
|
||||
public:
|
||||
// Constants for Render() flags.
|
||||
@ -43,8 +72,7 @@ public:
|
||||
// TODO-MULTILINE-MARKUP: Currently only single line labels are supported,
|
||||
// search for other occurrences of this comment to find the places which
|
||||
// need to be updated to support multiline labels with markup.
|
||||
wxMarkupText(const wxString& markup)
|
||||
: m_markup(markup)
|
||||
wxMarkupText(const wxString& markup) : wxMarkupTextBase(markup)
|
||||
{
|
||||
}
|
||||
|
||||
@ -55,21 +83,6 @@ public:
|
||||
// The same rules for mnemonics as in the ctor apply to this string.
|
||||
void SetMarkup(const wxString& markup) { m_markup = markup; }
|
||||
|
||||
// This is a convenience method which can be used with the string in which
|
||||
// mnemonics should be completely ignored, i.e. not interpreted in any way
|
||||
// but just handled as ordinary characters.
|
||||
void SetMarkupText(const wxString& markup);
|
||||
|
||||
|
||||
// Return the width and height required by the given string and optionally
|
||||
// the height of the visible part above the baseline (i.e. ascent minus
|
||||
// internal leading).
|
||||
//
|
||||
// The font currently selected into the DC is used for measuring (notice
|
||||
// that it is changed by this function but normally -- i.e. if markup is
|
||||
// valid -- restored to its original value when it returns).
|
||||
wxSize Measure(wxDC& dc, int *visibleHeight = NULL) const;
|
||||
|
||||
// Render the markup string into the given DC in the specified rectangle.
|
||||
//
|
||||
// Notice that while the function uses the provided rectangle for alignment
|
||||
@ -77,24 +90,47 @@ public:
|
||||
// and set the clipping region before rendering if necessary.
|
||||
void Render(wxDC& dc, const wxRect& rect, int flags);
|
||||
|
||||
// Similar to Render(), but uses wxRendererNative::DrawItemText() instead
|
||||
// of generic wxDC::DrawLabel(), so is more suitable for use in controls
|
||||
// that already use DrawItemText() for its items.
|
||||
protected:
|
||||
virtual wxString GetMarkupForMeasuring() const wxOVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxItemMarkupText: variant of wxMarkupText for items without mnemonics
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This class has similar interface to wxItemMarkup, but no strings contain
|
||||
// mnemonics and no escaping is done.
|
||||
class WXDLLIMPEXP_CORE wxItemMarkupText : public wxMarkupTextBase
|
||||
{
|
||||
public:
|
||||
// Initialize with the given string containing markup (which is supposed to
|
||||
// be valid, the caller must check for it before constructing this object).
|
||||
// Notice that mnemonics are not interpreted at all by this class, so
|
||||
// literal ampersands shouldn't be escaped/doubled.
|
||||
wxItemMarkupText(const wxString& markup) : wxMarkupTextBase(markup)
|
||||
{
|
||||
}
|
||||
|
||||
// Default copy ctor, assignment operator and dtor are ok.
|
||||
|
||||
// Similar to wxMarkupText::Render(), but uses wxRendererNative::DrawItemText()
|
||||
// instead of generic wxDC::DrawLabel(), so is more suitable for use in
|
||||
// controls that already use DrawItemText() for its items.
|
||||
//
|
||||
// The meaning of the flags here is different than in the overload above:
|
||||
// they're passed to DrawItemText() and Render_ShowAccels is not supported
|
||||
// here.
|
||||
// The meaning of the flags here is different than in wxMarkupText too:
|
||||
// they're passed to DrawItemText().
|
||||
//
|
||||
// Currently the only supported ellipsize modes are wxELLIPSIZE_NONE and
|
||||
// wxELLIPSIZE_END, the others are treated as wxELLIPSIZE_END.
|
||||
void RenderItemText(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int rendererFlags,
|
||||
wxEllipsizeMode ellipsizeMode);
|
||||
void Render(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int rendererFlags,
|
||||
wxEllipsizeMode ellipsizeMode);
|
||||
|
||||
private:
|
||||
wxString m_markup;
|
||||
protected:
|
||||
virtual wxString GetMarkupForMeasuring() const wxOVERRIDE { return m_markup; }
|
||||
};
|
||||
|
||||
#endif // _WX_GENERIC_PRIVATE_MARKUPTEXT_H_
|
||||
|
@ -441,8 +441,8 @@ void MyListModel::GetValueByRow( wxVariant &variant,
|
||||
"<span color=\"#87ceeb\">light</span> and "
|
||||
"<span color=\"#000080\">dark</span> blue",
|
||||
"<big>growing green</big>",
|
||||
"<i>emphatic red</i>",
|
||||
"<b>bold cyan</b>",
|
||||
"<i>emphatic & red</i>",
|
||||
"<b>bold && cyan</b>",
|
||||
"<small><tt>dull default</tt></small>",
|
||||
};
|
||||
|
||||
|
@ -371,12 +371,7 @@ bool wxMarkupParser::Parse(const wxString& text)
|
||||
if ( text.compare(pos, xmlEnt.len, xmlEnt.name) == 0
|
||||
&& text[pos + xmlEnt.len] == ';' )
|
||||
{
|
||||
// Escape the ampersands if needed to protect them
|
||||
// from being interpreted as mnemonics indicators.
|
||||
if ( xmlEnt.value == '&' )
|
||||
current += "&&";
|
||||
else
|
||||
current += xmlEnt.value;
|
||||
current += xmlEnt.value;
|
||||
|
||||
it += xmlEnt.len + 1; // +1 for '&' itself
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ void wxDataViewTextRenderer::EnableMarkup(bool enable)
|
||||
{
|
||||
if ( !m_markupText )
|
||||
{
|
||||
m_markupText = new wxMarkupText(wxString());
|
||||
m_markupText = new wxItemMarkupText(wxString());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1087,7 +1087,7 @@ bool wxDataViewTextRenderer::SetValue( const wxVariant &value )
|
||||
|
||||
#if wxUSE_MARKUP
|
||||
if ( m_markupText )
|
||||
m_markupText->SetMarkupText(m_text);
|
||||
m_markupText->SetMarkup(m_text);
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
return true;
|
||||
@ -1135,7 +1135,7 @@ bool wxDataViewTextRenderer::Render(wxRect rect, wxDC *dc, int state)
|
||||
int flags = 0;
|
||||
if ( state & wxDATAVIEW_CELL_SELECTED )
|
||||
flags |= wxCONTROL_SELECTED;
|
||||
m_markupText->RenderItemText(GetView(), *dc, rect, flags, GetEllipsizeMode());
|
||||
m_markupText->Render(GetView(), *dc, rect, flags, GetEllipsizeMode());
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_MARKUP
|
||||
|
@ -66,10 +66,8 @@ public:
|
||||
const wxSize& GetSize() const { return m_size; }
|
||||
|
||||
|
||||
virtual void OnText(const wxString& text_) wxOVERRIDE
|
||||
virtual void OnText(const wxString& text) wxOVERRIDE
|
||||
{
|
||||
const wxString text(wxControl::RemoveMnemonics(text_));
|
||||
|
||||
// TODO-MULTILINE-MARKUP: Must use GetMultiLineTextExtent().
|
||||
const wxSize size = m_dc.GetTextExtent(text);
|
||||
|
||||
@ -253,10 +251,8 @@ public:
|
||||
m_ellipsizeMode = ellipsizeMode == wxELLIPSIZE_NONE ? wxELLIPSIZE_NONE : wxELLIPSIZE_END;
|
||||
}
|
||||
|
||||
virtual void OnText(const wxString& text_) wxOVERRIDE
|
||||
virtual void OnText(const wxString& text) wxOVERRIDE
|
||||
{
|
||||
const wxString text(wxControl::RemoveMnemonics(text_));
|
||||
|
||||
wxRect rect(m_rect);
|
||||
rect.x = m_pos;
|
||||
rect.SetRight(m_rect.GetRight());
|
||||
@ -315,16 +311,11 @@ private:
|
||||
// wxMarkupText implementation
|
||||
// ============================================================================
|
||||
|
||||
void wxMarkupText::SetMarkupText(const wxString& markup)
|
||||
{
|
||||
m_markup = wxControl::EscapeMnemonics(markup);
|
||||
}
|
||||
|
||||
wxSize wxMarkupText::Measure(wxDC& dc, int *visibleHeight) const
|
||||
wxSize wxMarkupTextBase::Measure(wxDC& dc, int *visibleHeight) const
|
||||
{
|
||||
wxMarkupParserMeasureOutput out(dc, visibleHeight);
|
||||
wxMarkupParser parser(out);
|
||||
if ( !parser.Parse(m_markup) )
|
||||
if ( !parser.Parse(GetMarkupForMeasuring()) )
|
||||
{
|
||||
wxFAIL_MSG( "Invalid markup" );
|
||||
return wxDefaultSize;
|
||||
@ -333,6 +324,11 @@ wxSize wxMarkupText::Measure(wxDC& dc, int *visibleHeight) const
|
||||
return out.GetSize();
|
||||
}
|
||||
|
||||
wxString wxMarkupText::GetMarkupForMeasuring() const
|
||||
{
|
||||
return wxControl::RemoveMnemonics(m_markup);
|
||||
}
|
||||
|
||||
void wxMarkupText::Render(wxDC& dc, const wxRect& rect, int flags)
|
||||
{
|
||||
// We want to center the above-baseline parts of the letter vertically, so
|
||||
@ -347,11 +343,16 @@ void wxMarkupText::Render(wxDC& dc, const wxRect& rect, int flags)
|
||||
parser.Parse(m_markup);
|
||||
}
|
||||
|
||||
void wxMarkupText::RenderItemText(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int rendererFlags,
|
||||
wxEllipsizeMode ellipsizeMode)
|
||||
|
||||
// ============================================================================
|
||||
// wxItemMarkupText implementation
|
||||
// ============================================================================
|
||||
|
||||
void wxItemMarkupText::Render(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int rendererFlags,
|
||||
wxEllipsizeMode ellipsizeMode)
|
||||
{
|
||||
wxMarkupParserRenderItemOutput out(win, dc, rect, rendererFlags, ellipsizeMode);
|
||||
wxMarkupParser parser(out);
|
||||
|
Loading…
Reference in New Issue
Block a user