You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
14 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013 CERN
  5. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  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. #ifndef __TOOL_MANAGER_H
  26. #define __TOOL_MANAGER_H
  27. #include <deque>
  28. #include <typeinfo>
  29. #include <map>
  30. #include <tool/tool_base.h>
  31. class TOOL_BASE;
  32. class ACTION_MANAGER;
  33. class CONTEXT_MENU;
  34. class wxWindow;
  35. /**
  36. * Class TOOL_MANAGER.
  37. * Master controller class:
  38. * - registers editing tools
  39. * - pumps UI events to tools requesting them
  40. * - manages tool state machines (transitions and wait requests)
  41. */
  42. class TOOL_MANAGER
  43. {
  44. public:
  45. TOOL_MANAGER();
  46. ~TOOL_MANAGER();
  47. /**
  48. * Generates a unique ID from for a tool with given name.
  49. */
  50. static TOOL_ID MakeToolId( const std::string& aToolName );
  51. /**
  52. * Function RegisterTool()
  53. * Adds a tool to the manager set and sets it up. Called once for
  54. * each tool during application initialization.
  55. * @param aTool: tool to be added. Ownership is transferred.
  56. */
  57. void RegisterTool( TOOL_BASE* aTool );
  58. /**
  59. * Function InvokeTool()
  60. * Calls a tool by sending a tool activation event to tool of given ID.
  61. *
  62. * @param aToolId is the ID number of the requested tool.
  63. * @return True if the requested tool was invoked successfully.
  64. */
  65. bool InvokeTool( TOOL_ID aToolId );
  66. /**
  67. * Function InvokeTool()
  68. * Calls a tool by sending a tool activation event to tool of given name.
  69. *
  70. * @param aToolName is the name of the requested tool.
  71. * @return True if the requested tool was invoked successfully.
  72. */
  73. bool InvokeTool( const std::string& aToolName );
  74. /**
  75. * Function RegisterAction()
  76. * Registers an action that can be used to control tools (eg. invoke, trigger specific
  77. * behaviours).
  78. *
  79. * @param aAction is the action to be registered.
  80. */
  81. void RegisterAction( TOOL_ACTION* aAction );
  82. /**
  83. * Function UnregisterAction()
  84. * Unregisters an action, so it is no longer active.
  85. *
  86. * @param aAction is the action to be unregistered.
  87. */
  88. void UnregisterAction( TOOL_ACTION* aAction );
  89. /**
  90. * Function RunAction()
  91. * Runs the specified action. The common format for action names is "application.ToolName.Action".
  92. *
  93. * @param aActionName is the name of action to be invoked.
  94. * @param aNow decides if the action has to be run immediately or after the current coroutine
  95. * is preemptied.
  96. * @param aParam is an optional parameter that might be used by the invoked action. Its meaning
  97. * depends on the action.
  98. * @return False if the action was not found.
  99. */
  100. template<typename T>
  101. bool RunAction( const std::string& aActionName, bool aNow = false, T aParam = NULL )
  102. {
  103. return RunAction( aActionName, aNow, reinterpret_cast<void*>( aParam ) );
  104. }
  105. bool RunAction( const std::string& aActionName, bool aNow, void* aParam );
  106. bool RunAction( const std::string& aActionName, bool aNow = false )
  107. {
  108. return RunAction( aActionName, aNow, (void*) NULL );
  109. }
  110. /**
  111. * Function RunAction()
  112. * Runs the specified action.
  113. *
  114. * @param aAction is the action to be invoked.
  115. * @param aNow decides if the action has to be run immediately or after the current coroutine
  116. * is preemptied.
  117. * @param aParam is an optional parameter that might be used by the invoked action. Its meaning
  118. * depends on the action.
  119. */
  120. template<typename T>
  121. void RunAction( const TOOL_ACTION& aAction, bool aNow = false, T aParam = NULL )
  122. {
  123. RunAction( aAction, aNow, reinterpret_cast<void*>( aParam ) );
  124. }
  125. void RunAction( const TOOL_ACTION& aAction, bool aNow, void* aParam );
  126. void RunAction( const TOOL_ACTION& aAction, bool aNow = false )
  127. {
  128. RunAction( aAction, aNow, (void*) NULL );
  129. }
  130. /**
  131. * Function FindTool()
  132. * Searches for a tool with given ID.
  133. *
  134. * @param aId is the ID number of the requested tool.
  135. * @return Pointer to the requested tool or NULL in case of failure.
  136. */
  137. TOOL_BASE* FindTool( int aId ) const;
  138. /**
  139. * Function FindTool()
  140. * Searches for a tool with given name.
  141. *
  142. * @param aName is the name of the requested tool.
  143. * @return Pointer to the requested tool or NULL in case of failure.
  144. */
  145. TOOL_BASE* FindTool( const std::string& aName ) const;
  146. /*
  147. * Function GetTool()
  148. * Returns the tool of given type or NULL if there is no such tool registered.
  149. */
  150. template<typename T>
  151. T* GetTool()
  152. {
  153. std::map<const char*, TOOL_BASE*>::iterator tool = m_toolTypes.find( typeid( T ).name() );
  154. if( tool != m_toolTypes.end() )
  155. return static_cast<T*>( tool->second );
  156. return NULL;
  157. }
  158. /**
  159. * Function ResetTools()
  160. * Resets all tools (i.e. calls their Reset() method).
  161. */
  162. void ResetTools( TOOL_BASE::RESET_REASON aReason );
  163. /**
  164. * Propagates an event to tools that requested events of matching type(s).
  165. * @param aEvent is the event to be processed.
  166. */
  167. bool ProcessEvent( const TOOL_EVENT& aEvent );
  168. /**
  169. * Puts an event to the event queue to be processed at the end of event processing cycle.
  170. * @param aEvent is the event to be put into the queue.
  171. */
  172. inline void PostEvent( const TOOL_EVENT& aEvent )
  173. {
  174. m_eventQueue.push_back( aEvent );
  175. }
  176. /**
  177. * Sets the work environment (model, view, view controls and the parent window).
  178. * These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME)
  179. * when the board is set up.
  180. */
  181. void SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView,
  182. KIGFX::VIEW_CONTROLS* aViewControls, wxWindow* aFrame );
  183. /* Accessors for the environment objects (view, model, etc.) */
  184. KIGFX::VIEW* GetView() const
  185. {
  186. return m_view;
  187. }
  188. inline KIGFX::VIEW_CONTROLS* GetViewControls() const
  189. {
  190. return m_viewControls;
  191. }
  192. inline EDA_ITEM* GetModel() const
  193. {
  194. return m_model;
  195. }
  196. inline wxWindow* GetEditFrame() const
  197. {
  198. return m_editFrame;
  199. }
  200. /**
  201. * Returns id of the tool that is on the top of the active tools stack
  202. * (was invoked the most recently).
  203. * @return Id of the currently used tool.
  204. */
  205. inline int GetCurrentToolId() const
  206. {
  207. return m_activeTools.front();
  208. }
  209. /**
  210. * Returns the tool that is on the top of the active tools stack
  211. * (was invoked the most recently).
  212. * @return Pointer to the currently used tool.
  213. */
  214. inline TOOL_BASE* GetCurrentTool() const
  215. {
  216. return FindTool( GetCurrentToolId() );
  217. }
  218. /**
  219. * Returns priority of a given tool. Higher number means that the tool is closer to the
  220. * beginning of the active tools queue (i.e. receives events earlier, tools with lower
  221. * priority receive events later).
  222. * @param aToolId is the id of queried tool.
  223. * @return The priority of a given tool. If returned number is negative, then it means that
  224. * the tool id is invalid or the tool is not active.
  225. */
  226. int GetPriority( int aToolId ) const;
  227. /**
  228. * Defines a state transition - the events that cause a given handler method in the tool
  229. * to be called. Called by TOOL_INTERACTIVE::Go(). May be called from a coroutine context.
  230. */
  231. void ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
  232. const TOOL_EVENT_LIST& aConditions );
  233. /**
  234. * Pauses execution of a given tool until one or more events matching aConditions arrives.
  235. * The pause/resume operation is done through COROUTINE object.
  236. * Called only from coroutines.
  237. */
  238. boost::optional<TOOL_EVENT> ScheduleWait( TOOL_BASE* aTool,
  239. const TOOL_EVENT_LIST& aConditions );
  240. /**
  241. * Sets behaviour of the tool's context popup menu.
  242. * @param aTool - the parent tool
  243. * @param aMenu - the menu structure, defined by the tool
  244. * @param aTrigger - when the menu is activated:
  245. * CMENU_NOW: opens the menu right now
  246. * CMENU_BUTTON: opens the menu when RMB is pressed
  247. * CMENU_OFF: menu is disabled.
  248. * May be called from a coroutine context.
  249. */
  250. void ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu,
  251. CONTEXT_MENU_TRIGGER aTrigger );
  252. /**
  253. * Allows a tool to pass the already handled event to the next tool on the stack.
  254. */
  255. void PassEvent()
  256. {
  257. m_passEvent = true;
  258. }
  259. /**
  260. * Stores an information to the system clipboard.
  261. * @param aText is the information to be stored.
  262. * @return False if error occured.
  263. */
  264. bool SaveClipboard( const std::string& aText );
  265. /**
  266. * Returns the information currently stored in the system clipboard. If data stored in the
  267. * clipboard is in non-text format, empty string is returned.
  268. */
  269. std::string GetClipboard() const;
  270. private:
  271. struct TOOL_STATE;
  272. typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;
  273. /**
  274. * Function dispatchInternal
  275. * Passes an event at first to the active tools, then to all others.
  276. */
  277. void dispatchInternal( const TOOL_EVENT& aEvent );
  278. /**
  279. * Function dispatchStandardEvents()
  280. * Handles specific events, that are intended for TOOL_MANAGER rather than tools.
  281. * @param aEvent is the event to be processed.
  282. * @return False if the event was processed and should not go any further.
  283. */
  284. bool dispatchStandardEvents( const TOOL_EVENT& aEvent );
  285. /**
  286. * Function dispatchActivation()
  287. * Checks if it is a valid activation event and invokes a proper tool.
  288. * @param aEvent is an event to be tested.
  289. * @return True if a tool was invoked, false otherwise.
  290. */
  291. bool dispatchActivation( const TOOL_EVENT& aEvent );
  292. /**
  293. * Function dispatchContextMenu()
  294. * Handles context menu related events.
  295. */
  296. void dispatchContextMenu( const TOOL_EVENT& aEvent );
  297. /**
  298. * Function invokeTool()
  299. * Invokes a tool by sending a proper event (in contrary to runTool, which makes the tool run
  300. * for real).
  301. * @param aTool is the tool to be invoked.
  302. */
  303. bool invokeTool( TOOL_BASE* aTool );
  304. /**
  305. * Function runTool()
  306. * Makes a tool active, so it can receive events and react to them. Activated tool is pushed
  307. * on the active tools stack, so the last activated tool receives events first.
  308. *
  309. * @param aToolId is the ID number of tool to be run.
  310. */
  311. bool runTool( TOOL_ID aToolId );
  312. /**
  313. * Function runTool()
  314. * Makes a tool active, so it can receive events and react to them. Activated tool is pushed
  315. * on the active tools stack, so the last activated tool receives events first.
  316. *
  317. * @param aName is the name of tool to be run.
  318. */
  319. bool runTool( const std::string& aName );
  320. /**
  321. * Function runTool()
  322. * Makes a tool active, so it can receive events and react to them. Activated tool is pushed
  323. * on the active tools stack, so the last activated tool receives events first.
  324. *
  325. * @param aTool is the tool to be run.
  326. */
  327. bool runTool( TOOL_BASE* aTool );
  328. template <class Parameters>
  329. void invokeTool( const std::string& aName, const Parameters& aToolParams );
  330. /**
  331. * Function finishTool()
  332. * Deactivates a tool and does the necessary clean up.
  333. *
  334. * @param aState is the state variable of the tool to be stopped.
  335. */
  336. void finishTool( TOOL_STATE* aState );
  337. /**
  338. * Function isRegistered()
  339. * Returns information about a tool registration status.
  340. *
  341. * @param aTool is the tool to be checked.
  342. * @return true if the tool is in the registered tools list, false otherwise.
  343. */
  344. bool isRegistered( TOOL_BASE* aTool ) const
  345. {
  346. return m_toolState.count( aTool ) > 0;
  347. }
  348. /**
  349. * Function isActive()
  350. * Returns information about a tool activation status.
  351. *
  352. * @param aTool is the tool to be checked.
  353. * @return True if the tool is on the active tools stack, false otherwise.
  354. */
  355. bool isActive( TOOL_BASE* aTool );
  356. /// Index of registered tools current states, associated by tools' objects.
  357. std::map<TOOL_BASE*, TOOL_STATE*> m_toolState;
  358. /// Index of the registered tools current states, associated by tools' names.
  359. std::map<std::string, TOOL_STATE*> m_toolNameIndex;
  360. /// Index of the registered tools to easily lookup by their type.
  361. std::map<const char*, TOOL_BASE*> m_toolTypes;
  362. /// Index of the registered tools current states, associated by tools' ID numbers.
  363. std::map<TOOL_ID, TOOL_STATE*> m_toolIdIndex;
  364. /// Stack of the active tools
  365. std::deque<TOOL_ID> m_activeTools;
  366. /// Instance of ACTION_MANAGER that handles TOOL_ACTIONs
  367. ACTION_MANAGER* m_actionMgr;
  368. EDA_ITEM* m_model;
  369. KIGFX::VIEW* m_view;
  370. KIGFX::VIEW_CONTROLS* m_viewControls;
  371. wxWindow* m_editFrame;
  372. /// Queue that stores events to be processed at the end of the event processing cycle.
  373. std::list<TOOL_EVENT> m_eventQueue;
  374. /// Flag saying if the currently processed event should be passed to other tools.
  375. bool m_passEvent;
  376. };
  377. #endif