KiCad PCB EDA Suite
conditional_menu.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 CERN
5  * Copyright (C) 2015-2019 KiCad Developers, see CHANGELOG.txt for contributors.
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <tool/conditional_menu.h>
27 #include <tool/action_menu.h>
28 
29 
31 {
33  clone->m_entries = m_entries;
34  return clone;
35 }
36 
37 
38 void CONDITIONAL_MENU::AddItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition,
39  int aOrder )
40 {
41  assert( aAction.GetId() > 0 ); // Check if action was previously registered in ACTION_MANAGER
42  addEntry( ENTRY( &aAction, aCondition, aOrder, false ) );
43 }
44 
45 
47  const SELECTION_CONDITION& aCondition, int aOrder )
48 {
49  assert( aAction.GetId() > 0 ); // Check if action was previously registered in ACTION_MANAGER
50  addEntry( ENTRY( &aAction, aCondition, aOrder, true ) );
51 }
52 
53 
54 void CONDITIONAL_MENU::AddItem( int aId, const wxString& aText, const wxString& aTooltip,
55  BITMAP_DEF aIcon, const SELECTION_CONDITION& aCondition,
56  int aOrder )
57 {
58  wxMenuItem* item = new wxMenuItem( nullptr, aId, aText, aTooltip, wxITEM_NORMAL );
59 
60  if( aIcon )
61  item->SetBitmap( KiBitmap( aIcon ) );
62 
63  addEntry( ENTRY( item, aCondition, aOrder, false ) );
64 }
65 
66 
67 void CONDITIONAL_MENU::AddCheckItem( int aId, const wxString& aText, const wxString& aTooltip,
68  BITMAP_DEF aIcon, const SELECTION_CONDITION& aCondition,
69  int aOrder )
70 {
71  wxMenuItem* item = new wxMenuItem( nullptr, aId, aText, aTooltip, wxITEM_CHECK );
72 
73  if( aIcon )
74  item->SetBitmap( KiBitmap( aIcon ) );
75 
76  addEntry( ENTRY( item, aCondition, aOrder, true ) );
77 }
78 
79 
81  int aOrder )
82 {
83  addEntry( ENTRY( aMenu, aCondition, aOrder ) );
84 }
85 
86 
87 void CONDITIONAL_MENU::AddSeparator( const SELECTION_CONDITION& aCondition, int aOrder )
88 {
89  addEntry( ENTRY( aCondition, aOrder ) );
90 }
91 
92 
94 {
95  Clear();
96 
97  for( const ENTRY& entry : m_entries )
98  {
99  const SELECTION_CONDITION& cond = entry.Condition();
100  bool result;
101  wxMenuItem* menuItem = nullptr;
102 
103  try
104  {
105  result = cond( aSelection );
106  }
107  catch( std::exception& )
108  {
109  continue;
110  }
111 
112  if( m_isContextMenu && !result )
113  continue;
114 
115  switch( entry.Type() )
116  {
117  case ENTRY::ACTION:
118  menuItem = Add( *entry.Action(), entry.IsCheckmarkEntry() );
119  break;
120  case ENTRY::MENU:
121  menuItem = Add( entry.Menu() );
122  break;
123  case ENTRY::WXITEM:
124  menuItem = Append( entry.wxItem()->GetId(), entry.wxItem()->GetItemLabel(),
125  entry.wxItem()->GetHelp(), entry.wxItem()->GetKind() );
126  break;
127  case ENTRY::SEPARATOR:
128  menuItem = AppendSeparator();
129  break;
130  default:
131  assert( false );
132  break;
133  }
134 
135  if( entry.IsCheckmarkEntry() )
136  menuItem->Check( result );
137  else
138  menuItem->Enable( result );
139  }
140 }
141 
142 
144 {
145  if( aEntry.Order() < 0 ) // Any order, so give it any order number
146  aEntry.SetOrder( m_entries.size() );
147 
148  std::list<ENTRY>::iterator it = m_entries.begin();
149 
150  // Find the right spot for the entry
151  while( it != m_entries.end() && it->Order() <= aEntry.Order() )
152  ++it;
153 
154  m_entries.insert( it, aEntry );
155 }
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
bool m_isContextMenu
Context menus include only items that resolve to true; Regular menus enable only menu items that reso...
Helper class to organize menu entries.
Class ACTION_MENU.
Definition: action_menu.h:43
void AddSeparator(const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddSeparator()
std::list< ENTRY > m_entries
List of all menu entries.
CONDITIONAL_MENU(bool isContextMenu, TOOL_INTERACTIVE *aTool)
void AddCheckItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddCheckItem()
void SetOrder(int aOrder)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
void Evaluate(SELECTION &aSelection)
Function Evaluate()
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
TOOL_INTERACTIVE * m_tool
Creator of the menu
Definition: action_menu.h:220
int GetId() const
Function GetId() Returns the unique id of the TOOL_ACTION object.
Definition: tool_action.h:85
void addEntry(ENTRY aEntry)
Inserts the entry, preserving the requested order.
Class TOOL_ACTION.
Definition: tool_action.h:46
void Clear()
Function Clear() Removes all the entries from the menu (as well as its title).
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon=NULL)
Function Add() Adds an entry to the menu.
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()