1. wxMenu changes: wxMenuBase appears, several new functions for dynamic menu
handling as well 2. new sample: menu 3. small corrections to wxFileHistory made possible by wxMenu changes 4. ugly fix for panel loaded from resources and TABbing 5. wxDataObject &c doc updates git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4288 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -31,6 +31,10 @@
|
||||
extern void wxapp_install_idle_handler();
|
||||
extern bool g_isIdle;
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||
static wxString GetHotKey( const wxMenuItem& item );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxMenuBar
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -355,7 +359,7 @@ int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemStr
|
||||
// Find a wxMenuItem using its id. Recurses down into sub-menus
|
||||
static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
|
||||
{
|
||||
wxMenuItem* result = menu->FindItem(id);
|
||||
wxMenuItem* result = menu->FindChildItem(id);
|
||||
|
||||
wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
|
||||
while ( node && result == NULL )
|
||||
@@ -440,7 +444,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
|
||||
if (!menu->IsEnabled(id))
|
||||
return;
|
||||
|
||||
wxMenuItem* item = menu->FindItem( id );
|
||||
wxMenuItem* item = menu->FindChildItem( id );
|
||||
wxCHECK_RET( item, wxT("error in menu item callback") );
|
||||
|
||||
if (item->IsCheckable())
|
||||
@@ -569,18 +573,40 @@ wxMenuItem::~wxMenuItem()
|
||||
// don't delete menu items, the menus take care of that
|
||||
}
|
||||
|
||||
void wxMenuItem::SetText( const wxString& str )
|
||||
{
|
||||
DoSetText(str);
|
||||
// return the menu item text without any menu accels
|
||||
wxString wxMenuItem::GetLabel() const
|
||||
{
|
||||
wxString label;
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
for ( const wxChar *pc = m_text.c_str(); *pc; pc++ )
|
||||
{
|
||||
if ( *pc == wxT('_') )
|
||||
{
|
||||
// this is the escape character for GTK+ - skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
label += *pc;
|
||||
}
|
||||
#else // GTK+ 1.0
|
||||
label = m_text;
|
||||
#endif // GTK+ 1.2/1.0
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
void wxMenuItem::SetText( const wxString& str )
|
||||
{
|
||||
DoSetText(str);
|
||||
|
||||
if (m_menuItem)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL( GTK_BIN(m_menuItem)->child );
|
||||
|
||||
/* set new text */
|
||||
|
||||
/* set new text */
|
||||
gtk_label_set( label, m_text.mb_str());
|
||||
|
||||
/* reparse key accel */
|
||||
|
||||
/* reparse key accel */
|
||||
guint accel_key = gtk_label_parse_uline (GTK_LABEL(label), m_text.mb_str() );
|
||||
gtk_accel_label_refetch( GTK_ACCEL_LABEL(label) );
|
||||
}
|
||||
@@ -623,6 +649,25 @@ void wxMenuItem::DoSetText( const wxString& str )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if wxUSE_ACCEL
|
||||
|
||||
wxAcceleratorEntry *wxMenuItem::GetAccel() const
|
||||
{
|
||||
if ( !item.GetHotKey() )
|
||||
{
|
||||
// nothing
|
||||
return (wxAcceleratorEntry *)NULL;
|
||||
}
|
||||
|
||||
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
||||
wxString label;
|
||||
label << wxT('\t') << item.GetHotKey();
|
||||
|
||||
return wxGetAccelFromString(label);
|
||||
}
|
||||
|
||||
#endif // wxUSE_ACCEL
|
||||
|
||||
void wxMenuItem::Check( bool check )
|
||||
{
|
||||
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
|
||||
@@ -658,12 +703,8 @@ wxString wxMenuItem::GetFactoryPath() const
|
||||
{
|
||||
/* in order to get the pointer to the item we need the item text _without_ underscores */
|
||||
wxString path( wxT("<main>/") );
|
||||
for ( const wxChar *pc = m_text; *pc != wxT('\0'); pc++ )
|
||||
{
|
||||
while (*pc == wxT('_')) pc++; /* skip it */
|
||||
path << *pc;
|
||||
}
|
||||
|
||||
path += GetLabel();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -673,17 +714,8 @@ wxString wxMenuItem::GetFactoryPath() const
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
|
||||
|
||||
void
|
||||
wxMenu::Init( const wxString& title,
|
||||
long style,
|
||||
const wxFunction func
|
||||
)
|
||||
void wxMenu::Init()
|
||||
{
|
||||
m_title = title;
|
||||
m_items.DeleteContents( TRUE );
|
||||
m_invokingWindow = (wxWindow *) NULL;
|
||||
m_style = style;
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
m_accel = gtk_accel_group_new();
|
||||
m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", m_accel );
|
||||
@@ -692,18 +724,6 @@ wxMenu::Init( const wxString& title,
|
||||
m_menu = gtk_menu_new(); // Do not show!
|
||||
#endif
|
||||
|
||||
m_callback = func;
|
||||
|
||||
m_eventHandler = this;
|
||||
m_clientData = (void*) NULL;
|
||||
|
||||
if (m_title.IsNull()) m_title = wxT("");
|
||||
if (m_title != wxT(""))
|
||||
{
|
||||
Append(-2, m_title);
|
||||
AppendSeparator();
|
||||
}
|
||||
|
||||
m_owner = (GtkWidget*) NULL;
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
@@ -722,242 +742,145 @@ wxMenu::Init( const wxString& title,
|
||||
//GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/tearoff" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// append the title as the very first entry if we have it
|
||||
if ( !!m_title )
|
||||
{
|
||||
Append(-2, m_title);
|
||||
AppendSeparator();
|
||||
}
|
||||
}
|
||||
|
||||
wxMenu::~wxMenu()
|
||||
{
|
||||
wxNode *node = m_items.First();
|
||||
while (node)
|
||||
{
|
||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||
wxMenu *submenu = item->GetSubMenu();
|
||||
if (submenu)
|
||||
delete submenu;
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
gtk_widget_destroy( m_menu );
|
||||
|
||||
gtk_object_unref( GTK_OBJECT(m_factory) );
|
||||
|
||||
// the menu items are deleted by the base class dtor
|
||||
}
|
||||
|
||||
void wxMenu::SetTitle( const wxString& title )
|
||||
virtual bool wxMenu::DoAppend(wxMenuItem *mitem)
|
||||
{
|
||||
// TODO Waiting for something better
|
||||
m_title = title;
|
||||
}
|
||||
GtkWidget *menuItem;
|
||||
|
||||
const wxString wxMenu::GetTitle() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void wxMenu::AppendSeparator()
|
||||
{
|
||||
wxMenuItem *mitem = new wxMenuItem(this, wxID_SEPARATOR);
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = "/sep";
|
||||
entry.callback = (GtkItemFactoryCallback) NULL;
|
||||
entry.callback_action = 0;
|
||||
entry.item_type = "<Separator>";
|
||||
entry.accelerator = (gchar*) NULL;
|
||||
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
|
||||
/* this will be wrong for more than one separator. do we care? */
|
||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
||||
#else
|
||||
GtkWidget *menuItem = gtk_menu_item_new();
|
||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||
gtk_widget_show( menuItem );
|
||||
#endif
|
||||
|
||||
mitem->SetMenuItem(menuItem);
|
||||
m_items.Append( mitem );
|
||||
}
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||
static wxString GetHotKey( const wxMenuItem& item )
|
||||
{
|
||||
wxString hotkey;
|
||||
|
||||
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
||||
wxString label;
|
||||
label << wxT('\t') << item.GetHotKey();
|
||||
|
||||
// but if the hotkey is empty don't do anything
|
||||
if ( label.length() > 1 )
|
||||
if ( mitem->IsSeparator() )
|
||||
{
|
||||
wxAcceleratorEntry *accel = wxGetAccelFromString(label);
|
||||
if ( accel )
|
||||
{
|
||||
int flags = accel->GetFlags();
|
||||
if ( flags & wxACCEL_ALT )
|
||||
hotkey += wxT("<alt>");
|
||||
if ( flags & wxACCEL_CTRL )
|
||||
hotkey += wxT("<control>");
|
||||
if ( flags & wxACCEL_SHIFT )
|
||||
hotkey += wxT("<shift>");
|
||||
|
||||
int code = accel->GetKeyCode();
|
||||
switch ( code )
|
||||
{
|
||||
case WXK_F1:
|
||||
case WXK_F2:
|
||||
case WXK_F3:
|
||||
case WXK_F4:
|
||||
case WXK_F5:
|
||||
case WXK_F6:
|
||||
case WXK_F7:
|
||||
case WXK_F8:
|
||||
case WXK_F9:
|
||||
case WXK_F10:
|
||||
case WXK_F11:
|
||||
case WXK_F12:
|
||||
hotkey << wxT('F') << code - WXK_F1 + 1;
|
||||
break;
|
||||
|
||||
// if there are any other keys wxGetAccelFromString() may return,
|
||||
// we should process them here
|
||||
|
||||
default:
|
||||
if ( wxIsalnum(code) )
|
||||
{
|
||||
hotkey << (wxChar)code;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
wxFAIL_MSG( wxT("unknown keyboard accel") );
|
||||
}
|
||||
|
||||
delete accel;
|
||||
}
|
||||
}
|
||||
|
||||
return hotkey;
|
||||
}
|
||||
#endif // wxUSE_ACCEL
|
||||
|
||||
void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
|
||||
{
|
||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, checkable);
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
/* text has "_" instead of "&" after mitem->SetText() */
|
||||
wxString text( mitem->GetText() );
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = "/sep";
|
||||
entry.callback = (GtkItemFactoryCallback) NULL;
|
||||
entry.callback_action = 0;
|
||||
entry.item_type = "<Separator>";
|
||||
entry.accelerator = (gchar*) NULL;
|
||||
|
||||
/* local buffer in multibyte form */
|
||||
char buf[200];
|
||||
strcpy( buf, "/" );
|
||||
strcat( buf, text.mb_str() );
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = buf;
|
||||
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
||||
entry.callback_action = 0;
|
||||
if (checkable)
|
||||
entry.item_type = "<CheckItem>";
|
||||
else
|
||||
entry.item_type = "<Item>";
|
||||
/* this will be wrong for more than one separator. do we care? */
|
||||
menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
||||
#else // GTK+ 1.0
|
||||
menuItem = gtk_menu_item_new();
|
||||
#endif // GTK 1.2/1.0
|
||||
}
|
||||
else if ( mitem->IsSubMenu() )
|
||||
{
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
/* text has "_" instead of "&" after mitem->SetText() */
|
||||
wxString text( mitem->GetText() );
|
||||
|
||||
/* local buffer in multibyte form */
|
||||
char buf[200];
|
||||
strcpy( buf, "/" );
|
||||
strcat( buf, text.mb_str() );
|
||||
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = buf;
|
||||
entry.callback = (GtkItemFactoryCallback) 0;
|
||||
entry.callback_action = 0;
|
||||
entry.item_type = "<Branch>";
|
||||
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
|
||||
wxString path( mitem->GetFactoryPath() );
|
||||
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
||||
#else // GTK+ 1.0
|
||||
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
||||
#endif // GTK 1.2/1.0
|
||||
|
||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
||||
}
|
||||
else // a normal item
|
||||
{
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
/* text has "_" instead of "&" after mitem->SetText() */
|
||||
wxString text( mitem->GetText() );
|
||||
|
||||
/* local buffer in multibyte form */
|
||||
char buf[200];
|
||||
strcpy( buf, "/" );
|
||||
strcat( buf, text.mb_str() );
|
||||
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = buf;
|
||||
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
||||
entry.callback_action = 0;
|
||||
if (checkable)
|
||||
entry.item_type = "<CheckItem>";
|
||||
else
|
||||
entry.item_type = "<Item>";
|
||||
|
||||
#if wxUSE_ACCEL
|
||||
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
||||
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
||||
// somehow! (VZ)
|
||||
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
||||
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
||||
entry.accelerator = s_accel;
|
||||
#else
|
||||
entry.accelerator = (char*) NULL;
|
||||
#endif
|
||||
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
||||
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
||||
// somehow! (VZ)
|
||||
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
||||
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
||||
entry.accelerator = s_accel;
|
||||
#else // !wxUSE_ACCEL
|
||||
entry.accelerator = (char*) NULL;
|
||||
#endif // wxUSE_ACCEL/!wxUSE_ACCEL
|
||||
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
|
||||
wxString path( mitem->GetFactoryPath() );
|
||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
||||
wxString path( mitem->GetFactoryPath() );
|
||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
||||
#else // GTK+ 1.0
|
||||
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
||||
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
||||
|
||||
#else
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||
(gpointer)this );
|
||||
#endif // GTK+ 1.2/1.0
|
||||
}
|
||||
|
||||
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
||||
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
||||
if ( !mitem->IsSeparator() )
|
||||
{
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||
(gpointer)this );
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||
(gpointer)this );
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||
(gpointer)this );
|
||||
}
|
||||
|
||||
#if GTK_MINOR_VERSION == 0
|
||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||
gtk_widget_show( menuItem );
|
||||
|
||||
#endif
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||
(gpointer)this );
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||
(gpointer)this );
|
||||
#endif // GTK+ 1.0
|
||||
|
||||
mitem->SetMenuItem(menuItem);
|
||||
|
||||
m_items.Append( mitem );
|
||||
}
|
||||
|
||||
void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
|
||||
{
|
||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, FALSE, subMenu);
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
/* text has "_" instead of "&" after mitem->SetText() */
|
||||
wxString text( mitem->GetText() );
|
||||
|
||||
/* local buffer in multibyte form */
|
||||
char buf[200];
|
||||
strcpy( buf, "/" );
|
||||
strcat( buf, text.mb_str() );
|
||||
|
||||
GtkItemFactoryEntry entry;
|
||||
entry.path = buf;
|
||||
entry.callback = (GtkItemFactoryCallback) 0;
|
||||
entry.callback_action = 0;
|
||||
entry.item_type = "<Branch>";
|
||||
|
||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||
|
||||
wxString path( mitem->GetFactoryPath() );
|
||||
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
||||
|
||||
#else
|
||||
|
||||
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
||||
|
||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||
gtk_widget_show( menuItem );
|
||||
|
||||
#endif
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||
(gpointer*)this );
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||
(gpointer*)this );
|
||||
|
||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
||||
|
||||
mitem->SetMenuItem(menuItem);
|
||||
|
||||
m_items.Append( mitem );
|
||||
return wxMenuBase::DoAppend(mitem);
|
||||
}
|
||||
|
||||
// VZ: this seems to be GTK+ 1.0 only code, I don't understand why there were
|
||||
// both specialized versions of Append() and this one before my changes,
|
||||
// but it seems that the others are better...
|
||||
#if 0
|
||||
void wxMenu::Append( wxMenuItem *item )
|
||||
{
|
||||
m_items.Append( item );
|
||||
|
||||
GtkWidget *menuItem = (GtkWidget*) NULL;
|
||||
|
||||
if (item->IsSeparator())
|
||||
@@ -988,126 +911,31 @@ void wxMenu::Append( wxMenuItem *item )
|
||||
|
||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||
gtk_widget_show( menuItem );
|
||||
|
||||
item->SetMenuItem(menuItem);
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
void wxMenu::Delete( int id )
|
||||
bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
|
||||
{
|
||||
wxNode *node = m_items.First();
|
||||
while (node)
|
||||
{
|
||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||
if (item->GetId() == id)
|
||||
{
|
||||
/* TODO: this code doesn't delete the item factory item and
|
||||
this seems impossible as of GTK 1.2.6. */
|
||||
gtk_widget_destroy( item->GetMenuItem() );
|
||||
m_items.DeleteNode( node );
|
||||
return;
|
||||
}
|
||||
node = node->Next();
|
||||
}
|
||||
if ( !wxMenuBase::DoInsert(pos, item) )
|
||||
return FALSE;
|
||||
|
||||
wxFAIL_MSG(wxT("not implemented"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int wxMenu::FindItem( const wxString itemString ) const
|
||||
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
||||
{
|
||||
wxString s = wxT("");
|
||||
for ( const wxChar *pc = itemString; *pc != wxT('\0'); pc++ )
|
||||
{
|
||||
if (*pc == wxT('&'))
|
||||
{
|
||||
pc++; /* skip it */
|
||||
#if (GTK_MINOR_VERSION > 0)
|
||||
s << wxT('_');
|
||||
#endif
|
||||
}
|
||||
s << *pc;
|
||||
}
|
||||
if ( !wxMenuBase::DoRemove(item) )
|
||||
return (wxMenuItem *)NULL;
|
||||
|
||||
wxNode *node = m_items.First();
|
||||
while (node)
|
||||
{
|
||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||
if (item->GetText() == s)
|
||||
{
|
||||
return item->GetId();
|
||||
}
|
||||
node = node->Next();
|
||||
}
|
||||
// TODO: this code doesn't delete the item factory item and this seems
|
||||
// impossible as of GTK 1.2.6.
|
||||
gtk_widget_destroy( item->GetMenuItem() );
|
||||
|
||||
return wxNOT_FOUND;
|
||||
}
|
||||
|
||||
void wxMenu::Enable( int id, bool enable )
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
|
||||
|
||||
item->Enable(enable);
|
||||
}
|
||||
|
||||
bool wxMenu::IsEnabled( int id ) const
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsEnabled: no such item") );
|
||||
|
||||
return item->IsEnabled();
|
||||
}
|
||||
|
||||
void wxMenu::Check( int id, bool enable )
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
|
||||
|
||||
item->Check(enable);
|
||||
}
|
||||
|
||||
bool wxMenu::IsChecked( int id ) const
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsChecked: no such item") );
|
||||
|
||||
return item->IsChecked();
|
||||
}
|
||||
|
||||
void wxMenu::SetLabel( int id, const wxString &label )
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
|
||||
|
||||
item->SetText(label);
|
||||
}
|
||||
|
||||
wxString wxMenu::GetLabel( int id ) const
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetLabel: no such item") );
|
||||
|
||||
return item->GetText();
|
||||
}
|
||||
|
||||
void wxMenu::SetHelpString( int id, const wxString& helpString )
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
|
||||
|
||||
item->SetHelp( helpString );
|
||||
}
|
||||
|
||||
wxString wxMenu::GetHelpString( int id ) const
|
||||
{
|
||||
wxMenuItem *item = FindItem(id);
|
||||
|
||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetHelpString: no such item") );
|
||||
|
||||
return item->GetHelp();
|
||||
return item;
|
||||
}
|
||||
|
||||
int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
||||
@@ -1124,72 +952,62 @@ int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
||||
return wxNOT_FOUND;
|
||||
}
|
||||
|
||||
wxMenuItem *wxMenu::FindItem(int id) const
|
||||
// ----------------------------------------------------------------------------
|
||||
// helpers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||
static wxString GetHotKey( const wxMenuItem& item )
|
||||
{
|
||||
wxNode *node = m_items.First();
|
||||
while (node)
|
||||
wxString hotkey;
|
||||
|
||||
wxAcceleratorEntry *accel = item.GetAccel();
|
||||
if ( accel )
|
||||
{
|
||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||
if (item->GetId() == id)
|
||||
int flags = accel->GetFlags();
|
||||
if ( flags & wxACCEL_ALT )
|
||||
hotkey += wxT("<alt>");
|
||||
if ( flags & wxACCEL_CTRL )
|
||||
hotkey += wxT("<control>");
|
||||
if ( flags & wxACCEL_SHIFT )
|
||||
hotkey += wxT("<shift>");
|
||||
|
||||
int code = accel->GetKeyCode();
|
||||
switch ( code )
|
||||
{
|
||||
return item;
|
||||
case WXK_F1:
|
||||
case WXK_F2:
|
||||
case WXK_F3:
|
||||
case WXK_F4:
|
||||
case WXK_F5:
|
||||
case WXK_F6:
|
||||
case WXK_F7:
|
||||
case WXK_F8:
|
||||
case WXK_F9:
|
||||
case WXK_F10:
|
||||
case WXK_F11:
|
||||
case WXK_F12:
|
||||
hotkey << wxT('F') << code - WXK_F1 + 1;
|
||||
break;
|
||||
|
||||
// if there are any other keys wxGetAccelFromString() may return,
|
||||
// we should process them here
|
||||
|
||||
default:
|
||||
if ( wxIsalnum(code) )
|
||||
{
|
||||
hotkey << (wxChar)code;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
wxFAIL_MSG( wxT("unknown keyboard accel") );
|
||||
}
|
||||
node = node->Next();
|
||||
|
||||
delete accel;
|
||||
}
|
||||
|
||||
/* Not finding anything here can be correct
|
||||
* when search the entire menu system for
|
||||
* an entry -> no error message. */
|
||||
|
||||
return (wxMenuItem *) NULL;
|
||||
}
|
||||
|
||||
void wxMenu::SetInvokingWindow( wxWindow *win )
|
||||
{
|
||||
m_invokingWindow = win;
|
||||
}
|
||||
|
||||
wxWindow *wxMenu::GetInvokingWindow()
|
||||
{
|
||||
return m_invokingWindow;
|
||||
}
|
||||
|
||||
// Update a menu and all submenus recursively. source is the object that has
|
||||
// the update event handlers defined for it. If NULL, the menu or associated
|
||||
// window will be used.
|
||||
void wxMenu::UpdateUI(wxEvtHandler* source)
|
||||
{
|
||||
if (!source && GetInvokingWindow())
|
||||
source = GetInvokingWindow()->GetEventHandler();
|
||||
if (!source)
|
||||
source = GetEventHandler();
|
||||
if (!source)
|
||||
source = this;
|
||||
|
||||
wxNode* node = GetItems().First();
|
||||
while (node)
|
||||
{
|
||||
wxMenuItem* item = (wxMenuItem*) node->Data();
|
||||
if ( !item->IsSeparator() )
|
||||
{
|
||||
wxWindowID id = item->GetId();
|
||||
wxUpdateUIEvent event(id);
|
||||
event.SetEventObject( source );
|
||||
|
||||
if (source->ProcessEvent(event))
|
||||
{
|
||||
if (event.GetSetText())
|
||||
SetLabel(id, event.GetText());
|
||||
if (event.GetSetChecked())
|
||||
Check(id, event.GetChecked());
|
||||
if (event.GetSetEnabled())
|
||||
Enable(id, event.GetEnabled());
|
||||
}
|
||||
|
||||
if (item->GetSubMenu())
|
||||
item->GetSubMenu()->UpdateUI(source);
|
||||
}
|
||||
node = node->Next();
|
||||
}
|
||||
return hotkey;
|
||||
}
|
||||
#endif // wxUSE_ACCEL
|
||||
|
||||
|
Reference in New Issue
Block a user