1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997-2000 Thingamahoochie Software
5 // SPDX-License-Identifier: GPL-2.0-or-later
6 /////////////////////////////////////////////////////////////////////////////
10 * @brief Declaration file for VBS Scriptlets, VB ActiveX DLL, VC++ COM DLL
14 #include <Poco/Foundation.h>
21 #include "UnicodeString.h"
23 struct FileFilterElement;
24 typedef std::shared_ptr<FileFilterElement> FileFilterElementPtr;
27 * @brief List of transformation categories (events)
29 * @note If you add some event, you have to complete this array in FileTransform.cpp
31 extern const wchar_t *TransformationCategories[];
34 * @brief Information structure for a plugin
40 : m_lpDispatch(nullptr)
45 , m_hasArgumentsProperty(false)
51 if (m_lpDispatch!=nullptr)
52 m_lpDispatch->Release();
55 int LoadPlugin(const String & scriptletFilepath);
56 int MakeInfo(const String & scriptletFilepath, IDispatch *pDispatch);
58 /// Parse the filter string (only for files), and create the filters
59 void LoadFilterString();
61 * @brief Does the plugin handles this(ese) filename(s) ?
63 * @param szTest String of filenames, delimited with '|'
65 bool TestAgainstRegList(const String& szTest) const;
67 std::optional<StringView> GetExtendedPropertyValue(const String& name) const;
71 LPDISPATCH m_lpDispatch;
72 String m_name; // usually filename, except for special cases (like auto or no)
74 String m_extendedProperties;
76 String m_argumentsDefault;
78 String m_filtersTextDefault;
82 bool m_bAutomaticDefault;
84 bool m_hasArgumentsProperty;
85 bool m_hasVariablesProperty;
86 std::vector<FileFilterElementPtr> m_filters;
87 /// only for plugins with free function names (EDITOR_SCRIPT)
91 PluginInfo( const PluginInfo& other ); // non construction-copyable
92 PluginInfo& operator=( const PluginInfo& ); // non copyable
95 typedef std::shared_ptr<PluginInfo> PluginInfoPtr;
97 typedef std::vector<PluginInfoPtr> PluginArray;
98 typedef std::shared_ptr<PluginArray> PluginArrayPtr;
101 * @brief Cache for the scriptlets' interfaces during the life of a thread.
102 * One instance and only one for each thread (necessary for VB)
104 * @note Never create CScriptsOfThread directly : use the class CAssureScriptsForThread
105 * to guarantee unicity
107 class CScriptsOfThread
109 friend class CAssureScriptsForThread;
110 friend class CAllThreadsScripts;
112 PluginArray * GetAvailableScripts(const wchar_t *transformationEvent);
113 PluginInfo * GetUnpackerPluginByFilter(const String& filteredText);
114 PluginInfo * GetAutomaticPluginByFilter(const wchar_t *transformationEvent, const String& filteredText);
115 PluginInfo * GetPluginByName(const wchar_t *transformationEvent, const String& name);
116 PluginInfo * GetPluginInfo(LPDISPATCH piScript);
119 void FreeAllScripts();
120 void FreeScriptsForEvent(const wchar_t *transformationEvent);
125 void Lock() { m_nLocks ++; };
126 bool Unlock() { m_nLocks --; return (m_nLocks == 0); };
127 /// Tell if this scripts is the one for main thread (by convention, the first in the repository)
128 bool bInMainThread();
132 unsigned long m_nThreadId;
133 /// Result of CoInitialize
134 HRESULT hrInitialize;
135 int nTransformationEvents;
136 std::map<String, PluginArrayPtr> m_aPluginsByEvent;
141 * @brief Repository of CScriptsOfThread
143 class CAllThreadsScripts
145 friend class CAssureScriptsForThread;
147 static void Add(CScriptsOfThread * scripts);
148 static void Remove(CScriptsOfThread * scripts);
149 static CScriptsOfThread * GetActiveSetNoAssert();
151 /// main public function : get the plugins array for the current thread
152 static CScriptsOfThread * GetActiveSet();
153 /// by convention, the scripts for main thread must be created before all others
154 static bool bInMainThread(CScriptsOfThread * scripts);
155 using InternalPluginLoaderFuncPtr = bool (*)(std::map<String, PluginArrayPtr>& aPluginsByEvent, String& errmsg);
156 static InternalPluginLoaderFuncPtr GetInternalPluginsLoader() { return m_funcInternalPluginsLoader; }
157 static void RegisterInternalPluginsLoader(InternalPluginLoaderFuncPtr func) { m_funcInternalPluginsLoader = func; }
158 static void ReloadCustomSettings();
160 // fixed size array, advantage : no mutex to allocate/free
161 static std::vector<CScriptsOfThread *> m_aAvailableThreads;
162 static inline InternalPluginLoaderFuncPtr m_funcInternalPluginsLoader = nullptr;
166 * @brief Simple control to add/remove a CScriptsOfThread in the repository.
167 * Create at least one CAssumeScriptsForThread for each thread, including the main one.
168 * It's OK to create several CAssumeScriptsForThread for the same thread (if you need scripts in one function
169 * and do not know what happened before the function).
171 class CAssureScriptsForThread
174 CAssureScriptsForThread();
175 ~CAssureScriptsForThread();
182 * @brief Check for the presence of Windows Script
184 * .sct plugins require this optional component
186 bool IsWindowsScriptThere();
188 * @brief Get a list of the function IDs and names in a script or activeX/COM DLL
190 * @return Returns the number of functions
193 int GetMethodsFromScript(LPDISPATCH piDispatch, std::vector<String>& namesArray, std::vector<int>& IdArray);
197 * @brief Get the ID of the a free function
198 * @param methodOrdinal : index of the free function (0,1,2...)
200 int GetMethodIDInScript(LPDISPATCH piDispatch, int methodIndex);
204 // Wrappers to call plugins methods
207 * @brief Call the plugin "PrediffBufferW" method, events PREDIFFING
209 * @param bstrBuf Overwrite/realloc this buffer
211 bool InvokePrediffBuffer(BSTR & bstrBuf, int & nChanged, LPDISPATCH piScript);
214 * @brief Call custom plugin functions : text transformation
216 bool InvokeTransformText(String & text, int & changed, LPDISPATCH piScript, int fncId);
219 * @brief Call the plugin "UnpackBufferA" method, event BUFFER_PACK_UNPACK
221 * @param pszBuf has unknown format, so a simple char*
222 * never owervrites this source buffer
224 bool InvokeUnpackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int & subcode);
226 * @brief Call the plugin "PackBufferA" method, event BUFFER_PACK_UNPACK
228 * @param pszBuf has unknown format, so a simple char*
229 * never owervrites this source buffer
231 bool InvokePackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int subcode);
233 * @brief Call the plugin "UnpackFile" method, event FILE_PACK_UNPACK
235 bool InvokeUnpackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int & subCode);
237 * @brief Call the plugin "PackFile" method, event FILE_PACK_UNPACK
239 bool InvokePackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int subCode);
241 * @brief Call the plugin "IsFolder" method, event FILE_FOLDER_PACK_UNPACK
243 bool InvokeIsFolder(const String& file, IDispatch *piScript);
245 * @brief Call the plugin "UnpackFolder" method, event FILE_FOLDER_PACK_UNPACK
247 bool InvokeUnpackFolder(const String& fileSource, const String& folderDest, int & nChanged, IDispatch *piScript, int & subCode);
249 * @brief Call the plugin "PackFolder" method, event FILE_FOLDER_PACK_UNPACK
251 bool InvokePackFolder(const String& folderSource, const String& fileDest, int & nChanged, IDispatch *piScript, int subCode);
253 * @brief Call the plugin "PrediffFile" method, event FILE_PREDIFF
255 bool InvokePrediffFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript);
257 * @brief Call the plugin "ShowSettingsDialog" method
259 bool InvokeShowSettingsDialog(LPDISPATCH piScript);
262 * @brief Set value to the plugin "PluginArguments" property
264 bool InvokePutPluginArguments(const String& args, LPDISPATCH piScript);
267 * @brief Set value to the plugin "PluginVariables" property
269 bool InvokePutPluginVariables(const String& args, LPDISPATCH piScript);