BrowseRefs: Context menu enhancements
[TortoiseGit.git] / src / TortoiseProc / Settings / SetOverlayIcons.cpp
blob91d081a4903e8c67fb7300cfbf213f7ae7e2bb4b
1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - 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 "TortoiseProc.h"
21 #include "DirFileEnum.h"
22 #include "MessageBox.h"
23 #include ".\setoverlayicons.h"
24 #include "GitStatus.h"
25 #include "AppUtils.h"
26 #include "PathUtils.h"
27 #include "ShellUpdater.h"
28 #include "XPTheme.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);
108 #if 0
109 WORD langID = (WORD)(DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());
110 TCHAR statustext[MAX_STATUS_STRING_LENGTH];
111 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_normal, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
112 m_sNormal = statustext;
113 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_modified, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
114 m_sModified = statustext;
115 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_conflicted, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
116 m_sConflicted = statustext;
117 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_deleted, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
118 m_sDeleted = statustext;
119 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_added, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
120 m_sAdded = statustext;
121 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_ignored, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
122 m_sIgnored = statustext;
123 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_unversioned, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
124 m_sUnversioned = statustext;
125 #endif
126 m_sReadOnly.LoadString(IDS_SETTINGS_READONLYNAME);
127 m_sLocked.LoadString(IDS_SETTINGS_LOCKEDNAME);
129 CXPTheme theme;
130 theme.SetWindowTheme(m_cIconList.GetSafeHwnd(), L"Explorer", NULL);
132 ShowIconSet(true);
134 return TRUE;
137 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons)
139 m_cIconList.SetRedraw(FALSE);
140 m_cIconList.DeleteAllItems();
141 m_ImageList.DeleteImageList();
142 m_ImageListBig.DeleteImageList();
143 m_ImageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 20, 10);
144 m_ImageListBig.Create(32, 32, ILC_COLOR32 | ILC_MASK, 20, 10);
145 m_cIconList.SetImageList(&m_ImageList, LVSIL_SMALL);
146 m_cIconList.SetImageList(&m_ImageListBig, LVSIL_NORMAL);
148 // find all the icons of the selected icon set
149 CString sIconSet;
150 int index = m_cIconSet.GetCurSel();
151 if (index == CB_ERR)
153 // nothing selected. Shouldn't happen!
154 return;
156 m_cIconSet.GetLBText(index, sIconSet);
157 CString sIconSetPath = m_sIconPath + _T("\\") + sIconSet;
159 CImageList * pImageList = bSmallIcons ? &m_ImageList : &m_ImageListBig;
160 int pixelsize = (bSmallIcons ? 16 : 32);
161 HICON hNormalOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\NormalIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
162 index = pImageList->Add(hNormalOverlay);
163 VERIFY(pImageList->SetOverlayImage(index, 1));
164 HICON hModifiedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ModifiedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
165 index = pImageList->Add(hModifiedOverlay);
166 VERIFY(pImageList->SetOverlayImage(index, 2));
167 HICON hConflictedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ConflictIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
168 index = pImageList->Add(hConflictedOverlay);
169 VERIFY(pImageList->SetOverlayImage(index, 3));
170 HICON hReadOnlyOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ReadOnlyIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
171 index = pImageList->Add(hReadOnlyOverlay);
172 VERIFY(pImageList->SetOverlayImage(index, 4));
173 HICON hDeletedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\DeletedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
174 index = pImageList->Add(hDeletedOverlay);
175 VERIFY(pImageList->SetOverlayImage(index, 5));
176 HICON hLockedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\LockedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
177 index = pImageList->Add(hLockedOverlay);
178 VERIFY(pImageList->SetOverlayImage(index, 6));
179 HICON hAddedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\AddedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
180 index = pImageList->Add(hAddedOverlay);
181 VERIFY(pImageList->SetOverlayImage(index, 7));
182 HICON hIgnoredOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\IgnoredIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
183 index = pImageList->Add(hIgnoredOverlay);
184 VERIFY(pImageList->SetOverlayImage(index, 8));
185 HICON hUnversionedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\UnversionedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
186 index = pImageList->Add(hUnversionedOverlay);
187 VERIFY(pImageList->SetOverlayImage(index, 9));
189 DestroyIcon(hNormalOverlay);
190 DestroyIcon(hModifiedOverlay);
191 DestroyIcon(hConflictedOverlay);
192 DestroyIcon(hReadOnlyOverlay);
193 DestroyIcon(hDeletedOverlay);
194 DestroyIcon(hLockedOverlay);
195 DestroyIcon(hAddedOverlay);
196 DestroyIcon(hIgnoredOverlay);
197 DestroyIcon(hUnversionedOverlay);
199 // create an image list with different file icons
200 SHFILEINFO sfi;
201 SecureZeroMemory(&sfi, sizeof sfi);
203 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
204 if (bSmallIcons)
205 flags |= SHGFI_SMALLICON;
206 else
207 flags |= SHGFI_LARGEICON;
208 SHGetFileInfo(
209 _T("Doesn't matter"),
210 FILE_ATTRIBUTE_DIRECTORY,
211 &sfi, sizeof sfi,
212 flags);
214 int folderindex = pImageList->Add(sfi.hIcon); //folder
215 DestroyIcon(sfi.hIcon);
216 //folders
217 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal, folderindex);
218 VERIFY(m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK));
219 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified, folderindex);
220 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
221 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted, folderindex);
222 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
223 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly, folderindex);
224 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
225 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted, folderindex);
226 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
227 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked, folderindex);
228 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
229 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded, folderindex);
230 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
231 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored, folderindex);
232 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
233 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned, folderindex);
234 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
236 AddFileTypeGroup(_T(".cpp"), bSmallIcons);
237 AddFileTypeGroup(_T(".h"), bSmallIcons);
238 AddFileTypeGroup(_T(".txt"), bSmallIcons);
239 AddFileTypeGroup(_T(".java"), bSmallIcons);
240 AddFileTypeGroup(_T(".doc"), bSmallIcons);
241 AddFileTypeGroup(_T(".pl"), bSmallIcons);
242 AddFileTypeGroup(_T(".php"), bSmallIcons);
243 AddFileTypeGroup(_T(".asp"), bSmallIcons);
244 AddFileTypeGroup(_T(".cs"), bSmallIcons);
245 AddFileTypeGroup(_T(".vb"), bSmallIcons);
246 AddFileTypeGroup(_T(".xml"), bSmallIcons);
247 AddFileTypeGroup(_T(".pas"), bSmallIcons);
248 AddFileTypeGroup(_T(".dpr"), bSmallIcons);
249 AddFileTypeGroup(_T(".dfm"), bSmallIcons);
250 AddFileTypeGroup(_T(".res"), bSmallIcons);
251 AddFileTypeGroup(_T(".asmx"), bSmallIcons);
252 AddFileTypeGroup(_T(".aspx"), bSmallIcons);
253 AddFileTypeGroup(_T(".resx"), bSmallIcons);
254 AddFileTypeGroup(_T(".vbp"), bSmallIcons);
255 AddFileTypeGroup(_T(".frm"), bSmallIcons);
256 AddFileTypeGroup(_T(".frx"), bSmallIcons);
257 AddFileTypeGroup(_T(".bas"), bSmallIcons);
258 AddFileTypeGroup(_T(".config"), bSmallIcons);
259 AddFileTypeGroup(_T(".css"), bSmallIcons);
260 AddFileTypeGroup(_T(".acsx"), bSmallIcons);
261 AddFileTypeGroup(_T(".jpg"), bSmallIcons);
262 AddFileTypeGroup(_T(".png"), bSmallIcons);
263 m_cIconList.SetRedraw(TRUE);
265 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType, bool bSmallIcons)
267 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
268 if (bSmallIcons)
269 flags |= SHGFI_SMALLICON;
270 else
271 flags |= SHGFI_LARGEICON;
272 SHFILEINFO sfi;
273 SecureZeroMemory(&sfi, sizeof sfi);
275 SHGetFileInfo(
276 sFileType,
277 FILE_ATTRIBUTE_NORMAL,
278 &sfi, sizeof sfi,
279 flags);
281 int imageindex = 0;
282 if (bSmallIcons)
283 imageindex = m_ImageList.Add(sfi.hIcon);
284 else
285 imageindex = m_ImageListBig.Add(sfi.hIcon);
287 DestroyIcon(sfi.hIcon);
288 int index = 0;
289 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal+sFileType, imageindex);
290 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK);
291 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified+sFileType, imageindex);
292 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
293 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted+sFileType, imageindex);
294 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
295 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly+sFileType, imageindex);
296 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
297 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted+sFileType, imageindex);
298 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
299 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked+sFileType, imageindex);
300 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
301 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded+sFileType, imageindex);
302 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
303 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored+sFileType, imageindex);
304 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
305 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned+sFileType, imageindex);
306 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
309 void CSetOverlayIcons::OnBnClickedListradio()
311 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
312 ShowIconSet(true);
315 void CSetOverlayIcons::OnBnClickedSymbolradio()
317 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
318 ShowIconSet(false);
321 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
323 bool bSmallIcons = (GetCheckedRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO) == IDC_LISTRADIO);
324 ShowIconSet(bSmallIcons);
325 m_selIndex = m_cIconSet.GetCurSel();
326 if (m_selIndex != CB_ERR)
328 m_cIconSet.GetLBText(m_selIndex, m_sIconSet);
330 if (m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0)
331 SetModified();
334 BOOL CSetOverlayIcons::OnApply()
336 UpdateData();
338 if ((!m_sIconSet.IsEmpty())&&(m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0))
340 // the selected icon set has changed.
341 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\NormalIcon.ico"), m_regNormal);
342 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ModifiedIcon.ico"), m_regModified);
343 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ConflictIcon.ico"), m_regConflicted);
344 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ReadOnlyIcon.ico"), m_regReadOnly);
345 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\DeletedIcon.ico"), m_regDeleted);
346 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\LockedIcon.ico"), m_regLocked);
347 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\AddedIcon.ico"), m_regAdded);
348 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\IgnoredIcon.ico"), m_regIgnored);
349 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\UnversionedIcon.ico"), m_regUnversioned);
351 m_restart = Restart_System;
352 m_sOriginalIconSet = m_sIconSet;
354 SetModified(FALSE);
355 return ISettingsPropPage::OnApply();