Apply backgroundcolors.patch
[TortoiseGit.git] / src / TortoiseShell / ExplorerCommand.cpp
blob527d523f113cd515e46e0b75afe993d552a6d97c
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.
19 #include "stdafx.h"
20 #include "ExplorerCommand.h"
22 #include "ShellExt.h"
24 CExplorerCommandEnum::CExplorerCommandEnum(const std::vector<Microsoft::WRL::ComPtr<CExplorerCommand>>& vec)
25 : m_vecCommands(vec)
29 HRESULT __stdcall CExplorerCommandEnum::Next(ULONG celt, IExplorerCommand** rgelt, ULONG* pceltFetched)
31 HRESULT hr = S_FALSE;
33 if (!celt)
34 celt = 1;
35 if (pceltFetched)
36 *pceltFetched = 0;
38 ULONG i = 0;
39 for (; i < celt; ++i)
41 if (m_iCur == static_cast<ULONG>(m_vecCommands.size()))
42 break;
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)
54 .Detach();
56 if (pceltFetched)
57 (*pceltFetched)++;
59 ++m_iCur;
62 if (i == celt)
63 hr = S_OK;
65 return hr;
68 HRESULT __stdcall CExplorerCommandEnum::Skip(ULONG celt)
70 if ((m_iCur + static_cast<int>(celt)) >= m_vecCommands.size())
71 return S_FALSE;
72 m_iCur += celt;
73 return S_OK;
76 HRESULT __stdcall CExplorerCommandEnum::Reset()
78 m_iCur = 0;
79 return S_OK;
82 HRESULT __stdcall CExplorerCommandEnum::Clone(IEnumExplorerCommand **ppenum)
84 if (!ppenum)
85 return E_POINTER;
87 try
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 &)
96 return E_OUTOFMEMORY;
98 return S_OK;
101 CExplorerCommand::CExplorerCommand(const std::wstring &title, UINT iconId,
102 int cmd,
103 const std::wstring & appDir,
104 const std::wstring & uuidSource,
105 DWORD itemStates,
106 DWORD itemStatesFolder,
107 std::vector<std::wstring> paths,
108 std::vector<Microsoft::WRL::ComPtr<CExplorerCommand>> subItems,
109 Microsoft::WRL::ComPtr<IUnknown> site)
110 : m_title(title)
111 , m_iconId(iconId)
112 , m_cmd(cmd)
113 , m_appDir(appDir)
114 , m_uuidSource(uuidSource)
115 , m_itemStates(itemStates)
116 , m_itemStatesFolder(itemStatesFolder)
117 , m_paths(paths)
118 , m_subItems(subItems)
119 , m_site(site)
123 HRESULT __stdcall CExplorerCommand::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
125 CTraceToOutputDebugString::Instance()(__FUNCTION__ L": title: %s\n", m_title.c_str());
126 if (m_title.empty())
128 *ppszName = nullptr;
129 return S_FALSE;
131 SHStrDupW(m_title.c_str(), ppszName);
132 return S_OK;
135 HRESULT __stdcall CExplorerCommand::GetIcon(IShellItemArray * /*psiItemArray*/, LPWSTR *ppszIcon)
137 CTraceToOutputDebugString::Instance()(__FUNCTION__ L": title: %s\n", m_title.c_str());
138 if (m_iconId == 0)
140 SHStrDupW(L"", ppszIcon);
141 return S_FALSE;
143 std::wstring iconPath = m_appDir + L"TortoiseGitProc.exe,-";
144 iconPath += std::to_wstring(m_iconId);
145 SHStrDupW(iconPath.c_str(), ppszIcon);
146 return S_OK;
149 HRESULT __stdcall CExplorerCommand::GetToolTip(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszInfotip)
151 CTraceToOutputDebugString::Instance()(__FUNCTION__ L": title: %s\n", m_title.c_str());
152 *ppszInfotip = nullptr;
153 return E_NOTIMPL;
156 HRESULT __stdcall CExplorerCommand::GetCanonicalName(GUID *pguidCommandName)
158 CTraceToOutputDebugString::Instance()(__FUNCTION__);
159 *pguidCommandName = GUID_NULL;
160 return S_OK;
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;
167 if (m_title.empty())
168 *pCmdState = ECS_DISABLED;
169 return S_OK;
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;
176 if (m_paths.empty())
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;
183 else
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);
197 return S_OK;
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;
209 if (m_title.empty())
210 *pFlags = ECF_ISSEPARATOR;
211 return S_OK;
214 HRESULT __stdcall CExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum)
216 CTraceToOutputDebugString::Instance()(__FUNCTION__ L": title: %s\n", m_title.c_str());
217 if (m_subItems.empty())
218 return E_NOTIMPL;
219 *ppEnum = Microsoft::WRL::Make<CExplorerCommandEnum>(m_subItems).Detach();
220 return S_OK;
223 HRESULT __stdcall CExplorerCommand::SetSite(IUnknown * pUnkSite)
225 CTraceToOutputDebugString::Instance()(__FUNCTION__ L": title: %s\n", m_title.c_str());
226 m_site = pUnkSite;
227 return S_OK;
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);