X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7c78e7c70271608b076b1dbed201b1204e6898d4..1d3dbc7b63b3a5bcceafd513c165f719b864e3c2:/src/qt/menu.cpp diff --git a/src/qt/menu.cpp b/src/qt/menu.cpp index 739e635d47..217e6c8b88 100644 --- a/src/qt/menu.cpp +++ b/src/qt/menu.cpp @@ -1,293 +1,568 @@ ///////////////////////////////////////////////////////////////////////////// // Name: menu.cpp -// Purpose: -// Author: Robert Roebling -// Created: 01/02/97 -// Id: $Id$ -// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Purpose: wxMenu, wxMenuBar, wxMenuItem +// Author: AUTHOR +// Modified by: +// Created: ??/??/98 +// RCS-ID: $Id$ +// Copyright: (c) AUTHOR +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// headers & declarations +// ============================================================================ + +// wxWindows headers +// ----------------- + #ifdef __GNUG__ #pragma implementation "menu.h" +#pragma implementation "menuitem.h" #endif #include "wx/menu.h" +#include "wx/menuitem.h" #include "wx/log.h" -//----------------------------------------------------------------------------- -// wxMenuBar -//----------------------------------------------------------------------------- +// other standard headers +// ---------------------- +#include + +#if !USE_SHARED_LIBRARY +IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler) +IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler) +#endif -IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow) +// ============================================================================ +// implementation +// ============================================================================ -wxMenuBar::wxMenuBar() +// Menus + +// Construct a menu with optional title (then use append) +wxMenu::wxMenu(const wxString& title, const wxFunction func) { -}; + m_title = title; + m_parent = NULL; + m_eventHandler = this; + m_noItems = 0; + m_menuBar = NULL; + if (m_title != "") + { + Append(-2, m_title) ; + AppendSeparator() ; + } + + Callback(func); + + // TODO create menu +} -void wxMenuBar::Append( wxMenu *menu, const wxString &title ) -{ - m_menus.Append( menu ); - menu->m_title = title; // ?????? +// The wxWindow destructor will take care of deleting the submenus. +wxMenu::~wxMenu() +{ + // TODO destroy menu and children + + wxNode *node = m_menuItems.First(); + while (node) + { + wxMenuItem *item = (wxMenuItem *)node->Data(); + + // Delete child menus. + // Beware: they must not be appended to children list!!! + // (because order of delete is significant) + if (item->GetSubMenu()) + item->DeleteSubMenu(); + + wxNode *next = node->Next(); + delete item; + delete node; + node = next; + } +} - int pos; - do { - pos = menu->m_title.First( '&' ); - if (pos != -1) menu->m_title.Remove( pos, 1 ); - } while (pos != -1); +void wxMenu::Break() +{ + // TODO +} -}; +// function appends a new item or submenu to the menu +void wxMenu::Append(wxMenuItem *pItem) +{ + // TODO -static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString ) + wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" ); + + m_menuItems.Append(pItem); + + m_noItems++; +} + +void wxMenu::AppendSeparator() { - if (menu->m_title == menuString) - { - int res = menu->FindItem( itemString ); - if (res != -1) return res; - }; - wxNode *node = menu->m_items.First(); - while (node) - { - wxMenuItem *item = (wxMenuItem*)node->Data(); - if (item->IsSubMenu()) - return FindMenuItemRecursive(item->GetSubMenu(), menuString, itemString); - node = node->Next(); - }; - return -1; -}; + // TODO + Append(new wxMenuItem(this, ID_SEPARATOR)); +} -int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const +// Pullright item +void wxMenu::Append(int Id, const wxString& label, wxMenu *SubMenu, + const wxString& helpString) { - wxNode *node = m_menus.First(); - while (node) - { - wxMenu *menu = (wxMenu*)node->Data(); - int res = FindMenuItemRecursive( menu, menuString, itemString); - if (res != -1) return res; - node = node->Next(); - }; - return -1; -}; + Append(new wxMenuItem(this, Id, label, helpString, FALSE, SubMenu)); +} -// Find a wxMenuItem using its id. Recurses down into sub-menus -static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id) +// Ordinary menu item +void wxMenu::Append(int Id, const wxString& label, + const wxString& helpString, bool checkable) { - wxMenuItem* result = menu->FindItem(id); + // 'checkable' parameter is useless for Windows. + Append(new wxMenuItem(this, Id, label, helpString, checkable)); +} + +void wxMenu::Delete(int id) +{ + wxNode *node; + wxMenuItem *item; + int pos; + + for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) { + item = (wxMenuItem *)node->Data(); + if (item->GetId() == id) + break; + } - wxNode *node = menu->m_items.First(); - while ( node && result == NULL ) { - wxMenuItem *item = (wxMenuItem*)node->Data(); - if ( item->IsSubMenu() ) - result = FindMenuItemByIdRecursive( item->GetSubMenu(), id ); - node = node->Next(); - }; + if (!node) + return; - return result; -}; + m_menuItems.DeleteNode(node); + delete item; -wxMenuItem* wxMenuBar::FindMenuItemById( int id ) const + // TODO +} + +void wxMenu::Enable(int Id, bool Flag) { - wxMenuItem* result = 0; - wxNode *node = m_menus.First(); - while (node && result == 0) - { - wxMenu *menu = (wxMenu*)node->Data(); - result = FindMenuItemByIdRecursive( menu, id ); - node = node->Next(); - } - return result; + wxMenuItem *item = FindItemForId(Id); + wxCHECK_RET( item != NULL, "can't enable non-existing menu item" ); + + item->Enable(Flag); } -void wxMenuBar::Check( int id, bool check ) +bool wxMenu::Enabled(int Id) const { - wxMenuItem* item = FindMenuItemById( id ); - if (item) item->Check(check); -}; + wxMenuItem *item = FindItemForId(Id); + wxCHECK( item != NULL, FALSE ); + + return item->IsEnabled(); +} -bool wxMenuBar::Checked( int id ) const +void wxMenu::Check(int Id, bool Flag) { - wxMenuItem* item = FindMenuItemById( id ); - if (item) return item->IsChecked(); - return FALSE; -}; + wxMenuItem *item = FindItemForId(Id); + wxCHECK_RET( item != NULL, "can't get status of non-existing menu item" ); -void wxMenuBar::Enable( int id, bool enable ) + item->Check(Flag); +} + +bool wxMenu::Checked(int Id) const { - wxMenuItem* item = FindMenuItemById( id ); - if (item) item->Enable(enable); -}; + wxMenuItem *item = FindItemForId(Id); + wxCHECK( item != NULL, FALSE ); + + return item->IsChecked(); +} -bool wxMenuBar::Enabled( int id ) const +void wxMenu::SetTitle(const wxString& label) { - wxMenuItem* item = FindMenuItemById( id ); - if (item) return item->IsEnabled(); - return FALSE; -}; + m_title = label ; + // TODO +} -//----------------------------------------------------------------------------- -// wxMenu -//----------------------------------------------------------------------------- +const wxString& wxMenu::GetTitle() const +{ + return m_title; +} +void wxMenu::SetLabel(int id, const wxString& label) +{ + wxMenuItem *item = FindItemForId(id) ; + if (item==NULL) + return; + + if (item->GetSubMenu()==NULL) + { + // TODO + } + else + { + // TODO + } + item->SetName(label); +} -IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject) +wxString wxMenu::GetLabel(int Id) const +{ + // TODO + return wxString("") ; +} -wxMenuItem::wxMenuItem() +// Finds the item id matching the given string, -1 if not found. +int wxMenu::FindItem (const wxString& itemString) const { - m_id = ID_SEPARATOR; - m_isCheckMenu = FALSE; - m_isChecked = FALSE; - m_isEnabled = TRUE; - m_subMenu = NULL; -}; + char buf1[200]; + char buf2[200]; + wxStripMenuCodes ((char *)(const char *)itemString, buf1); + + for (wxNode * node = m_menuItems.First (); node; node = node->Next ()) + { + wxMenuItem *item = (wxMenuItem *) node->Data (); + if (item->GetSubMenu()) + { + int ans = item->GetSubMenu()->FindItem(itemString); + if (ans > -1) + return ans; + } + if ( !item->IsSeparator() ) + { + wxStripMenuCodes((char *)item->GetName().c_str(), buf2); + if (strcmp(buf1, buf2) == 0) + return item->GetId(); + } + } + + return -1; +} -void wxMenuItem::SetText(const wxString& str) +wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const { - for ( const char *pc = str; *pc != '\0'; pc++ ) { - if ( *pc == '&' ) - pc++; // skip it + if (itemMenu) + *itemMenu = NULL; + for (wxNode * node = m_menuItems.First (); node; node = node->Next ()) + { + wxMenuItem *item = (wxMenuItem *) node->Data (); + + if (item->GetId() == itemId) + { + if (itemMenu) + *itemMenu = (wxMenu *) this; + return item; + } + + if (item->GetSubMenu()) + { + wxMenuItem *ans = item->GetSubMenu()->FindItemForId (itemId, itemMenu); + if (ans) + return ans; + } + } + + if (itemMenu) + *itemMenu = NULL; + return NULL; +} - m_text << *pc; - } +void wxMenu::SetHelpString(int itemId, const wxString& helpString) +{ + wxMenuItem *item = FindItemForId (itemId); + if (item) + item->SetHelp(helpString); } -void wxMenuItem::Check( bool check ) +wxString wxMenu::GetHelpString (int itemId) const { - wxCHECK_RET( IsCheckable(), "can't check uncheckable item!" ) + wxMenuItem *item = FindItemForId (itemId); + wxString str(""); + return (item == NULL) ? str : item->GetHelp(); +} - m_isChecked = check; +void wxMenu::ProcessCommand(wxCommandEvent & event) +{ + bool processed = FALSE; + + // Try a callback + if (m_callback) + { + (void) (*(m_callback)) (*this, event); + processed = TRUE; + } + + // Try the menu's event handler + if ( !processed && GetEventHandler()) + { + processed = GetEventHandler()->ProcessEvent(event); + } + + // Try the window the menu was popped up from (and up + // through the hierarchy) + if ( !processed && GetInvokingWindow()) + processed = GetInvokingWindow()->ProcessEvent(event); +} + +bool wxWindow::PopupMenu(wxMenu *menu, int x, int y) +{ + // TODO + return FALSE; } -bool wxMenuItem::IsChecked() const +// Menu Bar +wxMenuBar::wxMenuBar() { - wxCHECK( IsCheckable(), FALSE ); // can't get state of uncheckable item! + m_eventHandler = this; + m_menuCount = 0; + m_menus = NULL; + m_titles = NULL; + m_menuBarFrame = NULL; - return FALSE; + // TODO } -IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler) +wxMenuBar::wxMenuBar(int n, wxMenu *Mmnus[], const wxString titles[]) +{ + m_eventHandler = this; + m_menuCount = n; + m_menus = menus; + m_titles = new wxString[n]; + int i; + for ( i = 0; i < n; i++ ) + m_titles[i] = titles[i]; + m_menuBarFrame = NULL; + + // TODO +} -wxMenu::wxMenu( const wxString &title ) +wxMenuBar::~wxMenuBar() { - m_title = title; - m_items.DeleteContents( TRUE ); - m_invokingWindow = NULL; -}; + int i; + for (i = 0; i < m_menuCount; i++) + { + delete m_menus[i]; + } + delete[] m_menus; + delete[] m_titles; + + // TODO +} -void wxMenu::AppendSeparator() +// 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 flag) +{ + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; + if (!item) + return; + + // TODO +} + +void wxMenuBar::EnableTop(int pos, bool flag) +{ + // TODO +} + +// Must only be used AFTER menu has been attached to frame, +// otherwise use individual menus +void wxMenuBar::Check(int id, bool flag) { - wxMenuItem *mitem = new wxMenuItem(); - mitem->SetId(ID_SEPARATOR); + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; + if (!item) + return; - m_items.Append( mitem ); -}; + if (!item->IsCheckable()) + return ; -void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable ) + // TODO +} + +bool wxMenuBar::Checked(int id) const { - wxMenuItem *mitem = new wxMenuItem(); - mitem->SetId(id); - mitem->SetText(item); - mitem->SetHelpString(helpStr); - mitem->SetCheckable(checkable); - - m_items.Append( mitem ); -}; + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; + if (!item) + return FALSE; + + // TODO + return FALSE; +} -void wxMenu::Append( int id, const wxString &text, wxMenu *subMenu, const wxString &helpStr ) +bool wxMenuBar::Enabled(int id) const { - wxMenuItem *mitem = new wxMenuItem(); - mitem->SetId(id); - mitem->SetText(text); - mitem->SetHelpString(helpStr); - mitem->SetSubMenu(subMenu); + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; + if (!item) + return FALSE; + + // TODO + return FALSE ; +} - m_items.Append( mitem ); -}; -int wxMenu::FindItem( const wxString itemString ) const +void wxMenuBar::SetLabel(int id, const wxString& label) { - wxString s( itemString ); + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; + + if (!item) + return; - int pos; - do { - pos = s.First( '&' ); - if (pos != -1) s.Remove( pos, 1 ); - } while (pos != -1); + // TODO +} - wxNode *node = m_items.First(); - while (node) - { - wxMenuItem *item = (wxMenuItem*)node->Data(); - if (item->GetText() == s) - return item->GetId(); - node = node->Next(); - }; +wxString wxMenuBar::GetLabel(int id) const +{ + wxMenu *itemMenu = NULL; + wxMenuItem *item = FindItemForId(id, &itemMenu) ; - return -1; -}; + if (!item) + return wxString(""); -void wxMenu::Enable( int id, bool enable ) + // TODO + return wxString("") ; +} + +void wxMenuBar::SetLabelTop(int pos, const wxString& label) { - wxMenuItem *item = FindItem(id); - if ( item ) - item->Enable(enable); -}; + // TODO +} -bool wxMenu::IsEnabled( int id ) const +wxString wxMenuBar::GetLabelTop(int pos) const { - wxMenuItem *item = FindItem(id); - if ( item ) - return item->IsEnabled(); - else - return FALSE; -}; + // TODO + return wxString(""); +} -void wxMenu::Check( int id, bool enable ) +bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos) { - wxMenuItem *item = FindItem(id); - if ( item ) - item->Check(enable); -}; + // TODO + return FALSE; +} -bool wxMenu::IsChecked( int id ) const +bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title) { - wxMenuItem *item = FindItem(id); - if ( item ) - return item->IsChecked(); - else + // TODO return FALSE; -}; +} -void wxMenu::SetLabel( int id, const wxString &label ) +void wxMenuBar::Append (wxMenu * menu, const wxString& title) { - wxMenuItem *item = FindItem(id); - if ( item ) - item->SetText(label); -}; + if (!OnAppend(menu, title)) + return; + + m_menuCount ++; + wxMenu **new_menus = new wxMenu *[m_menuCount]; + wxString *new_titles = new wxString[m_menuCount]; + int i; + + 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] = ""; + } + if (m_menus) + { + delete[]m_menus; + delete[]m_titles; + } + m_menus = new_menus; + m_titles = new_titles; + + m_menus[m_menuCount - 1] = (wxMenu *)menu; + m_titles[m_menuCount - 1] = title; + + // TODO +} -wxMenuItem *wxMenu::FindItem(int id) const +void wxMenuBar::Delete(wxMenu * menu, int i) { - wxNode *node = m_items.First(); - while (node) { - wxMenuItem *item = (wxMenuItem*)node->Data(); - if ( item->GetId() == id ) - return item; - node = node->Next(); - }; + int j; + int ii = (int) i; + + if (menu != 0) + { + for (ii = 0; ii < m_menuCount; ii++) + { + if (m_menus[ii] == menu) + break; + } + if (ii >= m_menuCount) + return; + } else + { + if (ii < 0 || ii >= m_menuCount) + return; + menu = m_menus[ii]; + } + + if (!OnDelete(menu, ii)) + return; + + 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]; + } +} - wxLogDebug("wxMenu::FindItem: item %d not found.", id); +// Find the menu menuString, item itemString, and return the item id. +// Returns -1 if none found. +int wxMenuBar::FindMenuItem (const wxString& menuString, const wxString& itemString) const +{ + char buf1[200]; + char buf2[200]; + wxStripMenuCodes ((char *)(const char *)menuString, buf1); + int i; + for (i = 0; i < m_menuCount; i++) + { + wxStripMenuCodes ((char *)(const char *)m_titles[i], buf2); + if (strcmp (buf1, buf2) == 0) + return m_menus[i]->FindItem (itemString); + } + return -1; +} - return NULL; +wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const +{ + if (itemMenu) + *itemMenu = NULL; + + wxMenuItem *item = NULL; + int i; + for (i = 0; i < m_menuCount; i++) + if ((item = m_menus[i]->FindItemForId (Id, itemMenu))) + return item; + return NULL; } -void wxMenu::SetInvokingWindow( wxWindow *win ) +void wxMenuBar::SetHelpString (int Id, const wxString& helpString) { - m_invokingWindow = win; -}; + int i; + for (i = 0; i < m_menuCount; i++) + { + if (m_menus[i]->FindItemForId (Id)) + { + m_menus[i]->SetHelpString (Id, helpString); + return; + } + } +} -wxWindow *wxMenu::GetInvokingWindow() +wxString wxMenuBar::GetHelpString (int Id) const { - return m_invokingWindow; -}; + int i; + for (i = 0; i < m_menuCount; i++) + { + if (m_menus[i]->FindItemForId (Id)) + eturn wxString(m_menus[i]->GetHelpString (Id)); + } + return wxString(""); +}