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[];
33 enum { EVENTID_INITIALIZE, EVENTID_TERMINATE };
36 * @brief Information structure for a plugin
44 int LoadPlugin(const String & scriptletFilepath);
45 int MakeInfo(const String & scriptletFilepath, IDispatch *pDispatch);
47 /// Parse the filter string (only for files), and create the filters
48 void LoadFilterString();
50 * @brief Does the plugin handles this(ese) filename(s) ?
52 * @param szTest String of filenames, delimited with '|'
54 bool TestAgainstRegList(const String& szTest) const;
56 std::optional<StringView> GetExtendedPropertyValue(const String& name) const;
60 LPDISPATCH m_lpDispatch;
61 String m_name; // usually filename, except for special cases (like auto or no)
63 String m_extendedProperties;
65 String m_argumentsDefault;
67 String m_filtersTextDefault;
71 bool m_bAutomaticDefault;
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)
81 PluginInfo( const PluginInfo& other ) = delete; // non construction-copyable
82 PluginInfo& operator=( const PluginInfo& ) = delete; // non copyable
85 typedef std::shared_ptr<PluginInfo> PluginInfoPtr;
87 typedef std::vector<PluginInfoPtr> PluginArray;
88 typedef std::shared_ptr<PluginArray> PluginArrayPtr;
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)
94 * @note Never create CScriptsOfThread directly : use the class CAssureScriptsForThread
95 * to guarantee unicity
97 class CScriptsOfThread
99 friend class CAssureScriptsForThread;
100 friend class CAllThreadsScripts;
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);
110 void FreeAllScripts();
111 void ReloadAllScripts();
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();
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;
133 * @brief Repository of CScriptsOfThread
135 class CAllThreadsScripts
137 friend class CAssureScriptsForThread;
139 static void Add(CScriptsOfThread * scripts);
140 static void Remove(CScriptsOfThread * scripts);
141 static CScriptsOfThread * GetActiveSetNoAssert();
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();
153 // fixed size array, advantage : no mutex to allocate/free
154 static std::vector<CScriptsOfThread *> m_aAvailableThreads;
155 static inline InternalPluginLoaderFuncPtr m_funcInternalPluginsLoader = nullptr;
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).
164 class CAssureScriptsForThread
167 CAssureScriptsForThread(IDispatch* pHostObject);
168 ~CAssureScriptsForThread();
175 * @brief Check for the presence of Windows Script
177 * .sct plugins require this optional component
179 bool IsWindowsScriptThere();
181 * @brief Get a list of the function IDs and names in a script or activeX/COM DLL
183 * @return Returns the number of functions
186 int GetMethodsFromScript(LPDISPATCH piDispatch, std::vector<String>& namesArray, std::vector<int>& IdArray);
190 * @brief Get the ID of the a free function
191 * @param methodOrdinal : index of the free function (0,1,2...)
193 int GetMethodIDInScript(LPDISPATCH piDispatch, int methodIndex);
197 // Wrappers to call plugins methods
200 * @brief Call the plugin "PrediffBufferW" method, events PREDIFFING
202 * @param bstrBuf Overwrite/realloc this buffer
204 bool InvokePrediffBuffer(BSTR & bstrBuf, int & nChanged, LPDISPATCH piScript);
207 * @brief Call custom plugin functions : text transformation
209 bool InvokeTransformText(String & text, int & changed, LPDISPATCH piScript, int fncId);
212 * @brief Call the plugin "UnpackBufferA" method, event BUFFER_PACK_UNPACK
214 * @param pszBuf has unknown format, so a simple char*
215 * never owervrites this source buffer
217 bool InvokeUnpackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int & subcode);
219 * @brief Call the plugin "PackBufferA" method, event BUFFER_PACK_UNPACK
221 * @param pszBuf has unknown format, so a simple char*
222 * never owervrites this source buffer
224 bool InvokePackBuffer(VARIANT & array, int & nChanged, LPDISPATCH piScript, int subcode);
226 * @brief Call the plugin "UnpackFile" method, event FILE_PACK_UNPACK
228 bool InvokeUnpackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int & subCode);
230 * @brief Call the plugin "PackFile" method, event FILE_PACK_UNPACK
232 bool InvokePackFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript, int subCode);
234 * @brief Call the plugin "IsFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
236 bool InvokeIsFolder(const String& file, IDispatch *piScript);
238 * @brief Call the plugin "UnpackFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
240 bool InvokeUnpackFolder(const String& fileSource, const String& folderDest, int & nChanged, IDispatch *piScript, int & subCode);
242 * @brief Call the plugin "PackFolder" method, event FILE_FOLDER_PACK_UNPACK or URL_PACK_UNPACK
244 bool InvokePackFolder(const String& folderSource, const String& fileDest, int & nChanged, IDispatch *piScript, int subCode);
246 * @brief Call the plugin "PrediffFile" method, event FILE_PREDIFF
248 bool InvokePrediffFile(const String& fileSource, const String& fileDest, int & nChanged, LPDISPATCH piScript);
250 * @brief Call the plugin "ShowSettingsDialog" method
252 bool InvokeShowSettingsDialog(LPDISPATCH piScript);
255 * @brief Set value to the plugin "PluginArguments" property
257 bool InvokePutPluginArguments(const String& args, LPDISPATCH piScript);
260 * @brief Set value to the plugin "PluginVariables" property
262 bool InvokePutPluginVariables(const String& args, LPDISPATCH piScript);
265 * @brief call the plugin "PluginOnEvent" method
267 bool InvokePluginOnEvent(int eventType, LPDISPATCH piScript);