[RSHELL]
[reactos.git] / base / shell / rshell / CMergedFolder.cpp
1 /*
2 * Shell Menu Site
3 *
4 * Copyright 2014 David Quintana
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20 #include "precomp.h"
21 #include <atlwin.h>
22 #include <shlwapi_undoc.h>
23
24 #include "CMergedFolder.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(CMergedFolder);
27
28 class CEnumMergedFolder :
29 public CComObjectRootEx<CComMultiThreadModelNoCS>,
30 public IEnumIDList
31 {
32 private:
33 CComPtr<IEnumIDList> m_UserLocal;
34 CComPtr<IEnumIDList> m_AllUSers;
35 BOOL m_FirstDone;
36
37 public:
38 CEnumMergedFolder() : m_UserLocal(NULL), m_AllUSers(NULL), m_FirstDone(FALSE) {}
39 ~CEnumMergedFolder() {}
40
41 DECLARE_NOT_AGGREGATABLE(CEnumMergedFolder)
42 DECLARE_PROTECT_FINAL_CONSTRUCT()
43
44 BEGIN_COM_MAP(CEnumMergedFolder)
45 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
46 END_COM_MAP()
47
48 HRESULT Begin(HWND hwndOwner, SHCONTF flags, IShellFolder * userLocal, IShellFolder * allUSers)
49 {
50 HRESULT hr;
51 hr = userLocal->EnumObjects(hwndOwner, flags, &m_UserLocal);
52 if (FAILED_UNEXPECTEDLY(hr))
53 return hr;
54 hr = userLocal->EnumObjects(hwndOwner, flags, &m_AllUSers);
55 if (FAILED_UNEXPECTEDLY(hr))
56 {
57 m_UserLocal = NULL;
58 return hr;
59 }
60 m_FirstDone = FALSE;
61 return S_OK;
62 }
63
64 virtual HRESULT STDMETHODCALLTYPE Next(
65 ULONG celt,
66 LPITEMIDLIST *rgelt,
67 ULONG *pceltFetched)
68 {
69 HRESULT hr;
70
71 *pceltFetched = 0;
72
73 if (!m_FirstDone)
74 {
75 hr = m_UserLocal->Next(celt, rgelt, pceltFetched);
76 if (FAILED_UNEXPECTEDLY(hr))
77 return hr;
78 if (hr == S_FALSE)
79 m_FirstDone = true;
80 else if (celt < 2)
81 return hr;
82 }
83
84 DWORD offset = *pceltFetched;
85 if (*pceltFetched < celt)
86 {
87 rgelt += *pceltFetched;
88 celt = (celt - *pceltFetched);
89 *pceltFetched = 0;
90
91 hr = m_AllUSers->Next(celt, rgelt, pceltFetched);
92 if (FAILED_UNEXPECTEDLY(hr))
93 return hr;
94
95 *pceltFetched += offset;
96
97 return hr;
98 }
99
100 return S_OK;
101 }
102
103 virtual HRESULT STDMETHODCALLTYPE Skip(
104 ULONG celt)
105 {
106 UNIMPLEMENTED;
107 return E_NOTIMPL;
108 }
109
110 virtual HRESULT STDMETHODCALLTYPE Reset(
111 )
112 {
113 if (m_FirstDone)
114 m_AllUSers->Reset();
115 return m_UserLocal->Reset();
116 }
117
118 virtual HRESULT STDMETHODCALLTYPE Clone(
119 IEnumIDList **ppenum)
120 {
121 UNIMPLEMENTED;
122 return E_NOTIMPL;
123 }
124 };
125
126 extern "C"
127 HRESULT WINAPI CMergedFolder_Constructor(IShellFolder* userLocal, IShellFolder* allUsers, REFIID riid, LPVOID *ppv)
128 {
129 *ppv = NULL;
130
131 CMergedFolder * fld = new CComObject<CMergedFolder>();
132
133 if (!fld)
134 return E_OUTOFMEMORY;
135
136 HRESULT hr;
137
138 hr = fld->_SetSources(userLocal, allUsers);
139
140 hr = fld->QueryInterface(riid, ppv);
141 if (FAILED_UNEXPECTEDLY(hr))
142 fld->Release();
143
144 return hr;
145 }
146
147 HRESULT CMergedFolder::_SetSources(IShellFolder* userLocal, IShellFolder* allUsers)
148 {
149 m_UserLocal = userLocal;
150 m_AllUSers = allUsers;
151 return S_OK;
152 }
153
154 // IShellFolder
155 HRESULT STDMETHODCALLTYPE CMergedFolder::ParseDisplayName(
156 HWND hwndOwner,
157 LPBC pbcReserved,
158 LPOLESTR lpszDisplayName,
159 ULONG *pchEaten,
160 LPITEMIDLIST *ppidl,
161 ULONG *pdwAttributes)
162 {
163 UNIMPLEMENTED;
164 return E_NOTIMPL;
165 }
166
167 HRESULT STDMETHODCALLTYPE CMergedFolder::EnumObjects(
168 HWND hwndOwner,
169 SHCONTF grfFlags,
170 IEnumIDList **ppenumIDList)
171 {
172 CEnumMergedFolder * merged = new CComObject<CEnumMergedFolder>();
173 *ppenumIDList = merged;
174 return merged->Begin(hwndOwner, grfFlags, m_UserLocal, m_AllUSers);
175 }
176
177 HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject(
178 LPCITEMIDLIST pidl,
179 LPBC pbcReserved,
180 REFIID riid,
181 void **ppvOut)
182 {
183 HRESULT hr;
184
185 hr = m_UserLocal->BindToObject(pidl, pbcReserved, riid, ppvOut);
186 if (SUCCEEDED(hr))
187 return hr;
188
189 hr = m_AllUSers->BindToObject(pidl, pbcReserved, riid, ppvOut);
190
191 return hr;
192 }
193
194 HRESULT STDMETHODCALLTYPE CMergedFolder::BindToStorage(
195 LPCITEMIDLIST pidl,
196 LPBC pbcReserved,
197 REFIID riid,
198 void **ppvObj)
199 {
200 UNIMPLEMENTED;
201 return E_NOTIMPL;
202 }
203
204 HRESULT STDMETHODCALLTYPE CMergedFolder::CompareIDs(
205 LPARAM lParam,
206 LPCITEMIDLIST pidl1,
207 LPCITEMIDLIST pidl2)
208 {
209 UNIMPLEMENTED;
210 return E_NOTIMPL;
211 }
212
213 HRESULT STDMETHODCALLTYPE CMergedFolder::CreateViewObject(
214 HWND hwndOwner,
215 REFIID riid,
216 void **ppvOut)
217 {
218 UNIMPLEMENTED;
219 return E_NOTIMPL;
220 }
221
222 HRESULT STDMETHODCALLTYPE CMergedFolder::GetAttributesOf(
223 UINT cidl,
224 LPCITEMIDLIST *apidl,
225 SFGAOF *rgfInOut)
226 {
227 HRESULT hr;
228
229 hr = m_UserLocal->GetAttributesOf(cidl, apidl, rgfInOut);
230 if (SUCCEEDED(hr))
231 return hr;
232
233 *rgfInOut = 0;
234 hr = m_AllUSers->GetAttributesOf(cidl, apidl, rgfInOut);
235
236 return hr;
237 }
238
239 HRESULT STDMETHODCALLTYPE CMergedFolder::GetUIObjectOf(
240 HWND hwndOwner,
241 UINT cidl,
242 LPCITEMIDLIST *apidl,
243 REFIID riid,
244 UINT *prgfInOut,
245 void **ppvOut)
246 {
247 HRESULT hr;
248
249 hr = m_UserLocal->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
250 if (SUCCEEDED(hr))
251 return hr;
252
253 hr = m_AllUSers->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
254
255 return hr;
256 }
257
258 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDisplayNameOf(
259 LPCITEMIDLIST pidl,
260 SHGDNF uFlags,
261 STRRET *lpName)
262 {
263 HRESULT hr;
264
265 hr = m_UserLocal->GetDisplayNameOf(pidl, uFlags, lpName);
266 if (SUCCEEDED(hr))
267 return hr;
268
269 hr = m_AllUSers->GetDisplayNameOf(pidl, uFlags, lpName);
270
271 return hr;
272 }
273
274 HRESULT STDMETHODCALLTYPE CMergedFolder::SetNameOf(
275 HWND hwnd,
276 LPCITEMIDLIST pidl,
277 LPCOLESTR lpszName,
278 SHGDNF uFlags,
279 LPITEMIDLIST *ppidlOut)
280 {
281 UNIMPLEMENTED;
282 return E_NOTIMPL;
283 }
284
285 // IShellFolder2
286 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDefaultSearchGUID(
287 GUID *lpguid)
288 {
289 UNIMPLEMENTED;
290 return E_NOTIMPL;
291 }
292
293 HRESULT STDMETHODCALLTYPE CMergedFolder::EnumSearches(
294 IEnumExtraSearch **ppenum)
295 {
296 UNIMPLEMENTED;
297 return E_NOTIMPL;
298 }
299
300 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDefaultColumn(
301 DWORD dwReserved,
302 ULONG *pSort,
303 ULONG *pDisplay)
304 {
305 UNIMPLEMENTED;
306 return E_NOTIMPL;
307 }
308
309 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDefaultColumnState(
310 UINT iColumn,
311 SHCOLSTATEF *pcsFlags)
312 {
313 UNIMPLEMENTED;
314 return E_NOTIMPL;
315 }
316
317 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDetailsEx(
318 LPCITEMIDLIST pidl,
319 const SHCOLUMNID *pscid,
320 VARIANT *pv)
321 {
322 UNIMPLEMENTED;
323 return E_NOTIMPL;
324 }
325
326 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDetailsOf(
327 LPCITEMIDLIST pidl,
328 UINT iColumn,
329 SHELLDETAILS *psd)
330 {
331 UNIMPLEMENTED;
332 return E_NOTIMPL;
333 }
334
335 HRESULT STDMETHODCALLTYPE CMergedFolder::MapColumnToSCID(
336 UINT iColumn,
337 SHCOLUMNID *pscid)
338 {
339 UNIMPLEMENTED;
340 return E_NOTIMPL;
341 }