From: Robert Roebling Date: Sun, 3 Sep 2006 12:23:04 +0000 (+0000) Subject: Commited FRM's stockitem patch (empty stock items). X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ee0a94cfc2f71e8b770eedda5197a1f4bd62b5cb Commited FRM's stockitem patch (empty stock items). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40978 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/menu.tex b/docs/latex/wx/menu.tex index fed7774d60..dcec1b5257 100644 --- a/docs/latex/wx/menu.tex +++ b/docs/latex/wx/menu.tex @@ -127,7 +127,7 @@ and recreation of internal data structures. \membersection{wxMenu::Append}\label{wxmenuappend} -\func{wxMenuItem*}{Append}{\param{int}{ id}, \param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp +\func{wxMenuItem*}{Append}{\param{int}{ id}, \param{const wxString\& }{ item = ""}, \param{const wxString\& }{helpString = ""},\rtfsp \param{wxItemKind}{ kind = wxITEM\_NORMAL}} Adds a string item to the end of the menu. @@ -475,7 +475,7 @@ menubar. \func{wxMenuItem*}{Insert}{\param{size\_t }{pos}, \param{wxMenuItem *}{item}} \func{wxMenuItem*}{Insert}{\param{size\_t }{pos}, \param{int}{ id},\rtfsp -\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp +\param{const wxString\& }{ item = ""}, \param{const wxString\& }{helpString = ""},\rtfsp \param{wxItemKind}{ kind = wxITEM\_NORMAL}} Inserts the given {\it item} before the position {\it pos}. Inserting the item @@ -569,7 +569,7 @@ true if the menu item is enabled, false otherwise. \func{wxMenuItem*}{Prepend}{\param{wxMenuItem *}{item}} \func{wxMenuItem*}{Prepend}{\param{int}{ id},\rtfsp -\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp +\param{const wxString\& }{ item = ""}, \param{const wxString\& }{helpString = ""},\rtfsp \param{wxItemKind}{ kind = wxITEM\_NORMAL}} Inserts the given {\it item} at position $0$, i.e. before all the other diff --git a/docs/latex/wx/menuitem.tex b/docs/latex/wx/menuitem.tex index a3e9a9a620..c80fea13a9 100644 --- a/docs/latex/wx/menuitem.tex +++ b/docs/latex/wx/menuitem.tex @@ -42,6 +42,12 @@ only implemented for Windows and GTK+. Constructs a wxMenuItem object. +The preferred way to create standard menu items is to use default value of +\arg{text}. If no text is supplied and \arg{id} is one of standard IDs from +\helpref{this list}{stockitems}, a standard label and a standard accelerator +will be used. In addition to that, the button will be decorated with stock +icons under GTK+ 2. + \wxheading{Parameters} \docparam{parentMenu}{Menu that the menu item belongs to.} diff --git a/docs/latex/wx/stdevtid.tex b/docs/latex/wx/stdevtid.tex index 1ec3eba9d1..5e288682df 100644 --- a/docs/latex/wx/stdevtid.tex +++ b/docs/latex/wx/stdevtid.tex @@ -47,7 +47,8 @@ own constants in this range. wxID_HELP_CONTEXT, wxID_CLOSE_ALL, - wxID_CUT = 5030, + wxID_EDIT = 5030, + wxID_CUT, wxID_COPY, wxID_PASTE, wxID_CLEAR, @@ -68,7 +69,8 @@ own constants in this range. wxID_VIEW_SORTSIZE, wxID_VIEW_SORTTYPE, - wxID_FILE1 = 5050, + wxID_FILE = 5050, + wxID_FILE1, wxID_FILE2, wxID_FILE3, wxID_FILE4, diff --git a/docs/latex/wx/stockitems.tex b/docs/latex/wx/stockitems.tex index 5c1b1f2eba..9c335b8099 100644 --- a/docs/latex/wx/stockitems.tex +++ b/docs/latex/wx/stockitems.tex @@ -4,6 +4,7 @@ Window IDs for which stock buttons are created (see \helpref{wxButton constructor}{wxbuttonctor}): \begin{twocollist}\itemsep=0pt +\twocolitem{wxID\_ABOUT}{"\&About"} \twocolitem{wxID\_ADD}{"Add"} \twocolitem{wxID\_APPLY}{"\&Apply"} \twocolitem{wxID\_BOLD}{"\&Bold"} @@ -13,7 +14,9 @@ Window IDs for which stock buttons are created \twocolitem{wxID\_COPY}{"\&Copy"} \twocolitem{wxID\_CUT}{"Cu\&t"} \twocolitem{wxID\_DELETE}{"\&Delete"} +\twocolitem{wxID\_EDIT}{"\&Edit"} \twocolitem{wxID\_FIND}{"\&Find"} +\twocolitem{wxID\_FILE}{"\&File"} \twocolitem{wxID\_REPLACE}{"Find and rep\&lace"} \twocolitem{wxID\_BACKWARD}{"\&Back"} \twocolitem{wxID\_DOWN}{"\&Down"} @@ -44,6 +47,7 @@ Window IDs for which stock buttons are created \twocolitem{wxID\_REVERT\_TO\_SAVED}{"Revert to Saved"} \twocolitem{wxID\_SAVE}{"\&Save"} \twocolitem{wxID\_SAVEAS}{"Save \&As..."} +\twocolitem{wxID\_SELECTALL}{"Select all"} \twocolitem{wxID\_STOP}{"\&Stop"} \twocolitem{wxID\_UNDELETE}{"Undelete"} \twocolitem{wxID\_UNDERLINE}{"\&Underline"} diff --git a/include/wx/accel.h b/include/wx/accel.h index 8ce5622370..02135de643 100644 --- a/include/wx/accel.h +++ b/include/wx/accel.h @@ -100,6 +100,26 @@ public: bool MatchesEvent(const wxKeyEvent& event) const; #endif + bool IsOk() const + { + return m_flags != 0 && + m_keyCode != 0; + } + + + // string <-> wxAcceleratorEntry conversion + // ---------------------------------------- + + // returns a wxString for the this accelerator. + // this function formats it using the - format + // where maybe a hyphen-separed list of "shift|alt|ctrl" + wxString ToString() const; + + // returns true if the given string correctly initialized this object + // (i.e. if IsOk() returns true after this call) + bool FromString(const wxString &str); + + private: int m_flags; // combination of wxACCEL_XXX constants int m_keyCode; // ASCII or virtual keycode diff --git a/include/wx/defs.h b/include/wx/defs.h index fae61c24ed..ce6b9e9575 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1759,7 +1759,8 @@ enum wxID_CLOSE_ALL, wxID_PREFERENCES, - wxID_CUT = 5030, + wxID_EDIT = 5030, + wxID_CUT, wxID_COPY, wxID_PASTE, wxID_CLEAR, @@ -1780,7 +1781,8 @@ enum wxID_VIEW_SORTSIZE, wxID_VIEW_SORTTYPE, - wxID_FILE1 = 5050, + wxID_FILE = 5050, + wxID_FILE1, wxID_FILE2, wxID_FILE3, wxID_FILE4, diff --git a/include/wx/gtk/menuitem.h b/include/wx/gtk/menuitem.h index e732318285..b6f403e0a2 100644 --- a/include/wx/gtk/menuitem.h +++ b/include/wx/gtk/menuitem.h @@ -48,6 +48,10 @@ public: wxString GetHotKey() const { return m_hotKey; } + // splits given string in the label, doing & => _ translation, which is returned, + // and in the hotkey which is used to set given pointer + static wxString GTKProcessMenuItemLabel(const wxString& str, wxString *hotKey); + // compatibility only, don't use in new code wxMenuItem(wxMenu *parentMenu, int id, diff --git a/include/wx/menu.h b/include/wx/menu.h index f03dc59acb..9967d81d0d 100644 --- a/include/wx/menu.h +++ b/include/wx/menu.h @@ -60,7 +60,7 @@ public: // append any kind of item (normal/check/radio/separator) wxMenuItem* Append(int itemid, - const wxString& text, + const wxString& text = wxEmptyString, const wxString& help = wxEmptyString, wxItemKind kind = wxITEM_NORMAL) { @@ -108,7 +108,7 @@ public: // insert an item before given position wxMenuItem* Insert(size_t pos, int itemid, - const wxString& text, + const wxString& text = wxEmptyString, const wxString& help = wxEmptyString, wxItemKind kind = wxITEM_NORMAL) { @@ -158,7 +158,7 @@ public: // prepend any item to the menu wxMenuItem* Prepend(int itemid, - const wxString& text, + const wxString& text = wxEmptyString, const wxString& help = wxEmptyString, wxItemKind kind = wxITEM_NORMAL) { diff --git a/include/wx/stockitem.h b/include/wx/stockitem.h index 7d2b214297..a7480db878 100644 --- a/include/wx/stockitem.h +++ b/include/wx/stockitem.h @@ -15,6 +15,7 @@ #include "wx/defs.h" #include "wx/wxchar.h" #include "wx/string.h" +#include "wx/accel.h" // ---------------------------------------------------------------------------- // Helper functions for stock items handling: @@ -27,15 +28,34 @@ WXDLLEXPORT bool wxIsStockID(wxWindowID id); // given ID WXDLLEXPORT bool wxIsStockLabel(wxWindowID id, const wxString& label); +enum wxStockLabelQueryFlag +{ + wxSTOCK_NOFLAGS = 0, + + wxSTOCK_WITH_MNEMONIC = 1, + wxSTOCK_WITH_ACCELERATOR = 2 +}; + // Returns label that should be used for given stock UI element (e.g. "&OK" -// for wxSTOCK_OK): +// for wxSTOCK_OK); if wxSTOCK_WITH_MNEMONIC is given, the & character +// is included; if wxSTOCK_WITH_ACCELERATOR is given, the stock accelerator +// for given ID is concatenated to the label using \t as separator WXDLLEXPORT wxString wxGetStockLabel(wxWindowID id, - bool withCodes = true, - const wxString& accelerator = wxEmptyString); + long flags = wxSTOCK_WITH_MNEMONIC); + +// Returns the accelerator that should be used for given stock UI element +// (e.g. "Ctrl+x" for wxSTOCK_EXIT) +WXDLLEXPORT wxAcceleratorEntry wxGetStockAccelerator(wxWindowID id); #ifdef __WXGTK20__ + +#include + // Translates stock ID to GTK+'s stock item string indentifier: WXDLLEXPORT const char *wxGetStockGtkID(wxWindowID id); + +// Returns stock accelerator modifier and key code for the given ID +WXDLLEXPORT bool wxGetStockGtkAccelerator(const char *id, GdkModifierType *mod, guint *key); #endif #endif // _WX_STOCKITEM_H_ diff --git a/include/wx/utils.h b/include/wx/utils.h index 549899ae7c..75426eca32 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -567,7 +567,9 @@ wxDEPRECATED( #if wxUSE_ACCEL class WXDLLEXPORT wxAcceleratorEntry; -WXDLLEXPORT wxAcceleratorEntry *wxGetAccelFromString(const wxString& label); +wxDEPRECATED( + WXDLLEXPORT wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +); #endif // wxUSE_ACCEL // ---------------------------------------------------------------------------- diff --git a/samples/menu/menu.cpp b/samples/menu/menu.cpp index 6d19fa4af4..82a5864d3c 100644 --- a/samples/menu/menu.cpp +++ b/samples/menu/menu.cpp @@ -360,6 +360,8 @@ bool MyApp::OnInit() // MyFrame // ---------------------------------------------------------------------------- +#include + // Define my frame constructor MyFrame::MyFrame() : wxFrame((wxFrame *)NULL, wxID_ANY, _T("wxWidgets menu sample")) @@ -379,56 +381,56 @@ MyFrame::MyFrame() wxMenu *fileMenu = new wxMenu; wxMenu *stockSubMenu = new wxMenu; - stockSubMenu->Append(wxID_ADD, "wxID_ADD"); - stockSubMenu->Append(wxID_APPLY, "wxID_APPLY"); - stockSubMenu->Append(wxID_BOLD, "wxID_BOLD"); - stockSubMenu->Append(wxID_CANCEL, "wxID_CANCEL"); - stockSubMenu->Append(wxID_CLEAR, "wxID_CLEAR"); - stockSubMenu->Append(wxID_CLOSE, "wxID_CLOSE"); - stockSubMenu->Append(wxID_COPY, "wxID_COPY"); - stockSubMenu->Append(wxID_CUT, "wxID_CUT"); - stockSubMenu->Append(wxID_DELETE, "wxID_DELETE"); - stockSubMenu->Append(wxID_FIND, "wxID_FIND"); - stockSubMenu->Append(wxID_REPLACE, "wxID_REPLACE"); - stockSubMenu->Append(wxID_BACKWARD, "wxID_BACKWARD"); - stockSubMenu->Append(wxID_DOWN, "wxID_DOWN"); - stockSubMenu->Append(wxID_FORWARD, "wxID_FORWARD"); - stockSubMenu->Append(wxID_UP, "wxID_UP"); - stockSubMenu->Append(wxID_HELP, "wxID_HELP"); - stockSubMenu->Append(wxID_HOME, "wxID_HOME"); - stockSubMenu->Append(wxID_INDENT, "wxID_INDENT"); - stockSubMenu->Append(wxID_INDEX, "wxID_INDEX"); - stockSubMenu->Append(wxID_ITALIC, "wxID_ITALIC"); - stockSubMenu->Append(wxID_JUSTIFY_CENTER, "wxID_JUSTIFY_CENTER"); - stockSubMenu->Append(wxID_JUSTIFY_FILL, "wxID_JUSTIFY_FILL"); - stockSubMenu->Append(wxID_JUSTIFY_LEFT, "wxID_JUSTIFY_LEFT"); - stockSubMenu->Append(wxID_JUSTIFY_RIGHT, "wxID_JUSTIFY_RIGHT"); - stockSubMenu->Append(wxID_NEW, "wxID_NEW"); - stockSubMenu->Append(wxID_NO, "wxID_NO"); - stockSubMenu->Append(wxID_OK, "wxID_OK"); - stockSubMenu->Append(wxID_OPEN, "wxID_OPEN"); - stockSubMenu->Append(wxID_PASTE, "wxID_PASTE"); - stockSubMenu->Append(wxID_PREFERENCES, "wxID_PREFERENCES"); - stockSubMenu->Append(wxID_PRINT, "wxID_PRINT"); - stockSubMenu->Append(wxID_PREVIEW, "wxID_PREVIEW"); - stockSubMenu->Append(wxID_PROPERTIES, "wxID_PROPERTIES"); - stockSubMenu->Append(wxID_EXIT, "wxID_EXIT"); - stockSubMenu->Append(wxID_REDO, "wxID_REDO"); - stockSubMenu->Append(wxID_REFRESH, "wxID_REFRESH"); - stockSubMenu->Append(wxID_REMOVE, "wxID_REMOVE"); - stockSubMenu->Append(wxID_REVERT_TO_SAVED, "wxID_REVERT_TO_SAVED"); - stockSubMenu->Append(wxID_SAVE, "wxID_SAVE"); - stockSubMenu->Append(wxID_SAVEAS, "wxID_SAVEAS"); - stockSubMenu->Append(wxID_STOP, "wxID_STOP"); - stockSubMenu->Append(wxID_UNDELETE, "wxID_UNDELETE"); - stockSubMenu->Append(wxID_UNDERLINE, "wxID_UNDERLINE"); - stockSubMenu->Append(wxID_UNDO, "wxID_UNDO"); - stockSubMenu->Append(wxID_UNINDENT, "wxID_UNINDENT"); - stockSubMenu->Append(wxID_YES, "wxID_YES"); - stockSubMenu->Append(wxID_ZOOM_100, "wxID_ZOOM_100"); - stockSubMenu->Append(wxID_ZOOM_FIT, "wxID_ZOOM_FIT"); - stockSubMenu->Append(wxID_ZOOM_IN, "wxID_ZOOM_IN"); - stockSubMenu->Append(wxID_ZOOM_OUT, "wxID_ZOOM_OUT"); + stockSubMenu->Append(wxID_ADD); + stockSubMenu->Append(wxID_APPLY); + stockSubMenu->Append(wxID_BOLD); + stockSubMenu->Append(wxID_CANCEL); + stockSubMenu->Append(wxID_CLEAR); + stockSubMenu->Append(wxID_CLOSE); + stockSubMenu->Append(wxID_COPY); + stockSubMenu->Append(wxID_CUT); + stockSubMenu->Append(wxID_DELETE); + stockSubMenu->Append(wxID_FIND); + stockSubMenu->Append(wxID_REPLACE); + stockSubMenu->Append(wxID_BACKWARD); + stockSubMenu->Append(wxID_DOWN); + stockSubMenu->Append(wxID_FORWARD); + stockSubMenu->Append(wxID_UP); + stockSubMenu->Append(wxID_HELP); + stockSubMenu->Append(wxID_HOME); + stockSubMenu->Append(wxID_INDENT); + stockSubMenu->Append(wxID_INDEX); + stockSubMenu->Append(wxID_ITALIC); + stockSubMenu->Append(wxID_JUSTIFY_CENTER); + stockSubMenu->Append(wxID_JUSTIFY_FILL); + stockSubMenu->Append(wxID_JUSTIFY_LEFT); + stockSubMenu->Append(wxID_JUSTIFY_RIGHT); + stockSubMenu->Append(wxID_NEW); + stockSubMenu->Append(wxID_NO); + stockSubMenu->Append(wxID_OK); + stockSubMenu->Append(wxID_OPEN); + stockSubMenu->Append(wxID_PASTE); + stockSubMenu->Append(wxID_PREFERENCES); + stockSubMenu->Append(wxID_PRINT); + stockSubMenu->Append(wxID_PREVIEW); + stockSubMenu->Append(wxID_PROPERTIES); + stockSubMenu->Append(wxID_EXIT); + stockSubMenu->Append(wxID_REDO); + stockSubMenu->Append(wxID_REFRESH); + stockSubMenu->Append(wxID_REMOVE); + stockSubMenu->Append(wxID_REVERT_TO_SAVED); + stockSubMenu->Append(wxID_SAVE); + stockSubMenu->Append(wxID_SAVEAS); + stockSubMenu->Append(wxID_STOP); + stockSubMenu->Append(wxID_UNDELETE); + stockSubMenu->Append(wxID_UNDERLINE); + stockSubMenu->Append(wxID_UNDO); + stockSubMenu->Append(wxID_UNINDENT); + stockSubMenu->Append(wxID_YES); + stockSubMenu->Append(wxID_ZOOM_100); + stockSubMenu->Append(wxID_ZOOM_FIT); + stockSubMenu->Append(wxID_ZOOM_IN); + stockSubMenu->Append(wxID_ZOOM_OUT); fileMenu->AppendSubMenu(stockSubMenu, _T("&Standard items demo")); #if USE_LOG_WINDOW diff --git a/src/aui/tabmdi.cpp b/src/aui/tabmdi.cpp index a995ee8462..71f53429d4 100644 --- a/src/aui/tabmdi.cpp +++ b/src/aui/tabmdi.cpp @@ -161,7 +161,7 @@ void wxTabMDIParentFrame::SetChildMenuBar(wxTabMDIChildFrame* pChild) { if (pChild->GetMenuBar() == NULL) return; - + // Do we need to save the current bar? if (m_pMyMenuBar == NULL) m_pMyMenuBar = GetMenuBar(); @@ -283,7 +283,7 @@ void wxTabMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar) { if (pMenuBar && m_pWindowMenu) { - int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false)); + int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,wxSTOCK_NOFLAGS)); if (pos == wxNOT_FOUND) pMenuBar->Append(m_pWindowMenu, _("&Window")); else diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index bbee944250..09251fcb4d 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -48,36 +48,9 @@ WX_DEFINE_LIST(wxMenuItemList) // ============================================================================ // ---------------------------------------------------------------------------- -// wxMenuItem +// wxAcceleratorEntry // ---------------------------------------------------------------------------- -wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, - int id, - const wxString& text, - const wxString& help, - wxItemKind kind, - wxMenu *subMenu) - : m_text(text), - m_help(help) -{ - wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") ); - - m_parentMenu = parentMenu; - m_subMenu = subMenu; - m_isEnabled = true; - m_isChecked = false; - m_id = id; - m_kind = kind; - if (m_id == wxID_ANY) - m_id = wxNewId(); - if (m_id == wxID_SEPARATOR) - m_kind = wxITEM_SEPARATOR; -} - -wxMenuItemBase::~wxMenuItemBase() -{ - delete m_subMenu; -} #if wxUSE_ACCEL @@ -172,11 +145,11 @@ static inline bool CompareAccelString(const wxString& str, const wxChar *accel) // // first and last parameter specify the valid domain for "number" part static int -IsNumberedAccelKey(const wxString& str, - const wxChar *prefix, - wxKeyCode prefixCode, - unsigned first, - unsigned last) + IsNumberedAccelKey(const wxString& str, + const wxChar *prefix, + wxKeyCode prefixCode, + unsigned first, + unsigned last) { const size_t lenPrefix = wxStrlen(prefix); if ( !CompareAccelString(str.Left(lenPrefix), prefix) ) @@ -197,13 +170,19 @@ IsNumberedAccelKey(const wxString& str, return prefixCode + num - first; } -// return wxAcceleratorEntry for the given menu string or NULL if none -wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +bool wxAcceleratorEntry::FromString(const wxString& text) { + // the parser won't like leading/trailing spaces + wxString label = text.Strip(wxString::both); + + // set to invalid state: + m_flags = 0; + m_keyCode = 0; + // check for accelerators: they are given after '\t' int posTab = label.Find(wxT('\t')); if ( posTab == wxNOT_FOUND ) - return NULL; + return false; // parse the accelerator string int accelFlags = wxACCEL_NORMAL; @@ -252,7 +231,7 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) { case 0: wxLogDebug(wxT("No accel key found, accel string ignored.")); - return NULL; + return false; case 1: // it's just a letter @@ -267,7 +246,7 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) default: keyCode = IsNumberedAccelKey(current, wxTRANSLATE("F"), - WXK_F1, 1, 12); + WXK_F1, 1, 12); if ( !keyCode ) { for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ ) @@ -283,25 +262,116 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_"), - WXK_NUMPAD0, 0, 9); + WXK_NUMPAD0, 0, 9); if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("SPECIAL"), - WXK_SPECIAL1, 1, 20); + WXK_SPECIAL1, 1, 20); if ( !keyCode ) { wxLogDebug(wxT("Unrecognized accel key '%s', accel string ignored."), current.c_str()); - return NULL; + return false; } } wxASSERT_MSG( keyCode, _T("logic error: should have key code here") ); - return new wxAcceleratorEntry(accelFlags, keyCode); + m_flags = accelFlags; + m_keyCode = keyCode; + return true; } +wxString wxAcceleratorEntry::ToString() const +{ + wxString text; + + int flags = GetFlags(); + if ( flags & wxACCEL_ALT ) + text += _("Alt-"); + if ( flags & wxACCEL_CTRL ) + text += _("Ctrl-"); + if ( flags & wxACCEL_SHIFT ) + text += _("Shift-"); + + const int code = GetKeyCode(); + + if ( wxIsalnum(code) ) + text << (wxChar)code; + else if ( code >= WXK_F1 && code <= WXK_F12 ) + text << _("F") << code - WXK_F1 + 1; + else if ( code >= WXK_NUMPAD0 && code <= WXK_NUMPAD9 ) + text << _("KP_") << code - WXK_NUMPAD0; + else if ( code >= WXK_SPECIAL1 && code <= WXK_SPECIAL20 ) + text << _("SPECIAL") << code - WXK_SPECIAL1 + 1; + else // check the named keys + { + size_t n; + for ( n = 0; n < WXSIZEOF(wxKeyNames); n++ ) + { + const wxKeyName& kn = wxKeyNames[n]; + if ( code == kn.code ) + { + text << wxGetTranslation(kn.name); + break; + } + } + + wxASSERT_MSG( n != WXSIZEOF(wxKeyNames), + wxT("unknown keyboard accelerator code") ); + } + + return text; +} + +wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +{ + wxAcceleratorEntry *ret = new wxAcceleratorEntry(); + if (ret->FromString(label)) + return ret; + + wxDELETE(ret); + return NULL; +} + +#endif // wxUSE_ACCEL + + +// ---------------------------------------------------------------------------- +// wxMenuItem +// ---------------------------------------------------------------------------- + +wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, + int id, + const wxString& text, + const wxString& help, + wxItemKind kind, + wxMenu *subMenu) + : m_text(text), + m_help(help) +{ + wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") ); + + m_parentMenu = parentMenu; + m_subMenu = subMenu; + m_isEnabled = true; + m_isChecked = false; + m_id = id; + m_kind = kind; + if (m_id == wxID_ANY) + m_id = wxNewId(); + if (m_id == wxID_SEPARATOR) + m_kind = wxITEM_SEPARATOR; +} + +wxMenuItemBase::~wxMenuItemBase() +{ + delete m_subMenu; +} + +#if wxUSE_ACCEL + wxAcceleratorEntry *wxMenuItemBase::GetAccel() const { return wxGetAccelFromString(GetText()); @@ -313,41 +383,7 @@ void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel) if ( accel ) { text += wxT('\t'); - - int flags = accel->GetFlags(); - if ( flags & wxACCEL_ALT ) - text += _("Alt-"); - if ( flags & wxACCEL_CTRL ) - text += _("Ctrl-"); - if ( flags & wxACCEL_SHIFT ) - text += _("Shift-"); - - const int code = accel->GetKeyCode(); - - if ( wxIsalnum(code) ) - text << (wxChar)code; - else if ( code >= WXK_F1 && code <= WXK_F12 ) - text << _("F") << code - WXK_F1 + 1; - else if ( code >= WXK_NUMPAD0 && code <= WXK_NUMPAD9 ) - text << _("KP_") << code - WXK_NUMPAD0; - else if ( code >= WXK_SPECIAL1 && code <= WXK_SPECIAL20 ) - text << _("SPECIAL") << code - WXK_SPECIAL1 + 1; - else // check the named keys - { - size_t n; - for ( n = 0; n < WXSIZEOF(wxKeyNames); n++ ) - { - const wxKeyName& kn = wxKeyNames[n]; - if ( code == kn.code ) - { - text << wxGetTranslation(kn.name); - break; - } - } - - wxASSERT_MSG( n != WXSIZEOF(wxKeyNames), - wxT("unknown keyboard accelerator code") ); - } + text += accel->ToString(); } SetText(text); diff --git a/src/common/stockitem.cpp b/src/common/stockitem.cpp index 9b2d4e2b1e..bac9c10c1f 100644 --- a/src/common/stockitem.cpp +++ b/src/common/stockitem.cpp @@ -35,6 +35,7 @@ bool wxIsStockID(wxWindowID id) { switch (id) { + case wxID_ABOUT: case wxID_ADD: case wxID_APPLY: case wxID_BOLD: @@ -44,7 +45,9 @@ bool wxIsStockID(wxWindowID id) case wxID_COPY: case wxID_CUT: case wxID_DELETE: + case wxID_EDIT: case wxID_FIND: + case wxID_FILE: case wxID_REPLACE: case wxID_BACKWARD: case wxID_DOWN: @@ -75,6 +78,7 @@ bool wxIsStockID(wxWindowID id) case wxID_REVERT_TO_SAVED: case wxID_SAVE: case wxID_SAVEAS: + case wxID_SELECTALL: case wxID_STOP: case wxID_UNDELETE: case wxID_UNDERLINE: @@ -92,7 +96,7 @@ bool wxIsStockID(wxWindowID id) } } -wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelerator) +wxString wxGetStockLabel(wxWindowID id, long flags) { wxString stockLabel; @@ -103,6 +107,7 @@ wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelera switch (id) { + STOCKITEM(wxID_ABOUT, _("&About")) STOCKITEM(wxID_ADD, _("Add")) STOCKITEM(wxID_APPLY, _("&Apply")) STOCKITEM(wxID_BOLD, _("&Bold")) @@ -112,7 +117,9 @@ wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelera STOCKITEM(wxID_COPY, _("&Copy")) STOCKITEM(wxID_CUT, _("Cu&t")) STOCKITEM(wxID_DELETE, _("&Delete")) + STOCKITEM(wxID_EDIT, _("&Edit")) STOCKITEM(wxID_FIND, _("&Find")) + STOCKITEM(wxID_FILE, _("&File")) STOCKITEM(wxID_REPLACE, _("Rep&lace")) STOCKITEM(wxID_BACKWARD, _("&Back")) STOCKITEM(wxID_DOWN, _("&Down")) @@ -143,6 +150,7 @@ wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelera STOCKITEM(wxID_REVERT_TO_SAVED, _("Revert to Saved")) STOCKITEM(wxID_SAVE, _("&Save")) STOCKITEM(wxID_SAVEAS, _("Save &As...")) + STOCKITEM(wxID_SELECTALL, _("Select all")) STOCKITEM(wxID_STOP, _("&Stop")) STOCKITEM(wxID_UNDELETE, _("Undelete")) STOCKITEM(wxID_UNDERLINE, _("&Underline")) @@ -161,19 +169,57 @@ wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelera #undef STOCKITEM - if(!withCodes) + if(flags & wxSTOCK_WITH_MNEMONIC) { stockLabel = wxStripMenuCodes( stockLabel ); } - else if (!stockLabel.empty() && !accelerator.empty()) + + if (!stockLabel.empty() && (flags & wxSTOCK_WITH_ACCELERATOR)) { stockLabel += _T("\t"); - stockLabel += accelerator; + + wxAcceleratorEntry accel = wxGetStockAccelerator(id); + if (accel.IsOk()) + stockLabel += accel.ToString(); } return stockLabel; } +wxAcceleratorEntry wxGetStockAccelerator(wxWindowID id) +{ + wxAcceleratorEntry ret; + + #define STOCKITEM(stockid, flags, keycode) \ + case stockid: \ + ret.Set(flags, keycode, stockid); \ + break; + + switch (id) + { + STOCKITEM(wxID_COPY, wxACCEL_CTRL,'C') + STOCKITEM(wxID_CUT, wxACCEL_CTRL,'X') + STOCKITEM(wxID_FIND, wxACCEL_CTRL,'F') + STOCKITEM(wxID_REPLACE, wxACCEL_CTRL,'R') + STOCKITEM(wxID_HELP, wxACCEL_CTRL,'H') + STOCKITEM(wxID_NEW, wxACCEL_CTRL,'N') + STOCKITEM(wxID_OPEN, wxACCEL_CTRL,'O') + STOCKITEM(wxID_PASTE, wxACCEL_CTRL,'V') + STOCKITEM(wxID_SAVE, wxACCEL_CTRL,'S') + + default: + // set the wxAcceleratorEntry to return into an invalid state: + // there's no stock accelerator for that. + ret.Set(0, 0, id); + break; + }; + + #undef STOCKITEM + + // always use wxAcceleratorEntry::IsOk on returned value ! + return ret; +} + bool wxIsStockLabel(wxWindowID id, const wxString& label) { if (label.empty()) @@ -212,8 +258,22 @@ const char *wxGetStockGtkID(wxWindowID id) #define STOCKITEM_24(wx,gtk) STOCKITEM_MISSING(wx) #endif + #if GTK_CHECK_VERSION(2,6,0) + #define STOCKITEM_26(wx,gtk) STOCKITEM(wx,gtk) + #else + #define STOCKITEM_26(wx,gtk) STOCKITEM_MISSING(wx) + #endif + + #if GTK_CHECK_VERSION(2,10,0) + #define STOCKITEM_210(wx,gtk) STOCKITEM(wx,gtk) + #else + #define STOCKITEM_210(wx,gtk) STOCKITEM_MISSING(wx) + #endif + + switch (id) { + STOCKITEM_26(wxID_ABOUT, GTK_STOCK_ABOUT) STOCKITEM(wxID_ADD, GTK_STOCK_ADD) STOCKITEM(wxID_APPLY, GTK_STOCK_APPLY) STOCKITEM(wxID_BOLD, GTK_STOCK_BOLD) @@ -223,7 +283,9 @@ const char *wxGetStockGtkID(wxWindowID id) STOCKITEM(wxID_COPY, GTK_STOCK_COPY) STOCKITEM(wxID_CUT, GTK_STOCK_CUT) STOCKITEM(wxID_DELETE, GTK_STOCK_DELETE) + STOCKITEM_26(wxID_EDIT, GTK_STOCK_EDIT) STOCKITEM(wxID_FIND, GTK_STOCK_FIND) + STOCKITEM_26(wxID_FILE, GTK_STOCK_FILE) STOCKITEM(wxID_REPLACE, GTK_STOCK_FIND_AND_REPLACE) STOCKITEM(wxID_BACKWARD, GTK_STOCK_GO_BACK) STOCKITEM(wxID_DOWN, GTK_STOCK_GO_DOWN) @@ -254,6 +316,7 @@ const char *wxGetStockGtkID(wxWindowID id) STOCKITEM(wxID_REVERT_TO_SAVED, GTK_STOCK_REVERT_TO_SAVED) STOCKITEM(wxID_SAVE, GTK_STOCK_SAVE) STOCKITEM(wxID_SAVEAS, GTK_STOCK_SAVE_AS) + STOCKITEM_210(wxID_SELECTALL, GTK_STOCK_SELECT_ALL) STOCKITEM(wxID_STOP, GTK_STOCK_STOP) STOCKITEM(wxID_UNDELETE, GTK_STOCK_UNDELETE) STOCKITEM(wxID_UNDERLINE, GTK_STOCK_UNDERLINE) @@ -275,4 +338,21 @@ const char *wxGetStockGtkID(wxWindowID id) return NULL; } +bool wxGetStockGtkAccelerator(const char *id, GdkModifierType *mod, guint *key) +{ + GtkStockItem stock_item; + if (gtk_stock_lookup (id, &stock_item)) + { + if (key) *key = stock_item.keyval; + if (mod) *mod = stock_item.modifier; + + // some GTK stock items have zero values for the keyval; + // it means that they do not have an accelerator... + if (stock_item.keyval) + return true; + } + + return false; +} + #endif // __WXGTK20__ diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index ff08f83f5a..e38027d8e2 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -733,6 +733,12 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text) void wxMenuItem::SetText( const wxString& str ) { + // cache some data which must be used later + bool isstock = wxIsStockID(GetId()); + const char *stockid = NULL; + if (isstock) + stockid = wxGetStockGtkID(GetId()); + // Some optimization to avoid flicker wxString oldLabel = m_text; oldLabel = wxStripMenuCodes(oldLabel); @@ -744,7 +750,7 @@ void wxMenuItem::SetText( const wxString& str ) DoSetText(str); if (oldLabel == label1 && - oldhotkey == GetHotKey()) // Make sure we can change a hotkey even if the label is unaltered + oldhotkey == GetHotKey()) // Make sure we can change a hotkey even if the label is unaltered return; if (m_menuItem) @@ -755,38 +761,78 @@ void wxMenuItem::SetText( const wxString& str ) else label = GTK_LABEL( GTK_BIN(m_menuItem)->child ); - gtk_label_set_text_with_mnemonic( GTK_LABEL(label), wxGTK_CONV_SYS(m_text) ); + // stock menu items can have empty labels: + wxString text = m_text; + if (text.IsEmpty() && !IsSeparator()) + { + wxASSERT_MSG(isstock, wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(GetId()); + + // need & => _ conversion + text = GTKProcessMenuItemLabel(text, NULL); + } + + gtk_label_set_text_with_mnemonic( GTK_LABEL(label), wxGTK_CONV_SYS(text) ); } + // remove old accelerator from our parent's accelerator group, if present guint accel_key; GdkModifierType accel_mods; - gtk_accelerator_parse( (const char*) oldbuf, &accel_key, &accel_mods); - if (accel_key != 0) + if (oldbuf[(size_t)0] != '\0') { - gtk_widget_remove_accelerator( GTK_WIDGET(m_menuItem), - m_parentMenu->m_accel, - accel_key, - accel_mods ); + gtk_accelerator_parse( (const char*) oldbuf, &accel_key, &accel_mods); + if (accel_key != 0) + { + gtk_widget_remove_accelerator( GTK_WIDGET(m_menuItem), + m_parentMenu->m_accel, + accel_key, + accel_mods ); + } + } + else if (isstock) + { + // if the accelerator was taken from a stock ID, just get it back from GTK+ stock + if (wxGetStockGtkAccelerator(stockid, &accel_mods, &accel_key)) + gtk_widget_remove_accelerator( GTK_WIDGET(m_menuItem), + m_parentMenu->m_accel, + accel_key, + accel_mods ); } + // add new accelerator to our parent's accelerator group wxCharBuffer buf = wxGTK_CONV_SYS( GetGtkHotKey(*this) ); - gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); - if (accel_key != 0) + if (buf[(size_t)0] != '\0') { - gtk_widget_add_accelerator( GTK_WIDGET(m_menuItem), - "activate", - m_parentMenu->m_accel, - accel_key, - accel_mods, - GTK_ACCEL_VISIBLE); + gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); + if (accel_key != 0) + { + gtk_widget_add_accelerator( GTK_WIDGET(m_menuItem), + "activate", + m_parentMenu->m_accel, + accel_key, + accel_mods, + GTK_ACCEL_VISIBLE); + } + } + else if (isstock) + { + // if the accelerator was taken from a stock ID, just get it back from GTK+ stock + if (wxGetStockGtkAccelerator(stockid, &accel_mods, &accel_key)) + gtk_widget_remove_accelerator( GTK_WIDGET(m_menuItem), + m_parentMenu->m_accel, + accel_key, + accel_mods ); } } -// it's valid for this function to be called even if m_menuItem == NULL -void wxMenuItem::DoSetText( const wxString& str ) +// NOTE: this function is different from the similar functions GTKProcessMnemonics() +// implemented in control.cpp and from wxMenuItemBase::GetLabelFromText... +// so there's no real code duplication +wxString wxMenuItem::GTKProcessMenuItemLabel(const wxString& str, wxString *hotKey) { + wxString text; + // '\t' is the deliminator indicating a hot key - m_text.Empty(); const wxChar *pc = str; while ( (*pc != wxT('\0')) && (*pc != wxT('\t')) ) { @@ -794,31 +840,41 @@ void wxMenuItem::DoSetText( const wxString& str ) { // "&" is doubled to indicate "&" instead of accelerator ++pc; - m_text << wxT('&'); + text << wxT('&'); } else if (*pc == wxT('&')) { - m_text << wxT('_'); + text << wxT('_'); } else if ( *pc == wxT('_') ) // escape underscores { - m_text << wxT("__"); + text << wxT("__"); } else { - m_text << *pc; + text << *pc; } ++pc; } - m_hotKey = wxT(""); - - if(*pc == wxT('\t')) + if (hotKey) { - pc++; - m_hotKey = pc; + hotKey->Empty(); + if(*pc == wxT('\t')) + { + pc++; + *hotKey = pc; + } } + return text; +} + +// it's valid for this function to be called even if m_menuItem == NULL +void wxMenuItem::DoSetText( const wxString& str ) +{ + m_text.Empty(); + m_text = GTKProcessMenuItemLabel(str, &m_hotKey); // wxPrintf( wxT("DoSetText(): str %s m_text %s hotkey %s\n"), str.c_str(), m_text.c_str(), m_hotKey.c_str() ); } @@ -935,17 +991,31 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) { GtkWidget *menuItem; - wxString text; + // cache some data used later + wxString text = mitem->GetText(); + int id = mitem->GetId(); + bool isstock = wxIsStockID(id); + const char *stockid = NULL; + if (isstock) + stockid = wxGetStockGtkID(mitem->GetId()); + + // stock menu items can have an empty label + if (text.IsEmpty() && !mitem->IsSeparator()) + { + wxASSERT_MSG(isstock, wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(id); + + // need & => _ conversion + text = wxMenuItem::GTKProcessMenuItemLabel(text, NULL); + } if ( mitem->IsSeparator() ) { menuItem = gtk_separator_menu_item_new(); } else if ( mitem->GetBitmap().Ok() || - (mitem->GetKind() == wxITEM_NORMAL && - wxIsStockID(mitem->GetId())) ) + (mitem->GetKind() == wxITEM_NORMAL && isstock) ) { - text = mitem->GetText(); wxBitmap bitmap(mitem->GetBitmap()); menuItem = gtk_image_menu_item_new_with_mnemonic( wxGTK_CONV_SYS( text ) ); @@ -955,9 +1025,8 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) { // use stock bitmap for this item if available on the assumption // that it never hurts to follow GTK+ conventions more closely - const char *stock = wxGetStockGtkID(mitem->GetId()); - image = stock ? gtk_image_new_from_stock(stock, GTK_ICON_SIZE_MENU) - : NULL; + image = stockid ? gtk_image_new_from_stock(stockid, GTK_ICON_SIZE_MENU) + : NULL; } else // we have a custom bitmap { @@ -989,8 +1058,8 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) } else // a normal item { - // text has "_" instead of "&" after mitem->SetText() so don't use it - text = mitem->GetText() ; + // NB: 'text' variable has "_" instead of "&" after mitem->SetText() + // so don't use it switch ( mitem->GetKind() ) { @@ -1038,15 +1107,29 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) wxCharBuffer buf = wxGTK_CONV_SYS( GetGtkHotKey(*mitem) ); // wxPrintf( wxT("item: %s hotkey %s\n"), mitem->GetText().c_str(), GetGtkHotKey(*mitem).c_str() ); - gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); - if (accel_key != 0) + if (buf[(size_t)0] != '\0') + { + gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); + if (accel_key != 0) + { + gtk_widget_add_accelerator (GTK_WIDGET(menuItem), + "activate", + m_accel, + accel_key, + accel_mods, + GTK_ACCEL_VISIBLE); + } + } + else if (isstock) { - gtk_widget_add_accelerator (GTK_WIDGET(menuItem), - "activate", - m_accel, - accel_key, - accel_mods, - GTK_ACCEL_VISIBLE); + // if the accelerator was taken from a stock ID, just get it back from GTK+ stock + if (wxGetStockGtkAccelerator(stockid, &accel_mods, &accel_key)) + gtk_widget_add_accelerator( GTK_WIDGET(menuItem), + "activate", + m_accel, + accel_key, + accel_mods, + GTK_ACCEL_VISIBLE); } if (pos == -1) diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp index f19e78a481..016f700872 100644 --- a/src/gtk1/menu.cpp +++ b/src/gtk1/menu.cpp @@ -11,6 +11,7 @@ #include "wx/wxprec.h" #include "wx/menu.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/intl.h" @@ -765,8 +766,15 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text) return label; } -void wxMenuItem::SetText( const wxString& str ) +void wxMenuItem::SetText( const wxString& string ) { + wxString str = string; + if (str.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + str = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + // Some optimization to avoid flicker wxString oldLabel = m_text; oldLabel = wxStripMenuCodes(oldLabel); diff --git a/src/mac/carbon/menuitem.cpp b/src/mac/carbon/menuitem.cpp index 7929831fb4..de6298870b 100644 --- a/src/mac/carbon/menuitem.cpp +++ b/src/mac/carbon/menuitem.cpp @@ -12,6 +12,7 @@ #include "wx/wxprec.h" #include "wx/menuitem.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/app.h" @@ -136,8 +137,15 @@ void wxMenuItem::UpdateItemText() if (mhandle == NULL || index == 0) return ; - UMASetMenuItemText( mhandle , index , wxStripMenuCodes(m_text) , wxFont::GetDefaultEncoding() ) ; - wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ; + wxString text = m_text; + if (text.IsEmpty() && !IsSeparator()) + { + wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + + UMASetMenuItemText( mhandle , index , wxStripMenuCodes(text) , wxFont::GetDefaultEncoding() ) ; + wxAcceleratorEntry *entry = wxGetAccelFromString( text ) ; UMASetMenuItemShortcut( mhandle , index , entry ) ; delete entry ; } diff --git a/src/mac/classic/menuitem.cpp b/src/mac/classic/menuitem.cpp index 615f4c0c29..f541a795a2 100644 --- a/src/mac/classic/menuitem.cpp +++ b/src/mac/classic/menuitem.cpp @@ -16,6 +16,7 @@ #include "wx/wxprec.h" #include "wx/menuitem.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/app.h" @@ -150,8 +151,15 @@ void wxMenuItem::UpdateItemText() if( mhandle == NULL || index == 0) return ; - UMASetMenuItemText( mhandle , index , m_text , wxFont::GetDefaultEncoding() ) ; - wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ; + wxString text = m_text; + if (text.IsEmpty() && !IsSeparator()) + { + wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + + UMASetMenuItemText( mhandle , index , text , wxFont::GetDefaultEncoding() ) ; + wxAcceleratorEntry *entry = wxGetAccelFromString( text ) ; UMASetMenuItemShortcut( mhandle , index , entry ) ; delete entry ; } diff --git a/src/motif/menuitem.cpp b/src/motif/menuitem.cpp index 08bf34a5ff..9d096e847f 100644 --- a/src/motif/menuitem.cpp +++ b/src/motif/menuitem.cpp @@ -21,6 +21,7 @@ #include "wx/wxprec.h" #include "wx/menuitem.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/utils.h" @@ -172,9 +173,17 @@ void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, (wxStripMenuCodes(m_text), xmLabelGadgetClass, (Widget) menu, NULL); } - else if (!m_text.empty() && !m_subMenu) + else if (!IsSeparator() && !m_subMenu) { - wxString strName = wxStripMenuCodes(m_text); + wxString txt = m_text; + + if (m_text.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + txt = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + + wxString strName = wxStripMenuCodes(txt); if (IsCheckable()) { m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName, @@ -230,7 +239,7 @@ void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, (XtCallbackProc) wxMenuItemDisarmCallback, (XtPointer) this); } - else if (GetId() == wxID_SEPARATOR) + else if (IsSeparator()) { m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator", xmSeparatorGadgetClass, (Widget) menu, diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 25958f2c6e..5307cd148e 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -27,6 +27,7 @@ #if wxUSE_MENUS #include "wx/menuitem.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/font.h" @@ -153,6 +154,12 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu, void wxMenuItem::Init() { + if (m_text.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + m_radioGroup.start = -1; m_isRadioGroupStart = false; @@ -336,12 +343,20 @@ void wxMenuItem::Check(bool check) wxMenuItemBase::Check(check); } -void wxMenuItem::SetText(const wxString& text) +void wxMenuItem::SetText(const wxString& txt) { + wxString text = txt; + // don't do anything if label didn't change - if ( m_text == text ) + if ( m_text == txt ) return; + if (text.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + wxMenuItemBase::SetText(text); OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) ); #if wxUSE_OWNER_DRAWN diff --git a/src/msw/wince/menuce.cpp b/src/msw/wince/menuce.cpp index 477b00dac1..238e2f0f95 100644 --- a/src/msw/wince/menuce.cpp +++ b/src/msw/wince/menuce.cpp @@ -78,7 +78,7 @@ void wxTopLevelWindowMSW::ButtonMenu::SetButton(int id, const wxString& label, w m_assigned = true; m_id = id; if(label.empty() && wxIsStockID(id)) - m_label = wxGetStockLabel(id, false); + m_label = wxGetStockLabel(id, wxSTOCK_NOFLAGS); else m_label = label; m_menu = subMenu; diff --git a/src/os2/menuitem.cpp b/src/os2/menuitem.cpp index f72deae3e1..055d634f55 100644 --- a/src/os2/menuitem.cpp +++ b/src/os2/menuitem.cpp @@ -17,6 +17,7 @@ #include "wx/wxprec.h" #include "wx/menuitem.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/font.h" @@ -372,10 +373,19 @@ void wxMenuItem::SetText( const wxString& rText ) if (m_text == sText) return; + if (sText.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + sText = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + wxMenuItemBase::SetText(sText); OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(sText)); #if wxUSE_OWNER_DRAWN - SetAccelString(rText.AfterFirst(_T('\t'))); + if (rText.IsEmpty()) + SetAccelString(sText.AfterFirst(_T('\t'))); + else + SetAccelString(rText.AfterFirst(_T('\t'))); #endif // wxUSE_OWNER_DRAWN HWND hMenu = GetHmenuOf(m_parentMenu); diff --git a/src/palmos/button.cpp b/src/palmos/button.cpp index 2e036b19aa..fc794449ad 100644 --- a/src/palmos/button.cpp +++ b/src/palmos/button.cpp @@ -169,7 +169,7 @@ bool wxButton::Create(wxWindow *parent, // take the stock label wxString palmLabel = label; if( palmLabel.empty() && wxIsStockID(id) ) - palmLabel = wxGetStockLabel(id, false); + palmLabel = wxGetStockLabel(id, wxSTOCK_NOFLAGS); if(!wxControl::Create(parent, id, palmPos, palmSize, style, validator, name)) return false; diff --git a/src/univ/menu.cpp b/src/univ/menu.cpp index e25a936355..c3170fa2d9 100644 --- a/src/univ/menu.cpp +++ b/src/univ/menu.cpp @@ -26,6 +26,7 @@ #if wxUSE_MENUS #include "wx/menu.h" +#include "wx/stockitem.h" #ifndef WX_PRECOMP #include "wx/dynarray.h" @@ -1537,10 +1538,17 @@ void wxMenuItem::UpdateAccelInfo() m_strAccel = m_text.AfterFirst(_T('\t')); } -void wxMenuItem::SetText(const wxString& text) +void wxMenuItem::SetText(const wxString& txt) { - if ( text != m_text ) + if ( txt != m_text ) { + wxString text = txt; + if (text.IsEmpty()) + { + wxASSERT_MSG(wxIsStockId(GetId()), wxT("A non-stock menu item with an empty label?")); + text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); + } + // first call the base class version to change m_text wxMenuItemBase::SetText(text);