Added CString wrapper for get_windows_home_directory()
[TortoiseGit.git] / src / TortoiseProc / Settings / SetOverlayIcons.cpp
blob4e539dfb7846d79604b92659253f0e1b4cc2479f
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2011 - TortoiseGit
4 // Copyright (C) 2003-2008 - 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 "MessageBox.h"
24 #include ".\setoverlayicons.h"
25 #include "GitStatus.h"
26 #include "AppUtils.h"
27 #include "PathUtils.h"
28 #include "ShellUpdater.h"
30 IMPLEMENT_DYNAMIC(CSetOverlayIcons, ISettingsPropPage)
31 CSetOverlayIcons::CSetOverlayIcons()
32 : ISettingsPropPage(CSetOverlayIcons::IDD)
34 m_regNormal = CRegString(_T("Software\\TortoiseOverlays\\NormalIcon"));
35 m_regModified = CRegString(_T("Software\\TortoiseOverlays\\ModifiedIcon"));
36 m_regConflicted = CRegString(_T("Software\\TortoiseOverlays\\ConflictIcon"));
37 m_regReadOnly = CRegString(_T("Software\\TortoiseOverlays\\ReadOnlyIcon"));
38 m_regDeleted = CRegString(_T("Software\\TortoiseOverlays\\DeletedIcon"));
39 m_regLocked = CRegString(_T("Software\\TortoiseOverlays\\LockedIcon"));
40 m_regAdded = CRegString(_T("Software\\TortoiseOverlays\\AddedIcon"));
41 m_regIgnored = CRegString(_T("Software\\TortoiseOverlays\\IgnoredIcon"));
42 m_regUnversioned = CRegString(_T("Software\\TortoiseOverlays\\UnversionedIcon"));
45 CSetOverlayIcons::~CSetOverlayIcons()
49 void CSetOverlayIcons::DoDataExchange(CDataExchange* pDX)
51 ISettingsPropPage::DoDataExchange(pDX);
52 DDX_Control(pDX, IDC_ICONSETCOMBO, m_cIconSet);
53 DDX_Control(pDX, IDC_ICONLIST, m_cIconList);
57 BEGIN_MESSAGE_MAP(CSetOverlayIcons, ISettingsPropPage)
58 ON_BN_CLICKED(IDC_LISTRADIO, OnBnClickedListradio)
59 ON_BN_CLICKED(IDC_SYMBOLRADIO, OnBnClickedSymbolradio)
60 ON_CBN_SELCHANGE(IDC_ICONSETCOMBO, OnCbnSelchangeIconsetcombo)
61 END_MESSAGE_MAP()
63 BOOL CSetOverlayIcons::OnInitDialog()
65 ISettingsPropPage::OnInitDialog();
67 m_cIconList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_SUBITEMIMAGES);
68 // get the path to our icon sets
69 TCHAR buf[MAX_PATH] = {0};
70 SHGetSpecialFolderPath(m_hWnd, buf, CSIDL_PROGRAM_FILES_COMMON, true);
71 m_sIconPath = buf;
72 m_sIconPath += _T("\\TortoiseOverlays\\Icons");
73 // list all the icon sets
74 CDirFileEnum filefinder(m_sIconPath);
75 bool isDir = false;
76 CString item;
77 while (filefinder.NextFile(item, &isDir))
79 if (!isDir)
80 continue;
81 m_cIconSet.AddString(CPathUtils::GetFileNameFromPath(item));
83 CheckRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO, IDC_LISTRADIO);
84 CString sModifiedIcon = m_regModified;
85 if (sModifiedIcon.IsEmpty())
87 // no custom icon set, use the default
88 sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
90 if (sModifiedIcon.Left(m_sIconPath.GetLength()).CompareNoCase(m_sIconPath)!=0)
92 // an icon set outside our own installation? We don't support that,
93 // so fall back to the default!
94 sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
96 // the name of the icon set is the folder of the icon location
97 m_sOriginalIconSet = sModifiedIcon.Mid(m_sIconPath.GetLength()+1);
98 m_sOriginalIconSet = m_sOriginalIconSet.Left(m_sOriginalIconSet.ReverseFind('\\'));
99 // now we have the name of the icon set. Set the combobox to show
100 // that as selected
101 CString ComboItem;
102 for (int i=0; i<m_cIconSet.GetCount(); ++i)
104 m_cIconSet.GetLBText(i, ComboItem);
105 if (ComboItem.CompareNoCase(m_sOriginalIconSet)==0)
106 m_cIconSet.SetCurSel(i);
109 WORD langID = (WORD)(DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());
110 TCHAR statustext[MAX_STATUS_STRING_LENGTH];
111 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_normal, statustext, _countof(statustext), langID);
112 m_sNormal = statustext;
113 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_modified, statustext, _countof(statustext), langID);
114 m_sModified = statustext;
115 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_conflicted, statustext, _countof(statustext), langID);
116 m_sConflicted = statustext;
117 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_deleted, statustext, _countof(statustext), langID);
118 m_sDeleted = statustext;
119 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_added, statustext, _countof(statustext), langID);
120 m_sAdded = statustext;
121 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_ignored, statustext, _countof(statustext), langID);
122 m_sIgnored = statustext;
123 GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_unversioned, statustext, _countof(statustext), langID);
124 m_sUnversioned = statustext;
126 m_sReadOnly.LoadString(IDS_SETTINGS_READONLYNAME);
127 m_sLocked.LoadString(IDS_SETTINGS_LOCKEDNAME);
129 SetWindowTheme(m_hWnd, L"Explorer", NULL);
131 ShowIconSet(true);
133 return TRUE;
136 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons)
138 m_cIconList.SetRedraw(FALSE);
139 m_cIconList.DeleteAllItems();
140 m_ImageList.DeleteImageList();
141 m_ImageListBig.DeleteImageList();
142 m_ImageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 20, 10);
143 m_ImageListBig.Create(32, 32, ILC_COLOR32 | ILC_MASK, 20, 10);
144 m_cIconList.SetImageList(&m_ImageList, LVSIL_SMALL);
145 m_cIconList.SetImageList(&m_ImageListBig, LVSIL_NORMAL);
147 // find all the icons of the selected icon set
148 CString sIconSet;
149 int index = m_cIconSet.GetCurSel();
150 if (index == CB_ERR)
152 // nothing selected. Shouldn't happen!
153 return;
155 m_cIconSet.GetLBText(index, sIconSet);
156 CString sIconSetPath = m_sIconPath + _T("\\") + sIconSet;
158 CImageList * pImageList = bSmallIcons ? &m_ImageList : &m_ImageListBig;
159 int pixelsize = (bSmallIcons ? 16 : 32);
160 HICON hNormalOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\NormalIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
161 index = pImageList->Add(hNormalOverlay);
162 VERIFY(pImageList->SetOverlayImage(index, 1));
163 HICON hModifiedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ModifiedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
164 index = pImageList->Add(hModifiedOverlay);
165 VERIFY(pImageList->SetOverlayImage(index, 2));
166 HICON hConflictedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ConflictIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
167 index = pImageList->Add(hConflictedOverlay);
168 VERIFY(pImageList->SetOverlayImage(index, 3));
169 HICON hReadOnlyOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ReadOnlyIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
170 index = pImageList->Add(hReadOnlyOverlay);
171 VERIFY(pImageList->SetOverlayImage(index, 4));
172 HICON hDeletedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\DeletedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
173 index = pImageList->Add(hDeletedOverlay);
174 VERIFY(pImageList->SetOverlayImage(index, 5));
175 HICON hLockedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\LockedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
176 index = pImageList->Add(hLockedOverlay);
177 VERIFY(pImageList->SetOverlayImage(index, 6));
178 HICON hAddedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\AddedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
179 index = pImageList->Add(hAddedOverlay);
180 VERIFY(pImageList->SetOverlayImage(index, 7));
181 HICON hIgnoredOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\IgnoredIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
182 index = pImageList->Add(hIgnoredOverlay);
183 VERIFY(pImageList->SetOverlayImage(index, 8));
184 HICON hUnversionedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\UnversionedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
185 index = pImageList->Add(hUnversionedOverlay);
186 VERIFY(pImageList->SetOverlayImage(index, 9));
188 DestroyIcon(hNormalOverlay);
189 DestroyIcon(hModifiedOverlay);
190 DestroyIcon(hConflictedOverlay);
191 DestroyIcon(hReadOnlyOverlay);
192 DestroyIcon(hDeletedOverlay);
193 DestroyIcon(hLockedOverlay);
194 DestroyIcon(hAddedOverlay);
195 DestroyIcon(hIgnoredOverlay);
196 DestroyIcon(hUnversionedOverlay);
198 // create an image list with different file icons
199 SHFILEINFO sfi;
200 SecureZeroMemory(&sfi, sizeof sfi);
202 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
203 if (bSmallIcons)
204 flags |= SHGFI_SMALLICON;
205 else
206 flags |= SHGFI_LARGEICON;
207 SHGetFileInfo(
208 _T("Doesn't matter"),
209 FILE_ATTRIBUTE_DIRECTORY,
210 &sfi, sizeof sfi,
211 flags);
213 int folderindex = pImageList->Add(sfi.hIcon); //folder
214 DestroyIcon(sfi.hIcon);
215 //folders
216 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal, folderindex);
217 VERIFY(m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK));
218 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified, folderindex);
219 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
220 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted, folderindex);
221 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
222 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly, folderindex);
223 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
224 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted, folderindex);
225 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
226 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked, folderindex);
227 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
228 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded, folderindex);
229 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
230 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored, folderindex);
231 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
232 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned, folderindex);
233 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
235 AddFileTypeGroup(_T(".cpp"), bSmallIcons);
236 AddFileTypeGroup(_T(".h"), bSmallIcons);
237 AddFileTypeGroup(_T(".txt"), bSmallIcons);
238 AddFileTypeGroup(_T(".java"), bSmallIcons);
239 AddFileTypeGroup(_T(".doc"), bSmallIcons);
240 AddFileTypeGroup(_T(".pl"), bSmallIcons);
241 AddFileTypeGroup(_T(".php"), bSmallIcons);
242 AddFileTypeGroup(_T(".asp"), bSmallIcons);
243 AddFileTypeGroup(_T(".cs"), bSmallIcons);
244 AddFileTypeGroup(_T(".vb"), bSmallIcons);
245 AddFileTypeGroup(_T(".xml"), bSmallIcons);
246 AddFileTypeGroup(_T(".pas"), bSmallIcons);
247 AddFileTypeGroup(_T(".dpr"), bSmallIcons);
248 AddFileTypeGroup(_T(".dfm"), bSmallIcons);
249 AddFileTypeGroup(_T(".res"), bSmallIcons);
250 AddFileTypeGroup(_T(".asmx"), bSmallIcons);
251 AddFileTypeGroup(_T(".aspx"), bSmallIcons);
252 AddFileTypeGroup(_T(".resx"), bSmallIcons);
253 AddFileTypeGroup(_T(".vbp"), bSmallIcons);
254 AddFileTypeGroup(_T(".frm"), bSmallIcons);
255 AddFileTypeGroup(_T(".frx"), bSmallIcons);
256 AddFileTypeGroup(_T(".bas"), bSmallIcons);
257 AddFileTypeGroup(_T(".config"), bSmallIcons);
258 AddFileTypeGroup(_T(".css"), bSmallIcons);
259 AddFileTypeGroup(_T(".acsx"), bSmallIcons);
260 AddFileTypeGroup(_T(".jpg"), bSmallIcons);
261 AddFileTypeGroup(_T(".png"), bSmallIcons);
262 m_cIconList.SetRedraw(TRUE);
264 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType, bool bSmallIcons)
266 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
267 if (bSmallIcons)
268 flags |= SHGFI_SMALLICON;
269 else
270 flags |= SHGFI_LARGEICON;
271 SHFILEINFO sfi;
272 SecureZeroMemory(&sfi, sizeof sfi);
274 SHGetFileInfo(
275 sFileType,
276 FILE_ATTRIBUTE_NORMAL,
277 &sfi, sizeof sfi,
278 flags);
280 int imageindex = 0;
281 if (bSmallIcons)
282 imageindex = m_ImageList.Add(sfi.hIcon);
283 else
284 imageindex = m_ImageListBig.Add(sfi.hIcon);
286 DestroyIcon(sfi.hIcon);
287 int index = 0;
288 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal+sFileType, imageindex);
289 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK);
290 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified+sFileType, imageindex);
291 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
292 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted+sFileType, imageindex);
293 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
294 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly+sFileType, imageindex);
295 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
296 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted+sFileType, imageindex);
297 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
298 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked+sFileType, imageindex);
299 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
300 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded+sFileType, imageindex);
301 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
302 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored+sFileType, imageindex);
303 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
304 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned+sFileType, imageindex);
305 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
308 void CSetOverlayIcons::OnBnClickedListradio()
310 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
311 ShowIconSet(true);
314 void CSetOverlayIcons::OnBnClickedSymbolradio()
316 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
317 ShowIconSet(false);
320 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
322 bool bSmallIcons = (GetCheckedRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO) == IDC_LISTRADIO);
323 ShowIconSet(bSmallIcons);
324 m_selIndex = m_cIconSet.GetCurSel();
325 if (m_selIndex != CB_ERR)
327 m_cIconSet.GetLBText(m_selIndex, m_sIconSet);
329 if (m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0)
330 SetModified();
333 BOOL CSetOverlayIcons::OnApply()
335 UpdateData();
337 if ((!m_sIconSet.IsEmpty())&&(m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0))
339 // the selected icon set has changed.
340 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\NormalIcon.ico"), m_regNormal);
341 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ModifiedIcon.ico"), m_regModified);
342 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ConflictIcon.ico"), m_regConflicted);
343 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ReadOnlyIcon.ico"), m_regReadOnly);
344 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\DeletedIcon.ico"), m_regDeleted);
345 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\LockedIcon.ico"), m_regLocked);
346 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\AddedIcon.ico"), m_regAdded);
347 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\IgnoredIcon.ico"), m_regIgnored);
348 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\UnversionedIcon.ico"), m_regUnversioned);
350 m_restart = Restart_System;
351 m_sOriginalIconSet = m_sIconSet;
353 SetModified(FALSE);
354 return ISettingsPropPage::OnApply();