1
// TortoiseGit- a Windows shell extension for easy version control
3 // Copyright (C) 2021-2023 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "ExplorerCommand.h"
24 CExplorerCommandEnum::CExplorerCommandEnum(const std::vector
<Microsoft::WRL::ComPtr
<CExplorerCommand
>>& vec
)
29 HRESULT __stdcall
CExplorerCommandEnum::Next(ULONG celt
, IExplorerCommand
** rgelt
, ULONG
* pceltFetched
)
41 if (m_iCur
== static_cast<ULONG
>(m_vecCommands
.size()))
44 rgelt
[i
] = Microsoft::WRL::Make
<CExplorerCommand
>(m_vecCommands
[m_iCur
]->m_title
,
45 m_vecCommands
[m_iCur
]->m_iconId
,
46 m_vecCommands
[m_iCur
]->m_cmd
,
47 m_vecCommands
[m_iCur
]->m_appDir
,
48 m_vecCommands
[m_iCur
]->m_uuidSource
,
49 m_vecCommands
[m_iCur
]->m_itemStates
,
50 m_vecCommands
[m_iCur
]->m_itemStatesFolder
,
51 m_vecCommands
[m_iCur
]->m_paths
,
52 m_vecCommands
[m_iCur
]->m_subItems
,
53 m_vecCommands
[m_iCur
]->m_site
)
68 HRESULT __stdcall
CExplorerCommandEnum::Skip(ULONG celt
)
70 if ((m_iCur
+ static_cast<int>(celt
)) >= m_vecCommands
.size())
76 HRESULT __stdcall
CExplorerCommandEnum::Reset()
82 HRESULT __stdcall
CExplorerCommandEnum::Clone(IEnumExplorerCommand
**ppenum
)
89 auto newEnum
= Microsoft::WRL::Make
<CExplorerCommandEnum
>(m_vecCommands
);
91 newEnum
->m_iCur
= m_iCur
;
92 *ppenum
= newEnum
.Detach();
94 catch (const std::bad_alloc
&)
101 CExplorerCommand::CExplorerCommand(const std::wstring
&title
, UINT iconId
,
103 const std::wstring
& appDir
,
104 const std::wstring
& uuidSource
,
106 DWORD itemStatesFolder
,
107 std::vector
<std::wstring
> paths
,
108 std::vector
<Microsoft::WRL::ComPtr
<CExplorerCommand
>> subItems
,
109 Microsoft::WRL::ComPtr
<IUnknown
> site
)
114 , m_uuidSource(uuidSource
)
115 , m_itemStates(itemStates
)
116 , m_itemStatesFolder(itemStatesFolder
)
118 , m_subItems(subItems
)
123 HRESULT __stdcall
CExplorerCommand::GetTitle(IShellItemArray
* /*psiItemArray*/, LPWSTR
* ppszName
)
125 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
131 SHStrDupW(m_title
.c_str(), ppszName
);
135 HRESULT __stdcall
CExplorerCommand::GetIcon(IShellItemArray
* /*psiItemArray*/, LPWSTR
*ppszIcon
)
137 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
140 SHStrDupW(L
"", ppszIcon
);
143 std::wstring iconPath
= m_appDir
+ L
"TortoiseGitProc.exe,-";
144 iconPath
+= std::to_wstring(m_iconId
);
145 SHStrDupW(iconPath
.c_str(), ppszIcon
);
149 HRESULT __stdcall
CExplorerCommand::GetToolTip(IShellItemArray
* /*psiItemArray*/, LPWSTR
* ppszInfotip
)
151 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
152 *ppszInfotip
= nullptr;
156 HRESULT __stdcall
CExplorerCommand::GetCanonicalName(GUID
*pguidCommandName
)
158 CTraceToOutputDebugString::Instance()(__FUNCTION__
);
159 *pguidCommandName
= GUID_NULL
;
163 HRESULT __stdcall
CExplorerCommand::GetState(IShellItemArray
* /*psiItemArray*/, BOOL
/*fOkToBeSlow*/, EXPCMDSTATE
*pCmdState
)
165 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
166 *pCmdState
= ECS_ENABLED
;
168 *pCmdState
= ECS_DISABLED
;
172 HRESULT __stdcall
CExplorerCommand::Invoke(IShellItemArray
* /*psiItemArray*/, IBindCtx
* /*pbc*/)
174 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
175 std::wstring cwdFolder
;
178 // use the users desktop path as the CWD
179 wchar_t desktopDir
[MAX_PATH
] = {0};
180 SHGetSpecialFolderPath(nullptr, desktopDir
, CSIDL_DESKTOPDIRECTORY
, TRUE
);
181 cwdFolder
= desktopDir
;
185 cwdFolder
= m_paths
[0];
186 if (!PathIsDirectory(cwdFolder
.c_str()))
188 cwdFolder
= cwdFolder
.substr(0, cwdFolder
.rfind('\\'));
192 CRegStdString regDiffLater
{ L
"Software\\TortoiseGitMerge\\DiffLater", L
"" };
193 CShellExt::InvokeCommand(m_cmd
, m_appDir
, m_uuidSource
,
194 GetForegroundWindow(), m_itemStates
, m_itemStatesFolder
, m_paths
,
195 m_paths
.empty() ? L
"" : m_paths
[0],
196 regDiffLater
, m_site
);
200 HRESULT __stdcall
CExplorerCommand::GetFlags(EXPCMDFLAGS
*pFlags
)
202 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
203 *pFlags
= ECF_DEFAULT
;
204 if (!m_subItems
.empty())
206 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": has subItems\n");
207 *pFlags
= ECF_HASSUBCOMMANDS
;
210 *pFlags
= ECF_ISSEPARATOR
;
214 HRESULT __stdcall
CExplorerCommand::EnumSubCommands(IEnumExplorerCommand
**ppEnum
)
216 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
217 if (m_subItems
.empty())
219 *ppEnum
= Microsoft::WRL::Make
<CExplorerCommandEnum
>(m_subItems
).Detach();
223 HRESULT __stdcall
CExplorerCommand::SetSite(IUnknown
* pUnkSite
)
225 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
230 HRESULT __stdcall
CExplorerCommand::GetSite(REFIID riid
, void ** ppvSite
)
232 CTraceToOutputDebugString::Instance()(__FUNCTION__ L
": title: %s\n", m_title
.c_str());
233 return m_site
.CopyTo(riid
, ppvSite
);