Merge branch 'statictext-setlabel'
wxControl label-related fixes and improvements. See https://github.com/wxWidgets/wxWidgets/pull/1364
This commit is contained in:
@@ -178,11 +178,6 @@ protected:
|
||||
// initialize the common fields of wxCommandEvent
|
||||
void InitCommandEvent(wxCommandEvent& event) const;
|
||||
|
||||
// Ellipsize() helper:
|
||||
static wxString DoEllipsizeSingleLine(const wxString& label, const wxDC& dc,
|
||||
wxEllipsizeMode mode, int maxWidth,
|
||||
int replacementWidth);
|
||||
|
||||
#if wxUSE_MARKUP
|
||||
// Remove markup from the given string, returns empty string on error i.e.
|
||||
// if markup was syntactically invalid.
|
||||
|
@@ -54,8 +54,8 @@ public:
|
||||
protected:
|
||||
virtual wxSize DoGetBestClientSize() const wxOVERRIDE;
|
||||
|
||||
virtual wxString DoGetLabel() const wxOVERRIDE { return m_label; }
|
||||
virtual void DoSetLabel(const wxString& label) wxOVERRIDE;
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE { return m_label; }
|
||||
virtual void WXSetVisibleLabel(const wxString& label) wxOVERRIDE;
|
||||
|
||||
void DoSetSize(int x, int y, int width, int height, int sizeFlags) wxOVERRIDE;
|
||||
|
||||
|
@@ -49,8 +49,8 @@ protected:
|
||||
|
||||
virtual wxSize DoGetBestSize() const wxOVERRIDE;
|
||||
|
||||
virtual wxString DoGetLabel() const wxOVERRIDE;
|
||||
virtual void DoSetLabel(const wxString& str) wxOVERRIDE;
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE;
|
||||
virtual void WXSetVisibleLabel(const wxString& str) wxOVERRIDE;
|
||||
#if wxUSE_MARKUP
|
||||
virtual bool DoSetLabelMarkup(const wxString& markup) wxOVERRIDE;
|
||||
#endif // wxUSE_MARKUP
|
||||
|
@@ -51,8 +51,8 @@ public:
|
||||
virtual WXWidget GetLabelWidget() const
|
||||
{ return m_labelWidget; }
|
||||
|
||||
virtual void DoSetLabel(const wxString& str);
|
||||
virtual wxString DoGetLabel() const;
|
||||
virtual void WXSetVisibleLabel(const wxString& str);
|
||||
virtual wxString WXGetVisibleLabel() const;
|
||||
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
protected:
|
||||
|
@@ -47,8 +47,8 @@ protected:
|
||||
int sizeFlags = wxSIZE_AUTO) wxOVERRIDE;
|
||||
virtual wxSize DoGetBestClientSize() const wxOVERRIDE;
|
||||
|
||||
virtual wxString DoGetLabel() const wxOVERRIDE;
|
||||
virtual void DoSetLabel(const wxString& str) wxOVERRIDE;
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE;
|
||||
virtual void WXSetVisibleLabel(const wxString& str) wxOVERRIDE;
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText);
|
||||
};
|
||||
|
@@ -41,8 +41,8 @@ public:
|
||||
|
||||
protected :
|
||||
|
||||
virtual wxString DoGetLabel() const wxOVERRIDE;
|
||||
virtual void DoSetLabel(const wxString& str) wxOVERRIDE;
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE;
|
||||
virtual void WXSetVisibleLabel(const wxString& str) wxOVERRIDE;
|
||||
|
||||
virtual wxSize DoGetBestSize() const wxOVERRIDE;
|
||||
|
||||
|
@@ -31,10 +31,13 @@ public:
|
||||
const wxString &name = wxStaticTextNameStr );
|
||||
|
||||
virtual void SetLabel(const wxString& label) wxOVERRIDE;
|
||||
virtual wxString GetLabel() const wxOVERRIDE;
|
||||
|
||||
virtual QWidget *GetHandle() const wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE;
|
||||
virtual void WXSetVisibleLabel(const wxString& str) wxOVERRIDE;
|
||||
|
||||
private:
|
||||
QLabel *m_qtLabel;
|
||||
|
||||
|
@@ -63,21 +63,27 @@ protected: // functions required for wxST_ELLIPSIZE_* support
|
||||
// style. Shouldn't be called if we don't have any.
|
||||
wxString Ellipsize(const wxString& label) const;
|
||||
|
||||
// to be called when updating the size of the static text:
|
||||
// updates the label redoing ellipsization calculations
|
||||
|
||||
// Note that even though ports with native support for ellipsization
|
||||
// (currently only wxGTK) don't need this stuff, we still need to define it
|
||||
// as it's used by wxGenericStaticText.
|
||||
|
||||
// Must be called when the size or font changes to redo the ellipsization
|
||||
// for the new size. Calls WXSetVisibleLabel() to actually update the
|
||||
// display.
|
||||
void UpdateLabel();
|
||||
|
||||
// These functions are platform-specific and must be overridden in ports
|
||||
// which do not natively support ellipsization and they must be implemented
|
||||
// in a way so that the m_labelOrig member of wxControl is not touched:
|
||||
// These functions are platform-specific and must be implemented in the
|
||||
// platform-specific code. They must not use or update m_labelOrig.
|
||||
|
||||
// returns the real label currently displayed inside the control.
|
||||
virtual wxString DoGetLabel() const { return wxEmptyString; }
|
||||
// Returns the label currently displayed inside the control, with mnemonics
|
||||
// if any.
|
||||
virtual wxString WXGetVisibleLabel() const = 0;
|
||||
|
||||
// sets the real label currently displayed inside the control,
|
||||
// _without_ invalidating the size. The text passed is always markup-free
|
||||
// but may contain the mnemonic characters.
|
||||
virtual void DoSetLabel(const wxString& WXUNUSED(str)) { }
|
||||
// Sets the real label currently displayed inside the control, _without_
|
||||
// invalidating the size. The text passed is always markup-free but may
|
||||
// contain the mnemonic characters.
|
||||
virtual void WXSetVisibleLabel(const wxString& str) = 0;
|
||||
|
||||
// Update the current size to match the best size unless wxST_NO_AUTORESIZE
|
||||
// style is explicitly used.
|
||||
|
@@ -58,8 +58,8 @@ protected:
|
||||
// draw the control
|
||||
virtual void DoDraw(wxControlRenderer *renderer) wxOVERRIDE;
|
||||
|
||||
virtual void DoSetLabel(const wxString& str) wxOVERRIDE;
|
||||
virtual wxString DoGetLabel() const wxOVERRIDE;
|
||||
virtual void WXSetVisibleLabel(const wxString& str) wxOVERRIDE;
|
||||
virtual wxString WXGetVisibleLabel() const wxOVERRIDE;
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS(wxStaticText);
|
||||
};
|
||||
|
@@ -49,15 +49,6 @@
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// control ids
|
||||
enum
|
||||
{
|
||||
StaticPage_Reset = wxID_HIGHEST,
|
||||
StaticPage_BoxText,
|
||||
StaticPage_LabelText,
|
||||
StaticPage_LabelTextWithMarkup
|
||||
};
|
||||
|
||||
// alignment radiobox values
|
||||
enum
|
||||
{
|
||||
@@ -114,7 +105,7 @@ public:
|
||||
|
||||
protected:
|
||||
// event handlers
|
||||
void OnCheckOrRadioBox(wxCommandEvent& event);
|
||||
void OnCheckEllipsize(wxCommandEvent& event);
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
void OnBoxCheckBox(wxCommandEvent& event);
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
@@ -176,26 +167,9 @@ protected:
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
private:
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
DECLARE_WIDGETS_PAGE(StaticWidgetsPage)
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// event tables
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxBEGIN_EVENT_TABLE(StaticWidgetsPage, WidgetsPage)
|
||||
EVT_BUTTON(StaticPage_Reset, StaticWidgetsPage::OnButtonReset)
|
||||
EVT_BUTTON(StaticPage_LabelText, StaticWidgetsPage::OnButtonLabelText)
|
||||
#if wxUSE_MARKUP
|
||||
EVT_BUTTON(StaticPage_LabelTextWithMarkup, StaticWidgetsPage::OnButtonLabelWithMarkupText)
|
||||
#endif // wxUSE_MARKUP
|
||||
EVT_BUTTON(StaticPage_BoxText, StaticWidgetsPage::OnButtonBoxText)
|
||||
|
||||
EVT_CHECKBOX(wxID_ANY, StaticWidgetsPage::OnCheckOrRadioBox)
|
||||
EVT_RADIOBOX(wxID_ANY, StaticWidgetsPage::OnCheckOrRadioBox)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
@@ -286,6 +260,8 @@ void StaticWidgetsPage::CreateContent()
|
||||
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
|
||||
|
||||
m_chkEllipsize = CreateCheckBoxAndAddToSizer(sizerLeft, "&Ellipsize");
|
||||
m_chkEllipsize->Bind(wxEVT_CHECKBOX,
|
||||
&StaticWidgetsPage::OnCheckEllipsize, this);
|
||||
|
||||
static const wxString ellipsizeMode[] =
|
||||
{
|
||||
@@ -301,8 +277,9 @@ void StaticWidgetsPage::CreateContent()
|
||||
|
||||
sizerLeft->Add(m_radioEllipsize, 0, wxGROW | wxALL, 5);
|
||||
|
||||
wxButton *btn = new wxButton(this, StaticPage_Reset, "&Reset");
|
||||
sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
|
||||
wxButton *b0 = new wxButton(this, wxID_ANY, "&Reset");
|
||||
b0->Bind(wxEVT_BUTTON, &StaticWidgetsPage::OnButtonReset, this);
|
||||
sizerLeft->Add(b0, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
|
||||
|
||||
// middle pane
|
||||
wxSizer *sizerMiddle = new wxStaticBoxSizer(wxVERTICAL, this,
|
||||
@@ -346,8 +323,8 @@ void StaticWidgetsPage::CreateContent()
|
||||
#if wxUSE_MARKUP
|
||||
m_textLabelWithMarkup->SetValue("Another label, this time <b>decorated</b> "
|
||||
"with <u>markup</u>; here you need entities "
|
||||
"for the symbols: < > & ' " "
|
||||
" but you can still place &mnemonics...");
|
||||
"for the symbols: < > && ' " "
|
||||
" but you can still use &mnemonics too");
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
// right pane
|
||||
@@ -573,12 +550,9 @@ void StaticWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
|
||||
CreateStatic();
|
||||
}
|
||||
|
||||
void StaticWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
|
||||
void StaticWidgetsPage::OnCheckEllipsize(wxCommandEvent& event)
|
||||
{
|
||||
if (event.GetEventObject() == static_cast<wxObject*>(m_chkEllipsize))
|
||||
{
|
||||
m_radioEllipsize->Enable(event.IsChecked());
|
||||
}
|
||||
|
||||
CreateStatic();
|
||||
}
|
||||
|
@@ -194,20 +194,24 @@ int wxControlBase::FindAccelIndex(const wxString& label, wxString *labelOnly)
|
||||
labelOnly->Alloc(label.length());
|
||||
}
|
||||
|
||||
// When computing the offset below, we need to ignore the characters that
|
||||
// are not actually displayed, i.e. the ampersands themselves.
|
||||
int numSkipped = 0;
|
||||
int indexAccel = -1;
|
||||
for ( wxString::const_iterator pc = label.begin(); pc != label.end(); ++pc )
|
||||
{
|
||||
if ( *pc == MNEMONIC_PREFIX )
|
||||
{
|
||||
++pc; // skip it
|
||||
++numSkipped;
|
||||
|
||||
if ( pc == label.end() )
|
||||
break;
|
||||
else if ( *pc != MNEMONIC_PREFIX )
|
||||
{
|
||||
if ( indexAccel == -1 )
|
||||
{
|
||||
// remember it (-1 is for MNEMONIC_PREFIX itself
|
||||
indexAccel = pc - label.begin() - 1;
|
||||
indexAccel = pc - label.begin() - numSkipped;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,7 +282,8 @@ namespace
|
||||
struct EllipsizeCalculator
|
||||
{
|
||||
EllipsizeCalculator(const wxString& s, const wxDC& dc,
|
||||
int maxFinalWidthPx, int replacementWidthPx)
|
||||
int maxFinalWidthPx, int replacementWidthPx,
|
||||
int flags)
|
||||
:
|
||||
m_initialCharToRemove(0),
|
||||
m_nCharsToRemove(0),
|
||||
@@ -290,6 +295,31 @@ struct EllipsizeCalculator
|
||||
{
|
||||
m_isOk = dc.GetPartialTextExtents(s, m_charOffsetsPx);
|
||||
wxASSERT( m_charOffsetsPx.GetCount() == s.length() );
|
||||
|
||||
if ( flags & wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS )
|
||||
{
|
||||
// The ampersand itself shouldn't count for the width calculation
|
||||
// as it won't be displayed: either it's an ampersand before some
|
||||
// other character in which case it indicates a mnemonic, or it's
|
||||
// an escaped ampersand, in which case only the second one of the
|
||||
// pair of ampersands will be displayed. But we can't just remove
|
||||
// the ampersand as we still need it in the final label, in order
|
||||
// not to lose the mnemonics. Hence we use this hack, and pretend
|
||||
// that ampersands simply have zero width. Of course, it could be
|
||||
// not completely precise, but this is the best we can do without
|
||||
// completely changing this code structure.
|
||||
size_t n = 0;
|
||||
int delta = 0;
|
||||
for ( wxString::const_iterator it = s.begin();
|
||||
it != s.end();
|
||||
++it, ++n )
|
||||
{
|
||||
if ( *it == '&' )
|
||||
delta += dc.GetTextExtent(wxS('&')).GetWidth();
|
||||
|
||||
m_charOffsetsPx[n] -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsOk() const { return m_isOk; }
|
||||
@@ -399,12 +429,9 @@ struct EllipsizeCalculator
|
||||
bool m_isOk;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static and protected */
|
||||
wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxDC& dc,
|
||||
wxString DoEllipsizeSingleLine(const wxString& curLine, const wxDC& dc,
|
||||
wxEllipsizeMode mode, int maxFinalWidthPx,
|
||||
int replacementWidthPx)
|
||||
int replacementWidthPx, int flags)
|
||||
{
|
||||
wxASSERT_MSG(replacementWidthPx > 0, "Invalid parameters");
|
||||
wxASSERT_LEVEL_2_MSG(!curLine.Contains('\n'),
|
||||
@@ -412,9 +439,6 @@ wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxD
|
||||
|
||||
wxASSERT_MSG( mode != wxELLIPSIZE_NONE, "shouldn't be called at all then" );
|
||||
|
||||
// NOTE: this function assumes that any mnemonic/tab character has already
|
||||
// been handled if it was necessary to handle them (see Ellipsize())
|
||||
|
||||
if (maxFinalWidthPx <= 0)
|
||||
return wxEmptyString;
|
||||
|
||||
@@ -422,7 +446,7 @@ wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxD
|
||||
if (len <= 1 )
|
||||
return curLine;
|
||||
|
||||
EllipsizeCalculator calc(curLine, dc, maxFinalWidthPx, replacementWidthPx);
|
||||
EllipsizeCalculator calc(curLine, dc, maxFinalWidthPx, replacementWidthPx, flags);
|
||||
|
||||
if ( !calc.IsOk() )
|
||||
return curLine;
|
||||
@@ -519,6 +543,9 @@ wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxD
|
||||
return calc.GetEllipsizedText();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/* static */
|
||||
wxString wxControlBase::Ellipsize(const wxString& label, const wxDC& dc,
|
||||
wxEllipsizeMode mode, int maxFinalWidth,
|
||||
@@ -541,7 +568,7 @@ wxString wxControlBase::Ellipsize(const wxString& label, const wxDC& dc,
|
||||
if ( pc == label.end() || *pc == wxS('\n') )
|
||||
{
|
||||
curLine = DoEllipsizeSingleLine(curLine, dc, mode, maxFinalWidth,
|
||||
replacementWidth);
|
||||
replacementWidth, flags);
|
||||
|
||||
// add this (ellipsized) row to the rest of the label
|
||||
ret << curLine;
|
||||
@@ -551,15 +578,6 @@ wxString wxControlBase::Ellipsize(const wxString& label, const wxDC& dc,
|
||||
ret << *pc;
|
||||
curLine.clear();
|
||||
}
|
||||
// we need to remove mnemonics from the label for correct calculations
|
||||
else if ( *pc == wxS('&') && (flags & wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS) )
|
||||
{
|
||||
// pc+1 is safe: at worst we'll be at end()
|
||||
wxString::const_iterator next = pc + 1;
|
||||
if ( next != label.end() && *next == wxS('&') )
|
||||
curLine += wxS('&'); // && becomes &
|
||||
//else: remove this ampersand
|
||||
}
|
||||
// we need also to expand tabs to properly calc their size
|
||||
else if ( *pc == wxS('\t') && (flags & wxELLIPSIZE_FLAGS_EXPAND_TABS) )
|
||||
{
|
||||
|
@@ -232,7 +232,7 @@ void wxStaticTextBase::UpdateLabel()
|
||||
if (!IsEllipsized())
|
||||
return;
|
||||
|
||||
wxString newlabel = GetEllipsizedLabel();
|
||||
const 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().
|
||||
@@ -240,9 +240,9 @@ void wxStaticTextBase::UpdateLabel()
|
||||
// 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())
|
||||
if (newlabel == WXGetVisibleLabel())
|
||||
return;
|
||||
DoSetLabel(newlabel);
|
||||
WXSetVisibleLabel(newlabel);
|
||||
}
|
||||
|
||||
wxString wxStaticTextBase::GetEllipsizedLabel() const
|
||||
|
@@ -100,7 +100,7 @@ wxSize wxGenericStaticText::DoGetBestClientSize() const
|
||||
void wxGenericStaticText::SetLabel(const wxString& label)
|
||||
{
|
||||
wxControl::SetLabel(label);
|
||||
DoSetLabel(GetEllipsizedLabel());
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
|
||||
AutoResizeIfNecessary();
|
||||
|
||||
@@ -115,7 +115,7 @@ void wxGenericStaticText::SetLabel(const wxString& label)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void wxGenericStaticText::DoSetLabel(const wxString& label)
|
||||
void wxGenericStaticText::WXSetVisibleLabel(const wxString& label)
|
||||
{
|
||||
m_mnemonic = FindAccelIndex(label, &m_label);
|
||||
}
|
||||
|
@@ -270,17 +270,23 @@ void wxStaticText::GTKWidgetDoSetMnemonic(GtkWidget* w)
|
||||
}
|
||||
|
||||
|
||||
// These functions should be used only when GTK+ < 2.6 by wxStaticTextBase::UpdateLabel()
|
||||
// These functions are not used as GTK supports ellipsization natively and we
|
||||
// never call the base class UpdateText() which uses them.
|
||||
//
|
||||
// Note that, unfortunately, we still need to define them because they still
|
||||
// exist, as pure virtuals, in the base class even in wxGTK to allow
|
||||
// wxGenericStaticText to override them.
|
||||
|
||||
wxString wxStaticText::DoGetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL(m_widget);
|
||||
return wxGTK_CONV_BACK( gtk_label_get_text( label ) );
|
||||
wxFAIL_MSG(wxS("Unreachable"));
|
||||
|
||||
return wxString();
|
||||
}
|
||||
|
||||
void wxStaticText::DoSetLabel(const wxString& str)
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& WXUNUSED(str))
|
||||
{
|
||||
GTKSetLabelForLabel(GTK_LABEL(m_widget), str);
|
||||
wxFAIL_MSG(wxS("Unreachable"));
|
||||
}
|
||||
|
||||
// static
|
||||
|
@@ -77,12 +77,12 @@ void wxStaticText::SetLabel(const wxString& label)
|
||||
m_labelOrig = label; // save original label
|
||||
|
||||
// Motif does not support ellipsized labels natively
|
||||
DoSetLabel(GetEllipsizedLabel());
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
}
|
||||
|
||||
// for wxST_ELLIPSIZE_* support:
|
||||
|
||||
wxString wxStaticText::DoGetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
XmString label = NULL;
|
||||
XtVaGetValues((Widget)m_labelWidget, XmNlabelString, &label, NULL);
|
||||
@@ -90,7 +90,7 @@ wxString wxStaticText::DoGetLabel() const
|
||||
return wxXmStringToString(label);
|
||||
}
|
||||
|
||||
void wxStaticText::DoSetLabel(const wxString& str)
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& str)
|
||||
{
|
||||
// build our own cleaned label
|
||||
wxXmString label_str(RemoveMnemonics(str));
|
||||
|
@@ -179,10 +179,10 @@ void wxStaticText::SetLabel(const wxString& label)
|
||||
|
||||
#ifdef SS_ENDELLIPSIS
|
||||
if ( updateStyle.IsOn(SS_ENDELLIPSIS) )
|
||||
DoSetLabel(GetLabel());
|
||||
WXSetVisibleLabel(GetLabel());
|
||||
else
|
||||
#endif // SS_ENDELLIPSIS
|
||||
DoSetLabel(GetEllipsizedLabel());
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
|
||||
AutoResizeIfNecessary();
|
||||
}
|
||||
@@ -197,16 +197,18 @@ bool wxStaticText::SetFont(const wxFont& font)
|
||||
return true;
|
||||
}
|
||||
|
||||
// for wxST_ELLIPSIZE_* support:
|
||||
// These functions are used by wxST_ELLIPSIZE_* supporting code in
|
||||
// wxStaticTextBase which requires us to implement them, but actually the base
|
||||
// wxWindow methods already do exactly what we need under this platform.
|
||||
|
||||
wxString wxStaticText::DoGetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
return wxGetWindowText(GetHwnd());
|
||||
return wxWindow::GetLabel();
|
||||
}
|
||||
|
||||
void wxStaticText::DoSetLabel(const wxString& str)
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& str)
|
||||
{
|
||||
SetWindowText(GetHwnd(), str.c_str());
|
||||
wxWindow::SetLabel(str);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -71,11 +71,11 @@ void wxStaticText::SetLabel(const wxString& label)
|
||||
)
|
||||
{
|
||||
// leave ellipsization to the OS
|
||||
DoSetLabel(GetLabel());
|
||||
WXSetVisibleLabel(GetLabel());
|
||||
}
|
||||
else // not supported natively
|
||||
{
|
||||
DoSetLabel(GetEllipsizedLabel());
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
}
|
||||
|
||||
AutoResizeIfNecessary();
|
||||
@@ -98,7 +98,7 @@ bool wxStaticText::SetFont(const wxFont& font)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wxStaticText::DoSetLabel(const wxString& label)
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& label)
|
||||
{
|
||||
m_label = RemoveMnemonics(label);
|
||||
GetPeer()->SetLabel(m_label , GetFont().GetEncoding() );
|
||||
@@ -118,7 +118,7 @@ bool wxStaticText::DoSetLabelMarkup(const wxString& markup)
|
||||
|
||||
#endif // wxUSE_MARKUP && wxOSX_USE_COCOA
|
||||
|
||||
wxString wxStaticText::DoGetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
@@ -68,11 +68,26 @@ bool wxStaticText::Create(wxWindow *parent,
|
||||
}
|
||||
|
||||
void wxStaticText::SetLabel(const wxString& label)
|
||||
{
|
||||
// If the label doesn't really change, avoid flicker by not doing anything.
|
||||
if ( label == m_labelOrig )
|
||||
return;
|
||||
|
||||
// save the label in m_labelOrig with both the markup (if any) and
|
||||
// the mnemonics characters (if any)
|
||||
m_labelOrig = label;
|
||||
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
|
||||
AutoResizeIfNecessary();
|
||||
}
|
||||
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& label)
|
||||
{
|
||||
m_qtLabel->setText( wxQtConvertString( label ) );
|
||||
}
|
||||
|
||||
wxString wxStaticText::GetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
return wxQtConvertString( m_qtLabel->text() );
|
||||
}
|
||||
|
@@ -77,15 +77,15 @@ void wxStaticText::SetLabel(const wxString& str)
|
||||
m_labelOrig = str;
|
||||
|
||||
// draw as real label the abbreviated version of it
|
||||
DoSetLabel(GetEllipsizedLabel());
|
||||
WXSetVisibleLabel(GetEllipsizedLabel());
|
||||
}
|
||||
|
||||
void wxStaticText::DoSetLabel(const wxString& str)
|
||||
void wxStaticText::WXSetVisibleLabel(const wxString& str)
|
||||
{
|
||||
UnivDoSetLabel(str);
|
||||
}
|
||||
|
||||
wxString wxStaticText::DoGetLabel() const
|
||||
wxString wxStaticText::WXGetVisibleLabel() const
|
||||
{
|
||||
return wxControl::GetLabel();
|
||||
}
|
||||
|
@@ -20,176 +20,120 @@
|
||||
#include "wx/app.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/control.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/control.h"
|
||||
#include "wx/scopedptr.h"
|
||||
#include "wx/stattext.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "wx/generic/stattextg.h"
|
||||
|
||||
class LabelTestCase : public CppUnit::TestCase
|
||||
namespace
|
||||
{
|
||||
public:
|
||||
LabelTestCase() { }
|
||||
|
||||
virtual void setUp() wxOVERRIDE;
|
||||
virtual void tearDown() wxOVERRIDE;
|
||||
const char* const ORIGINAL_LABEL = "origin label";
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( LabelTestCase );
|
||||
CPPUNIT_TEST( GetLabel );
|
||||
CPPUNIT_TEST( GetLabelText );
|
||||
CPPUNIT_TEST( Statics );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void GetLabel();
|
||||
void GetLabelText();
|
||||
void Statics();
|
||||
|
||||
wxStaticText *m_st;
|
||||
|
||||
// we cannot test wxControl directly (it's abstract) so we rather test wxCheckBox
|
||||
wxCheckBox *m_cb;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(LabelTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( LabelTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LabelTestCase, "LabelTestCase" );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test initialization
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define ORIGINAL_LABEL "original label"
|
||||
|
||||
void LabelTestCase::setUp()
|
||||
// The actual testing function. It will change the label of the provided
|
||||
// control, which is assumed to be ORIGINAL_LABEL initially.
|
||||
void DoTestLabel(wxControl* c)
|
||||
{
|
||||
m_st = new wxStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL);
|
||||
CHECK( c->GetLabel() == ORIGINAL_LABEL );
|
||||
|
||||
m_cb = new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( ORIGINAL_LABEL, m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( ORIGINAL_LABEL, m_cb->GetLabel() );
|
||||
}
|
||||
|
||||
void LabelTestCase::tearDown()
|
||||
{
|
||||
wxDELETE(m_st);
|
||||
wxDELETE(m_cb);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// the tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define SET_LABEL(str) \
|
||||
m_st->SetLabel(str); \
|
||||
m_cb->SetLabel(str);
|
||||
|
||||
#define SET_LABEL_TEXT(str) \
|
||||
m_st->SetLabelText(str); \
|
||||
m_cb->SetLabelText(str);
|
||||
|
||||
void LabelTestCase::GetLabel()
|
||||
{
|
||||
const wxString testLabelArray[] = {
|
||||
"label without mnemonics and markup",
|
||||
"label with &mnemonic",
|
||||
"label with <span foreground='blue'>some</span> <b>markup</b>",
|
||||
"label with <span foreground='blue'>some</span> <b>markup</b> and &mnemonic",
|
||||
"label with an && (ampersand)",
|
||||
"label with an && (&ersand)",
|
||||
"", // empty label should work too
|
||||
};
|
||||
|
||||
// test calls to SetLabel() and then to GetLabel()
|
||||
|
||||
for ( unsigned int s = 0; s < WXSIZEOF(testLabelArray); s++ )
|
||||
{
|
||||
SET_LABEL(testLabelArray[s]);
|
||||
const wxString& l = testLabelArray[s];
|
||||
|
||||
// GetLabel() should always return the string passed to SetLabel()
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelArray[s], m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelArray[s], m_cb->GetLabel() );
|
||||
}
|
||||
c->SetLabel(l);
|
||||
CHECK( c->GetLabel() == l );
|
||||
|
||||
|
||||
// test calls to SetLabelText() and then to GetLabel()
|
||||
|
||||
const wxString& testLabel = "label without mnemonics and markup";
|
||||
SET_LABEL_TEXT(testLabel);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel, m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel, m_cb->GetLabel() );
|
||||
|
||||
const wxString& testLabel2 = "label with &mnemonic";
|
||||
const wxString& testLabelText2 = "label with &&mnemonic";
|
||||
SET_LABEL_TEXT(testLabel2);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText2, m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText2, m_cb->GetLabel() );
|
||||
|
||||
const wxString& testLabel3 = "label with <span foreground='blue'>some</span> <b>markup</b>";
|
||||
SET_LABEL_TEXT(testLabel3);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel3, m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel3, m_cb->GetLabel() );
|
||||
|
||||
const wxString& testLabel4 = "label with <span foreground='blue'>some</span> <b>markup</b> and &mnemonic";
|
||||
const wxString& testLabelText4 = "label with <span foreground='blue'>some</span> <b>markup</b> and &&mnemonic";
|
||||
SET_LABEL_TEXT(testLabel4);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText4, m_st->GetLabel() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText4, m_cb->GetLabel() );
|
||||
}
|
||||
|
||||
void LabelTestCase::GetLabelText()
|
||||
{
|
||||
// test calls to SetLabel() and then to GetLabelText()
|
||||
|
||||
const wxString& testLabel = "label without mnemonics and markup";
|
||||
SET_LABEL(testLabel);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel, m_st->GetLabelText() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel, m_cb->GetLabelText() );
|
||||
|
||||
const wxString& testLabel2 = "label with &mnemonic";
|
||||
const wxString& testLabelText2 = "label with mnemonic";
|
||||
SET_LABEL(testLabel2);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText2, m_st->GetLabelText() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText2, m_cb->GetLabelText() );
|
||||
|
||||
const wxString& testLabel3 = "label with <span foreground='blue'>some</span> <b>markup</b>";
|
||||
SET_LABEL(testLabel3);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel3, m_st->GetLabelText() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabel3, m_cb->GetLabelText() );
|
||||
|
||||
const wxString& testLabel4 = "label with <span foreground='blue'>some</span> <b>markup</b> and &mnemonic";
|
||||
const wxString& testLabelText4 = "label with <span foreground='blue'>some</span> <b>markup</b> and mnemonic";
|
||||
SET_LABEL(testLabel4);
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText4, m_st->GetLabelText() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelText4, m_cb->GetLabelText() );
|
||||
|
||||
|
||||
const wxString testLabelArray[] = {
|
||||
"label without mnemonics and markup",
|
||||
"label with &mnemonic",
|
||||
"label with <span foreground='blue'>some</span> <b>markup</b>",
|
||||
"label with <span foreground='blue'>some</span> <b>markup</b> and &mnemonic",
|
||||
};
|
||||
|
||||
// test calls to SetLabelText() and then to GetLabelText()
|
||||
|
||||
for ( unsigned int s = 0; s < WXSIZEOF(testLabelArray); s++ )
|
||||
{
|
||||
SET_LABEL_TEXT(testLabelArray[s]);
|
||||
// GetLabelText() should always return unescaped version of the label
|
||||
CHECK( c->GetLabelText() == wxControl::RemoveMnemonics(l) );
|
||||
|
||||
// GetLabelText() should always return the string passed to SetLabelText()
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelArray[s], m_st->GetLabelText() );
|
||||
CPPUNIT_ASSERT_EQUAL( testLabelArray[s], m_cb->GetLabelText() );
|
||||
c->SetLabelText(l);
|
||||
CHECK( c->GetLabelText() == l );
|
||||
|
||||
// And GetLabel() should be the escaped version of the text
|
||||
CHECK( l == wxControl::RemoveMnemonics(c->GetLabel()) );
|
||||
}
|
||||
|
||||
// Check that both "&" and "&" work in markup.
|
||||
#if wxUSE_MARKUP
|
||||
c->SetLabelMarkup("mnemonic in &markup");
|
||||
CHECK( c->GetLabel() == "mnemonic in &markup" );
|
||||
CHECK( c->GetLabelText() == "mnemonic in markup" );
|
||||
|
||||
c->SetLabelMarkup("mnemonic in &markup");
|
||||
CHECK( c->GetLabel() == "mnemonic in &markup" );
|
||||
CHECK( c->GetLabelText() == "mnemonic in markup" );
|
||||
|
||||
c->SetLabelMarkup("&& finally");
|
||||
CHECK( c->GetLabel() == "&& finally" );
|
||||
CHECK( c->GetLabelText() == "& finally" );
|
||||
|
||||
c->SetLabelMarkup("&& finally");
|
||||
CHECK( c->GetLabel() == "&& finally" );
|
||||
CHECK( c->GetLabelText() == "& finally" );
|
||||
#endif // wxUSE_MARKUP
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_CASE("wxControl::Label", "[wxControl][label]")
|
||||
{
|
||||
SECTION("wxStaticText")
|
||||
{
|
||||
const wxScopedPtr<wxStaticText>
|
||||
st(new wxStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL));
|
||||
DoTestLabel(st.get());
|
||||
}
|
||||
|
||||
SECTION("wxStaticText/ellipsized")
|
||||
{
|
||||
const wxScopedPtr<wxStaticText>
|
||||
st(new wxStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxST_ELLIPSIZE_START));
|
||||
DoTestLabel(st.get());
|
||||
}
|
||||
|
||||
SECTION("wxGenericStaticText")
|
||||
{
|
||||
const wxScopedPtr<wxGenericStaticText>
|
||||
gst(new wxGenericStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL));
|
||||
DoTestLabel(gst.get());
|
||||
}
|
||||
|
||||
SECTION("wxCheckBox")
|
||||
{
|
||||
const wxScopedPtr<wxCheckBox>
|
||||
cb(new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL));
|
||||
DoTestLabel(cb.get());
|
||||
}
|
||||
}
|
||||
|
||||
void LabelTestCase::Statics()
|
||||
TEST_CASE("wxControl::RemoveMnemonics", "[wxControl][label][mnemonics]")
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL( "mnemonic", wxControl::RemoveMnemonics("&mnemonic") );
|
||||
CPPUNIT_ASSERT_EQUAL( "&mnemonic", wxControl::RemoveMnemonics("&&mnemonic") );
|
||||
CPPUNIT_ASSERT_EQUAL( "&mnemonic", wxControl::RemoveMnemonics("&&&mnemonic") );
|
||||
CHECK( "mnemonic" == wxControl::RemoveMnemonics("&mnemonic") );
|
||||
CHECK( "&mnemonic" == wxControl::RemoveMnemonics("&&mnemonic") );
|
||||
CHECK( "&mnemonic" == wxControl::RemoveMnemonics("&&&mnemonic") );
|
||||
}
|
||||
|
||||
TEST_CASE("wxControl::FindAccelIndex", "[wxControl][label][mnemonics]")
|
||||
{
|
||||
CHECK( wxControl::FindAccelIndex("foo") == wxNOT_FOUND );
|
||||
CHECK( wxControl::FindAccelIndex("&foo") == 0 );
|
||||
CHECK( wxControl::FindAccelIndex("f&oo") == 1 );
|
||||
CHECK( wxControl::FindAccelIndex("foo && bar") == wxNOT_FOUND );
|
||||
CHECK( wxControl::FindAccelIndex("foo && &bar") == 6 );
|
||||
}
|
||||
|
@@ -108,6 +108,16 @@ void EllipsizationTestCase::NormalCase()
|
||||
flagsToTest[f]
|
||||
);
|
||||
|
||||
// Note that we must measure the width of the text that
|
||||
// will be rendered, and when mnemonics are used, this
|
||||
// means we have to remove them first.
|
||||
const wxString
|
||||
displayed = flagsToTest[f] & wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS
|
||||
? wxControl::RemoveMnemonics(ret)
|
||||
: ret;
|
||||
const int
|
||||
width = dc.GetMultiLineTextExtent(displayed).GetWidth();
|
||||
|
||||
WX_ASSERT_MESSAGE
|
||||
(
|
||||
(
|
||||
@@ -115,10 +125,10 @@ void EllipsizationTestCase::NormalCase()
|
||||
s, f, m,
|
||||
str,
|
||||
ret,
|
||||
dc.GetMultiLineTextExtent(ret).GetWidth(),
|
||||
width,
|
||||
widthsToTest[w]
|
||||
),
|
||||
dc.GetMultiLineTextExtent(ret).GetWidth() <= widthsToTest[w]
|
||||
width <= widthsToTest[w]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user