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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -525,6 +525,13 @@ void dialog_about::OnCopyVersionInfo( wxCommandEvent& event )
msg_version << OFF;
#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=";
#ifdef BUILD_GITHUB_PLUGIN
msg_version << ON;

View File

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

View File

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

View File

@ -40,7 +40,13 @@
class ACTION_PLUGIN
{
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();
/**
@ -94,15 +100,9 @@ private:
/**
* ACTION_PLUGIN system wide static list
*/
static std::vector<ACTION_PLUGIN*> m_Actions;
/**
* system wide static association between Plugin and menu id
*/
static std::vector<int> m_ActionsMenu;
static std::vector<ACTION_PLUGIN*> m_actionsList;
public:
/**
* Function register_action
* An action calls this static method when it wants to register itself
@ -150,10 +150,10 @@ public:
/**
* Function GetActionByMenu
* 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)
*/
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 ) );
submenuActionPluginsMenu->AppendSeparator();
#endif
wxMenu* designRulesMenu = new wxMenu;
AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
@ -723,4 +720,10 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
SetMenuBar( menuBar );
else
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();
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
initActionPluginMenus();
#endif
// disable Export STEP item if kicad2step does not exist
wxString strK2S = Pgm().GetExecutablePath();
#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)
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();
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( ACTION_PLUGINS::GetActionMenu( i ) == 0 )
if( act_menu_count < 0 )
continue;
wxMenuItem* item = *iter;
if( act_menu_count < ACTION_PLUGINS::GetActionsCount() )
{
wxMenuItem* item = AddMenuItem( actionMenu, wxID_ANY,
ACTION_PLUGINS::GetAction( i )->GetName(),
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 );
available_menus.push_back( item );
continue;
}
// 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() );
}
}