Use STL algorithms more often
[TortoiseGit.git] / src / TortoiseShell / ItemIDList.cpp
blob1e94ef8bf26e204cf68000c76b4c8b70e002f17d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016 - TortoiseGit
4 // Copyright (C) 2003-2006, 2009, 2011-2013, 2015-2016 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program 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
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "ShellExt.h"
22 #include "ItemIDList.h"
23 #include "StringUtils.h"
25 ItemIDList::ItemIDList(PCUITEMID_CHILD item, PCUIDLIST_RELATIVE parent)
26 : item_ (item)
27 , parent_ (parent)
28 , count_ (-1)
32 ItemIDList::ItemIDList(PCIDLIST_ABSOLUTE item)
33 : item_((PCUITEMID_CHILD)item)
34 , parent_(0)
35 , count_(-1)
39 ItemIDList::~ItemIDList()
43 int ItemIDList::size() const
45 if (count_ == -1)
47 count_ = 0;
48 if (item_)
50 LPCSHITEMID ptr = &item_->mkid;
51 while (ptr && ptr->cb != 0)
53 ++count_;
54 LPBYTE byte = (LPBYTE) ptr;
55 byte += ptr->cb;
56 ptr = (LPCSHITEMID) byte;
60 return count_;
63 LPCSHITEMID ItemIDList::get(int index) const
65 int count = 0;
67 if (!item_)
68 return nullptr;
69 LPCSHITEMID ptr = &item_->mkid;
70 if (!ptr)
71 return nullptr;
72 while (ptr->cb != 0)
74 if (count == index)
75 break;
77 ++count;
78 LPBYTE byte = (LPBYTE) ptr;
79 byte += ptr->cb;
80 ptr = (LPCSHITEMID) byte;
82 return ptr;
85 tstring ItemIDList::toString(bool resolveLibraries /*= true*/)
87 CComPtr<IShellFolder> shellFolder;
88 CComPtr<IShellFolder> parentFolder;
89 tstring ret;
91 if (FAILED(::SHGetDesktopFolder(&shellFolder)))
92 return ret;
93 if (!parent_ || FAILED(shellFolder->BindToObject(parent_, 0, IID_IShellFolder, (void**)&parentFolder)))
94 parentFolder = shellFolder;
96 STRRET name;
97 TCHAR* szDisplayName = nullptr;
98 if (parentFolder && item_ != 0)
100 if (FAILED(parentFolder->GetDisplayNameOf(item_, SHGDN_NORMAL | SHGDN_FORPARSING, &name)))
101 return ret;
102 if (FAILED(StrRetToStr(&name, item_, &szDisplayName)))
103 return ret;
105 if (!szDisplayName)
106 return ret;
107 ret = szDisplayName;
108 CoTaskMemFree(szDisplayName);
110 if (!((resolveLibraries) && (CStringUtils::StartsWith(ret.c_str(), L"::{"))))
111 return ret;
113 CComPtr<IShellLibrary> plib;
114 if (FAILED(plib.CoCreateInstance(CLSID_ShellLibrary, nullptr, CLSCTX_INPROC_SERVER)))
115 return ret;
117 CComPtr<IShellItem> psiLibrary;
118 if (FAILED(SHCreateItemFromParsingName(ret.c_str(), nullptr, IID_PPV_ARGS(&psiLibrary))))
119 return ret;
121 if (FAILED(plib->LoadLibraryFromItem(psiLibrary, STGM_READ | STGM_SHARE_DENY_NONE)))
122 return ret;
124 CComPtr<IShellItem> psiSaveLocation;
125 if (FAILED(plib->GetDefaultSaveFolder(DSFT_DETECT, IID_PPV_ARGS(&psiSaveLocation))))
126 return ret;
128 PWSTR pszName = nullptr;
129 if (SUCCEEDED(psiSaveLocation->GetDisplayName(SIGDN_FILESYSPATH, &pszName)))
131 ret = pszName;
132 CoTaskMemFree(pszName);
135 return ret;
138 PCUITEMID_CHILD ItemIDList::operator& ()
140 return item_;