OSDN Git Service

Fix the issue where the Apache Tika plugin becomes enabled again when reopening the...
[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 <optional>
18 #include <windows.h>
19 #include <oleauto.h>
20 #include <memory>
21 #include "UnicodeString.h"
22
23 struct FileFilterElement;
24 typedef std::shared_ptr<FileFilterElement> FileFilterElementPtr;
25
26 /**
27  * @brief List of transformation categories (events)
28  *
29  * @note If you add some event, you have to complete this array in FileTransform.cpp
30  */
31 extern const wchar_t *TransformationCategories[];
32
33 enum { EVENTID_INITIALIZE, EVENTID_TERMINATE };
34
35 /** 
36  * @brief Information structure for a plugin
37  */
38 class PluginInfo
39 {
40 public:
41         PluginInfo();
42         ~PluginInfo();
43
44         int LoadPlugin(const String & scriptletFilepath);
45         int MakeInfo(const String & scriptletFilepath, IDispatch *pDispatch);
46
47         /// Parse the filter string (only for files), and create the filters
48         void LoadFilterString();
49         /**
50          * @brief Does the plugin handles this(ese) filename(s) ?
51          *
52          * @param szTest String of filenames, delimited with '|'
53          */
54         bool TestAgainstRegList(const String& szTest) const;
55
56         std::optional<StringView> GetExtendedPropertyValue(const String& name) const;
57
58 public:
59         String      m_filepath;
60         LPDISPATCH  m_lpDispatch;
61         String      m_name; // usually filename, except for special cases (like auto or no)
62         String      m_ext;
63         String      m_extendedProperties;
64         String      m_arguments;
65         String      m_argumentsDefault;
66         String      m_filtersText;
67         String      m_filtersTextDefault;
68         String      m_description;
69         String      m_event;
70         bool        m_bAutomatic;
71         bool        m_bAutomaticDefault;
72         bool        m_disabled;
73         bool        m_hasArgumentsProperty;
74         bool        m_hasVariablesProperty;
75         bool        m_hasPluginOnEventMethod;
76         std::vector<FileFilterElementPtr> m_filters;
77         /// only for plugins with free function names (EDITOR_SCRIPT)
78         int         m_nFreeFunctions;
79
80 private:
81         PluginInfo( const PluginInfo& other ) = delete; // non construction-copyable
82         PluginInfo& operator=( const PluginInfo& ) = delete; // non copyable
83 };
84
85 typedef std::shared_ptr<PluginInfo> PluginInfoPtr;
86
87 typedef std::vector<PluginInfoPtr> PluginArray;
88 typedef std::shared_ptr<PluginArray> PluginArrayPtr;
89
90 /**
91  * @brief Cache for the scriptlets' interfaces during the life of a thread. 
92  * One instance and only one for each thread (necessary for VB)
93  *
94  * @note Never create CScriptsOfThread directly : use the class CAssureScriptsForThread
95  * to guarantee unicity
96  */
97 class CScriptsOfThread
98 {
99 friend class CAssureScriptsForThread;
100 friend class CAllThreadsScripts;
101 public:
102         IDispatch* GetHostObject() const { return m_pHostObject; };
103         void SetHostObject(IDispatch* pHostObject);
104         PluginArray * GetAvailableScripts(const wchar_t *transformationEvent);
105         PluginInfo * GetAutomaticPluginByFilter(const wchar_t *transformationEvent, const String& filteredText);
106         PluginInfo * GetPluginByName(const wchar_t *transformationEvent, const String& name);
107         PluginInfo * GetPluginInfo(LPDISPATCH piScript);
108         void SaveSettings();
109
110         void FreeAllScripts();
111         void ReloadAllScripts();
112
113 protected:
114         CScriptsOfThread();
115         ~CScriptsOfThread();
116         void Lock()       { m_nLocks ++; };
117         bool Unlock()   { m_nLocks --; return (m_nLocks == 0); };
118         /// Tell if this scripts is the one for main thread (by convention, the first in the repository)
119         bool bInMainThread();
120
121 private:
122         unsigned m_nLocks;
123         unsigned long m_nThreadId;
124         /// Result of CoInitialize
125         HRESULT hrInitialize;
126         int nTransformationEvents;
127         std::map<String, PluginArrayPtr> m_aPluginsByEvent;
128         IDispatch* m_pHostObject;
129 };
130
131
132 /**
133  * @brief Repository of CScriptsOfThread
134  */
135 class CAllThreadsScripts
136 {
137 friend class CAssureScriptsForThread;
138 protected:
139         static void Add(CScriptsOfThread * scripts);
140         static void Remove(CScriptsOfThread * scripts);
141         static CScriptsOfThread * GetActiveSetNoAssert();
142 public:
143         /// main public function : get the plugins array for the current thread
144         static CScriptsOfThread * GetActiveSet();
145         /// by convention, the scripts for main thread must be created before all others
146         static bool bInMainThread(CScriptsOfThread * scripts);
147         using InternalPluginLoaderFuncPtr = bool (*)(std::map<String, PluginArrayPtr>& aPluginsByEvent, String& errmsg);
148         static InternalPluginLoaderFuncPtr GetInternalPluginsLoader() { return m_funcInternalPluginsLoader; }
149         static void RegisterInternalPluginsLoader(InternalPluginLoaderFuncPtr func) { m_funcInternalPluginsLoader = func; }
150         static void ReloadCustomSettings();
151         static void ReloadAllScripts();
152 private:
153         // fixed size array, advantage : no mutex to allocate/free
154         static std::vector<CScriptsOfThread *> m_aAvailableThreads;
155         static inline InternalPluginLoaderFuncPtr m_funcInternalPluginsLoader = nullptr;
156 };
157
158 /**
159  * @brief Simple control to add/remove a CScriptsOfThread in the repository. 
160  * Create at least one CAssumeScriptsForThread for each thread, including the main one.
161  * It's OK to create several CAssumeScriptsForThread for the same thread (if you need scripts in one function 
162  * and do not know what happened before the function).
163  */
164 class CAssureScriptsForThread
165 {
166 public:
167         CAssureScriptsForThread(IDispatch* pHostObject);
168         ~CAssureScriptsForThread();
169 };
170
171 namespace plugin
172 {
173
174 /**
175  * @brief Check for the presence of Windows Script
176  *
177  * .sct plugins require this optional component
178  */
179 bool IsWindowsScriptThere();
180 /**
181  * @brief Get a list of the function IDs and names in a script or activeX/COM DLL
182  *
183  * @return Returns the number of functions
184  *
185  */
186 int GetMethodsFromScript(LPDISPATCH piDispatch, std::vector<String>& namesArray, std::vector<int>& IdArray);
187
188 /**
189 /**
190  * @brief Get the ID of the a free function
191  * @param methodOrdinal : index of the free function (0,1,2...)
192  */
193 int GetMethodIDInScript(LPDISPATCH piDispatch, int methodIndex);
194
195
196
197 // Wrappers to call plugins methods
198
199 /**
200  * @brief Call the plugin "PrediffBufferW" method, events PREDIFFING
201  *
202  * @param bstrBuf Overwrite/realloc this buffer
203  */
204 bool InvokePrediffBuffer(BSTR & bstrBuf, int & nChanged, LPDISPATCH piScript);
205
206 /** 
207  * @brief Call custom plugin functions : text transformation
208  */
209 bool InvokeTransformText(String & text, int & changed, LPDISPATCH piScript, int fncId);
210
211 /**
212  * @brief Call the plugin "UnpackBufferA" method, event BUFFER_PACK_UNPACK
213  *
214  * @param pszBuf has unknown format, so a simple char*
215  * never owervrites this source buffer
216  */
217 bool InvokeUnpackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int & subcode);
218 /**
219  * @brief Call the plugin "PackBufferA" method, event BUFFER_PACK_UNPACK
220  *
221  * @param pszBuf has unknown format, so a simple char*
222  * never owervrites this source buffer
223  */
224 bool InvokePackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int subcode);
225 /**
226  * @brief Call the plugin "UnpackFile" method, event FILE_PACK_UNPACK
227  */
228 bool InvokeUnpackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int & subCode);
229 /**
230  * @brief Call the plugin "PackFile" method, event FILE_PACK_UNPACK
231  */
232 bool InvokePackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int subCode);
233 /**
234  * @brief Call the plugin "IsFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
235  */
236 bool InvokeIsFolder(const String& file, IDispatch *piScript);
237 /**
238  * @brief Call the plugin "UnpackFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
239  */
240 bool InvokeUnpackFolder(const String& fileSource, const String& folderDest, int & nChanged, IDispatch *piScript, int & subCode);
241 /**
242  * @brief Call the plugin "PackFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
243  */
244 bool InvokePackFolder(const String& folderSource, const String& fileDest, int & nChanged, IDispatch *piScript, int subCode);
245 /**
246  * @brief Call the plugin "PrediffFile" method, event FILE_PREDIFF
247  */
248 bool InvokePrediffFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript);
249 /**
250  * @brief Call the plugin "ShowSettingsDialog" method
251  */
252 bool InvokeShowSettingsDialog(LPDISPATCH piScript);
253
254 /**
255  * @brief Set value to the plugin "PluginArguments" property 
256  */
257 bool InvokePutPluginArguments(const String& args, LPDISPATCH piScript);
258
259 /**
260  * @brief Set value to the plugin "PluginVariables" property 
261  */
262 bool InvokePutPluginVariables(const String& args, LPDISPATCH piScript);
263
264 /**
265  * @brief call the plugin "PluginOnEvent" method 
266  */
267 bool InvokePluginOnEvent(int eventType, LPDISPATCH piScript);
268
269 }