#include "wx/menu.h"
#endif
+#include "wx/stockitem.h"
+
// ----------------------------------------------------------------------------
// template lists
// ----------------------------------------------------------------------------
// ============================================================================
// ----------------------------------------------------------------------------
-// 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)
+/* static */
+bool
+wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)
{
+ // the parser won't like trailing spaces
+ wxString label = text;
+ label.Trim(true); // the initial \t must be preserved so don't strip leading whitespaces
+
// 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);
+ if ( flagsOut )
+ *flagsOut = accelFlags;
+ if ( keyOut )
+ *keyOut = keyCode;
+
+ return true;
}
-wxAcceleratorEntry *wxMenuItemBase::GetAccel() const
+/* static */
+wxAcceleratorEntry *wxAcceleratorEntry::Create(const wxString& str)
{
- return wxGetAccelFromString(GetText());
+ int flags,
+ keyCode;
+ if ( !ParseAccel(str, &flags, &keyCode) )
+ return NULL;
+
+ return new wxAcceleratorEntry(flags, keyCode);
}
-void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
+bool wxAcceleratorEntry::FromString(const wxString& str)
{
- wxString text = m_text.BeforeFirst(wxT('\t'));
- if ( accel )
- {
- text += wxT('\t');
+ return ParseAccel(str, &m_flags, &m_keyCode);
+}
- 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
+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 ( 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++ )
{
- size_t n;
- for ( n = 0; n < WXSIZEOF(wxKeyNames); n++ )
+ const wxKeyName& kn = wxKeyNames[n];
+ if ( code == kn.code )
{
- const wxKeyName& kn = wxKeyNames[n];
- if ( code == kn.code )
- {
- text << wxGetTranslation(kn.name);
- break;
- }
+ text << wxGetTranslation(kn.name);
+ break;
}
+ }
- wxASSERT_MSG( n != WXSIZEOF(wxKeyNames),
- wxT("unknown keyboard accelerator code") );
+ if ( n == WXSIZEOF(wxKeyNames) )
+ {
+ // must be a simple key
+ if (
+#if !wxUSE_UNICODE
+ isascii(code) &&
+#endif // ANSI
+ wxIsalnum(code) )
+ {
+ text << (wxChar)code;
+ }
+ else
+ {
+ wxFAIL_MSG( wxT("unknown keyboard accelerator code") );
+ }
}
}
+ return text;
+}
+
+wxAcceleratorEntry *wxGetAccelFromString(const wxString& label)
+{
+ return wxAcceleratorEntry::Create(label);
+}
+
+#endif // wxUSE_ACCEL
+
+
+// ----------------------------------------------------------------------------
+// wxMenuItem
+// ----------------------------------------------------------------------------
+
+wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
+ int id,
+ const wxString& text,
+ const wxString& help,
+ wxItemKind kind,
+ wxMenu *subMenu)
+{
+ 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;
+
+ SetText(text);
+ SetHelp(help);
+}
+
+wxMenuItemBase::~wxMenuItemBase()
+{
+ delete m_subMenu;
+}
+
+#if wxUSE_ACCEL
+
+wxAcceleratorEntry *wxMenuItemBase::GetAccel() const
+{
+ return wxAcceleratorEntry::Create(GetText());
+}
+
+void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
+{
+ wxString text = m_text.BeforeFirst(wxT('\t'));
+ if ( accel )
+ {
+ text += wxT('\t');
+ text += accel->ToString();
+ }
+
SetText(text);
}
#endif // wxUSE_ACCEL
+void wxMenuItemBase::SetText(const wxString& str)
+{
+ m_text = str;
+
+ if ( m_text.empty() && !IsSeparator() )
+ {
+ wxASSERT_MSG( wxIsStockID(GetId()),
+ wxT("A non-stock menu item with an empty label?") );
+ m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR |
+ wxSTOCK_WITH_MNEMONIC);
+ }
+}
+
+void wxMenuItemBase::SetHelp(const wxString& str)
+{
+ m_help = str;
+
+ if ( m_help.empty() && !IsSeparator() && wxIsStockID(GetId()) )
+ {
+ // get a stock help string
+ m_help = wxGetStockHelpString(GetId());
+ }
+}
+
bool wxMenuBase::ms_locked = true;
// ----------------------------------------------------------------------------