1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  */
5 
6 #ifndef EDITOR_HOOKS_H
7 #define EDITOR_HOOKS_H
8 
9 #include "settings.h"
10 
11 //uncomment the below line if you want to do the hook performance measure
12 //#define EDITOR_HOOK_PERFORMANCE_MEASURE
13 
14 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
15     #include <typeinfo> // typeid
16 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
17 
18 class cbEditor;
19 class cbSmartIndentPlugin;
20 class wxScintillaEvent;
21 
22 /** Provides static functions to add hooks to the editor modification operations. */
23 namespace EditorHooks
24 {
25     /** Abstract base hook functor interface. Similar to cbEventFunctor class*/
26     class DLLIMPORT HookFunctorBase
27     {
28         public:
~HookFunctorBase()29             virtual ~HookFunctorBase(){}
30             virtual void Call(cbEditor*, wxScintillaEvent&) const = 0;
31 
32 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
33             virtual const char* GetTypeName() const = 0;
34 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
35 
36     };
37 
38     /** Functor class for use as a editor modification operations hook.
39       * Passed as the first parameter in RegisterHook() and
40       * UnregisterHook().
41       *
42       * example:
43       * EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<MyClass>(this, &MyClass::OnHookCalled);
44       * int id = EditorHooks::RegisterHook(myhook);
45       * ...
46       * (and before your class' destruction - or earlier):
47       * EditorHooks::UnregisterHook(id, true);
48       *
49       * Member functions used as hook callbacks must have the following signature:
50       * void YourFunctionName(cbEditor*, wxScintillaEvent&)
51       */
52     template<class T> class HookFunctor : public HookFunctorBase
53     {
54         public:
55             typedef void (T::*Func)(cbEditor*, wxScintillaEvent&);
HookFunctor(T * obj,Func func)56             HookFunctor(T* obj, Func func) : m_pObj(obj), m_pFunc(func)
57             { ; }
Call(cbEditor * editor,wxScintillaEvent & event)58             void Call(cbEditor* editor, wxScintillaEvent& event) const override
59             {
60                 if (m_pObj && m_pFunc)
61                     (m_pObj->*m_pFunc)(editor, event);
62             }
63 
64 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
65             /** return the name (usually mangled C++ name for the member function) */
GetTypeName()66             virtual const char* GetTypeName() const
67             {
68                 return typeid(m_pFunc).name();
69             }
70 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
71 
72         protected:
73             T* m_pObj;
74             Func m_pFunc;
75     };
76 
77     /** Register a project loading/saving hook.
78       * @param functor The functor to use as a callback.
79       * @return An ID. Use this to unregister your hook later.
80       */
81     extern DLLIMPORT int RegisterHook(HookFunctorBase* functor);
82     /** Unregister a previously registered project loading/saving hook.
83       * @param id The hook's ID. You should have the ID from when RegisterHook() was called.
84       * @param deleteHook If true, the hook will be deleted (default). If not, it's
85       * up to you to delete it.
86       * @return The functor. If @c deleteHook was true, it always returns NULL.
87       */
88     extern DLLIMPORT HookFunctorBase* UnregisterHook(int id, bool deleteHook = true);
89     /** Are there any hooks registered?
90       * @return True if any hooks are registered, false if none.
91       */
92     extern DLLIMPORT bool HasRegisteredHooks();
93     /** Call all registered hooks using the supplied parameters.
94       * This is called by ProjectLoader.
95       * @param editor The editor in question.
96       * @param event Parameter (wxScintilla event) to provide to the registered hook
97       */
98     extern DLLIMPORT void CallHooks(cbEditor* editor, wxScintillaEvent& event);
99 
100     /** Provides a HookFunctor which redirects the Call() of a cbSmartIndentPlugin
101       * so only the interface of cbSmartIndentPlugin has to be implemented for a new language.
102       */
103     class cbSmartIndentEditorHookFunctor : public HookFunctorBase
104     {
105         public:
106             /** ctor. */
107             cbSmartIndentEditorHookFunctor(cbSmartIndentPlugin* plugin);
108             /** dtor. */
~cbSmartIndentEditorHookFunctor()109             ~cbSmartIndentEditorHookFunctor() override{}
110             /** Needs to be implemented by the plugin to act(smart indent) accordingly.
111               * @param editor The editor that is active and whose content is changed
112               * @param event  The wxScintilla event fired to react accordingly (see cbEditor::CreateEditor, namely scintilla_events)
113               */
114             void Call(cbEditor* editor, wxScintillaEvent& event) const override;
115 
116 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
GetTypeName()117             virtual const char* GetTypeName() const
118             {
119                 return typeid(m_plugin).name();
120             }
121 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
122 
123         private:
124             cbSmartIndentPlugin* m_plugin;
125     };
126 }
127 
128 #endif // EDITOR_HOOKS_H
129