diff --git a/include/wx/control.h b/include/wx/control.h
index 86563645e0..0e646b2faa 100644
--- a/include/wx/control.h
+++ b/include/wx/control.h
@@ -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.
diff --git a/include/wx/generic/stattextg.h b/include/wx/generic/stattextg.h
index 2a85d99c17..84210423d4 100644
--- a/include/wx/generic/stattextg.h
+++ b/include/wx/generic/stattextg.h
@@ -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;
diff --git a/include/wx/gtk/stattext.h b/include/wx/gtk/stattext.h
index b94f399a50..37f2939c47 100644
--- a/include/wx/gtk/stattext.h
+++ b/include/wx/gtk/stattext.h
@@ -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
diff --git a/include/wx/motif/stattext.h b/include/wx/motif/stattext.h
index e92780cd02..2e6ce08699 100644
--- a/include/wx/motif/stattext.h
+++ b/include/wx/motif/stattext.h
@@ -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:
diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h
index e52248fc84..9c9f0fb227 100644
--- a/include/wx/msw/stattext.h
+++ b/include/wx/msw/stattext.h
@@ -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);
};
diff --git a/include/wx/osx/stattext.h b/include/wx/osx/stattext.h
index 45249da560..87136c1861 100644
--- a/include/wx/osx/stattext.h
+++ b/include/wx/osx/stattext.h
@@ -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;
diff --git a/include/wx/qt/stattext.h b/include/wx/qt/stattext.h
index f427f16490..5a19698191 100644
--- a/include/wx/qt/stattext.h
+++ b/include/wx/qt/stattext.h
@@ -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;
diff --git a/include/wx/stattext.h b/include/wx/stattext.h
index 237f93620e..369ab6dc87 100644
--- a/include/wx/stattext.h
+++ b/include/wx/stattext.h
@@ -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.
diff --git a/include/wx/univ/stattext.h b/include/wx/univ/stattext.h
index 891ad7cf60..54a0284c58 100644
--- a/include/wx/univ/stattext.h
+++ b/include/wx/univ/stattext.h
@@ -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);
};
diff --git a/samples/widgets/static.cpp b/samples/widgets/static.cpp
index 163d500cda..73821d9666 100644
--- a/samples/widgets/static.cpp
+++ b/samples/widgets/static.cpp
@@ -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 decorated "
"with markup; 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(m_chkEllipsize))
- {
- m_radioEllipsize->Enable(event.IsChecked());
- }
+ m_radioEllipsize->Enable(event.IsChecked());
CreateStatic();
}
diff --git a/src/common/ctrlcmn.cpp b/src/common/ctrlcmn.cpp
index cb1c0fcf41..8aabe0bfa7 100644
--- a/src/common/ctrlcmn.cpp
+++ b/src/common/ctrlcmn.cpp
@@ -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,
- wxEllipsizeMode mode, int maxFinalWidthPx,
- int replacementWidthPx)
+wxString DoEllipsizeSingleLine(const wxString& curLine, const wxDC& dc,
+ wxEllipsizeMode mode, int maxFinalWidthPx,
+ 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) )
{
diff --git a/src/common/stattextcmn.cpp b/src/common/stattextcmn.cpp
index 811aceb190..553c607647 100644
--- a/src/common/stattextcmn.cpp
+++ b/src/common/stattextcmn.cpp
@@ -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
diff --git a/src/generic/stattextg.cpp b/src/generic/stattextg.cpp
index fe2f13759c..ce32239065 100644
--- a/src/generic/stattextg.cpp
+++ b/src/generic/stattextg.cpp
@@ -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);
}
diff --git a/src/gtk/stattext.cpp b/src/gtk/stattext.cpp
index 36d87b502c..524b6d97b8 100644
--- a/src/gtk/stattext.cpp
+++ b/src/gtk/stattext.cpp
@@ -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
diff --git a/src/motif/stattext.cpp b/src/motif/stattext.cpp
index 44822abbfe..2fdea861ff 100644
--- a/src/motif/stattext.cpp
+++ b/src/motif/stattext.cpp
@@ -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));
diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp
index f5a29f380e..fd171211a8 100644
--- a/src/msw/stattext.cpp
+++ b/src/msw/stattext.cpp
@@ -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);
}
diff --git a/src/osx/stattext_osx.cpp b/src/osx/stattext_osx.cpp
index 53e0e0ced9..cea4cf5c19 100644
--- a/src/osx/stattext_osx.cpp
+++ b/src/osx/stattext_osx.cpp
@@ -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;
}
diff --git a/src/qt/stattext.cpp b/src/qt/stattext.cpp
index f6d2bcde63..369d15f7e2 100644
--- a/src/qt/stattext.cpp
+++ b/src/qt/stattext.cpp
@@ -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() );
}
diff --git a/src/univ/stattext.cpp b/src/univ/stattext.cpp
index a79338873c..7d25958ad9 100644
--- a/src/univ/stattext.cpp
+++ b/src/univ/stattext.cpp
@@ -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();
}
diff --git a/tests/controls/label.cpp b/tests/controls/label.cpp
index 3ba89c2f7e..94806a8cd7 100644
--- a/tests/controls/label.cpp
+++ b/tests/controls/label.cpp
@@ -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 some markup",
"label with some markup 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 some markup";
- SET_LABEL_TEXT(testLabel3);
- CPPUNIT_ASSERT_EQUAL( testLabel3, m_st->GetLabel() );
- CPPUNIT_ASSERT_EQUAL( testLabel3, m_cb->GetLabel() );
-
- const wxString& testLabel4 = "label with some markup and &mnemonic";
- const wxString& testLabelText4 = "label with some markup 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 some markup";
- SET_LABEL(testLabel3);
- CPPUNIT_ASSERT_EQUAL( testLabel3, m_st->GetLabelText() );
- CPPUNIT_ASSERT_EQUAL( testLabel3, m_cb->GetLabelText() );
-
- const wxString& testLabel4 = "label with some markup and &mnemonic";
- const wxString& testLabelText4 = "label with some markup 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 some markup",
- "label with some markup 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
+ st(new wxStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL));
+ DoTestLabel(st.get());
+ }
+
+ SECTION("wxStaticText/ellipsized")
+ {
+ const wxScopedPtr
+ st(new wxStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL,
+ wxDefaultPosition, wxDefaultSize,
+ wxST_ELLIPSIZE_START));
+ DoTestLabel(st.get());
+ }
+
+ SECTION("wxGenericStaticText")
+ {
+ const wxScopedPtr
+ gst(new wxGenericStaticText(wxTheApp->GetTopWindow(), wxID_ANY, ORIGINAL_LABEL));
+ DoTestLabel(gst.get());
+ }
+
+ SECTION("wxCheckBox")
+ {
+ const wxScopedPtr
+ 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 );
}
diff --git a/tests/graphics/ellipsization.cpp b/tests/graphics/ellipsization.cpp
index 2a584762f2..d7c90242b7 100644
--- a/tests/graphics/ellipsization.cpp
+++ b/tests/graphics/ellipsization.cpp
@@ -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]
);
}
}