Action plugins: simplify code, and fix an issue: the menubar was not correctly rebuilt after closing and reopening pcbnew from kicad.

It was also not correctly rebuilt after language change.
This commit is contained in:
jean-pierre charras 2017-01-22 20:23:00 +01:00
parent 5ef3e5a15d
commit 2b5769c0a8
7 changed files with 90 additions and 56 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2010 Rafael Sokolowski <Rafael.Sokolowski@web.de> * Copyright (C) 2010 Rafael Sokolowski <Rafael.Sokolowski@web.de>
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2017 KiCad Developers, see CHANGELOG.TXT for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -525,6 +525,13 @@ void dialog_about::OnCopyVersionInfo( wxCommandEvent& event )
msg_version << OFF; msg_version << OFF;
#endif #endif
msg_version << " KICAD_SCRIPTING_ACTION_MENU=";
#ifdef KICAD_SCRIPTING_ACTION_MENU
msg_version << ON;
#else
msg_version << OFF;
#endif
msg_version << " BUILD_GITHUB_PLUGIN="; msg_version << " BUILD_GITHUB_PLUGIN=";
#ifdef BUILD_GITHUB_PLUGIN #ifdef BUILD_GITHUB_PLUGIN
msg_version << ON; msg_version << ON;

View File

@ -119,10 +119,10 @@ protected:
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) #if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
/** /**
* Function initActionPluginMenus * Function RebuildActionPluginMenus
* Fill action menu with all registred action plugins * Fill action menu with all registred action plugins
*/ */
void initActionPluginMenus(); void RebuildActionPluginMenus();
/** /**
* Function OnActionPlugin * Function OnActionPlugin

View File

@ -41,24 +41,23 @@ void ACTION_PLUGIN::register_action()
} }
std::vector<ACTION_PLUGIN*> ACTION_PLUGINS::m_Actions; std::vector<ACTION_PLUGIN*> ACTION_PLUGINS::m_actionsList;
std::vector<int> ACTION_PLUGINS::m_ActionsMenu;
ACTION_PLUGIN* ACTION_PLUGINS::GetAction( int aIndex ) ACTION_PLUGIN* ACTION_PLUGINS::GetAction( int aIndex )
{ {
return m_Actions[aIndex]; return m_actionsList[aIndex];
} }
ACTION_PLUGIN* ACTION_PLUGINS::GetActionByMenu( int menu ) ACTION_PLUGIN* ACTION_PLUGINS::GetActionByMenu( int aMenu )
{ {
int max = GetActionsCount(); int max = GetActionsCount();
for( int i = 0; i<max; i++ ) for( int i = 0; i < max; i++ )
{ {
if( m_ActionsMenu[i] == menu ) if( m_actionsList[i]->m_actionMenuId == aMenu )
return m_Actions[i]; return m_actionsList[i];
} }
return NULL; return NULL;
@ -67,13 +66,13 @@ ACTION_PLUGIN* ACTION_PLUGINS::GetActionByMenu( int menu )
void ACTION_PLUGINS::SetActionMenu( int aIndex, int idMenu ) void ACTION_PLUGINS::SetActionMenu( int aIndex, int idMenu )
{ {
m_ActionsMenu[aIndex] = idMenu; m_actionsList[aIndex]->m_actionMenuId = idMenu;
} }
int ACTION_PLUGINS::GetActionMenu( int aIndex ) int ACTION_PLUGINS::GetActionMenu( int aIndex )
{ {
return m_ActionsMenu[aIndex]; return m_actionsList[aIndex]->m_actionMenuId;
} }
@ -97,14 +96,12 @@ ACTION_PLUGIN* ACTION_PLUGINS::GetAction( wxString aName )
int ACTION_PLUGINS::GetActionsCount() int ACTION_PLUGINS::GetActionsCount()
{ {
return m_Actions.size(); return m_actionsList.size();
} }
void ACTION_PLUGINS::register_action( ACTION_PLUGIN* aAction ) void ACTION_PLUGINS::register_action( ACTION_PLUGIN* aAction )
{ {
int updatedMenu = 0;
// Search for this entry do not register twice this action: // Search for this entry do not register twice this action:
for( int ii = 0; ii < GetActionsCount(); ii++ ) for( int ii = 0; ii < GetActionsCount(); ii++ )
{ {
@ -119,9 +116,7 @@ void ACTION_PLUGINS::register_action( ACTION_PLUGIN* aAction )
if( action->GetName() == aAction->GetName() ) if( action->GetName() == aAction->GetName() )
{ {
updatedMenu = GetActionMenu( ii ); m_actionsList.erase( m_actionsList.begin() + ii );
m_Actions.erase( m_Actions.begin() + ii );
m_ActionsMenu.erase( m_ActionsMenu.begin() + ii );
delete action; delete action;
@ -129,8 +124,7 @@ void ACTION_PLUGINS::register_action( ACTION_PLUGIN* aAction )
} }
} }
m_Actions.push_back( aAction ); m_actionsList.push_back( aAction );
m_ActionsMenu.push_back( updatedMenu );
} }
@ -144,8 +138,8 @@ bool ACTION_PLUGINS::deregister_object( void* aObject )
if( action->GetObject() == aObject ) if( action->GetObject() == aObject )
{ {
m_Actions.erase( m_Actions.begin() + i ); m_actionsList.erase( m_actionsList.begin() + i );
m_ActionsMenu.erase( m_ActionsMenu.begin() + i ); //m_actionsListMenu.erase( m_actionsListMenu.begin() + i );
delete action; delete action;
return true; return true;
} }

View File

@ -40,7 +40,13 @@
class ACTION_PLUGIN class ACTION_PLUGIN
{ {
public: public:
ACTION_PLUGIN() {} // association between the plugin and its menu id
// m_actionMenuId set to 0 means the corresponding menuitem to call this
// action is not yet created
int m_actionMenuId;
public:
ACTION_PLUGIN() : m_actionMenuId( 0 ) {}
virtual ~ACTION_PLUGIN(); virtual ~ACTION_PLUGIN();
/** /**
@ -94,15 +100,9 @@ private:
/** /**
* ACTION_PLUGIN system wide static list * ACTION_PLUGIN system wide static list
*/ */
static std::vector<ACTION_PLUGIN*> m_Actions; static std::vector<ACTION_PLUGIN*> m_actionsList;
/**
* system wide static association between Plugin and menu id
*/
static std::vector<int> m_ActionsMenu;
public: public:
/** /**
* Function register_action * Function register_action
* An action calls this static method when it wants to register itself * An action calls this static method when it wants to register itself
@ -150,10 +150,10 @@ public:
/** /**
* Function GetActionByMenu * Function GetActionByMenu
* find action plugin associated to a menu id * find action plugin associated to a menu id
* @param menu is the menu id (defined with SetActionMenu) * @param aMenu is the menu id (defined with SetActionMenu)
* @return the associated ACTION_PLUGIN (or null if not found) * @return the associated ACTION_PLUGIN (or null if not found)
*/ */
static ACTION_PLUGIN* GetActionByMenu( int menu ); static ACTION_PLUGIN* GetActionByMenu( int aMenu );
/** /**

View File

@ -658,11 +658,8 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
KiBitmap( reload_xpm ) ); KiBitmap( reload_xpm ) );
submenuActionPluginsMenu->AppendSeparator(); submenuActionPluginsMenu->AppendSeparator();
#endif #endif
wxMenu* designRulesMenu = new wxMenu; wxMenu* designRulesMenu = new wxMenu;
AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
@ -723,4 +720,10 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
SetMenuBar( menuBar ); SetMenuBar( menuBar );
else else
menuBar->Refresh(); menuBar->Refresh();
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
// Populate the Action Plugin sub-menu
RebuildActionPluginMenus();
#endif
} }

View File

@ -479,10 +479,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
enableGALSpecificMenus(); enableGALSpecificMenus();
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
initActionPluginMenus();
#endif
// disable Export STEP item if kicad2step does not exist // disable Export STEP item if kicad2step does not exist
wxString strK2S = Pgm().GetExecutablePath(); wxString strK2S = Pgm().GetExecutablePath();
#ifdef __WXMAC__ #ifdef __WXMAC__

View File

@ -208,33 +208,67 @@ void PCB_EDIT_FRAME::OnActionPluginRefresh( wxCommandEvent& aEvent )
// ReRun the Python method pcbnew.LoadPlugins (already called when starting Pcbnew) // ReRun the Python method pcbnew.LoadPlugins (already called when starting Pcbnew)
PyRun_SimpleString( cmd ); PyRun_SimpleString( cmd );
initActionPluginMenus(); RebuildActionPluginMenus();
} }
void PCB_EDIT_FRAME::initActionPluginMenus() void PCB_EDIT_FRAME::RebuildActionPluginMenus()
{ {
wxMenu* actionMenu = GetMenuBar()->FindItem( ID_TOOLBARH_PCB_ACTION_PLUGIN )->GetSubMenu(); wxMenu* actionMenu = GetMenuBar()->FindItem( ID_TOOLBARH_PCB_ACTION_PLUGIN )->GetSubMenu();
for( int i = 0; i < ACTION_PLUGINS::GetActionsCount(); i++ ) if( !actionMenu ) // Should not occur.
return;
// First, remove existing submenus, if they are too many
wxMenuItemList list = actionMenu->GetMenuItems();
// The first menuitems are the refresh menu and separator. do not count them
int act_menu_count = -2;
std::vector<wxMenuItem*> available_menus;
for( auto iter = list.begin(); iter != list.end(); ++iter, act_menu_count++ )
{ {
// Init menu only for not already created Items if( act_menu_count < 0 )
if( ACTION_PLUGINS::GetActionMenu( i ) == 0 ) continue;
wxMenuItem* item = *iter;
if( act_menu_count < ACTION_PLUGINS::GetActionsCount() )
{ {
wxMenuItem* item = AddMenuItem( actionMenu, wxID_ANY, available_menus.push_back( item );
ACTION_PLUGINS::GetAction( i )->GetName(), continue;
ACTION_PLUGINS::GetAction( i )->GetDescription(),
KiBitmap( hammer_xpm ) );
ACTION_PLUGINS::SetActionMenu( i, item->GetId() );
Connect(
item->GetId(), wxEVT_COMMAND_MENU_SELECTED,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &
PCB_EDIT_FRAME::OnActionPlugin );
} }
// Delete is not handled by plugins system (yet) // Remove menus which are not usable for our current plugin list
Disconnect( item->GetId(), wxEVT_COMMAND_MENU_SELECTED,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &
PCB_EDIT_FRAME::OnActionPlugin );
actionMenu->Delete( item );
}
for( int ii = 0; ii < ACTION_PLUGINS::GetActionsCount(); ii++ )
{
wxMenuItem* item;
if( ii < (int)available_menus.size() )
{
item = available_menus[ii];
item->SetItemLabel( ACTION_PLUGINS::GetAction( ii )->GetName() );
item->SetHelp( ACTION_PLUGINS::GetAction( ii )->GetDescription() );
}
else
{
item = AddMenuItem( actionMenu, wxID_ANY,
ACTION_PLUGINS::GetAction( ii )->GetName(),
ACTION_PLUGINS::GetAction( ii )->GetDescription(),
KiBitmap( hammer_xpm ) );
Connect( item->GetId(), wxEVT_COMMAND_MENU_SELECTED,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &
PCB_EDIT_FRAME::OnActionPlugin );
}
ACTION_PLUGINS::SetActionMenu( ii, item->GetId() );
} }
} }