1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "TortoiseProc.h"
\r
21 #include "DirFileEnum.h"
\r
22 #include "MessageBox.h"
\r
23 #include ".\setoverlayicons.h"
\r
24 #include "GitStatus.h"
\r
25 #include "AppUtils.h"
\r
26 #include "PathUtils.h"
\r
27 #include "ShellUpdater.h"
\r
28 #include "XPTheme.h"
\r
30 IMPLEMENT_DYNAMIC(CSetOverlayIcons, ISettingsPropPage)
\r
31 CSetOverlayIcons::CSetOverlayIcons()
\r
32 : ISettingsPropPage(CSetOverlayIcons::IDD)
\r
34 m_regNormal = CRegString(_T("Software\\TortoiseOverlays\\NormalIcon"));
\r
35 m_regModified = CRegString(_T("Software\\TortoiseOverlays\\ModifiedIcon"));
\r
36 m_regConflicted = CRegString(_T("Software\\TortoiseOverlays\\ConflictIcon"));
\r
37 m_regReadOnly = CRegString(_T("Software\\TortoiseOverlays\\ReadOnlyIcon"));
\r
38 m_regDeleted = CRegString(_T("Software\\TortoiseOverlays\\DeletedIcon"));
\r
39 m_regLocked = CRegString(_T("Software\\TortoiseOverlays\\LockedIcon"));
\r
40 m_regAdded = CRegString(_T("Software\\TortoiseOverlays\\AddedIcon"));
\r
41 m_regIgnored = CRegString(_T("Software\\TortoiseOverlays\\IgnoredIcon"));
\r
42 m_regUnversioned = CRegString(_T("Software\\TortoiseOverlays\\UnversionedIcon"));
\r
45 CSetOverlayIcons::~CSetOverlayIcons()
\r
49 void CSetOverlayIcons::DoDataExchange(CDataExchange* pDX)
\r
51 ISettingsPropPage::DoDataExchange(pDX);
\r
52 DDX_Control(pDX, IDC_ICONSETCOMBO, m_cIconSet);
\r
53 DDX_Control(pDX, IDC_ICONLIST, m_cIconList);
\r
57 BEGIN_MESSAGE_MAP(CSetOverlayIcons, ISettingsPropPage)
\r
58 ON_BN_CLICKED(IDC_LISTRADIO, OnBnClickedListradio)
\r
59 ON_BN_CLICKED(IDC_SYMBOLRADIO, OnBnClickedSymbolradio)
\r
60 ON_CBN_SELCHANGE(IDC_ICONSETCOMBO, OnCbnSelchangeIconsetcombo)
\r
63 BOOL CSetOverlayIcons::OnInitDialog()
\r
65 ISettingsPropPage::OnInitDialog();
\r
67 m_cIconList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_SUBITEMIMAGES);
\r
68 // get the path to our icon sets
\r
69 TCHAR buf[MAX_PATH] = {0};
\r
70 SHGetSpecialFolderPath(m_hWnd, buf, CSIDL_PROGRAM_FILES_COMMON, true);
\r
72 m_sIconPath += _T("\\TortoiseOverlays\\Icons");
\r
73 // list all the icon sets
\r
74 CDirFileEnum filefinder(m_sIconPath);
\r
77 while (filefinder.NextFile(item, &isDir))
\r
81 m_cIconSet.AddString(CPathUtils::GetFileNameFromPath(item));
\r
83 CheckRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO, IDC_LISTRADIO);
\r
84 CString sModifiedIcon = m_regModified;
\r
85 if (sModifiedIcon.IsEmpty())
\r
87 // no custom icon set, use the default
\r
88 sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
\r
90 if (sModifiedIcon.Left(m_sIconPath.GetLength()).CompareNoCase(m_sIconPath)!=0)
\r
92 // an icon set outside our own installation? We don't support that,
\r
93 // so fall back to the default!
\r
94 sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
\r
96 // the name of the icon set is the folder of the icon location
\r
97 m_sOriginalIconSet = sModifiedIcon.Mid(m_sIconPath.GetLength()+1);
\r
98 m_sOriginalIconSet = m_sOriginalIconSet.Left(m_sOriginalIconSet.ReverseFind('\\'));
\r
99 // now we have the name of the icon set. Set the combobox to show
\r
100 // that as selected
\r
102 for (int i=0; i<m_cIconSet.GetCount(); ++i)
\r
104 m_cIconSet.GetLBText(i, ComboItem);
\r
105 if (ComboItem.CompareNoCase(m_sOriginalIconSet)==0)
\r
106 m_cIconSet.SetCurSel(i);
\r
109 WORD langID = (WORD)(DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());
\r
110 TCHAR statustext[MAX_STATUS_STRING_LENGTH];
\r
111 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_normal, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
112 m_sNormal = statustext;
\r
113 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_modified, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
114 m_sModified = statustext;
\r
115 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_conflicted, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
116 m_sConflicted = statustext;
\r
117 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_deleted, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
118 m_sDeleted = statustext;
\r
119 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_added, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
120 m_sAdded = statustext;
\r
121 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_ignored, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
122 m_sIgnored = statustext;
\r
123 SVNStatus::GetStatusString(AfxGetResourceHandle(), svn_wc_status_unversioned, statustext, sizeof(statustext)/sizeof(TCHAR), langID);
\r
124 m_sUnversioned = statustext;
\r
126 m_sReadOnly.LoadString(IDS_SETTINGS_READONLYNAME);
\r
127 m_sLocked.LoadString(IDS_SETTINGS_LOCKEDNAME);
\r
130 theme.SetWindowTheme(m_cIconList.GetSafeHwnd(), L"Explorer", NULL);
\r
137 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons)
\r
139 m_cIconList.SetRedraw(FALSE);
\r
140 m_cIconList.DeleteAllItems();
\r
141 m_ImageList.DeleteImageList();
\r
142 m_ImageListBig.DeleteImageList();
\r
143 m_ImageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 20, 10);
\r
144 m_ImageListBig.Create(32, 32, ILC_COLOR32 | ILC_MASK, 20, 10);
\r
145 m_cIconList.SetImageList(&m_ImageList, LVSIL_SMALL);
\r
146 m_cIconList.SetImageList(&m_ImageListBig, LVSIL_NORMAL);
\r
148 // find all the icons of the selected icon set
\r
150 int index = m_cIconSet.GetCurSel();
\r
151 if (index == CB_ERR)
\r
153 // nothing selected. Shouldn't happen!
\r
156 m_cIconSet.GetLBText(index, sIconSet);
\r
157 CString sIconSetPath = m_sIconPath + _T("\\") + sIconSet;
\r
159 CImageList * pImageList = bSmallIcons ? &m_ImageList : &m_ImageListBig;
\r
160 int pixelsize = (bSmallIcons ? 16 : 32);
\r
161 HICON hNormalOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\NormalIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
162 index = pImageList->Add(hNormalOverlay);
\r
163 VERIFY(pImageList->SetOverlayImage(index, 1));
\r
164 HICON hModifiedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ModifiedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
165 index = pImageList->Add(hModifiedOverlay);
\r
166 VERIFY(pImageList->SetOverlayImage(index, 2));
\r
167 HICON hConflictedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ConflictIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
168 index = pImageList->Add(hConflictedOverlay);
\r
169 VERIFY(pImageList->SetOverlayImage(index, 3));
\r
170 HICON hReadOnlyOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\ReadOnlyIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
171 index = pImageList->Add(hReadOnlyOverlay);
\r
172 VERIFY(pImageList->SetOverlayImage(index, 4));
\r
173 HICON hDeletedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\DeletedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
174 index = pImageList->Add(hDeletedOverlay);
\r
175 VERIFY(pImageList->SetOverlayImage(index, 5));
\r
176 HICON hLockedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\LockedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
177 index = pImageList->Add(hLockedOverlay);
\r
178 VERIFY(pImageList->SetOverlayImage(index, 6));
\r
179 HICON hAddedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\AddedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
180 index = pImageList->Add(hAddedOverlay);
\r
181 VERIFY(pImageList->SetOverlayImage(index, 7));
\r
182 HICON hIgnoredOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\IgnoredIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
183 index = pImageList->Add(hIgnoredOverlay);
\r
184 VERIFY(pImageList->SetOverlayImage(index, 8));
\r
185 HICON hUnversionedOverlay = (HICON)LoadImage(NULL, sIconSetPath+_T("\\UnversionedIcon.ico"), IMAGE_ICON, pixelsize, pixelsize, LR_LOADFROMFILE);
\r
186 index = pImageList->Add(hUnversionedOverlay);
\r
187 VERIFY(pImageList->SetOverlayImage(index, 9));
\r
189 DestroyIcon(hNormalOverlay);
\r
190 DestroyIcon(hModifiedOverlay);
\r
191 DestroyIcon(hConflictedOverlay);
\r
192 DestroyIcon(hReadOnlyOverlay);
\r
193 DestroyIcon(hDeletedOverlay);
\r
194 DestroyIcon(hLockedOverlay);
\r
195 DestroyIcon(hAddedOverlay);
\r
196 DestroyIcon(hIgnoredOverlay);
\r
197 DestroyIcon(hUnversionedOverlay);
\r
199 // create an image list with different file icons
\r
201 SecureZeroMemory(&sfi, sizeof sfi);
\r
203 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
\r
205 flags |= SHGFI_SMALLICON;
\r
207 flags |= SHGFI_LARGEICON;
\r
209 _T("Doesn't matter"),
\r
210 FILE_ATTRIBUTE_DIRECTORY,
\r
214 int folderindex = pImageList->Add(sfi.hIcon); //folder
\r
215 DestroyIcon(sfi.hIcon);
\r
217 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal, folderindex);
\r
218 VERIFY(m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK));
\r
219 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified, folderindex);
\r
220 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
\r
221 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted, folderindex);
\r
222 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
\r
223 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly, folderindex);
\r
224 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
\r
225 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted, folderindex);
\r
226 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
\r
227 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked, folderindex);
\r
228 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
\r
229 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded, folderindex);
\r
230 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
\r
231 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored, folderindex);
\r
232 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
\r
233 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned, folderindex);
\r
234 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
\r
236 AddFileTypeGroup(_T(".cpp"), bSmallIcons);
\r
237 AddFileTypeGroup(_T(".h"), bSmallIcons);
\r
238 AddFileTypeGroup(_T(".txt"), bSmallIcons);
\r
239 AddFileTypeGroup(_T(".java"), bSmallIcons);
\r
240 AddFileTypeGroup(_T(".doc"), bSmallIcons);
\r
241 AddFileTypeGroup(_T(".pl"), bSmallIcons);
\r
242 AddFileTypeGroup(_T(".php"), bSmallIcons);
\r
243 AddFileTypeGroup(_T(".asp"), bSmallIcons);
\r
244 AddFileTypeGroup(_T(".cs"), bSmallIcons);
\r
245 AddFileTypeGroup(_T(".vb"), bSmallIcons);
\r
246 AddFileTypeGroup(_T(".xml"), bSmallIcons);
\r
247 AddFileTypeGroup(_T(".pas"), bSmallIcons);
\r
248 AddFileTypeGroup(_T(".dpr"), bSmallIcons);
\r
249 AddFileTypeGroup(_T(".dfm"), bSmallIcons);
\r
250 AddFileTypeGroup(_T(".res"), bSmallIcons);
\r
251 AddFileTypeGroup(_T(".asmx"), bSmallIcons);
\r
252 AddFileTypeGroup(_T(".aspx"), bSmallIcons);
\r
253 AddFileTypeGroup(_T(".resx"), bSmallIcons);
\r
254 AddFileTypeGroup(_T(".vbp"), bSmallIcons);
\r
255 AddFileTypeGroup(_T(".frm"), bSmallIcons);
\r
256 AddFileTypeGroup(_T(".frx"), bSmallIcons);
\r
257 AddFileTypeGroup(_T(".bas"), bSmallIcons);
\r
258 AddFileTypeGroup(_T(".config"), bSmallIcons);
\r
259 AddFileTypeGroup(_T(".css"), bSmallIcons);
\r
260 AddFileTypeGroup(_T(".acsx"), bSmallIcons);
\r
261 AddFileTypeGroup(_T(".jpg"), bSmallIcons);
\r
262 AddFileTypeGroup(_T(".png"), bSmallIcons);
\r
263 m_cIconList.SetRedraw(TRUE);
\r
265 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType, bool bSmallIcons)
\r
267 UINT flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
\r
269 flags |= SHGFI_SMALLICON;
\r
271 flags |= SHGFI_LARGEICON;
\r
273 SecureZeroMemory(&sfi, sizeof sfi);
\r
277 FILE_ATTRIBUTE_NORMAL,
\r
281 int imageindex = 0;
\r
283 imageindex = m_ImageList.Add(sfi.hIcon);
\r
285 imageindex = m_ImageListBig.Add(sfi.hIcon);
\r
287 DestroyIcon(sfi.hIcon);
\r
289 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sNormal+sFileType, imageindex);
\r
290 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK);
\r
291 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sModified+sFileType, imageindex);
\r
292 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK);
\r
293 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sConflicted+sFileType, imageindex);
\r
294 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK);
\r
295 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sReadOnly+sFileType, imageindex);
\r
296 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK);
\r
297 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sDeleted+sFileType, imageindex);
\r
298 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK);
\r
299 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sLocked+sFileType, imageindex);
\r
300 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK);
\r
301 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sAdded+sFileType, imageindex);
\r
302 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK);
\r
303 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sIgnored+sFileType, imageindex);
\r
304 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK);
\r
305 index = m_cIconList.InsertItem(m_cIconList.GetItemCount(), m_sUnversioned+sFileType, imageindex);
\r
306 m_cIconList.SetItemState(index, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK);
\r
309 void CSetOverlayIcons::OnBnClickedListradio()
\r
311 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
\r
315 void CSetOverlayIcons::OnBnClickedSymbolradio()
\r
317 m_cIconList.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
\r
318 ShowIconSet(false);
\r
321 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
\r
323 bool bSmallIcons = (GetCheckedRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO) == IDC_LISTRADIO);
\r
324 ShowIconSet(bSmallIcons);
\r
325 m_selIndex = m_cIconSet.GetCurSel();
\r
326 if (m_selIndex != CB_ERR)
\r
328 m_cIconSet.GetLBText(m_selIndex, m_sIconSet);
\r
330 if (m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0)
\r
334 BOOL CSetOverlayIcons::OnApply()
\r
338 if ((!m_sIconSet.IsEmpty())&&(m_sIconSet.CompareNoCase(m_sOriginalIconSet)!=0))
\r
340 // the selected icon set has changed.
\r
341 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\NormalIcon.ico"), m_regNormal);
\r
342 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ModifiedIcon.ico"), m_regModified);
\r
343 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ConflictIcon.ico"), m_regConflicted);
\r
344 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\ReadOnlyIcon.ico"), m_regReadOnly);
\r
345 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\DeletedIcon.ico"), m_regDeleted);
\r
346 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\LockedIcon.ico"), m_regLocked);
\r
347 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\AddedIcon.ico"), m_regAdded);
\r
348 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\IgnoredIcon.ico"), m_regIgnored);
\r
349 Store (m_sIconPath + _T("\\") + m_sIconSet + _T("\\UnversionedIcon.ico"), m_regUnversioned);
\r
351 m_restart = Restart_System;
\r
352 m_sOriginalIconSet = m_sIconSet;
\r
354 SetModified(FALSE);
\r
355 return ISettingsPropPage::OnApply();
\r