Replace all calls to LoadIcon and LoadImage with calls to LoadIconWithScaleDown
[TortoiseGit.git] / src / TortoiseProc / Settings / SetOverlayIcons.cpp
blobaca2d90682a5034a841c3b5ab3c1caa6db460113
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2011, 2013-2014, 2016 - TortoiseGit
4 // Copyright (C) 2003-2008, 2014 - 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 "TortoiseProc.h"
22 #include "DirFileEnum.h"
23 #include "SetOverlayIcons.h"
24 #include "StringUtils.h"
25 #include "PathUtils.h"
26 #include "LoadIconEx.h"
28 IMPLEMENT_DYNAMIC(CSetOverlayIcons, ISettingsPropPage)
29 CSetOverlayIcons::CSetOverlayIcons()
30 : ISettingsPropPage(CSetOverlayIcons::IDD)
32 m_regNormal = CRegString(L"Software\\TortoiseOverlays\\NormalIcon");
33 m_regModified = CRegString(L"Software\\TortoiseOverlays\\ModifiedIcon");
34 m_regConflicted = CRegString(L"Software\\TortoiseOverlays\\ConflictIcon");
35 m_regReadOnly = CRegString(L"Software\\TortoiseOverlays\\ReadOnlyIcon");
36 m_regDeleted = CRegString(L"Software\\TortoiseOverlays\\DeletedIcon");
37 m_regLocked = CRegString(L"Software\\TortoiseOverlays\\LockedIcon");
38 m_regAdded = CRegString(L"Software\\TortoiseOverlays\\AddedIcon");
39 m_regIgnored = CRegString(L"Software\\TortoiseOverlays\\IgnoredIcon");
40 m_regUnversioned = CRegString(L"Software\\TortoiseOverlays\\UnversionedIcon");
41 m_selIndex = CB_ERR;
44 CSetOverlayIcons::~CSetOverlayIcons()
48 void CSetOverlayIcons::DoDataExchange(CDataExchange* pDX)
50 ISettingsPropPage::DoDataExchange(pDX);
51 DDX_Control(pDX, IDC_ICONSETCOMBO, m_cIconSet);
52 DDX_Control(pDX, IDC_ICONLIST, m_cIconList);
56 BEGIN_MESSAGE_MAP(CSetOverlayIcons, ISettingsPropPage)
57 ON_BN_CLICKED(IDC_LISTRADIO, OnBnClickedListradio)
58 ON_BN_CLICKED(IDC_SYMBOLRADIO, OnBnClickedSymbolradio)
59 ON_CBN_SELCHANGE(IDC_ICONSETCOMBO, OnCbnSelchangeIconsetcombo)
60 END_MESSAGE_MAP()
62 BOOL CSetOverlayIcons::OnInitDialog()
64 ISettingsPropPage::OnInitDialog();
66 AdjustControlSize(IDC_LISTRADIO);
67 AdjustControlSize(IDC_SYMBOLRADIO);
69 m_cIconList.SetExtendedStyle(LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_SUBITEMIMAGES);
70 // get the path to our icon sets
71 TCHAR buf[MAX_PATH] = {0};
72 SHGetSpecialFolderPath(m_hWnd, buf, CSIDL_PROGRAM_FILES_COMMON, true);
73 m_sIconPath = buf;
74 m_sIconPath += L"\\TortoiseOverlays\\Icons";
75 // list all the icon sets
76 CDirFileEnum filefinder(m_sIconPath);
77 bool isDir = false;
78 CString item;
79 while (filefinder.NextFile(item, &isDir))
81 if (!isDir)
82 continue;
83 m_cIconSet.AddString(CPathUtils::GetFileNameFromPath(item));
85 CheckRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO, IDC_LISTRADIO);
86 CString sModifiedIcon = m_regModified;
87 if (sModifiedIcon.IsEmpty())
89 // no custom icon set, use the default
90 sModifiedIcon = m_sIconPath + L"\\XPStyle\\ModifiedIcon.ico";
92 if (!CStringUtils::StartsWithI(sModifiedIcon, m_sIconPath))
94 // an icon set outside our own installation? We don't support that,
95 // so fall back to the default!
96 sModifiedIcon = m_sIconPath + L"\\XPStyle\\ModifiedIcon.ico";
98 // the name of the icon set is the folder of the icon location
99 m_sOriginalIconSet = sModifiedIcon.Mid(m_sIconPath.GetLength()+1);
100 m_sOriginalIconSet = m_sOriginalIconSet.Left(m_sOriginalIconSet.ReverseFind('\\'));
101 // now we have the name of the icon set. Set the combobox to show
102 // that as selected
103 CString ComboItem;
104 for (int i=0; i<m_cIconSet.GetCount(); ++i)
106 m_cIconSet.GetLBText(i, ComboItem);
107 if (ComboItem.CompareNoCase(m_sOriginalIconSet)==0)
108 m_cIconSet.SetCurSel(i);
111 m_sNormal.LoadString(IDS_STATUSNORMAL);
112 m_sModified.LoadString(IDS_STATUSMODIFIED);
113 m_sConflicted.LoadString(IDS_STATUSCONFLICTED);
114 m_sDeleted.LoadString(IDS_STATUSDELETED);
115 m_sAdded.LoadString(IDS_STATUSADDED);
116 m_sIgnored.LoadString(IDS_STATUSIGNORED);
117 m_sUnversioned.LoadString(IDS_STATUSUNVERSIONED);
119 m_sReadOnly.LoadString(IDS_SETTINGS_READONLYNAME);
120 m_sLocked.LoadString(IDS_SETTINGS_LOCKEDNAME);
122 SetWindowTheme(m_hWnd, L"Explorer", nullptr);
124 ShowIconSet(true);
126 return TRUE;
129 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons)
131 m_cIconList.SetRedraw(FALSE);
132 m_cIconList.DeleteAllItems();
133 m_ImageList.DeleteImageList();
134 m_ImageListBig.DeleteImageList();
135 int smallIconWidth = GetSystemMetrics(SM_CXSMICON);
136 int smallIconHeight = GetSystemMetrics(SM_CYSMICON);
137 int normalIconWidth = GetSystemMetrics(SM_CXICON);
138 int normalIconHeight = GetSystemMetrics(SM_CYICON);
139 m_ImageList.Create(smallIconWidth, smallIconHeight, ILC_COLOR32 | ILC_MASK, 20, 10);
140 m_ImageListBig.Create(normalIconWidth, normalIconHeight, ILC_COLOR32 | ILC_MASK, 20, 10);
141 m_cIconList.SetImageList(&m_ImageList, LVSIL_SMALL);
142 m_cIconList.SetImageList(&m_ImageListBig, LVSIL_NORMAL);
144 // find all the icons of the selected icon set
145 CString sIconSet;
146 int index = m_cIconSet.GetCurSel();
147 if (index == CB_ERR)
149 // nothing selected. Shouldn't happen!
150 return;
152 m_cIconSet.GetLBText(index, sIconSet);
153 CString sIconSetPath = m_sIconPath + L'\\' + sIconSet;
155 CImageList * pImageList = bSmallIcons ? &m_ImageList : &m_ImageListBig;
156 int iconWidth = (bSmallIcons ? smallIconWidth : normalIconWidth);
157 int iconHeight = (bSmallIcons ? smallIconHeight : normalIconHeight);
158 auto hNormalOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\NormalIcon.ico", iconWidth, iconHeight);
159 index = pImageList->Add(hNormalOverlay);
160 VERIFY(pImageList->SetOverlayImage(index, 1));
161 auto hModifiedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\ModifiedIcon.ico", iconWidth, iconHeight);
162 index = pImageList->Add(hModifiedOverlay);
163 VERIFY(pImageList->SetOverlayImage(index, 2));
164 auto hConflictedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\ConflictIcon.ico", iconWidth, iconHeight);
165 index = pImageList->Add(hConflictedOverlay);
166 VERIFY(pImageList->SetOverlayImage(index, 3));
167 auto hReadOnlyOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\ReadOnlyIcon.ico", iconWidth, iconHeight);
168 index = pImageList->Add(hReadOnlyOverlay);
169 VERIFY(pImageList->SetOverlayImage(index, 4));
170 auto hDeletedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\DeletedIcon.ico", iconWidth, iconHeight);
171 index = pImageList->Add(hDeletedOverlay);
172 VERIFY(pImageList->SetOverlayImage(index, 5));
173 auto hLockedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\LockedIcon.ico", iconWidth, iconHeight);
174 index = pImageList->Add(hLockedOverlay);
175 VERIFY(pImageList->SetOverlayImage(index, 6));
176 auto hAddedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\AddedIcon.ico", iconWidth, iconHeight);
177 index = pImageList->Add(hAddedOverlay);
178 VERIFY(pImageList->SetOverlayImage(index, 7));
179 auto hIgnoredOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\IgnoredIcon.ico", iconWidth, iconHeight);
180 index = pImageList->Add(hIgnoredOverlay);
181 VERIFY(pImageList->SetOverlayImage(index, 8));
182 auto hUnversionedOverlay = LoadIconEx(nullptr, sIconSetPath + L"\\UnversionedIcon.ico", iconWidth, iconHeight);
183 index = pImageList->Add(hUnversionedOverlay);
184 VERIFY(pImageList->SetOverlayImage(index, 9));
186 DestroyIcon(hNormalOverlay);
187 DestroyIcon(hModifiedOverlay);
188 DestroyIcon(hConflictedOverlay);
189 DestroyIcon(hReadOnlyOverlay);
190 DestroyIcon(hDeletedOverlay);
191 DestroyIcon(hLockedOverlay);
192 DestroyIcon(hAddedOverlay);
193 DestroyIcon(hIgnoredOverlay);
194 DestroyIcon(hUnversionedOverlay);
196 // create an image list with different file icons
197 SHFILEINFO sfi = { 0 };
199 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
200 if (bSmallIcons)
201 flags |= SHGFI_SMALLICON;
202 else
203 flags |= SHGFI_LARGEICON;
204 SHGetFileInfo(
205 L"Doesn't matter",
206 FILE_ATTRIBUTE_DIRECTORY,
207 &sfi, sizeof sfi,
208 flags);
210 int folderindex = pImageList->Add(sfi.hIcon); //folder
211 DestroyIcon(sfi.hIcon);
212 //folders
213 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal, folderindex);
214 VERIFY(m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK));
215 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified, folderindex);
216 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
217 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted, folderindex);
218 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
219 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly, folderindex);
220 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
221 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted, folderindex);
222 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
223 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked, folderindex);
224 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
225 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded, folderindex);
226 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
227 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored, folderindex);
228 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
229 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned, folderindex);
230 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
232 AddFileTypeGroup(L".cpp", bSmallIcons);
233 AddFileTypeGroup(L".h", bSmallIcons);
234 AddFileTypeGroup(L".txt", bSmallIcons);
235 AddFileTypeGroup(L".java", bSmallIcons);
236 AddFileTypeGroup(L".doc", bSmallIcons);
237 AddFileTypeGroup(L".pl", bSmallIcons);
238 AddFileTypeGroup(L".php", bSmallIcons);
239 AddFileTypeGroup(L".asp", bSmallIcons);
240 AddFileTypeGroup(L".cs", bSmallIcons);
241 AddFileTypeGroup(L".vb", bSmallIcons);
242 AddFileTypeGroup(L".xml", bSmallIcons);
243 AddFileTypeGroup(L".pas", bSmallIcons);
244 AddFileTypeGroup(L".dpr", bSmallIcons);
245 AddFileTypeGroup(L".dfm", bSmallIcons);
246 AddFileTypeGroup(L".res", bSmallIcons);
247 AddFileTypeGroup(L".asmx", bSmallIcons);
248 AddFileTypeGroup(L".aspx", bSmallIcons);
249 AddFileTypeGroup(L".resx", bSmallIcons);
250 AddFileTypeGroup(L".vbp", bSmallIcons);
251 AddFileTypeGroup(L".frm", bSmallIcons);
252 AddFileTypeGroup(L".frx", bSmallIcons);
253 AddFileTypeGroup(L".bas", bSmallIcons);
254 AddFileTypeGroup(L".config", bSmallIcons);
255 AddFileTypeGroup(L".css", bSmallIcons);
256 AddFileTypeGroup(L".acsx", bSmallIcons);
257 AddFileTypeGroup(L".jpg", bSmallIcons);
258 AddFileTypeGroup(L".png", bSmallIcons);
259 m_cIconList.SetRedraw(TRUE);
261 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType, bool bSmallIcons)
263 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
264 if (bSmallIcons)
265 flags |= SHGFI_SMALLICON;
266 else
267 flags |= SHGFI_LARGEICON;
268 SHFILEINFO sfi = { 0 };
270 SHGetFileInfo(
271 sFileType,
272 FILE_ATTRIBUTE_NORMAL,
273 &sfi, sizeof sfi,
274 flags);
276 int imageindex = 0;
277 if (bSmallIcons)
278 imageindex = m_ImageList.Add(sfi.hIcon);
279 else
280 imageindex = m_ImageListBig.Add(sfi.hIcon);
282 DestroyIcon(sfi.hIcon);
283 int index = 0;
284 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal+sFileType, imageindex);
285 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK);
286 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified+sFileType, imageindex);
287 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
288 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted+sFileType, imageindex);
289 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
290 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly+sFileType, imageindex);
291 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
292 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted+sFileType, imageindex);
293 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
294 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked+sFileType, imageindex);
295 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
296 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded+sFileType, imageindex);
297 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
298 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored+sFileType, imageindex);
299 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
300 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned+sFileType, imageindex);
301 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
304 void CSetOverlayIcons::OnBnClickedListradio()
306 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
307 ShowIconSet(true);
310 void CSetOverlayIcons::OnBnClickedSymbolradio()
312 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
313 ShowIconSet(false);
316 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
318 bool bSmallIcons = (GetCheckedRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO) == IDC_LISTRADIO);
319 ShowIconSet(bSmallIcons);
320 m_selIndex = m_cIconSet.GetCurSel();
321 if (m_selIndex != CB_ERR)
322 m_cIconSet.GetLBText(m_selIndex, m_sIconSet);
323 if (m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0)
324 SetModified();
327 BOOL CSetOverlayIcons::OnApply()
329 UpdateData();
331 if ((!m_sIconSet.IsEmpty())&&(m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0))
333 // the selected icon set has changed.
334 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\NormalIcon.ico", m_regNormal);
335 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\ModifiedIcon.ico", m_regModified);
336 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\ConflictIcon.ico", m_regConflicted);
337 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\ReadOnlyIcon.ico", m_regReadOnly);
338 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\DeletedIcon.ico", m_regDeleted);
339 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\LockedIcon.ico", m_regLocked);
340 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\AddedIcon.ico", m_regAdded);
341 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\IgnoredIcon.ico", m_regIgnored);
342 Store(m_sIconPath + L'\\' + m_sIconSet + L"\\UnversionedIcon.ico", m_regUnversioned);
344 m_restart = Restart_System;
345 m_sOriginalIconSet = m_sIconSet;
347 SetModified(FALSE);
348 return ISettingsPropPage::OnApply();