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 CBPLUGIN_H
7 #define CBPLUGIN_H
8 
9 #include <wx/arrstr.h>
10 #include <wx/event.h>
11 #include <wx/intl.h>
12 #include <wx/string.h>
13 
14 #include "settings.h" // build settings
15 #include "globals.h"
16 #include "logger.h"
17 #include "manager.h"
18 #include "pluginmanager.h"
19 #include "prep.h"
20 
21 #ifdef __WXMSW__
22     #ifndef PLUGIN_EXPORT
23         #ifdef EXPORT_LIB
24             #define PLUGIN_EXPORT __declspec (dllexport)
25         #else // !EXPORT_LIB
26             #ifdef BUILDING_PLUGIN
27                 #define PLUGIN_EXPORT __declspec (dllexport)
28             #else // !BUILDING_PLUGIN
29                 #define PLUGIN_EXPORT __declspec (dllimport)
30             #endif // BUILDING_PLUGIN
31         #endif // EXPORT_LIB
32     #endif // PLUGIN_EXPORT
33 #else
34     #define PLUGIN_EXPORT
35 #endif
36 
37 // this is the plugins SDK version number
38 // it will change when the SDK interface breaks
39 #define PLUGIN_SDK_VERSION_MAJOR   2
40 #define PLUGIN_SDK_VERSION_MINOR   0
41 #define PLUGIN_SDK_VERSION_RELEASE 0
42 
43 // class decls
44 class wxMenuBar;
45 class wxMenu;
46 class wxToolBar;
47 class wxPanel;
48 class wxWindow;
49 
50 class cbBreakpoint;
51 class cbConfigurationPanel;
52 class cbDebuggerConfiguration;
53 class cbEditor;
54 class cbProject;
55 class cbStackFrame;
56 class cbStatusBar;
57 class cbThread;
58 class cbWatch;
59 class Compiler;
60 class CompileTargetBase;
61 class ConfigManagerWrapper;
62 class FileTreeData;
63 class ProjectBuildTarget;
64 
65 struct PluginInfo;
66 
67 // Define basic groups for plugins' configuration.
68 static const int cgCompiler         = 0x01; ///< Compiler related.
69 static const int cgEditor           = 0x02; ///< Editor related.
70 static const int cgCorePlugin       = 0x04; ///< One of the core plugins.
71 static const int cgContribPlugin    = 0x08; ///< One of the contrib plugins (or any third-party plugin for that matter).
72 static const int cgUnknown          = 0x10; ///< Unknown. This will be probably grouped with cgContribPlugin.
73 
74 /** @brief Base class for plugins
75   *
76   * This is the most basic class a plugin must descend
77   * from.
78   * cbPlugin descends from wxEvtHandler, so it provides its methods as well...
79   * \n \n
80   * It's not enough to create a new plugin. You must also provide a resource
81   * zip file containing a file named "manifest.xml". Check the manifest.xml
82   * file of existing plugins to see how to create one (it's ultra-simple).
83   */
84 class PLUGIN_EXPORT cbPlugin : public wxEvtHandler
85 {
86     public:
87         /** In default cbPlugin's constructor the associated PluginInfo structure
88           * is filled with default values. If you inherit from cbPlugin, you
89           * should fill the m_PluginInfo members with the appropriate values.
90           */
91         cbPlugin();
92 
93         /** cbPlugin destructor. */
94         ~cbPlugin() override;
95 
96         /** The plugin must return its type on request. */
GetType()97         virtual PluginType GetType() const { return m_Type; }
98 
99         /** Return the plugin's configuration priority.
100           * This is a number (default is 50) that is used to sort plugins
101           * in configuration dialogs. Lower numbers mean the plugin's
102           * configuration is put higher in the list.
103           */
GetConfigurationPriority()104         virtual int GetConfigurationPriority() const { return 50; }
105 
106         /** Return the configuration group for this plugin. Default is cgUnknown.
107           * Notice that you can logically AND more than one configuration groups,
108           * so you could set it, for example, as "cgCompiler | cgContribPlugin".
109           */
GetConfigurationGroup()110         virtual int GetConfigurationGroup() const { return cgUnknown; }
111 
112         /** Return plugin's configuration panel.
113           * @param parent The parent window.
114           * @return A pointer to the plugin's cbConfigurationPanel. It is deleted by the caller.
115           */
GetConfigurationPanel(cb_optional wxWindow * parent)116         virtual cbConfigurationPanel* GetConfigurationPanel(cb_optional wxWindow* parent){ return nullptr; }
117 
118         /** Return plugin's configuration panel for projects.
119           * The panel returned from this function will be added in the project's
120           * configuration dialog.
121           * @param parent The parent window.
122           * @param project The project that is being edited.
123           * @return A pointer to the plugin's cbConfigurationPanel. It is deleted by the caller.
124           */
GetProjectConfigurationPanel(cb_optional wxWindow * parent,cb_optional cbProject * project)125         virtual cbConfigurationPanel* GetProjectConfigurationPanel(cb_optional wxWindow* parent, cb_optional cbProject* project){ return nullptr; }
126 
127         /** This method is called by Code::Blocks and is used by the plugin
128           * to add any menu items it needs on Code::Blocks's menu bar.\n
129           * It is a pure virtual method that needs to be implemented by all
130           * plugins. If the plugin does not need to add items on the menu,
131           * just do nothing ;)
132           *
133           * @note This function may be called more than one time. This can happen,
134           * for example, when a plugin is installed or uninstalled.
135           *
136           * @param menuBar the wxMenuBar to create items in
137           */
BuildMenu(cb_optional wxMenuBar * menuBar)138         virtual void BuildMenu(cb_optional wxMenuBar* menuBar) {}
139 
140         /** This method is called by Code::Blocks core modules (EditorManager,
141           * ProjectManager etc) and is used by the plugin to add any menu
142           * items it needs in the module's popup menu. For example, when
143           * the user right-clicks on a project file in the project tree,
144           * ProjectManager prepares a popup menu to display with context
145           * sensitive options for that file. Before it displays this popup
146           * menu, it asks all attached plugins (by asking PluginManager to call
147           * this method), if they need to add any entries
148           * in that menu. This method is called.\n
149           * If the plugin does not need to add items in the menu,
150           * just do nothing ;)
151           * @param type the module that's preparing a popup menu
152           * @param menu pointer to the popup menu
153           * @param data pointer to FileTreeData object (to access/modify the file tree)
154           */
155         virtual void BuildModuleMenu(cb_optional const ModuleType type, cb_optional wxMenu* menu, cb_optional const FileTreeData* data = nullptr) { }
156 
157         /** This method is called by Code::Blocks and is used by the plugin
158           * to add any toolbar items it needs on Code::Blocks's toolbar.\n
159           * It is a pure virtual method that needs to be implemented by all
160           * plugins. If the plugin does not need to add items on the toolbar,
161           * just do nothing ;)
162           * @param toolBar the wxToolBar to create items on
163           * @return The plugin should return true if it needed the toolbar, false if not
164           */
BuildToolBar(cb_optional wxToolBar * toolBar)165         virtual bool BuildToolBar(cb_optional wxToolBar* toolBar ) { return false; }
166 
167         /** This method return the priority of the plugin's toolbar, the less value
168           * indicates a more preceding position when C::B starts with no configuration file
169           */
GetToolBarPriority()170         virtual int GetToolBarPriority() { return 50; }
171 
172 #if wxUSE_STATUSBAR
173         /** This method is called by Code::Blocks and is used by the plugin
174           * to add a field on Code::Blocks's statusbar.\n
175           * If the plugin does not need to add items on the statusbar, just
176           * do nothing ;)
177           * @param statusBar the cbStatusBar to create items on
178           */
CreateStatusField(cbStatusBar * statusBar)179         virtual void CreateStatusField(cbStatusBar *statusBar) { wxUnusedVar(statusBar); }
180 #endif
181 
182         /** See whether this plugin is attached or not. A plugin should not perform
183           * any of its tasks, if not attached...
184           * @note This function is *not* virtual.
185           * @return Returns true if it attached, false if not.
186           */
IsAttached()187         bool IsAttached() const { return m_IsAttached; }
188 
189         /** See whether this plugin can be detached (unloaded) or not.
190           * This function is called usually when the user requests to
191           * uninstall or disable a plugin. Before disabling/uninstalling it, Code::Blocks
192           * asks the plugin if it can be detached or not. In other words, it checks
193           * to see if it can be disabled/uninstalled safely...
194           * @par
195           * A plugin should return true if it can be detached at this moment, false if not.
196           * @return The default implementation returns true.
197           */
CanDetach()198         virtual bool CanDetach() const { return true; }
199     protected:
200         /** Any descendent plugin should override this virtual method and
201           * perform any necessary initialization. This method is called by
202           * Code::Blocks (PluginManager actually) when the plugin has been
203           * loaded and should attach in Code::Blocks. When Code::Blocks
204           * starts up, it finds and <em>loads</em> all plugins but <em>does
205           * not</em> activate (attaches) them. It then activates all plugins
206           * that the user has selected to be activated on start-up.\n
207           * This means that a plugin might be loaded but <b>not</b> activated...\n
208           * Think of this method as the actual constructor...
209           */
OnAttach()210         virtual void OnAttach(){}
211 
212         /** Any descendent plugin should override this virtual method and
213           * perform any necessary de-initialization. This method is called by
214           * Code::Blocks (PluginManager actually) when the plugin has been
215           * loaded, attached and should de-attach from Code::Blocks.\n
216           * Think of this method as the actual destructor...
217           * @param appShutDown If true, the application is shutting down. In this
218           *         case *don't* use Manager::Get()->Get...() functions or the
219           *         behaviour is undefined...
220           */
OnRelease(cb_optional bool appShutDown)221         virtual void OnRelease(cb_optional bool appShutDown){}
222 
223         /** This method logs a "Not implemented" message and is provided for
224           * convenience only.
225           */
226         virtual void NotImplemented(const wxString& log) const;
227 
228         /** Holds the plugin's type. Set in the default constructor. */
229         PluginType m_Type;
230 
231         /** Holds the "attached" state. */
232         bool m_IsAttached;
233 
234     private:
235         friend class PluginManager; // only the plugin manager has access here
236 
237         /** Attach is <b>not</b> a virtual function, so you can't override it.
238           * The default implementation hooks the plugin to Code::Block's
239           * event handling system, so that the plugin can receive (and process)
240           * events from Code::Blocks core library. Use OnAttach() for any
241           * initialization specific tasks.
242           * @see OnAttach()
243           */
244         void Attach();
245 
246         /** Release is <b>not</b> a virtual function, so you can't override it.
247           * The default implementation un-hooks the plugin from Code::Blocks's
248           * event handling system. Use OnRelease() for any clean-up specific
249           * tasks.
250           * @param appShutDown If true, the application is shutting down. In this
251           *         case *don't* use Manager::Get()->Get...() functions or the
252           *         behaviour is undefined...
253           * @see OnRelease()
254           */
255         void Release(bool appShutDown);
256 };
257 
258 /** @brief Base class for compiler plugins
259   *
260   * This plugin type must offer some pre-defined build facilities, on top
261   * of the generic plugin's.
262   */
263 class PLUGIN_EXPORT cbCompilerPlugin: public cbPlugin
264 {
265     public:
266         cbCompilerPlugin();
267 
268         /** @brief Run the project/target.
269           *
270           * Running a project means executing its build output. Of course
271           * this depends on the selected build target and its type.
272           *
273           * @param target The specific build target to "run". If NULL, the plugin
274           * should ask the user which target to "run" (except maybe if there is
275           * only one build target in the project).
276           */
277         virtual int Run(ProjectBuildTarget* target = nullptr) = 0;
278 
279         /** Same as Run(ProjectBuildTarget*) but with a wxString argument. */
280         virtual int Run(const wxString& target) = 0;
281 
282         /** @brief Clean the project/target.
283           *
284           * Cleaning a project means deleting any files created by building it.
285           * This includes any object files, the binary output file, etc.
286           *
287           * @param target The specific build target to "clean". If NULL, it
288           * cleans all the build targets of the current project.
289           */
290         virtual int Clean(ProjectBuildTarget* target = nullptr) = 0;
291 
292         /** Same as Clean(ProjectBuildTarget*) but with a wxString argument. */
293         virtual int Clean(const wxString& target) = 0;
294 
295         /** @brief DistClean the project/target.
296           *
297           * DistClean will typically remove any config files
298           * and anything else that got created as part of
299           * building a software package.
300           *
301           * @param target The specific build target to "distclean". If NULL, it
302           * cleans all the build targets of the current project.
303           */
304         virtual int DistClean(ProjectBuildTarget* target = nullptr) = 0;
305 
306         /** Same as DistClean(ProjectBuildTarget*) but with a wxString argument. */
307         virtual int DistClean(const wxString& target) = 0;
308 
309         /** @brief Build the project/target.
310           *
311           * @param target The specific build target to build. If NULL, it
312           * builds all the targets of the current project.
313           */
314         virtual int Build(ProjectBuildTarget* target = nullptr) = 0;
315 
316         /** Same as Build(ProjectBuildTarget*) but with a wxString argument. */
317         virtual int Build(const wxString& target) = 0;
318 
319         /** @brief Rebuild the project/target.
320           *
321           * Rebuilding a project is equal to calling Clean() and then Build().
322           * This makes sure that all compilable files in the project will be
323           * compiled again.
324           *
325           * @param target The specific build target to rebuild. If NULL, it
326           * rebuilds all the build targets of the current project.
327           */
328         virtual int Rebuild(ProjectBuildTarget* target = nullptr) = 0;
329 
330         /** Same as Rebuild(ProjectBuildTarget*) but with a wxString argument. */
331         virtual int Rebuild(const wxString& target) = 0;
332 
333         /** @brief Build all open projects.
334           * @param target If not empty, the target to build in each project. Else all targets.
335           */
336         virtual int BuildWorkspace(const wxString& target = wxEmptyString) = 0;
337 
338         /** @brief Rebuild all open projects.
339           * @param target If not empty, the target to rebuild in each project. Else all targets.
340           */
341         virtual int RebuildWorkspace(const wxString& target = wxEmptyString) = 0;
342 
343         /** @brief Clean all open projects.
344           * @param target If not empty, the target to clean in each project. Else all targets.
345           */
346         virtual int CleanWorkspace(const wxString& target = wxEmptyString) = 0;
347 
348         /** @brief Compile a specific file.
349           *
350           * @param file The file to compile (must be a project file!)
351           */
352         virtual int CompileFile(const wxString& file) = 0;
353 
354         /** @brief Abort the current build process. */
355         virtual int KillProcess() = 0;
356 
357         /** @brief Is the plugin currently compiling? */
358         virtual bool IsRunning() const = 0;
359 
360         /** @brief Get the exit code of the last build process. */
361         virtual int GetExitCode() const = 0;
362 
363         /** @brief Display configuration dialog.
364           *
365           * @param project The selected project (can be NULL).
366           * @param target The selected target (can be NULL).
367           */
368         virtual int Configure(cbProject* project, ProjectBuildTarget* target, wxWindow *parent) = 0;
369     private:
370 };
371 
372 
373 class wxScintillaEvent;
374 
375 struct cbDebuggerFeature
376 {
377     enum Flags
378     {
379         Breakpoints,
380         Callstack,
381         CPURegisters,
382         Disassembly,
383         ExamineMemory,
384         Threads,
385         Watches,
386         ValueTooltips,
387         RunToCursor,
388         SetNextStatement
389     };
390 };
391 
392 /** @brief Base class for debugger plugins
393   *
394   * This plugin type must offer some pre-defined debug facilities, on top
395   * of the generic plugin's.
396   */
397 class PLUGIN_EXPORT cbDebuggerPlugin: public cbPlugin
398 {
399     public:
400         cbDebuggerPlugin(const wxString& guiName, const wxString& settingsName);
401 
402     public:
403         void OnAttach() override;
404         void OnRelease(bool appShutDown) override;
405 
406         void BuildMenu(wxMenuBar* menuBar) override;
407         void BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = nullptr) override;
408         bool BuildToolBar(wxToolBar* toolBar) override;
409 
410         /** @brief Notify the debugger that lines were added or removed in an editor.
411           * This causes the debugger to keep the breakpoints list in-sync with the
412           * editors (i.e. what the user sees).
413           * @param editor The editor in question.
414           * @param startline The starting line this change took place.
415           * @param lines The number of lines added or removed. If it's a positive number,
416           *              lines were added. If it's a negative number, lines were removed.
417           */
418         virtual void EditorLinesAddedOrRemoved(cbEditor* editor, int startline, int lines);
419     public:
420         virtual void OnAttachReal() = 0;
421         virtual void OnReleaseReal(bool appShutDown) = 0;
422 
423         virtual void SetupToolsMenu(wxMenu &menu) = 0;
424         virtual bool ToolMenuEnabled() const;
425 
426         virtual bool SupportsFeature(cbDebuggerFeature::Flags flag) = 0;
427 
428         virtual cbDebuggerConfiguration* LoadConfig(const ConfigManagerWrapper &config) = 0;
429 
430         cbDebuggerConfiguration& GetActiveConfig();
431         void SetActiveConfig(int index);
432         int GetIndexOfActiveConfig() const;
433 
434         /** @brief Called when the user clicks OK in Settings -> Debugger... */
OnConfigurationChange(bool isActive)435         virtual void OnConfigurationChange(bool isActive) { wxUnusedVar(isActive); };
436 
437         /** @brief Start a new debugging process. */
438         virtual bool Debug(bool breakOnEntry) = 0;
439 
440         /** @brief Continue running the debugged program. */
441         virtual void Continue() = 0;
442 
443         /** @brief Run the debugged program until it reaches the cursor at the current editor */
444         virtual bool RunToCursor(const wxString& filename, int line, const wxString& line_text) = 0;
445 
446         /** @brief Sets the position of the Program counter to the specified filename:line */
447         virtual void SetNextStatement(const wxString& filename, int line) = 0;
448 
449         /** @brief Execute the next instruction and return control to the debugger. */
450         virtual void Next() = 0;
451 
452         /** @brief Execute the next instruction and return control to the debugger. */
453         virtual void NextInstruction() = 0;
454 
455         /** @brief Execute the next instruction and return control to the debugger, if the instruction is a function call step into it. */
456         virtual void StepIntoInstruction() = 0;
457 
458         /** @brief Execute the next instruction, stepping into function calls if needed, and return control to the debugger. */
459         virtual void Step() = 0;
460 
461         /** @brief Execute the next instruction, stepping out of function calls if needed, and return control to the debugger. */
462         virtual void StepOut() = 0;
463 
464         /** @brief Break the debugging process (stop the debuggee for debugging). */
465         virtual void Break() = 0;
466 
467         /** @brief Stop the debugging process (exit debugging). */
468         virtual void Stop() = 0;
469 
470         /** @brief Is the plugin currently debugging? */
471         virtual bool IsRunning() const = 0;
472 
473         /** @brief Is the plugin stopped on breakpoint? */
474         virtual bool IsStopped() const = 0;
475 
476         /** @brief Is the plugin processing something? */
477         virtual bool IsBusy() const = 0;
478 
479         /** @brief Get the exit code of the last debug process. */
480         virtual int GetExitCode() const = 0;
481 
482         // stack frame calls;
483         virtual int GetStackFrameCount() const = 0;
484         virtual cb::shared_ptr<const cbStackFrame> GetStackFrame(int index) const = 0;
485         virtual void SwitchToFrame(int number) = 0;
486         virtual int GetActiveStackFrame() const = 0;
487 
488         // breakpoints calls
489         /** @brief Request to add a breakpoint.
490           * @param file The file to add the breakpoint based on a file/line pair.
491           * @param line The line number to put the breakpoint in @c file.
492           * @return True if succeeded, false if not.
493           */
494         virtual cb::shared_ptr<cbBreakpoint> AddBreakpoint(const wxString& filename, int line) = 0;
495 
496         /** @brief Request to add a breakpoint based on a data expression.
497           * @param dataExpression The data expression to add the breakpoint.
498           * @return True if succeeded, false if not.
499           */
500         virtual cb::shared_ptr<cbBreakpoint> AddDataBreakpoint(const wxString& dataExpression) = 0;
501         virtual int GetBreakpointsCount() const = 0;
502         virtual cb::shared_ptr<cbBreakpoint> GetBreakpoint(int index) = 0;
503         virtual cb::shared_ptr<const cbBreakpoint> GetBreakpoint(int index) const = 0;
504         virtual void UpdateBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint) = 0;
505         virtual void DeleteBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint) = 0;
506         virtual void DeleteAllBreakpoints() = 0;
507         virtual void ShiftBreakpoint(int index, int lines_to_shift) = 0;
508         virtual void EnableBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint, bool enable) = 0;
509         // threads
510         virtual int GetThreadsCount() const = 0;
511         virtual cb::shared_ptr<const cbThread> GetThread(int index) const = 0;
512         virtual bool SwitchToThread(int thread_number) = 0;
513 
514         // watches
515 
516         /// Request to add a watch for a given symbol in your language.
517         /// @param symbol Symbol or expression the debugger could understand and return a value for.
518         /// @param update Pass true if you want the debugger to immediately read the value of the
519         ///        symbol/expression, else it would be delayed until a call to UpdateWatch or
520         ///        UpdateWatches is made or some stepping command finishes. Passing false might be
521         ///        useful if you want to add multiple watches in one batch.
522         virtual cb::shared_ptr<cbWatch> AddWatch(const wxString& symbol, bool update) = 0;
523         /// Request to add a watch which would allow read/write access to a given memory range.
524         /// @param address The start address of the range.
525         /// @param size The size in bytes of the range.
526         /// @param symbol The name of the watch shown in the UI.
527         /// @param update Pass true if you want to make the debugger to immediately read the value
528         ///        of the watch, else it would be delayed until UpdateWatch/UpdateWatches is called
529         ///        or some stepping command finishes. Passing false is useful if you want to add
530         ///        multiple watches in one batch.
531         virtual cb::shared_ptr<cbWatch> AddMemoryRange(uint64_t address, uint64_t size,
532                                                        const wxString &symbol, bool update) = 0;
533         virtual void DeleteWatch(cb::shared_ptr<cbWatch> watch) = 0;
534         virtual bool HasWatch(cb::shared_ptr<cbWatch> watch) = 0;
535         virtual void ShowWatchProperties(cb::shared_ptr<cbWatch> watch) = 0;
536         virtual bool SetWatchValue(cb::shared_ptr<cbWatch> watch, const wxString& value) = 0;
537         virtual void ExpandWatch(cb::shared_ptr<cbWatch> watch) = 0;
538         virtual void CollapseWatch(cb::shared_ptr<cbWatch> watch) = 0;
539         virtual void UpdateWatch(cb::shared_ptr<cbWatch> watch) = 0;
540 
541         /// Manually ask the debugger to read/update the values of the given list of watches.
542         /// Depending on the debugger it might be more efficient than calling UpdateWatch multiple
543         /// times. The default implementation does just that.
544         /// @note The caller must make sure that all watches in the array are for this plugin.
545         /// Passing watches for other plugins would have unexpected results. The plugins aren't
546         /// required to check for this.
547         virtual void UpdateWatches(const std::vector<cb::shared_ptr<cbWatch>> &watches);
548 
549         struct WatchesDisabledMenuItems
550         {
551             enum
552             {
553                 Empty        = 0,
554                 Rename       = 1 << 0,
555                 Properties   = 1 << 1,
556                 Delete       = 1 << 2,
557                 DeleteAll    = 1 << 3,
558                 AddDataBreak = 1 << 4,
559                 ExamineMemory = 1 << 5
560             };
561         };
562 
563         /**
564           * @param[out] disabledMenus A combination of WatchesDisabledMenuItems, which controls which of the default menu items are disabled
565           */
OnWatchesContextMenu(wxMenu & menu,const cbWatch & watch,wxObject * property,int & disabledMenus)566         virtual void OnWatchesContextMenu(wxMenu &menu, const cbWatch &watch, wxObject *property, int &disabledMenus)
567         { wxUnusedVar(menu); wxUnusedVar(watch); wxUnusedVar(property); wxUnusedVar(disabledMenus); };
568 
569         virtual void SendCommand(const wxString& cmd, bool debugLog) = 0;
570 
571         virtual void AttachToProcess(const wxString& pid) = 0;
572         virtual void DetachFromProcess() = 0;
573         virtual bool IsAttachedToProcess() const = 0;
574 
575         virtual void GetCurrentPosition(wxString& filename, int &line) = 0;
576 
577 
578         virtual void OnValueTooltip(const wxString& token, const wxRect &evalRect);
579         virtual bool ShowValueTooltip(int style);
580     private:
581         void RegisterValueTooltip();
582         void ProcessValueTooltip(CodeBlocksEvent& event);
583         void CancelValueTooltip(CodeBlocksEvent& event);
584 
585     protected:
586         enum StartType
587         {
588             StartTypeUnknown = 0,
589             StartTypeRun,
590             StartTypeStepInto
591         };
592     protected:
593         virtual void ConvertDirectory(wxString& str, wxString base = _T(""), bool relative = true) = 0;
594         virtual cbProject* GetProject() = 0;
595         virtual void ResetProject() = 0;
596         virtual void CleanupWhenProjectClosed(cbProject *project) = 0;
597 
598         /** @brief Called when the compilation has finished. The compilation is started when EnsureBuildUpToDate is called.
599           * @param compilerFailed the compilation failed for some reason.
600           * @param startType it is the same value given to the Debug method, when the debugger session was started.
601           * @return True if debug session is start, false if there are any errors or the users canceled the session.
602         */
CompilerFinished(bool compilerFailed,StartType startType)603         virtual bool CompilerFinished(bool compilerFailed, StartType startType)
604         { wxUnusedVar(compilerFailed); wxUnusedVar(startType); return false; }
605     public:
606         enum DebugWindows
607         {
608             Backtrace,
609             CPURegisters,
610             Disassembly,
611             ExamineMemory,
612             MemoryRange,
613             Threads,
614             Watches
615         };
616 
617         virtual void RequestUpdate(DebugWindows window) = 0;
618 
619     public:
620         virtual wxString GetEditorWordAtCaret(const wxPoint *mousePosition = NULL);
621         void ClearActiveMarkFromAllEditors();
622 
623         enum SyncEditorResult
624         {
625             SyncOk = 0,
626             SyncFileNotFound,
627             SyncFileUnknown
628         };
629 
630         SyncEditorResult SyncEditor(const wxString& filename, int line, bool setMarker = true);
631 
632         void BringCBToFront();
633 
634 
635         void ShowLog(bool clear);
636         void Log(const wxString& msg, Logger::level level = Logger::info);
637         void DebugLog(const wxString& msg, Logger::level level = Logger::info);
638         bool HasDebugLog() const;
639         void ClearLog();
640 
641         // Called only by DebuggerManager, when registering plugin or changing settings
642         void SetupLog(int normalIndex);
643 
GetGUIName()644         wxString GetGUIName() const { return m_guiName; }
GetSettingsName()645         wxString GetSettingsName() const { return m_settingsName; }
646 
647     protected:
648         void SwitchToDebuggingLayout();
649         void SwitchToPreviousLayout();
650 
651         bool GetDebuggee(wxString& pathToDebuggee, wxString& workingDirectory, ProjectBuildTarget* target);
652         bool EnsureBuildUpToDate(StartType startType);
WaitingCompilerToFinish()653         bool WaitingCompilerToFinish() const { return m_WaitingCompilerToFinish; }
654 
655         int RunNixConsole(wxString& consoleTty);
656         void MarkAsStopped();
657 
658     private:
659         void OnEditorOpened(CodeBlocksEvent& event);
660         void OnProjectActivated(CodeBlocksEvent& event);
661         void OnProjectClosed(CodeBlocksEvent& event);
662         void OnCompilerFinished(CodeBlocksEvent& event);
663     private:
664         wxString m_PreviousLayout;
665         cbCompilerPlugin* m_pCompiler;
666         bool m_WaitingCompilerToFinish;
667 
668         StartType m_StartType;
669 
670         int m_ActiveConfig;
671 
672         int m_LogPageIndex;
673         bool m_lastLineWasNormal;
674         wxString m_guiName, m_settingsName;
675 };
676 
677 /** @brief Base class for tool plugins
678   *
679   * This plugin is automatically managed by Code::Blocks, so the inherited
680   * functions to build menus/toolbars are hidden.
681   *
682   * Tool plugins are automatically added under the "Plugins" menu.
683   */
684 class PLUGIN_EXPORT cbToolPlugin : public cbPlugin
685 {
686     public:
687         cbToolPlugin();
688 
689         /** @brief Execute the plugin.
690           *
691           * This is the only function needed by a cbToolPlugin.
692           * This will be called when the user selects the plugin from the "Plugins"
693           * menu.
694           */
695         virtual int Execute() = 0;
696     private:
697         // "Hide" some virtual members, that are not needed in cbToolPlugin
BuildMenu(cb_unused wxMenuBar * menuBar)698         void BuildMenu(cb_unused wxMenuBar* menuBar) override{}
RemoveMenu(cb_unused wxMenuBar * menuBar)699         void RemoveMenu(cb_unused wxMenuBar* menuBar){}
700         void BuildModuleMenu(cb_unused const ModuleType type, cb_unused wxMenu* menu, cb_unused const FileTreeData* data = nullptr) override{}
BuildToolBar(cb_unused wxToolBar * toolBar)701         bool BuildToolBar(cb_unused wxToolBar* toolBar) override{ return false; }
RemoveToolBar(cb_unused wxToolBar * toolBar)702         void RemoveToolBar(cb_unused wxToolBar* toolBar){}
703 };
704 
705 /** @brief Base class for mime plugins
706   *
707   * Mime plugins are called by Code::Blocks to operate on files that Code::Blocks
708   * wouldn't know how to handle on itself.
709   */
710 class PLUGIN_EXPORT cbMimePlugin : public cbPlugin
711 {
712     public:
713         cbMimePlugin();
714 
715         /** @brief Can a file be handled by this plugin?
716           *
717           * @param filename The file in question.
718           * @return The plugin should return true if it can handle this file,
719           * false if not.
720           */
721         virtual bool CanHandleFile(const wxString& filename) const = 0;
722 
723         /** @brief Open the file.
724           *
725           * @param filename The file to open.
726           * @return The plugin should return zero on success, other value on error.
727           */
728         virtual int OpenFile(const wxString& filename) = 0;
729 
730         /** @brief Is this a default handler?
731           *
732           * This is a flag notifying the main app that this plugin can handle
733           * every file passed to it. Usually you 'll want to return false in
734           * this function, because you usually create specialized handler
735           * plugins (for specific MIME types)...
736           *
737           * @return True if this plugin can handle every possible MIME type,
738           * false if not.
739           */
740         virtual bool HandlesEverything() const = 0;
741     private:
742         // "Hide" some virtual members, that are not needed in cbMimePlugin
BuildMenu(cb_unused wxMenuBar * menuBar)743         void BuildMenu(cb_unused wxMenuBar* menuBar) override{}
RemoveMenu(cb_unused wxMenuBar * menuBar)744         void RemoveMenu(cb_unused wxMenuBar* menuBar){}
745         void BuildModuleMenu(cb_unused const ModuleType type, cb_unused wxMenu* menu, cb_unused const FileTreeData* data = nullptr) override{}
BuildToolBar(cb_unused wxToolBar * toolBar)746         bool BuildToolBar(cb_unused wxToolBar* toolBar) override{ return false; }
RemoveToolBar(cb_unused wxToolBar * toolBar)747         void RemoveToolBar(cb_unused wxToolBar* toolBar){}
748 };
749 
750 class wxHtmlLinkEvent;
751 
752 /** @brief Base class for code-completion plugins
753   *
754   * The main operations of a code-completion plugin are executed by CCManager
755   * at the appropriate times. Smaller CC plugins *should* not have need to
756   * register very many (if any) events/editor hooks.
757   */
758 class PLUGIN_EXPORT cbCodeCompletionPlugin : public cbPlugin
759 {
760     public:
761         cbCodeCompletionPlugin();
762 
763         /** Level of functionality a CC plugin is able to provide. */
764         enum CCProviderStatus
765         {
766             ccpsInactive, //!< CC plugin provides no functionality.
767             ccpsActive,   //!< CC plugin provides specialized functionality.
768             ccpsUniversal //!< CC plugin provides generic functionality.
769         };
770 
771         /** Structure representing a generic token, passed between CC plugins and CCManager. */
772         struct CCToken
773         {
774             /** @brief Convenience constructor.
775               *
776               * Represents a generic token, passed between CC plugins and CCManager.
777               *
778               * @param _id Internal identifier for a CC plugin to reference the token in its data structure.
779               * @param dispNm The string CCManager will use to display this token.
780               * @param categ The category corresponding to the index of the registered image (during autocomplete).
781               *              Negative values are reserved for CCManager.
782               */
783             CCToken(int _id, const wxString& dispNm, int categ = -1) :
idCCToken784                 id(_id), category(categ), weight(5), displayName(dispNm), name(dispNm) {}
785 
786             /** @brief Construct a fully specified CCToken.
787               *
788               * Represents a generic token, passed between CC plugins and CCManager.
789               *
790               * @param _id Internal identifier for a CC plugin to reference the token in its data structure.
791               * @param dispNm The verbose string CCManager will use to display this token.
792               * @param nm Minimal name of the token that CCManager may choose to display in restricted circumstances.
793               * @param _weight Lower numbers are placed earlier in listing, 5 is default; try to keep 0-10.
794               * @param categ The category corresponding to the index of the registered image (during autocomplete).
795               *              Negative values are reserved for CCManager.
796               */
797             CCToken(int _id, const wxString& dispNm, const wxString& nm, int _weight, int categ = -1) :
idCCToken798                 id(_id), category(categ), weight(_weight), displayName(dispNm), name(nm) {}
799 
800             int id;               //!< CCManager will pass this back unmodified. Use it as an internal identifier for the token.
801             int category;         //!< The category corresponding to the index of the registered image (during autocomplete).
802             int weight;           //!< Lower numbers are placed earlier in listing, 5 is default; try to keep 0-10.
803             wxString displayName; //!< Verbose string representing the token.
804             wxString name;        //!< Minimal name of the token that CCManager may choose to display in restricted circumstances.
805         };
806 
807         /** Structure representing an individual calltip with an optional highlighted range */
808         struct CCCallTip
809         {
810             /** @brief Convenience constructor.
811               *
812               * Represents an individual calltip to be processed and displayed by CCManager.
813               *
814               * @param tp The content of the calltip.
815               */
CCCallTipCCCallTip816             CCCallTip(const wxString& tp) :
817                 hlStart(-1), hlEnd(-1), tip(tp) {}
818 
819             /** @brief Construct a calltip, specifying a highlighted range
820               *
821               * Represents an individual calltip, containing a highlighted range (generally the
822               * active parameter), to be processed and displayed by CCManager.
823               *
824               * @param tp The content of the calltip.
825               * @param highlightStart The start index of the desired highlighted range.
826               * @param highlightEndThe end index of the desired highlighted range.
827               */
CCCallTipCCCallTip828             CCCallTip(const wxString& tp, int highlightStart, int highlightEnd) :
829                 hlStart(highlightStart), hlEnd(highlightEnd), tip(tp) {}
830 
831             int hlStart;  //!< The start index of the desired highlighted range.
832             int hlEnd;    //!< The end index of the desired highlighted range.
833             wxString tip; //!< The content of the calltip.
834         };
835 
836         /** @brief Does this plugin handle code completion for the editor <tt>ed</tt>?
837           *
838           * The plugin should check the lexer, the <tt>HighlightLanguage</tt>, the file extension,
839           * or some combination of these. Do @em not call @c CCManager::GetProviderFor()
840           * from this function.
841           *
842           * @param ed The editor being checked.
843           * @return The level of functionality this plugin is able to supply.
844           */
845         virtual CCProviderStatus GetProviderStatusFor(cbEditor* ed) = 0;
846 
847         /** @brief Supply content for the autocompletion list.
848           *
849           * CCManager takes care of calling this during most relevant situations. If the
850           * autocompletion mechanism is required at a time that CCManager does not initiate, call
851           * @code
852           * CodeBlocksEvent evt(cbEVT_COMPLETE_CODE);
853           * Manager::Get()->ProcessEvent(evt);
854           * @endcode
855           * In this case, the parameter isAuto is passed as false value.
856           *
857           * Here is an example
858           * @code
859           * #include <math.h>
860           * int main()
861           * {
862           *     float i = cos|------auto completion here
863           *               ^  ^
864           * }
865           * @endcode
866           * This is the case the user has just enter the chars "cos", now to get a suggestion list.
867           * The first '^' is the position of tknStart, and the second '^' is the position of tknEnd
868           * In this case, the cc plugin would supply a CCToken vectors, which could contains "cos",
869           * "cosh" and "cosh"...
870           * In some special cases, the tknStart tknEnd may point to the same position, such as
871           * @code
872           * struct AAA { int m_aaa1; };
873           * int main()
874           * {
875           *     AAA obj;
876           *     obj.|------auto completion here
877           *         ^
878           * }
879           * @endcode
880           * Here, '^' are the positions of both tknStart and tknEnd.
881           *
882           * @param isAuto Passed as @c true if autocompletion was launched by typing an 'interesting'
883           *               character such as '<tt>&gt;</tt>' (for '<tt>-&gt;</tt>'). It is the plugin's job
884           *               to filter out incorrect calls of this.
885           * @param ed The context of this codecompletion call.
886           * @param[in,out] tknStart The assumed beginning of the token to be autocompleted. Change this variable
887           *                         if the plugin calculates a different starting location.
888           * @param[in,out] tknEnd The current position/end of the known part of the token to be completed. The
889           *                       plugin is allowed to change this (but it is not recommended).
890           * @return Completable tokens, or empty vector to cancel autocompletion.
891           */
892         virtual std::vector<CCToken> GetAutocompList(bool isAuto, cbEditor* ed, int& tknStart, int& tknEnd) = 0;
893 
894         /** @brief Supply html formatted documentation for the passed token.
895           *
896           * Refer to http://docs.wxwidgets.org/stable/overview_html.html#overview_html_supptags for
897           * the available formatting. When selecting colours, prefer use of the ones CCManager has
898           * registered with ColourManager, which are (TODO: register colours). Returning an empty
899           * string will cancel the documentation popup.
900           *
901           * @param token The token to document.
902           * @return Either an html document or an empty string (if no documentation available).
903           */
904         virtual wxString GetDocumentation(const CCToken& token) = 0;
905 
906         /** @brief Supply content for the calltip at the specified location.
907           *
908           * The output parameter @c argsPos is required to be set to the same (but unique) position
909           * for each unique calltip. This position is the location corresponding to the beginning of
910           * the argument list:
911           * @code
912           * int endOfWord = stc->WordEndPosition(pos, true);
913           *                                     ^
914           * @endcode
915           * Each returned CCCallTip is allowed to have embedded '\\n' line breaks.
916           *
917           * @param pos The location in the editor that the calltip is requested for.
918           * @param style The scintilla style of the cbStyledTextCtrl at the given location. (TODO: This
919           *              is unusual, remove it?)
920           * @param ed The context of this calltip request.
921           * @param[out] argsPos The location in the editor of the beginning of the argument list. @em Required.
922           * @return Each entry in this vector is guaranteed either a new line or a separate page in the calltip.
923           *         CCManager will decide if lines should be further split (for formatting to fit the monitor).
924           */
925         virtual std::vector<CCCallTip> GetCallTips(int pos, int style, cbEditor* ed, int& argsPos) = 0;
926 
927         /** @brief Supply the definition of the token at the specified location.
928           *
929           * The token(s) returned by this function are used to display tooltips.
930           *
931           * @param pos The location being queried.
932           * @param ed The context of the request.
933           * @param[out] allowCallTip Allow CCManager to consider displaying a calltip if the results from this
934           *                          function are unsuitable/empty. True by default.
935           * @return A list of the token(s) that match the specified location, an empty vector if none.
936           */
937         virtual std::vector<CCToken> GetTokenAt(int pos, cbEditor* ed, bool& allowCallTip) = 0;
938 
939         /** @brief Callback to handle a click on a link in the documentation popup.
940          *
941          * Handle a link command by, for example, showing the definition of a member function, or opening
942          * an editor to the location of the declaration.
943          *
944          * @param event The generated event (it is the plugin's responsibility to Skip(), if desired).
945          * @param[out] dismissPopup If set to true, the popup will be hidden.
946          * @return If non-empty, the popup's content will be set to this html formatted string.
947          */
948         virtual wxString OnDocumentationLink(wxHtmlLinkEvent& event, bool& dismissPopup) = 0;
949 
950         /** @brief Callback for inserting the selected autocomplete entry into the editor.
951           *
952           * The default implementation executes (wx)Scintilla's insert. Override and call
953           * @c ed->GetControl()->AutoCompCancel() for different @c wxEVT_SCI_AUTOCOMP_SELECTION behaviour.
954           *
955           * @param token The CCToken corresponding to the selected entry.
956           * @param ed The editor to operate in.
957           */
958         virtual void DoAutocomplete(const CCToken& token, cbEditor* ed);
959 
960         /** @brief Callback for inserting the selected autocomplete entry into the editor.
961           *
962           * This function is only called if CCManager fails to retrieve the CCToken associated with the
963           * selection (which should never happen). The default implementation creates a CCToken and passes
964           * it to <tt>DoAutocomplete(const CCToken&, cbEditor*)</tt><br>
965           * Override for different behaviour.
966           *
967           * @param token A string corresponding to the selected entry.
968           * @param ed The editor to operate in.
969           */
970         virtual void DoAutocomplete(const wxString& token, cbEditor* ed);
971 
972     protected:
973         /** @brief Has this plugin been selected to provide content for the editor.
974           *
975           * Convenience function; asks CCManager if this plugin is granted jurisdiction over the editor.
976           *
977           * @param ed The editor to check.
978           * @return Is provider for the editor.
979           */
980         bool IsProviderFor(cbEditor* ed);
981 };
982 
983 /** @brief Base class for wizard plugins
984   *
985   * Wizard plugins are called by Code::Blocks when the user selects
986   * "File->New...".
987   *
988   * A plugin of this type can support more than one wizard. Additionally,
989   * each wizard can support new workspaces, new projects, new targets or new files.
990   * The @c index used as a parameter to most of the functions, denotes 0-based index
991   * of the project wizard to run.
992   */
993 class PLUGIN_EXPORT cbWizardPlugin : public cbPlugin
994 {
995     public:
996         cbWizardPlugin();
997 
998         /** @return the number of template wizards this plugin contains */
999         virtual int GetCount() const = 0;
1000 
1001         /** @param index the wizard index.
1002           * @return the output type of the specified wizard at @c index */
1003         virtual TemplateOutputType GetOutputType(int index) const = 0;
1004 
1005         /** @param index the wizard index.
1006           * @return the template's title */
1007         virtual wxString GetTitle(int index) const = 0;
1008 
1009         /** @param index the wizard index.
1010           * @return the template's description */
1011         virtual wxString GetDescription(int index) const = 0;
1012 
1013         /** @param index the wizard index.
1014           * @return the template's category (GUI, Console, etc; free-form text). Try to adhere to standard category names... */
1015         virtual wxString GetCategory(int index) const = 0;
1016 
1017         /** @param index the wizard index.
1018           * @return the template's bitmap */
1019         virtual const wxBitmap& GetBitmap(int index) const = 0;
1020 
1021         /** @param index the wizard index.
1022           * @return this wizard's script filename (if this wizard is scripted). */
1023         virtual wxString GetScriptFilename(int index) const = 0;
1024 
1025         /** When this is called, the wizard must get to work ;).
1026           * @param index the wizard index.
1027           * @param createdFilename if provided, on return it should contain the main filename
1028           *                         this wizard created. If the user created a project, that
1029           *                         would be the project's filename.
1030           *                         If the wizard created a build target, that would be an empty string.
1031           *                         If the wizard created a file, that would be the file's name.
1032           * @return a pointer to the generated cbProject or ProjectBuildTarget. NULL for everything else (failure too).
1033           * You should dynamic-cast this to the correct type based on GetOutputType() 's value. */
1034         virtual CompileTargetBase* Launch(int index, wxString* createdFilename = nullptr) = 0; // do your work ;)
1035     private:
1036         // "Hide" some virtual members, that are not needed in cbCreateWizardPlugin
BuildMenu(cb_unused wxMenuBar * menuBar)1037         void BuildMenu(cb_unused wxMenuBar* menuBar) override{}
RemoveMenu(cb_unused wxMenuBar * menuBar)1038         void RemoveMenu(cb_unused wxMenuBar* menuBar){}
1039         void BuildModuleMenu(cb_unused const ModuleType type, cb_unused wxMenu* menu, cb_unused const FileTreeData* data = nullptr) override{}
BuildToolBar(cb_unused wxToolBar * toolBar)1040         bool BuildToolBar(cb_unused wxToolBar* toolBar) override{ return false; }
RemoveToolBar(cb_unused wxToolBar * toolBar)1041         void RemoveToolBar(cb_unused wxToolBar* toolBar){}
1042 };
1043 
1044 /** @brief Base class for SmartIndent plugins
1045   *
1046   * SmartIndent plugins provide the smart indenting for different languages.
1047   * These plugins don't eat processing time after startup when they are not active.
1048   * The hook gets installed during OnAttach.
1049   */
1050 class cbStyledTextCtrl;
1051 class cbSmartIndentPlugin : public cbPlugin
1052 {
1053     public:
1054         cbSmartIndentPlugin();
1055     private:
1056         // "Hide" some virtual members, that are not needed in cbSmartIndentPlugin
BuildMenu(cb_unused wxMenuBar * menuBar)1057         void BuildMenu(cb_unused wxMenuBar* menuBar) override{}
RemoveMenu(cb_unused wxMenuBar * menuBar)1058         void RemoveMenu(cb_unused wxMenuBar* menuBar){}
1059         void BuildModuleMenu(cb_unused const ModuleType type, cb_unused wxMenu* menu, cb_unused const FileTreeData* data = nullptr) override{}
BuildToolBar(cb_unused wxToolBar * toolBar)1060         bool BuildToolBar(cb_unused wxToolBar* toolBar) override{ return false; }
RemoveToolBar(cb_unused wxToolBar * toolBar)1061         void RemoveToolBar(cb_unused wxToolBar* toolBar){}
1062     protected:
1063         void OnAttach() override;
1064         void OnRelease(bool appShutDown) override;
1065 
1066     public:
1067         /** When this is called, the smartIndent mechanism must get to work ;).
1068           *
1069           * Please check if this is the right smartIndent mechanism first:
1070           * Don't indent for languages you don't know.
1071           */
1072         virtual void OnEditorHook(cbEditor* editor, wxScintillaEvent& event) const = 0;
1073 
1074         /** This is called after a code completion operation finishes.
1075           *
1076           * Use it as an opportunity to tidy up CC's formating.
1077           * Don't indent for languages you don't know.
1078           */
OnCCDone(cb_unused cbEditor * ed)1079         virtual void OnCCDone(cb_unused cbEditor* ed){}
1080 
1081     protected:
1082         /** (reverse) search for the last word which is not comment **/
1083         wxString GetLastNonCommentWord(cbEditor* ed, int position = -1, unsigned int NumberOfWords = 1 ) const;
1084         /** (reverse) search for the last characters, which are not whitespace and not comment **/
1085         wxString GetLastNonWhitespaceChars(cbEditor* ed, int position = -1, unsigned int NumberOfChars = 1) const;
1086 
1087         /** forward search to the next character which is not a whitespace **/
1088         wxChar GetLastNonWhitespaceChar(cbEditor* ed, int position = -1) const;
1089         wxChar GetNextNonWhitespaceCharOnLine(cbStyledTextCtrl* stc, int position = -1, int *pos = nullptr) const;
1090 
1091         int FindBlockStart(cbStyledTextCtrl* stc, int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true) const;
1092         int FindBlockStart(cbStyledTextCtrl* stc, int position, wxString blockStart, wxString blockEnd, bool CaseSensitive = true) const;
1093 
1094         void Indent(cbStyledTextCtrl* stc, wxString& indent)const;
1095         bool Indent(cbStyledTextCtrl* stc, wxString& indent, int posInLine)const;
1096 
1097         /** Get the first brace in the line according to the line style */
1098         int GetFirstBraceInLine(cbStyledTextCtrl* stc, int string_style)const;
1099 
1100         /** Get the last non-whitespace character from position in line */
1101         wxChar GetNextNonWhitespaceCharOfLine(cbStyledTextCtrl* stc, int position = -1, int *pos = nullptr)const;
1102         bool AutoIndentEnabled()const;
1103         bool SmartIndentEnabled()const;
1104         bool BraceSmartIndentEnabled()const;
1105         bool BraceCompletionEnabled()const;
1106         bool SelectionBraceCompletionEnabled()const;
1107         void OnCCDoneEvent(CodeBlocksEvent& event);
1108     private:
1109         int m_FunctorId;
1110 };
1111 
1112 /** @brief Plugin registration object.
1113   *
1114   * Use this class to register your new plugin with Code::Blocks.
1115   * All you have to do is instantiate a PluginRegistrant object.
1116   * @par
1117   * Example code to use in one of your plugin's source files (supposedly called "MyPlugin"):
1118   * @code
1119   * namespace
1120   * {
1121   *     PluginRegistrant<MyPlugin> registration("MyPlugin");
1122   * }
1123   * @endcode
1124   */
1125 template<class T> class PluginRegistrant
1126 {
1127     public:
1128         /// @param name The plugin's name.
PluginRegistrant(const wxString & name)1129         PluginRegistrant(const wxString& name)
1130         {
1131             Manager::Get()->GetPluginManager()->RegisterPlugin(name, // plugin's name
1132                                                                 &CreatePlugin, // creation
1133                                                                 &FreePlugin, // destruction
1134                                                                 &SDKVersion); // SDK version
1135         }
1136 
CreatePlugin()1137         static cbPlugin* CreatePlugin()
1138         {
1139             return new T;
1140         }
1141 
FreePlugin(cbPlugin * plugin)1142         static void FreePlugin(cbPlugin* plugin)
1143         {
1144             delete plugin;
1145         }
1146 
SDKVersion(int * major,int * minor,int * release)1147         static void SDKVersion(int* major, int* minor, int* release)
1148         {
1149             if (major) *major = PLUGIN_SDK_VERSION_MAJOR;
1150             if (minor) *minor = PLUGIN_SDK_VERSION_MINOR;
1151             if (release) *release = PLUGIN_SDK_VERSION_RELEASE;
1152         }
1153 };
1154 
1155 #endif // CBPLUGIN_H
1156