void wxMenu::Init(const wxString& title, const wxFunction func )
{
m_title = title;
- m_parent = NULL;
m_eventHandler = this;
m_pInvokingWindow = NULL;
- m_doBreak = FALSE ;
+ m_doBreak = FALSE;
m_noItems = 0;
m_menuBar = NULL;
m_hMenu = (WXHMENU) CreatePopupMenu();
- m_savehMenu = 0 ;
+ m_savehMenu = 0;
m_topLevelMenu = this;
m_clientData = (void*) NULL;
if ( !!m_title )
{
- Append(idMenuTitle, m_title) ;
- AppendSeparator() ;
+ Append(idMenuTitle, m_title);
+ AppendSeparator();
}
Callback(func);
// free Windows resources
if ( m_hMenu )
{
- ::DestroyMenu((HMENU)m_hMenu);
- m_hMenu = 0;
+ if ( !::DestroyMenu(GetHmenu()) )
+ {
+ wxLogLastError("DestroyMenu");
+ }
}
// delete submenus
delete node;
node = next;
}
+
+#if wxUSE_ACCEL
+ // delete accels
+ WX_CLEAR_ARRAY(m_accels);
+#endif // wxUSE_ACCEL
}
void wxMenu::Break()
wxCHECK_RET( pItem != NULL, wxT("can't append NULL item to the menu") );
#if wxUSE_ACCEL
- // check for accelerators: they are given after '\t'
- wxString label = pItem->GetName();
- int posTab = label.Find(wxT('\t'));
- if ( posTab != wxNOT_FOUND ) {
- // parse the accelerator string
- int keyCode = 0;
- int accelFlags = wxACCEL_NORMAL;
- wxString current;
- for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
- if ( (label[n] == '+') || (label[n] == '-') ) {
- if ( current == _("ctrl") )
- accelFlags |= wxACCEL_CTRL;
- else if ( current == _("alt") )
- accelFlags |= wxACCEL_ALT;
- else if ( current == _("shift") )
- accelFlags |= wxACCEL_SHIFT;
- else {
- wxLogDebug(wxT("Unknown accel modifier: '%s'"),
- current.c_str());
- }
-
- current.Empty();
- }
- else {
- current += wxTolower(label[n]);
- }
- }
-
- if ( current.IsEmpty() ) {
- wxLogDebug(wxT("No accel key found, accel string ignored."));
- }
- else {
- if ( current.Len() == 1 ) {
- // it's a letter
- keyCode = wxToupper(current[0U]);
- }
- else {
- // it should be a function key
- if ( current[0U] == 'f' && isdigit(current[1U]) &&
- (current.Len() == 2 ||
- (current.Len() == 3 && isdigit(current[2U]))) ) {
- int n;
- wxSscanf(current.c_str() + 1, wxT("%d"), &n);
-
- keyCode = VK_F1 + n - 1;
- }
- else {
- wxLogDebug(wxT("Unrecognized accel key '%s', accel "
- "string ignored."), current.c_str());
- }
- }
- }
-
- if ( keyCode ) {
- // do add an entry
- m_accelKeyCodes.Add(keyCode);
- m_accelFlags.Add(accelFlags);
- m_accelIds.Add(pItem->GetId());
- }
+ wxAcceleratorEntry *accel = wxGetAccelFromString(pItem->GetText());
+ if ( accel ) {
+ m_accels.Add(accel);
+ accel->m_command = pItem->GetId();
}
#endif // wxUSE_ACCEL
id = (UINT)submenu->GetHMenu();
submenu->m_topLevelMenu = m_topLevelMenu;
- submenu->m_parent = this;
submenu->m_savehMenu = (WXHMENU)id;
submenu->m_hMenu = 0;
{
// menu is just a normal string (passed in data parameter)
flags |= MF_STRING;
- pData = label;
+
+ pData = (char*)pItem->GetText().c_str();
}
if ( !::AppendMenu(GetHmenu(), flags, id, pData) )
RemoveMenu(menu, (UINT)pos, MF_BYPOSITION);
pSubMenu->m_hMenu = pSubMenu->m_savehMenu;
pSubMenu->m_savehMenu = 0;
- pSubMenu->m_parent = NULL;
// RemoveChild(item->subMenu);
pSubMenu->m_topLevelMenu = NULL;
// TODO: Why isn't subMenu deleted here???
size_t count = GetAccelCount();
for ( size_t n = 0; n < count; n++ )
{
- (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]);
+ *accels++ = *m_accels[n];
}
return count;
void wxMenu::SetLabel(int id, const wxString& label)
{
- wxMenuItem *item = FindItemForId(id) ;
+ wxMenuItem *item = FindItemForId(id);
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
- item->SetName(label);
+ item->SetText(label);
}
wxString wxMenu::GetLabel(int id) const
{
wxString label;
- wxMenuItem *pItem = FindItemForId(id) ;
+ wxMenuItem *pItem = FindItemForId(id);
if (pItem)
- label = pItem->GetName() ;
+ label = pItem->GetText();
else
wxFAIL_MSG(wxT("wxMenu::GetLabel: item doesn't exist"));
}
else if ( !item->IsSeparator() )
{
- wxString label = wxStripMenuCodes(item->GetName());
+ wxString label = wxStripMenuCodes(item->GetText());
if ( itemLabel == label )
return item->GetId();
}
{
wxASSERT_MSG( m_menuBar, wxT("can't detach menu if it's not attached") );
+ m_menuBar = NULL;
m_hMenu = m_savehMenu;
m_savehMenu = 0;
}
void wxMenuBar::Init()
{
m_eventHandler = this;
- m_menuCount = 0;
- m_menus = NULL;
- m_titles = NULL;
m_menuBarFrame = NULL;
m_hMenu = 0;
}
{
Init();
- m_menuCount = count;
- m_menus = menus;
- m_titles = new wxString[count];
+ m_titles.Alloc(count);
- int i;
- for ( i = 0; i < count; i++ )
- m_titles[i] = titles[i];
+ for ( int i = 0; i < count; i++ )
+ {
+ m_menus.Append(menus[i]);
+ m_titles.Add(titles[i]);
- for ( i = 0; i < count; i++ )
- m_menus[i]->Attach(this);
+ menus[i]->Attach(this);
+ }
}
wxMenuBar::~wxMenuBar()
{
- for ( int i = 0; i < m_menuCount; i++ )
- {
- delete m_menus[i];
- }
-
- delete[] m_menus;
- delete[] m_titles;
}
// ---------------------------------------------------------------------------
void wxMenuBar::Refresh()
{
- wxCHECK_RET( m_menuBarFrame, wxT("can't refresh a menubar withotu a frame") );
+ wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
- DrawMenuBar((HWND)m_menuBarFrame->GetHWND()) ;
+ DrawMenuBar(GetHwndOf(m_menuBarFrame));
}
WXHMENU wxMenuBar::Create()
}
else
{
- for ( int i = 0; i < m_menuCount; i++ )
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; i < count; i++ )
{
if ( !::AppendMenu((HMENU)m_hMenu, MF_POPUP | MF_STRING,
(UINT)m_menus[i]->GetHMenu(),
}
// ---------------------------------------------------------------------------
-// wxMenuBar functions forwarded to wxMenuItem
+// wxMenuBar functions to work with the top level submenus
// ---------------------------------------------------------------------------
-// Must only be used AFTER menu has been attached to frame,
-// otherwise use individual menus to enable/disable items
-void wxMenuBar::Enable(int id, bool enable)
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_RET( item, wxT("attempt to enable an item which doesn't exist") );
-
- item->Enable(enable);
-}
+// NB: we don't support owner drawn top level items for now, if we do these
+// functions would have to be changed to use wxMenuItem as well
-void wxMenuBar::EnableTop(int pos, bool enable)
+void wxMenuBar::EnableTop(size_t pos, bool enable)
{
int flag = enable ? MF_ENABLED : MF_GRAYED;;
EnableMenuItem((HMENU)m_hMenu, pos, MF_BYPOSITION | flag);
-}
-// Must only be used AFTER menu has been attached to frame,
-// otherwise use individual menus
-void wxMenuBar::Check(int id, bool check)
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_RET( item, wxT("attempt to check an item which doesn't exist") );
- wxCHECK_RET( item->IsCheckable(), wxT("attempt to check an uncheckable item") );
-
- item->Check(check);
-}
-
-bool wxMenuBar::IsChecked(int id) const
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_MSG( item, FALSE, wxT("wxMenuBar::IsChecked(): no such item") );
-
- int flag = ::GetMenuState(GetHmenuOf(itemMenu), id, MF_BYCOMMAND);
-
- return (flag & MF_CHECKED) != 0;
-}
-
-bool wxMenuBar::IsEnabled(int id) const
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_MSG( item, FALSE, wxT("wxMenuBar::IsEnabled(): no such item") );
-
- int flag = ::GetMenuState(GetHmenuOf(itemMenu), id, MF_BYCOMMAND) ;
-
- // don't "and" with MF_ENABLED because its value is 0
- return (flag & MF_DISABLED) == 0;
-}
-
-void wxMenuBar::SetLabel(int id, const wxString& label)
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_RET( item, wxT("wxMenuBar::SetLabel(): no such item") );
-
- item->SetName(label);
-}
-
-wxString wxMenuBar::GetLabel(int id) const
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_MSG( item, wxT(""), wxT("wxMenuBar::GetLabel(): no such item") );
-
- return item->GetName();
-}
-
-void wxMenuBar::SetHelpString (int id, const wxString& helpString)
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_RET( item, wxT("wxMenuBar::SetHelpString(): no such item") );
-
- item->SetHelp(helpString);
+ Refresh();
}
-wxString wxMenuBar::GetHelpString (int id) const
-{
- wxMenu *itemMenu = NULL;
- wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-
- wxCHECK_MSG( item, wxT(""), wxT("wxMenuBar::GetHelpString(): no such item") );
-
- return item->GetHelp();
-}
-
-// ---------------------------------------------------------------------------
-// wxMenuBar functions to work with the top level submenus
-// ---------------------------------------------------------------------------
-
-// NB: we don't support owner drawn top level items for now, if we do these
-// functions would have to be changed to use wxMenuItem as well
-
-void wxMenuBar::SetLabelTop(int pos, const wxString& label)
+void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
{
UINT id;
UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION);
if ( flagsOld & MF_POPUP )
{
// HIBYTE contains the number of items in the submenu in this case
- flagsOld &= 0xff ;
- id = (UINT)::GetSubMenu((HMENU)m_hMenu, pos) ;
+ flagsOld &= 0xff;
+ id = (UINT)::GetSubMenu((HMENU)m_hMenu, pos);
}
else
{
}
}
-wxString wxMenuBar::GetLabelTop(int pos) const
+wxString wxMenuBar::GetLabelTop(size_t pos) const
{
int len = ::GetMenuString((HMENU)m_hMenu, pos, NULL, 0, MF_BYCOMMAND);
return label;
}
-// ---------------------------------------------------------------------------
-// wxMenuBar notifications
-// ---------------------------------------------------------------------------
-
-bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos)
-{
- if ( !m_menuBarFrame )
- return TRUE;
-
- if ( ::RemoveMenu((HMENU)m_hMenu, (UINT)pos, MF_BYPOSITION) )
- {
- // VZ: I'm not sure about what's going on here, so I leave an assert
- wxASSERT_MSG( m_menus[pos] == a_menu, wxT("what is this parameter for??") );
-
- a_menu->Detach();
-
- if ( m_menuBarFrame )
- Refresh();
-
- return TRUE;
- }
- else
- {
- wxLogLastError("RemoveMenu");
- }
-
- return FALSE;
-}
-
-bool wxMenuBar::OnAppend(wxMenu *a_menu, const wxChar *title)
-{
- WXHMENU submenu = a_menu->GetHMenu();
- if ( !submenu )
- return FALSE;
-
- if ( !m_menuBarFrame )
- return TRUE;
-
- a_menu->Attach(this);
-
- if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING,
- (UINT)submenu, title) )
- {
- wxLogLastError(wxT("AppendMenu"));
- }
-
- Refresh();
-
- return TRUE;
-}
-
-// ---------------------------------------------------------------------------
-// wxMenuBar construction
-// ---------------------------------------------------------------------------
int wxMenuBar::FindMenu(const wxString& title)
{
wxString menuTitle = wxStripMenuCodes(title);
- for ( int i = 0; i < m_menuCount; i++ )
+
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; i < count; i++ )
{
wxString title = wxStripMenuCodes(m_titles[i]);
if ( menuTitle == title )
}
+// ---------------------------------------------------------------------------
+// wxMenuBar construction
+// ---------------------------------------------------------------------------
-void wxMenuBar::ReplaceMenu(int pos, wxMenu * new_menu, const wxString& title)
+wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
{
- if (m_menuBarFrame) return;
+ wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
+ if ( !menuOld )
+ return FALSE;
+ m_titles[pos] = title;
- if ( pos >= 0 && pos < m_menuCount )
+ if ( IsAttached() )
{
- wxMenu *old_menu = m_menus[pos];
- m_menus[pos] = new_menu;
- delete old_menu;
+ // can't use ModifyMenu() because it deletes the submenu it replaces
+ if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) )
+ {
+ wxLogLastError("RemoveMenu");
+ }
+
+ if ( !::InsertMenu(GetHmenu(), (UINT)pos,
+ MF_BYPOSITION | MF_POPUP | MF_STRING,
+ (UINT)GetHmenuOf(menu), title) )
+ {
+ wxLogLastError("InsertMenu");
+ }
+
+ Refresh();
}
+ return menuOld;
}
-
-void wxMenuBar::Insert(int pos, wxMenu * menu, const wxString& title)
+bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
{
- if (m_menuBarFrame) return;
- if ( pos < 0 && pos >= m_menuCount ) return;
-
- m_menuCount ++;
- wxMenu **new_menus = new wxMenu *[m_menuCount];
- wxString *new_titles = new wxString[m_menuCount];
- int i;
+ if ( !wxMenuBarBase::Insert(pos, menu, title) )
+ return FALSE;
- for (i = 0; i < pos; i++)
- {
- new_menus[i] = m_menus[i];
- m_menus[i] = NULL;
- new_titles[i] = m_titles[i];
- m_titles[i] = wxT("");
- }
+ m_titles.Insert(title, pos);
- new_menus[pos] = (wxMenu *)menu;
- new_titles[i] = title;
+ menu->Attach(this);
- for (i = pos+1; i < m_menuCount; i++)
- {
- new_menus[i] = m_menus[i-1];
- m_menus[i-1] = NULL;
- new_titles[i] = m_titles[i-1];
- m_titles[i-1] = wxT("");
- }
- if (m_menus)
+ if ( IsAttached() )
{
- delete[]m_menus;
- delete[]m_titles;
- }
- m_menus = new_menus;
- m_titles = new_titles;
+ if ( !::InsertMenu(GetHmenu(), pos,
+ MF_BYPOSITION | MF_POPUP | MF_STRING,
+ (UINT)GetHmenuOf(menu), title) )
+ {
+ wxLogLastError("InsertMenu");
+ }
- menu->SetParent(this);
+ Refresh();
+ }
+ return TRUE;
}
-
-void wxMenuBar::Append (wxMenu * menu, const wxString& title)
+bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
{
- if (!OnAppend(menu, title))
- return;
+ WXHMENU submenu = menu ? menu->GetHMenu() : 0;
+ wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") );
- m_menuCount ++;
- wxMenu **new_menus = new wxMenu *[m_menuCount];
- wxString *new_titles = new wxString[m_menuCount];
- int i;
+ menu->Attach(this);
- for (i = 0; i < m_menuCount - 1; i++)
- {
- new_menus[i] = m_menus[i];
- m_menus[i] = NULL;
- new_titles[i] = m_titles[i];
- m_titles[i] = wxT("");
- }
- if (m_menus)
+ if ( IsAttached() )
{
- delete[]m_menus;
- delete[]m_titles;
+ if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING,
+ (UINT)submenu, title) )
+ {
+ wxLogLastError(wxT("AppendMenu"));
+ }
+
+ Refresh();
}
- m_menus = new_menus;
- m_titles = new_titles;
- m_menus[m_menuCount - 1] = (wxMenu *)menu;
- m_titles[m_menuCount - 1] = title;
+ wxMenuBarBase::Append(menu, title);
+
+ m_titles.Add(title);
- menu->SetParent(this);
+ return TRUE;
}
-void wxMenuBar::Delete(wxMenu * menu, int i)
+wxMenu *wxMenuBar::Remove(size_t pos)
{
- int j;
- int ii = (int) i;
+ wxMenu *menu = wxMenuBarBase::Remove(pos);
+ if ( !menu )
+ return NULL;
- if (menu != 0) {
- for (ii = 0; ii < m_menuCount; ii++) {
- if (m_menus[ii] == menu)
- break;
+ if ( IsAttached() )
+ {
+ if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) )
+ {
+ wxLogLastError("RemoveMenu");
}
- if (ii >= m_menuCount)
- return;
- } else {
- if (ii < 0 || ii >= m_menuCount)
- return;
- menu = m_menus[ii];
- }
- if (!OnDelete(menu, ii))
- return;
+ menu->Detach();
- menu->SetParent(NULL);
-
- -- m_menuCount;
- for (j = ii; j < m_menuCount; j++) {
- m_menus[j] = m_menus[j + 1];
- m_titles[j] = m_titles[j + 1];
+ Refresh();
}
+
+ m_titles.Remove(pos);
+
+ return menu;
}
void wxMenuBar::Attach(wxFrame *frame)
{
- wxASSERT_MSG( !m_menuBarFrame, wxT("menubar already attached!") );
+ wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
m_menuBarFrame = frame;
// create the accel table - we consider that the menubar construction is
// finished
size_t nAccelCount = 0;
- int i;
- for ( i = 0; i < m_menuCount; i++ )
+ size_t i, count = GetMenuCount();
+ for ( i = 0; i < count; i++ )
{
nAccelCount += m_menus[i]->GetAccelCount();
}
wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount];
nAccelCount = 0;
- for ( i = 0; i < m_menuCount; i++ )
+ for ( i = 0; i < count; i++ )
{
nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]);
}
const wxString& itemString) const
{
wxString menuLabel = wxStripMenuCodes(menuString);
- for ( int i = 0; i < m_menuCount; i++ )
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; i < count; i++ )
{
wxString title = wxStripMenuCodes(m_titles[i]);
if ( menuString == title )
return wxNOT_FOUND;
}
-wxMenuItem *wxMenuBar::FindItemForId (int id, wxMenu **itemMenu) const
+wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
{
if ( itemMenu )
*itemMenu = NULL;
wxMenuItem *item = NULL;
- for ( int i = 0; !item && (i < m_menuCount); i++ )
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; !item && (i < count); i++ )
{
item = m_menus[i]->FindItemForId(id, itemMenu);
}