• R/O
  • HTTP
  • SSH
  • HTTPS

winmerge-jp: Commit


Commit MetaInfo

Revisão8267621f227c5b743a97287f63c61ea9dee877aa (tree)
Hora2021-05-10 09:24:32
AutorTakashi Sawanaka <sdottaka@user...>
CommiterTakashi Sawanaka

Mensagem de Log

Add WinMergePluginBase.h

Mudança Sumário

Diff

--- a/Src/Merge.vcxproj
+++ b/Src/Merge.vcxproj
@@ -1337,6 +1337,7 @@
13371337 <ClInclude Include="Common\VersionInfo.h" />
13381338 <ClInclude Include="WildcardDropList.h" />
13391339 <ClInclude Include="WindowsManagerDialog.h" />
1340+ <ClInclude Include="WinMergePluginBase.h" />
13401341 <ClInclude Include="Win_VersionHelper.h" />
13411342 <ClInclude Include="WMGotoDlg.h" />
13421343 <ClInclude Include="xdiff_gnudiff_compat.h" />
--- a/Src/Merge.vcxproj.filters
+++ b/Src/Merge.vcxproj.filters
@@ -1218,6 +1218,9 @@
12181218 <ClInclude Include="Common\IniOptionsMgr.h">
12191219 <Filter>Common\Header Files</Filter>
12201220 </ClInclude>
1221+ <ClInclude Include="WinMergePluginBase.h">
1222+ <Filter>Header Files</Filter>
1223+ </ClInclude>
12211224 </ItemGroup>
12221225 <ItemGroup>
12231226 <None Include="res\binarydiff.ico">
--- a/Src/Plugins.cpp
+++ b/Src/Plugins.cpp
@@ -39,6 +39,7 @@
3939 #include "OptionsDef.h"
4040 #include "codepage_detect.h"
4141 #include "UniFile.h"
42+#include "WinMergePluginBase.h"
4243
4344 using std::vector;
4445 using Poco::RegularExpression;
@@ -375,50 +376,21 @@ static String GetCustomFilters(const String& name, const String& filtersTextDefa
375376 return filtersTextDefault;
376377 }
377378
378-class UnpackerGeneratedFromEditorScript: public IDispatch
379+class UnpackerGeneratedFromEditorScript: public WinMergePluginBase
379380 {
380381 public:
381- UnpackerGeneratedFromEditorScript(IDispatch *pDispatch, int id) : m_pDispatch(pDispatch), m_funcid(id), m_nRef(0)
382+ UnpackerGeneratedFromEditorScript(IDispatch *pDispatch, const std::wstring funcname, int id) : m_pDispatch(pDispatch), m_funcid(id)
382383 {
384+ m_sDescription =
385+ strutils::format_string1(_T("Unpacker to execute %1 script (automatically generated)") , funcname);
386+ m_sFileFilters = _T(".");
387+ m_bIsAutomatic = true;
388+ m_sEvent = L"FILE_PACK_UNPACK";
383389 m_pDispatch->AddRef();
384390 }
385391
386- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
392+ virtual ~UnpackerGeneratedFromEditorScript()
387393 {
388- return E_NOTIMPL;
389- }
390-
391- ULONG STDMETHODCALLTYPE AddRef(void) override
392- {
393- return ++m_nRef;
394- }
395-
396- ULONG STDMETHODCALLTYPE Release(void) override
397- {
398- if (--m_nRef == 0)
399- {
400- m_pDispatch->Release();
401- delete this;
402- return 0;
403- }
404- return m_nRef;
405- }
406-
407- HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override
408- {
409- return E_NOTIMPL;
410- }
411-
412- HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
413- {
414- return E_NOTIMPL;
415- }
416-
417- HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
418- {
419- for (unsigned i = 0; i < cNames; ++i)
420- rgDispId[i] = (wcscmp(L"UnpackFile", rgszNames[i]) == 0) ? 1 : -1;
421- return S_OK;
422394 }
423395
424396 static HRESULT ReadFile(const String& path, String& text)
@@ -454,53 +426,27 @@ public:
454426 return S_OK;
455427 }
456428
457- HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
429+ HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess) override
458430 {
459- if (!pDispParams)
460- return DISP_E_BADVARTYPE;
461- if (dispIdMember != 1)
462- return E_NOTIMPL;
463-
464- BSTR dstPath = pDispParams->rgvarg[2].bstrVal;
465- BSTR srcPath = pDispParams->rgvarg[3].bstrVal;
466-
467- int changed = 0;
468431 String text;
469- HRESULT hr = ReadFile(srcPath, text);
432+ HRESULT hr = ReadFile(fileSrc, text);
470433 if (FAILED(hr))
471434 return hr;
435+ int changed = 0;
472436 if (!plugin::InvokeTransformText(text, changed, m_pDispatch, m_funcid))
473437 return E_FAIL;
474- hr = WriteFile(dstPath, text);
438+ hr = WriteFile(fileDst, text);
475439 if (FAILED(hr))
476440 return hr;
477-
478- *pDispParams->rgvarg[1].pboolVal = VARIANT_TRUE;
479- pVarResult->boolVal = VARIANT_TRUE;
441+ *pSubcode = 0;
442+ *pbChanged = VARIANT_TRUE;
443+ *pbSuccess = VARIANT_TRUE;
480444 return S_OK;
481445 }
482446
483- static PluginInfoPtr MakePluginInfo(PluginInfo *pPluginBase, const String& funcname, int fncid)
484- {
485- PluginInfoPtr plugin(new PluginInfo);
486- plugin->m_lpDispatch = new UnpackerGeneratedFromEditorScript(pPluginBase->m_lpDispatch, fncid);
487- plugin->m_lpDispatch->AddRef();
488- plugin->m_name = pPluginBase->m_name + _T(":") + funcname;
489- plugin->m_description =
490- strutils::format_string2(_T("Unpacker to execute %1 script (automatically generated from %2)")
491- , funcname, pPluginBase->m_name);
492- plugin->m_disabled = false;
493- plugin->m_filtersTextDefault = _T(".");
494- plugin->m_filtersText = GetCustomFilters(plugin->m_name, plugin->m_filtersTextDefault);
495- plugin->m_bAutomatic = true;
496- plugin->m_event = L"FILE_PACK_UNPACK";
497- return plugin;
498- }
499-
500447 private:
501448 IDispatch *m_pDispatch;
502449 int m_funcid;
503- int m_nRef;
504450 };
505451
506452 /**
@@ -524,19 +470,11 @@ struct ScriptInfo
524470 *
525471 * @return 1 if loaded plugin successfully, negatives for errors
526472 */
527-int PluginInfo::LoadPlugin(const String & scriptletFilepath)
473+int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch)
528474 {
529475 // set up object in case we need to log info
530476 ScriptInfo scinfo(scriptletFilepath);
531477
532- // Search for the class "WinMergeScript"
533- LPDISPATCH lpDispatch = CreateDispatchBySource(scriptletFilepath.c_str(), L"WinMergeScript");
534- if (lpDispatch == nullptr)
535- {
536- scinfo.Log(_T("WinMergeScript entry point not found"));
537- return -10; // error
538- }
539-
540478 // Ensure that interface is released if any bad exit or exception
541479 AutoReleaser<IDispatch> drv(lpDispatch);
542480
@@ -702,6 +640,27 @@ int PluginInfo::LoadPlugin(const String & scriptletFilepath)
702640 return 1;
703641 }
704642
643+/**
644+ * @brief Try to load a plugin
645+ *
646+ * @return 1 if loaded plugin successfully, negatives for errors
647+ */
648+int PluginInfo::LoadPlugin(const String & scriptletFilepath)
649+{
650+ // set up object in case we need to log info
651+ ScriptInfo scinfo(scriptletFilepath);
652+
653+ // Search for the class "WinMergeScript"
654+ LPDISPATCH lpDispatch = CreateDispatchBySource(scriptletFilepath.c_str(), L"WinMergeScript");
655+ if (lpDispatch == nullptr)
656+ {
657+ scinfo.Log(_T("WinMergeScript entry point not found"));
658+ return -10; // error
659+ }
660+
661+ return MakeInfo(scriptletFilepath, lpDispatch);
662+}
663+
705664 static void ReportPluginLoadFailure(const String & scriptletFilepath)
706665 {
707666 AppErrorMessageBox(strutils::format(_T("Exception loading plugin\r\n%s"), scriptletFilepath));
@@ -862,8 +821,10 @@ static std::map<String, PluginArrayPtr> GetAvailableScripts()
862821 {
863822 if (plugins.find(L"FILE_PACK_UNPACK") == plugins.end())
864823 plugins[L"FILE_PACK_UNPACK"].reset(new PluginArray);
865- PluginInfoPtr pluginNew = UnpackerGeneratedFromEditorScript::MakePluginInfo(plugin.get(), namesArray[i], idArray[i]);
866- pluginNew->m_disabled = (disabled_plugin_list.find(pluginNew->m_name) != disabled_plugin_list.end());
824+ PluginInfoPtr pluginNew(new PluginInfo());
825+ IDispatch *pDispatch = new UnpackerGeneratedFromEditorScript(plugin->m_lpDispatch, namesArray[i], idArray[i]);
826+ pDispatch->AddRef();
827+ pluginNew->MakeInfo(plugin->m_filepath + _T(":") + namesArray[i], pDispatch);
867828 plugins[L"FILE_PACK_UNPACK"]->push_back(pluginNew);
868829 }
869830 }
--- a/Src/Plugins.h
+++ b/Src/Plugins.h
@@ -47,6 +47,7 @@ public:
4747 }
4848
4949 int LoadPlugin(const String & scriptletFilepath);
50+ int MakeInfo(const String & scriptletFilepath, IDispatch *pDispatch);
5051
5152 /// Parse the filter string (only for files), and create the filters
5253 void LoadFilterString();
--- /dev/null
+++ b/Src/WinMergePluginBase.h
@@ -0,0 +1,304 @@
1+#include <oleauto.h>
2+#include <string>
3+#include <map>
4+
5+class WinMergePluginBase : public IDispatch, public ITypeInfo
6+{
7+public:
8+ enum
9+ {
10+ DISPID_UnpackFile,
11+ DISPID_PackFile,
12+ DISPID_ShowSettingsDialog,
13+ DISPID_PluginFileFilters,
14+ DISPID_PluginIsAutomatic,
15+ DISPID_PluginDescription,
16+ DISPID_PluginEvent,
17+ };
18+ struct MemberInfo { std::wstring name; DISPID id; int flags; };
19+
20+ WinMergePluginBase() : m_nRef(0)
21+ {
22+ static const MemberInfo memberInfo[] =
23+ {
24+ { L"UnpackFile", DISPID_UnpackFile, DISPATCH_METHOD },
25+ { L"PackFile", DISPID_PackFile , DISPATCH_METHOD },
26+ { L"ShowSettingsDialog", DISPID_ShowSettingsDialog, DISPATCH_METHOD },
27+ { L"PluginFileFilters", DISPID_PluginFileFilters, DISPATCH_PROPERTYGET },
28+ { L"PluginIsAutomatic", DISPID_PluginIsAutomatic, DISPATCH_PROPERTYGET },
29+ { L"PluginDescription", DISPID_PluginDescription, DISPATCH_PROPERTYGET },
30+ { L"PluginEvent", DISPID_PluginEvent, DISPATCH_PROPERTYGET },
31+ };
32+ for (auto item : memberInfo)
33+ {
34+ m_memberInfo.push_back(item);
35+ m_mapNameToIndex.emplace(item.name, item.id);
36+ }
37+ }
38+
39+ virtual ~WinMergePluginBase() {}
40+
41+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
42+ {
43+ return E_NOTIMPL;
44+ }
45+
46+ ULONG STDMETHODCALLTYPE AddRef(void) override
47+ {
48+ return ++m_nRef;
49+ }
50+
51+ ULONG STDMETHODCALLTYPE Release(void) override
52+ {
53+ if (--m_nRef == 0)
54+ {
55+ delete this;
56+ return 0;
57+ }
58+ return m_nRef;
59+ }
60+
61+ HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override
62+ {
63+ *pctinfo = static_cast<UINT>(m_memberInfo.size());
64+ return S_OK;
65+ }
66+
67+ HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
68+ {
69+ *ppTInfo = this;
70+ (*ppTInfo)->AddRef();
71+ return S_OK;
72+ }
73+
74+ HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
75+ {
76+ for (unsigned i = 0; i < cNames; ++i)
77+ {
78+ auto it = m_mapNameToIndex.find(rgszNames[i]);
79+ if (it == m_mapNameToIndex.end())
80+ return DISP_E_UNKNOWNNAME;
81+ rgDispId[i] = it->second;
82+ }
83+ return S_OK;
84+ }
85+
86+ HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
87+ {
88+ if (!pDispParams)
89+ return DISP_E_BADVARTYPE;
90+ HRESULT hr = E_NOTIMPL;
91+ if (wFlags == DISPATCH_METHOD)
92+ {
93+ switch (dispIdMember)
94+ {
95+ case DISPID_UnpackFile:
96+ {
97+ BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
98+ BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
99+ VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
100+ INT* pSubcode = &pDispParams->rgvarg[0].intVal;
101+ VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
102+ hr = UnpackFile(fileSrc, fileDst, pbChanged, pSubcode, pbSuccess);
103+ break;
104+ }
105+ case DISPID_PackFile:
106+ {
107+ BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
108+ BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
109+ VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
110+ INT subcode = pDispParams->rgvarg[0].intVal;
111+ VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
112+ hr = PackFile(fileSrc, fileDst, pbChanged, subcode, pbSuccess);
113+ break;
114+ }
115+ case DISPID_ShowSettingsDialog:
116+ hr = ShowSettingsDialog(&pVarResult->boolVal);
117+ break;
118+ }
119+ }
120+ else if (wFlags == DISPATCH_PROPERTYGET)
121+ {
122+ switch (dispIdMember)
123+ {
124+ case DISPID_PluginFileFilters:
125+ pVarResult->vt = VT_BSTR;
126+ hr = get_PluginFileFilters(&pVarResult->bstrVal);
127+ break;
128+ case DISPID_PluginIsAutomatic:
129+ pVarResult->vt = VT_BOOL;
130+ hr = get_PluginIsAutomatic(&pVarResult->boolVal);
131+ break;
132+ case DISPID_PluginDescription:
133+ pVarResult->vt = VT_BSTR;
134+ hr = get_PluginDescription(&pVarResult->bstrVal);
135+ break;
136+ case DISPID_PluginEvent:
137+ pVarResult->vt = VT_BSTR;
138+ hr = get_PluginEvent(&pVarResult->bstrVal);
139+ break;
140+ }
141+ }
142+ return hr;
143+ }
144+
145+ HRESULT STDMETHODCALLTYPE GetTypeAttr(TYPEATTR** ppTypeAttr) override
146+ {
147+ auto* pTypeAttr = new TYPEATTR();
148+ pTypeAttr->cFuncs = static_cast<WORD>(m_memberInfo.size());
149+ *ppTypeAttr = pTypeAttr;
150+ return S_OK;
151+ }
152+
153+ HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp** ppTComp) override
154+ {
155+ return E_NOTIMPL;
156+ }
157+
158+ HRESULT STDMETHODCALLTYPE GetFuncDesc(UINT index, FUNCDESC** ppFuncDesc) override
159+ {
160+ if (index >= m_memberInfo.size())
161+ return E_INVALIDARG;
162+ auto* pFuncDesc = new FUNCDESC();
163+ pFuncDesc->invkind = static_cast<INVOKEKIND>(m_memberInfo[index].flags);
164+ pFuncDesc->wFuncFlags = 0;
165+ pFuncDesc->memid = index;
166+ *ppFuncDesc = pFuncDesc;
167+ return S_OK;
168+ }
169+
170+ HRESULT STDMETHODCALLTYPE GetVarDesc(UINT index, VARDESC** ppVarDesc) override
171+ {
172+ return E_NOTIMPL;
173+ }
174+
175+ HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) override
176+ {
177+ if (memid >= m_memberInfo.size())
178+ return E_INVALIDARG;
179+ *rgBstrNames = SysAllocString(m_memberInfo[memid].name.c_str());
180+ *pcNames = 1;
181+ return S_OK;
182+ }
183+
184+ HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType(UINT index, HREFTYPE *pRefType) override
185+ {
186+ return E_NOTIMPL;
187+ }
188+
189+ HRESULT STDMETHODCALLTYPE GetImplTypeFlags(UINT index, INT *pImplTypeFlags) override
190+ {
191+ return E_NOTIMPL;
192+ }
193+
194+ HRESULT STDMETHODCALLTYPE GetIDsOfNames(LPOLESTR* rgszNames, UINT cNames, MEMBERID* pMemId) override
195+ {
196+ return GetIDsOfNames(IID_NULL, rgszNames, cNames, 0, pMemId);
197+ }
198+
199+ HRESULT STDMETHODCALLTYPE Invoke(PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override
200+ {
201+ return reinterpret_cast<IDispatch*>(pvInstance)->Invoke(memid, IID_NULL, 0, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
202+ }
203+
204+ HRESULT STDMETHODCALLTYPE GetDocumentation(MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) override
205+ {
206+ return E_NOTIMPL;
207+ }
208+
209+ HRESULT STDMETHODCALLTYPE GetDllEntry(MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
210+ {
211+ return E_NOTIMPL;
212+ }
213+
214+ HRESULT STDMETHODCALLTYPE GetRefTypeInfo(HREFTYPE hRefType, ITypeInfo **ppTInfo) override
215+ {
216+ return E_NOTIMPL;
217+ }
218+
219+ HRESULT STDMETHODCALLTYPE AddressOfMember(MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) override
220+ {
221+ return E_NOTIMPL;
222+ }
223+
224+ HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj) override
225+ {
226+ return E_NOTIMPL;
227+ }
228+
229+ HRESULT STDMETHODCALLTYPE GetMops(MEMBERID memid, BSTR *pBstrMops) override
230+ {
231+ return E_NOTIMPL;
232+ }
233+
234+ HRESULT STDMETHODCALLTYPE GetContainingTypeLib(ITypeLib **ppTLib, UINT *pIndex) override
235+ {
236+ return E_NOTIMPL;
237+ }
238+
239+ void STDMETHODCALLTYPE ReleaseTypeAttr(TYPEATTR *pTypeAttr) override
240+ {
241+ delete pTypeAttr;
242+ }
243+
244+ void STDMETHODCALLTYPE ReleaseFuncDesc(FUNCDESC *pFuncDesc) override
245+ {
246+ delete pFuncDesc;
247+ }
248+
249+ void STDMETHODCALLTYPE ReleaseVarDesc(VARDESC *pVarDesc) override
250+ {
251+ }
252+
253+ virtual HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess)
254+ {
255+ *pbSuccess = VARIANT_FALSE;
256+ return E_NOTIMPL;
257+ }
258+
259+ virtual HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess)
260+ {
261+ *pbSuccess = VARIANT_FALSE;
262+ return E_NOTIMPL;
263+ }
264+
265+ virtual HRESULT STDMETHODCALLTYPE ShowSettingsDialog(VARIANT_BOOL* pbHandled)
266+ {
267+ *pbHandled = VARIANT_FALSE;
268+ return E_NOTIMPL;
269+ }
270+
271+ virtual HRESULT STDMETHODCALLTYPE get_PluginIsAutomatic(VARIANT_BOOL* pVal)
272+ {
273+ *pVal = m_bIsAutomatic ? -1 : 0;
274+ return S_OK;
275+ }
276+
277+ virtual HRESULT STDMETHODCALLTYPE get_PluginFileFilters(BSTR* pVal)
278+ {
279+ *pVal = SysAllocString(m_sFileFilters.c_str());
280+ return S_OK;
281+ }
282+
283+ virtual HRESULT STDMETHODCALLTYPE get_PluginDescription(BSTR* pVal)
284+ {
285+ *pVal = SysAllocString(m_sDescription.c_str());
286+ return S_OK;
287+ }
288+
289+ virtual HRESULT STDMETHODCALLTYPE get_PluginEvent(BSTR* pVal)
290+ {
291+ *pVal = SysAllocString(m_sEvent.c_str());
292+ return S_OK;
293+ }
294+
295+protected:
296+ int m_nRef;
297+ std::map<std::wstring, int> m_mapNameToIndex;
298+ std::vector<MemberInfo> m_memberInfo;
299+ std::wstring m_sEvent;
300+ std::wstring m_sDescription;
301+ std::wstring m_sFileFilters;
302+ bool m_bIsAutomatic;
303+};
304+
Show on old repository browser