1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2011,2013 - 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.
21 #include "TortoiseProc.h"
22 #include "DirFileEnum.h"
23 #include "MessageBox.h"
24 #include "SetOverlayIcons.h"
26 #include "PathUtils.h"
28 IMPLEMENT_DYNAMIC(CSetOverlayIcons
, ISettingsPropPage
)
29 CSetOverlayIcons::CSetOverlayIcons()
30 : ISettingsPropPage(CSetOverlayIcons::IDD
)
32 m_regNormal
= CRegString(_T("Software\\TortoiseOverlays\\NormalIcon"));
33 m_regModified
= CRegString(_T("Software\\TortoiseOverlays\\ModifiedIcon"));
34 m_regConflicted
= CRegString(_T("Software\\TortoiseOverlays\\ConflictIcon"));
35 m_regReadOnly
= CRegString(_T("Software\\TortoiseOverlays\\ReadOnlyIcon"));
36 m_regDeleted
= CRegString(_T("Software\\TortoiseOverlays\\DeletedIcon"));
37 m_regLocked
= CRegString(_T("Software\\TortoiseOverlays\\LockedIcon"));
38 m_regAdded
= CRegString(_T("Software\\TortoiseOverlays\\AddedIcon"));
39 m_regIgnored
= CRegString(_T("Software\\TortoiseOverlays\\IgnoredIcon"));
40 m_regUnversioned
= CRegString(_T("Software\\TortoiseOverlays\\UnversionedIcon"));
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
)
62 BOOL
CSetOverlayIcons::OnInitDialog()
64 ISettingsPropPage::OnInitDialog();
66 m_cIconList
.SetExtendedStyle(LVS_EX_FULLROWSELECT
| LVS_EX_DOUBLEBUFFER
| LVS_EX_INFOTIP
| LVS_EX_SUBITEMIMAGES
);
67 // get the path to our icon sets
68 TCHAR buf
[MAX_PATH
] = {0};
69 SHGetSpecialFolderPath(m_hWnd
, buf
, CSIDL_PROGRAM_FILES_COMMON
, true);
71 m_sIconPath
+= _T("\\TortoiseOverlays\\Icons");
72 // list all the icon sets
73 CDirFileEnum
filefinder(m_sIconPath
);
76 while (filefinder
.NextFile(item
, &isDir
))
80 m_cIconSet
.AddString(CPathUtils::GetFileNameFromPath(item
));
82 CheckRadioButton(IDC_LISTRADIO
, IDC_SYMBOLRADIO
, IDC_LISTRADIO
);
83 CString sModifiedIcon
= m_regModified
;
84 if (sModifiedIcon
.IsEmpty())
86 // no custom icon set, use the default
87 sModifiedIcon
= m_sIconPath
+ _T("\\XPStyle\\ModifiedIcon.ico");
89 if (sModifiedIcon
.Left(m_sIconPath
.GetLength()).CompareNoCase(m_sIconPath
)!=0)
91 // an icon set outside our own installation? We don't support that,
92 // so fall back to the default!
93 sModifiedIcon
= m_sIconPath
+ _T("\\XPStyle\\ModifiedIcon.ico");
95 // the name of the icon set is the folder of the icon location
96 m_sOriginalIconSet
= sModifiedIcon
.Mid(m_sIconPath
.GetLength()+1);
97 m_sOriginalIconSet
= m_sOriginalIconSet
.Left(m_sOriginalIconSet
.ReverseFind('\\'));
98 // now we have the name of the icon set. Set the combobox to show
101 for (int i
=0; i
<m_cIconSet
.GetCount(); ++i
)
103 m_cIconSet
.GetLBText(i
, ComboItem
);
104 if (ComboItem
.CompareNoCase(m_sOriginalIconSet
)==0)
105 m_cIconSet
.SetCurSel(i
);
108 m_sNormal
= CString(MAKEINTRESOURCE(IDS_STATUSNORMAL
));
109 m_sModified
= CString(MAKEINTRESOURCE(IDS_STATUSMODIFIED
));
110 m_sConflicted
= CString(MAKEINTRESOURCE(IDS_STATUSCONFLICTED
));
111 m_sDeleted
= CString(MAKEINTRESOURCE(IDS_STATUSDELETED
));
112 m_sAdded
= CString(MAKEINTRESOURCE(IDS_STATUSADDED
));
113 m_sIgnored
= CString(MAKEINTRESOURCE(IDS_STATUSIGNORED
));
114 m_sUnversioned
= CString(MAKEINTRESOURCE(IDS_STATUSUNVERSIONED
));
116 m_sReadOnly
.LoadString(IDS_SETTINGS_READONLYNAME
);
117 m_sLocked
.LoadString(IDS_SETTINGS_LOCKEDNAME
);
119 SetWindowTheme(m_hWnd
, L
"Explorer", NULL
);
126 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons
)
128 m_cIconList
.SetRedraw(FALSE
);
129 m_cIconList
.DeleteAllItems();
130 m_ImageList
.DeleteImageList();
131 m_ImageListBig
.DeleteImageList();
132 m_ImageList
.Create(16, 16, ILC_COLOR32
| ILC_MASK
, 20, 10);
133 m_ImageListBig
.Create(32, 32, ILC_COLOR32
| ILC_MASK
, 20, 10);
134 m_cIconList
.SetImageList(&m_ImageList
, LVSIL_SMALL
);
135 m_cIconList
.SetImageList(&m_ImageListBig
, LVSIL_NORMAL
);
137 // find all the icons of the selected icon set
139 int index
= m_cIconSet
.GetCurSel();
142 // nothing selected. Shouldn't happen!
145 m_cIconSet
.GetLBText(index
, sIconSet
);
146 CString sIconSetPath
= m_sIconPath
+ _T("\\") + sIconSet
;
148 CImageList
* pImageList
= bSmallIcons
? &m_ImageList
: &m_ImageListBig
;
149 int pixelsize
= (bSmallIcons
? 16 : 32);
150 HICON hNormalOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\NormalIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
151 index
= pImageList
->Add(hNormalOverlay
);
152 VERIFY(pImageList
->SetOverlayImage(index
, 1));
153 HICON hModifiedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\ModifiedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
154 index
= pImageList
->Add(hModifiedOverlay
);
155 VERIFY(pImageList
->SetOverlayImage(index
, 2));
156 HICON hConflictedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\ConflictIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
157 index
= pImageList
->Add(hConflictedOverlay
);
158 VERIFY(pImageList
->SetOverlayImage(index
, 3));
159 HICON hReadOnlyOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\ReadOnlyIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
160 index
= pImageList
->Add(hReadOnlyOverlay
);
161 VERIFY(pImageList
->SetOverlayImage(index
, 4));
162 HICON hDeletedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\DeletedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
163 index
= pImageList
->Add(hDeletedOverlay
);
164 VERIFY(pImageList
->SetOverlayImage(index
, 5));
165 HICON hLockedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\LockedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
166 index
= pImageList
->Add(hLockedOverlay
);
167 VERIFY(pImageList
->SetOverlayImage(index
, 6));
168 HICON hAddedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\AddedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
169 index
= pImageList
->Add(hAddedOverlay
);
170 VERIFY(pImageList
->SetOverlayImage(index
, 7));
171 HICON hIgnoredOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\IgnoredIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
172 index
= pImageList
->Add(hIgnoredOverlay
);
173 VERIFY(pImageList
->SetOverlayImage(index
, 8));
174 HICON hUnversionedOverlay
= (HICON
)LoadImage(NULL
, sIconSetPath
+_T("\\UnversionedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
175 index
= pImageList
->Add(hUnversionedOverlay
);
176 VERIFY(pImageList
->SetOverlayImage(index
, 9));
178 DestroyIcon(hNormalOverlay
);
179 DestroyIcon(hModifiedOverlay
);
180 DestroyIcon(hConflictedOverlay
);
181 DestroyIcon(hReadOnlyOverlay
);
182 DestroyIcon(hDeletedOverlay
);
183 DestroyIcon(hLockedOverlay
);
184 DestroyIcon(hAddedOverlay
);
185 DestroyIcon(hIgnoredOverlay
);
186 DestroyIcon(hUnversionedOverlay
);
188 // create an image list with different file icons
190 SecureZeroMemory(&sfi
, sizeof sfi
);
192 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
194 flags
|= SHGFI_SMALLICON
;
196 flags
|= SHGFI_LARGEICON
;
198 _T("Doesn't matter"),
199 FILE_ATTRIBUTE_DIRECTORY
,
203 int folderindex
= pImageList
->Add(sfi
.hIcon
); //folder
204 DestroyIcon(sfi
.hIcon
);
206 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sNormal
, folderindex
);
207 VERIFY(m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK
));
208 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sModified
, folderindex
);
209 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK
);
210 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sConflicted
, folderindex
);
211 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK
);
212 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sReadOnly
, folderindex
);
213 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK
);
214 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sDeleted
, folderindex
);
215 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK
);
216 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sLocked
, folderindex
);
217 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK
);
218 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sAdded
, folderindex
);
219 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK
);
220 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sIgnored
, folderindex
);
221 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK
);
222 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sUnversioned
, folderindex
);
223 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK
);
225 AddFileTypeGroup(_T(".cpp"), bSmallIcons
);
226 AddFileTypeGroup(_T(".h"), bSmallIcons
);
227 AddFileTypeGroup(_T(".txt"), bSmallIcons
);
228 AddFileTypeGroup(_T(".java"), bSmallIcons
);
229 AddFileTypeGroup(_T(".doc"), bSmallIcons
);
230 AddFileTypeGroup(_T(".pl"), bSmallIcons
);
231 AddFileTypeGroup(_T(".php"), bSmallIcons
);
232 AddFileTypeGroup(_T(".asp"), bSmallIcons
);
233 AddFileTypeGroup(_T(".cs"), bSmallIcons
);
234 AddFileTypeGroup(_T(".vb"), bSmallIcons
);
235 AddFileTypeGroup(_T(".xml"), bSmallIcons
);
236 AddFileTypeGroup(_T(".pas"), bSmallIcons
);
237 AddFileTypeGroup(_T(".dpr"), bSmallIcons
);
238 AddFileTypeGroup(_T(".dfm"), bSmallIcons
);
239 AddFileTypeGroup(_T(".res"), bSmallIcons
);
240 AddFileTypeGroup(_T(".asmx"), bSmallIcons
);
241 AddFileTypeGroup(_T(".aspx"), bSmallIcons
);
242 AddFileTypeGroup(_T(".resx"), bSmallIcons
);
243 AddFileTypeGroup(_T(".vbp"), bSmallIcons
);
244 AddFileTypeGroup(_T(".frm"), bSmallIcons
);
245 AddFileTypeGroup(_T(".frx"), bSmallIcons
);
246 AddFileTypeGroup(_T(".bas"), bSmallIcons
);
247 AddFileTypeGroup(_T(".config"), bSmallIcons
);
248 AddFileTypeGroup(_T(".css"), bSmallIcons
);
249 AddFileTypeGroup(_T(".acsx"), bSmallIcons
);
250 AddFileTypeGroup(_T(".jpg"), bSmallIcons
);
251 AddFileTypeGroup(_T(".png"), bSmallIcons
);
252 m_cIconList
.SetRedraw(TRUE
);
254 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType
, bool bSmallIcons
)
256 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
258 flags
|= SHGFI_SMALLICON
;
260 flags
|= SHGFI_LARGEICON
;
262 SecureZeroMemory(&sfi
, sizeof sfi
);
266 FILE_ATTRIBUTE_NORMAL
,
272 imageindex
= m_ImageList
.Add(sfi
.hIcon
);
274 imageindex
= m_ImageListBig
.Add(sfi
.hIcon
);
276 DestroyIcon(sfi
.hIcon
);
278 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sNormal
+sFileType
, imageindex
);
279 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK
);
280 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sModified
+sFileType
, imageindex
);
281 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK
);
282 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sConflicted
+sFileType
, imageindex
);
283 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK
);
284 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sReadOnly
+sFileType
, imageindex
);
285 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK
);
286 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sDeleted
+sFileType
, imageindex
);
287 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK
);
288 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sLocked
+sFileType
, imageindex
);
289 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK
);
290 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sAdded
+sFileType
, imageindex
);
291 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK
);
292 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sIgnored
+sFileType
, imageindex
);
293 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK
);
294 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sUnversioned
+sFileType
, imageindex
);
295 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK
);
298 void CSetOverlayIcons::OnBnClickedListradio()
300 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_LIST
);
304 void CSetOverlayIcons::OnBnClickedSymbolradio()
306 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
310 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
312 bool bSmallIcons
= (GetCheckedRadioButton(IDC_LISTRADIO
, IDC_SYMBOLRADIO
) == IDC_LISTRADIO
);
313 ShowIconSet(bSmallIcons
);
314 m_selIndex
= m_cIconSet
.GetCurSel();
315 if (m_selIndex
!= CB_ERR
)
317 m_cIconSet
.GetLBText(m_selIndex
, m_sIconSet
);
319 if (m_sIconSet
.CompareNoCase(m_sOriginalIconSet
)!=0)
323 BOOL
CSetOverlayIcons::OnApply()
327 if ((!m_sIconSet
.IsEmpty())&&(m_sIconSet
.CompareNoCase(m_sOriginalIconSet
)!=0))
329 // the selected icon set has changed.
330 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\NormalIcon.ico"), m_regNormal
);
331 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ModifiedIcon.ico"), m_regModified
);
332 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ConflictIcon.ico"), m_regConflicted
);
333 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ReadOnlyIcon.ico"), m_regReadOnly
);
334 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\DeletedIcon.ico"), m_regDeleted
);
335 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\LockedIcon.ico"), m_regLocked
);
336 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\AddedIcon.ico"), m_regAdded
);
337 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\IgnoredIcon.ico"), m_regIgnored
);
338 Store (m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\UnversionedIcon.ico"), m_regUnversioned
);
340 m_restart
= Restart_System
;
341 m_sOriginalIconSet
= m_sIconSet
;
344 return ISettingsPropPage::OnApply();