OSDN Git Service

crystaledit: Use GetProfile*()/WriteProfile*() to read and write the registry wheneve...
[winmerge-jp/winmerge-jp.git] / Src / Plugins.h
1 /////////////////////////////////////////////////////////////////////////////
2 //    WinMerge:  an interactive diff/merge utility
3 //    Copyright (C) 1997-2000  Thingamahoochie Software
4 //    Author: Dean Grimm
5 //    SPDX-License-Identifier: GPL-2.0-or-later
6 /////////////////////////////////////////////////////////////////////////////
7 /**
8  *  @file Plugins.h
9  *
10  *  @brief Declaration file for VBS Scriptlets, VB ActiveX DLL, VC++ COM DLL
11  */ 
12 #pragma once
13
14 #include <Poco/Foundation.h>
15 #include <string>
16 #include <vector>
17 #include <windows.h>
18 #include <oleauto.h>
19 #include <memory>
20 #include "UnicodeString.h"
21
22 struct FileFilterElement;
23 typedef std::shared_ptr<FileFilterElement> FileFilterElementPtr;
24
25 /**
26  * @brief List of transformation categories (events)
27  *
28  * @note If you add some event, you have to complete this array in FileTransform.cpp
29  */
30 extern const wchar_t *TransformationCategories[];
31
32 /** 
33  * @brief Information structure for a plugin
34  */
35 class PluginInfo
36 {
37 public:
38         PluginInfo()
39                 : m_lpDispatch(nullptr), m_filters(NULL), m_bAutomatic(false), m_nFreeFunctions(0), m_disabled(false)
40         {       
41         }
42
43         ~PluginInfo()
44         {
45                 if (m_lpDispatch!=nullptr)
46                         m_lpDispatch->Release();
47         }
48
49         int LoadPlugin(const String & scriptletFilepath);
50
51         /// Parse the filter string (only for files), and create the filters
52         void LoadFilterString();
53         /**
54          * @brief Does the plugin handles this(ese) filename(s) ?
55          *
56          * @param szTest String of filenames, delimited with '|'
57          */
58         bool TestAgainstRegList(const String& szTest) const;
59
60 public:
61         String      m_filepath;
62         LPDISPATCH  m_lpDispatch;
63         String      m_name; // usually filename, except for special cases (like auto or no)
64         String      m_ext;
65         String      m_filtersText;
66         String      m_filtersTextDefault;
67         String      m_description;
68         String      m_event;
69         bool        m_bAutomatic;
70         bool        m_disabled;
71         std::vector<FileFilterElementPtr> m_filters;
72         /// only for plugins with free function names (EDITOR_SCRIPT)
73         int         m_nFreeFunctions;
74
75 private:
76         PluginInfo( const PluginInfo& other ); // non construction-copyable
77         PluginInfo& operator=( const PluginInfo& ); // non copyable
78 };
79
80 typedef std::shared_ptr<PluginInfo> PluginInfoPtr;
81
82 typedef std::vector<PluginInfoPtr> PluginArray;
83 typedef std::shared_ptr<PluginArray> PluginArrayPtr;
84
85 /**
86  * @brief Cache for the scriptlets' interfaces during the life of a thread. 
87  * One instance and only one for each thread (necessary for VB)
88  *
89  * @note Never create CScriptsOfThread directly : use the class CAssureScriptsForThread
90  * to guarantee unicity
91  */
92 class CScriptsOfThread
93 {
94 friend class CAssureScriptsForThread;
95 friend class CAllThreadsScripts;
96 public:
97         PluginArray * GetAvailableScripts(const wchar_t *transformationEvent);
98         PluginInfo * GetAutomaticPluginByFilter(const wchar_t *transformationEvent, const String& filteredText);
99         PluginInfo * GetPluginByName(const wchar_t *transformationEvent, const String& name);
100         PluginInfo * GetPluginInfo(LPDISPATCH piScript);
101         void SaveSettings();
102
103         void FreeAllScripts();
104         void FreeScriptsForEvent(const wchar_t *transformationEvent);
105
106 protected:
107         CScriptsOfThread();
108         ~CScriptsOfThread();
109         void Lock()       { m_nLocks ++; };
110         bool Unlock()   { m_nLocks --; return (m_nLocks == 0); };
111         /// Tell if this scripts is the one for main thread (by convention, the first in the repository)
112         bool bInMainThread();
113
114 private:
115         unsigned m_nLocks;
116         unsigned long m_nThreadId;
117         /// Result of CoInitialize
118         HRESULT hrInitialize;
119         int nTransformationEvents;
120         std::map<String, PluginArrayPtr> m_aPluginsByEvent;
121 };
122
123
124 /**
125  * @brief Repository of CScriptsOfThread
126  */
127 class CAllThreadsScripts
128 {
129 friend class CAssureScriptsForThread;
130 protected:
131         static void Add(CScriptsOfThread * scripts);
132         static void Remove(CScriptsOfThread * scripts);
133         static CScriptsOfThread * GetActiveSetNoAssert();
134 public:
135         /// main public function : get the plugins array for the current thread
136         static CScriptsOfThread * GetActiveSet();
137         /// by convention, the scripts for main thread must be created before all others
138         static bool bInMainThread(CScriptsOfThread * scripts);
139 private:
140         // fixed size array, advantage : no mutex to allocate/free
141         static std::vector<CScriptsOfThread *> m_aAvailableThreads;
142 };
143
144 /**
145  * @brief Simple control to add/remove a CScriptsOfThread in the repository. 
146  * Create at least one CAssumeScriptsForThread for each thread, including the main one.
147  * It's OK to create several CAssumeScriptsForThread for the same thread (if you need scripts in one function 
148  * and do not know what happened before the function).
149  */
150 class CAssureScriptsForThread
151 {
152 public:
153         CAssureScriptsForThread();
154         ~CAssureScriptsForThread();
155 };
156
157 namespace plugin
158 {
159
160 /**
161  * @brief Check for the presence of Windows Script
162  *
163  * .sct plugins require this optional component
164  */
165 bool IsWindowsScriptThere();
166 /**
167  * @brief Get a list of the function IDs and names in a script or activeX/COM DLL
168  *
169  * @return Returns the number of functions
170  *
171  */
172 int GetMethodsFromScript(LPDISPATCH piDispatch, std::vector<String>& namesArray, std::vector<int>& IdArray);
173
174 /**
175  * @brief Get the number of methods in the script
176  * @note For free function scripts (EDITOR_SCRIPT)
177  */
178 int CountMethodsInScript(LPDISPATCH piDispatch);
179
180 /**
181  * @brief Get the ID of the a free function
182  * @param methodOrdinal : index of the free function (0,1,2...)
183  */
184 int GetMethodIDInScript(LPDISPATCH piDispatch, int methodIndex);
185
186
187
188 // Wrappers to call plugins methods
189
190 /**
191  * @brief Call the plugin "PrediffBufferW" method, events PREDIFFING
192  *
193  * @param bstrBuf Overwrite/realloc this buffer
194  */
195 bool InvokePrediffBuffer(BSTR & bstrBuf, int & nChanged, LPDISPATCH piScript);
196
197 /** 
198  * @brief Call custom plugin functions : text transformation
199  */
200 bool InvokeTransformText(String & text, int & changed, LPDISPATCH piScript, int fncId);
201
202 /**
203  * @brief Call the plugin "UnpackBufferA" method, event BUFFER_PACK_UNPACK
204  *
205  * @param pszBuf has unknown format, so a simple char*
206  * never owervrites this source buffer
207  */
208 bool InvokeUnpackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int & subcode);
209 /**
210  * @brief Call the plugin "PackBufferA" method, event BUFFER_PACK_UNPACK
211  *
212  * @param pszBuf has unknown format, so a simple char*
213  * never owervrites this source buffer
214  */
215 bool InvokePackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int subcode);
216 /**
217  * @brief Call the plugin "UnpackFile" method, event FILE_PACK_UNPACK
218  */
219 bool InvokeUnpackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int & subCode);
220 /**
221  * @brief Call the plugin "PackFile" method, event FILE_PACK_UNPACK
222  */
223 bool InvokePackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int subCode);
224 /**
225  * @brief Call the plugin "IsFolder" method, event FILE_FOLDER_PACK_UNPACK
226  */
227 bool InvokeIsFolder(const String& file, IDispatch *piScript);
228 /**
229  * @brief Call the plugin "UnpackFolder" method, event FILE_FOLDER_PACK_UNPACK
230  */
231 bool InvokeUnpackFolder(const String& fileSource, const String& folderDest, int & nChanged, IDispatch *piScript, int & subCode);
232 /**
233  * @brief Call the plugin "PackFolder" method, event FILE_FOLDER_PACK_UNPACK
234  */
235 bool InvokePackFolder(const String& folderSource, const String& fileDest, int & nChanged, IDispatch *piScript, int subCode);
236 /**
237  * @brief Call the plugin "PrediffFile" method, event FILE_PREDIFF
238  */
239 bool InvokePrediffFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript);
240 /**
241  * @brief Call the plugin "ShowSettingsDialog" method
242  */
243 bool InvokeShowSettingsDialog(LPDISPATCH piScript);
244
245 }