\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.
\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
\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
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.}
wxID_HELP_CONTEXT,
wxID_CLOSE_ALL,
- wxID_CUT = 5030,
+ wxID_EDIT = 5030,
+ wxID_CUT,
wxID_COPY,
wxID_PASTE,
wxID_CLEAR,
wxID_VIEW_SORTSIZE,
wxID_VIEW_SORTTYPE,
- wxID_FILE1 = 5050,
+ wxID_FILE = 5050,
+ wxID_FILE1,
wxID_FILE2,
wxID_FILE3,
wxID_FILE4,
(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"}
\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"}
\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"}
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 <flags>-<keycode> format
+ // where <flags> 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
wxID_CLOSE_ALL,
wxID_PREFERENCES,
- wxID_CUT = 5030,
+ wxID_EDIT = 5030,
+ wxID_CUT,
wxID_COPY,
wxID_PASTE,
wxID_CLEAR,
wxID_VIEW_SORTSIZE,
wxID_VIEW_SORTTYPE,
- wxID_FILE1 = 5050,
+ wxID_FILE = 5050,
+ wxID_FILE1,
wxID_FILE2,
wxID_FILE3,
wxID_FILE4,
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,
// 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)
{
// 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)
{
// 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)
{
#include "wx/defs.h"
#include "wx/wxchar.h"
#include "wx/string.h"
+#include "wx/accel.h"
// ----------------------------------------------------------------------------
// Helper functions for stock items handling:
// 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 <gdk/gdktypes.h>
+
// 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_
#if wxUSE_ACCEL
class WXDLLEXPORT wxAcceleratorEntry;
-WXDLLEXPORT wxAcceleratorEntry *wxGetAccelFromString(const wxString& label);
+wxDEPRECATED(
+ WXDLLEXPORT wxAcceleratorEntry *wxGetAccelFromString(const wxString& label)
+);
#endif // wxUSE_ACCEL
// ----------------------------------------------------------------------------
// MyFrame
// ----------------------------------------------------------------------------
+#include <wx/gtk/private.h>
+
// Define my frame constructor
MyFrame::MyFrame()
: wxFrame((wxFrame *)NULL, wxID_ANY, _T("wxWidgets menu sample"))
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
{
if (pChild->GetMenuBar() == NULL)
return;
-
+
// Do we need to save the current bar?
if (m_pMyMenuBar == NULL)
m_pMyMenuBar = GetMenuBar();
{
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
// ============================================================================
// ----------------------------------------------------------------------------
-// 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
//
// 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) )
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;
{
case 0:
wxLogDebug(wxT("No accel key found, accel string ignored."));
- return NULL;
+ return false;
case 1:
// it's just a letter
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++ )
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());
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);
{
switch (id)
{
+ case wxID_ABOUT:
case wxID_ADD:
case wxID_APPLY:
case wxID_BOLD:
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:
case wxID_REVERT_TO_SAVED:
case wxID_SAVE:
case wxID_SAVEAS:
+ case wxID_SELECTALL:
case wxID_STOP:
case wxID_UNDELETE:
case wxID_UNDERLINE:
}
}
-wxString wxGetStockLabel(wxWindowID id, bool withCodes, const wxString& accelerator)
+wxString wxGetStockLabel(wxWindowID id, long flags)
{
wxString stockLabel;
switch (id)
{
+ STOCKITEM(wxID_ABOUT, _("&About"))
STOCKITEM(wxID_ADD, _("Add"))
STOCKITEM(wxID_APPLY, _("&Apply"))
STOCKITEM(wxID_BOLD, _("&Bold"))
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"))
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"))
#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())
#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)
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)
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)
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__
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);
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)
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')) )
{
{
// "&" 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() );
}
{
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 ) );
{
// 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
{
}
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() )
{
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)
#include "wx/wxprec.h"
#include "wx/menu.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/intl.h"
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);
#include "wx/wxprec.h"
#include "wx/menuitem.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
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 ;
}
#include "wx/wxprec.h"
#include "wx/menuitem.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
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 ;
}
#include "wx/wxprec.h"
#include "wx/menuitem.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/utils.h"
(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,
(XtCallbackProc) wxMenuItemDisarmCallback,
(XtPointer) this);
}
- else if (GetId() == wxID_SEPARATOR)
+ else if (IsSeparator())
{
m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
xmSeparatorGadgetClass, (Widget) menu,
#if wxUSE_MENUS
#include "wx/menuitem.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/font.h"
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;
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
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;
#include "wx/wxprec.h"
#include "wx/menuitem.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/font.h"
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);
// 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;
#if wxUSE_MENUS
#include "wx/menu.h"
+#include "wx/stockitem.h"
#ifndef WX_PRECOMP
#include "wx/dynarray.h"
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);