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.
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 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);
74 m_sIconPath
+= _T("\\TortoiseOverlays\\Icons");
75 // list all the icon sets
76 CDirFileEnum
filefinder(m_sIconPath
);
79 while (filefinder
.NextFile(item
, &isDir
))
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
+ _T("\\XPStyle\\ModifiedIcon.ico");
92 if (sModifiedIcon
.Left(m_sIconPath
.GetLength()).CompareNoCase(m_sIconPath
)!=0)
94 // an icon set outside our own installation? We don't support that,
95 // so fall back to the default!
96 sModifiedIcon
= m_sIconPath
+ _T("\\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
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);
129 void CSetOverlayIcons::ShowIconSet(bool bSmallIcons
)
131 m_cIconList
.SetRedraw(FALSE
);
132 m_cIconList
.DeleteAllItems();
133 m_ImageList
.DeleteImageList();
134 m_ImageListBig
.DeleteImageList();
135 m_ImageList
.Create(16, 16, ILC_COLOR32
| ILC_MASK
, 20, 10);
136 m_ImageListBig
.Create(32, 32, ILC_COLOR32
| ILC_MASK
, 20, 10);
137 m_cIconList
.SetImageList(&m_ImageList
, LVSIL_SMALL
);
138 m_cIconList
.SetImageList(&m_ImageListBig
, LVSIL_NORMAL
);
140 // find all the icons of the selected icon set
142 int index
= m_cIconSet
.GetCurSel();
145 // nothing selected. Shouldn't happen!
148 m_cIconSet
.GetLBText(index
, sIconSet
);
149 CString sIconSetPath
= m_sIconPath
+ _T("\\") + sIconSet
;
151 CImageList
* pImageList
= bSmallIcons
? &m_ImageList
: &m_ImageListBig
;
152 int pixelsize
= (bSmallIcons
? 16 : 32);
153 HICON hNormalOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\NormalIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
154 index
= pImageList
->Add(hNormalOverlay
);
155 VERIFY(pImageList
->SetOverlayImage(index
, 1));
156 HICON hModifiedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\ModifiedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
157 index
= pImageList
->Add(hModifiedOverlay
);
158 VERIFY(pImageList
->SetOverlayImage(index
, 2));
159 HICON hConflictedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\ConflictIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
160 index
= pImageList
->Add(hConflictedOverlay
);
161 VERIFY(pImageList
->SetOverlayImage(index
, 3));
162 HICON hReadOnlyOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\ReadOnlyIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
163 index
= pImageList
->Add(hReadOnlyOverlay
);
164 VERIFY(pImageList
->SetOverlayImage(index
, 4));
165 HICON hDeletedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\DeletedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
166 index
= pImageList
->Add(hDeletedOverlay
);
167 VERIFY(pImageList
->SetOverlayImage(index
, 5));
168 HICON hLockedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\LockedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
169 index
= pImageList
->Add(hLockedOverlay
);
170 VERIFY(pImageList
->SetOverlayImage(index
, 6));
171 HICON hAddedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\AddedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
172 index
= pImageList
->Add(hAddedOverlay
);
173 VERIFY(pImageList
->SetOverlayImage(index
, 7));
174 HICON hIgnoredOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\IgnoredIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
175 index
= pImageList
->Add(hIgnoredOverlay
);
176 VERIFY(pImageList
->SetOverlayImage(index
, 8));
177 HICON hUnversionedOverlay
= (HICON
)LoadImage(nullptr, sIconSetPath
+ _T("\\UnversionedIcon.ico"), IMAGE_ICON
, pixelsize
, pixelsize
, LR_LOADFROMFILE
);
178 index
= pImageList
->Add(hUnversionedOverlay
);
179 VERIFY(pImageList
->SetOverlayImage(index
, 9));
181 DestroyIcon(hNormalOverlay
);
182 DestroyIcon(hModifiedOverlay
);
183 DestroyIcon(hConflictedOverlay
);
184 DestroyIcon(hReadOnlyOverlay
);
185 DestroyIcon(hDeletedOverlay
);
186 DestroyIcon(hLockedOverlay
);
187 DestroyIcon(hAddedOverlay
);
188 DestroyIcon(hIgnoredOverlay
);
189 DestroyIcon(hUnversionedOverlay
);
191 // create an image list with different file icons
192 SHFILEINFO sfi
= { 0 };
194 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
196 flags
|= SHGFI_SMALLICON
;
198 flags
|= SHGFI_LARGEICON
;
200 _T("Doesn't matter"),
201 FILE_ATTRIBUTE_DIRECTORY
,
205 int folderindex
= pImageList
->Add(sfi
.hIcon
); //folder
206 DestroyIcon(sfi
.hIcon
);
208 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sNormal
, folderindex
);
209 VERIFY(m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK
));
210 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sModified
, folderindex
);
211 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK
);
212 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sConflicted
, folderindex
);
213 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK
);
214 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sReadOnly
, folderindex
);
215 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK
);
216 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sDeleted
, folderindex
);
217 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK
);
218 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sLocked
, folderindex
);
219 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK
);
220 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sAdded
, folderindex
);
221 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK
);
222 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sIgnored
, folderindex
);
223 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK
);
224 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sUnversioned
, folderindex
);
225 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK
);
227 AddFileTypeGroup(_T(".cpp"), bSmallIcons
);
228 AddFileTypeGroup(_T(".h"), bSmallIcons
);
229 AddFileTypeGroup(_T(".txt"), bSmallIcons
);
230 AddFileTypeGroup(_T(".java"), bSmallIcons
);
231 AddFileTypeGroup(_T(".doc"), bSmallIcons
);
232 AddFileTypeGroup(_T(".pl"), bSmallIcons
);
233 AddFileTypeGroup(_T(".php"), bSmallIcons
);
234 AddFileTypeGroup(_T(".asp"), bSmallIcons
);
235 AddFileTypeGroup(_T(".cs"), bSmallIcons
);
236 AddFileTypeGroup(_T(".vb"), bSmallIcons
);
237 AddFileTypeGroup(_T(".xml"), bSmallIcons
);
238 AddFileTypeGroup(_T(".pas"), bSmallIcons
);
239 AddFileTypeGroup(_T(".dpr"), bSmallIcons
);
240 AddFileTypeGroup(_T(".dfm"), bSmallIcons
);
241 AddFileTypeGroup(_T(".res"), bSmallIcons
);
242 AddFileTypeGroup(_T(".asmx"), bSmallIcons
);
243 AddFileTypeGroup(_T(".aspx"), bSmallIcons
);
244 AddFileTypeGroup(_T(".resx"), bSmallIcons
);
245 AddFileTypeGroup(_T(".vbp"), bSmallIcons
);
246 AddFileTypeGroup(_T(".frm"), bSmallIcons
);
247 AddFileTypeGroup(_T(".frx"), bSmallIcons
);
248 AddFileTypeGroup(_T(".bas"), bSmallIcons
);
249 AddFileTypeGroup(_T(".config"), bSmallIcons
);
250 AddFileTypeGroup(_T(".css"), bSmallIcons
);
251 AddFileTypeGroup(_T(".acsx"), bSmallIcons
);
252 AddFileTypeGroup(_T(".jpg"), bSmallIcons
);
253 AddFileTypeGroup(_T(".png"), bSmallIcons
);
254 m_cIconList
.SetRedraw(TRUE
);
256 void CSetOverlayIcons::AddFileTypeGroup(CString sFileType
, bool bSmallIcons
)
258 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
260 flags
|= SHGFI_SMALLICON
;
262 flags
|= SHGFI_LARGEICON
;
263 SHFILEINFO sfi
= { 0 };
267 FILE_ATTRIBUTE_NORMAL
,
273 imageindex
= m_ImageList
.Add(sfi
.hIcon
);
275 imageindex
= m_ImageListBig
.Add(sfi
.hIcon
);
277 DestroyIcon(sfi
.hIcon
);
279 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sNormal
+sFileType
, imageindex
);
280 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(1), TVIS_OVERLAYMASK
);
281 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sModified
+sFileType
, imageindex
);
282 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(2), TVIS_OVERLAYMASK
);
283 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sConflicted
+sFileType
, imageindex
);
284 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(3), TVIS_OVERLAYMASK
);
285 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sReadOnly
+sFileType
, imageindex
);
286 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(4), TVIS_OVERLAYMASK
);
287 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sDeleted
+sFileType
, imageindex
);
288 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(5), TVIS_OVERLAYMASK
);
289 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sLocked
+sFileType
, imageindex
);
290 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(6), TVIS_OVERLAYMASK
);
291 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sAdded
+sFileType
, imageindex
);
292 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(7), TVIS_OVERLAYMASK
);
293 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sIgnored
+sFileType
, imageindex
);
294 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(8), TVIS_OVERLAYMASK
);
295 index
= m_cIconList
.InsertItem(m_cIconList
.GetItemCount(), m_sUnversioned
+sFileType
, imageindex
);
296 m_cIconList
.SetItemState(index
, INDEXTOOVERLAYMASK(9), TVIS_OVERLAYMASK
);
299 void CSetOverlayIcons::OnBnClickedListradio()
301 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_LIST
);
305 void CSetOverlayIcons::OnBnClickedSymbolradio()
307 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
311 void CSetOverlayIcons::OnCbnSelchangeIconsetcombo()
313 bool bSmallIcons
= (GetCheckedRadioButton(IDC_LISTRADIO
, IDC_SYMBOLRADIO
) == IDC_LISTRADIO
);
314 ShowIconSet(bSmallIcons
);
315 m_selIndex
= m_cIconSet
.GetCurSel();
316 if (m_selIndex
!= CB_ERR
)
317 m_cIconSet
.GetLBText(m_selIndex
, m_sIconSet
);
318 if (m_sIconSet
.CompareNoCase(m_sOriginalIconSet
)!=0)
322 BOOL
CSetOverlayIcons::OnApply()
326 if ((!m_sIconSet
.IsEmpty())&&(m_sIconSet
.CompareNoCase(m_sOriginalIconSet
)!=0))
328 // the selected icon set has changed.
329 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\NormalIcon.ico"), m_regNormal
);
330 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ModifiedIcon.ico"), m_regModified
);
331 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ConflictIcon.ico"), m_regConflicted
);
332 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\ReadOnlyIcon.ico"), m_regReadOnly
);
333 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\DeletedIcon.ico"), m_regDeleted
);
334 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\LockedIcon.ico"), m_regLocked
);
335 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\AddedIcon.ico"), m_regAdded
);
336 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\IgnoredIcon.ico"), m_regIgnored
);
337 Store(m_sIconPath
+ _T("\\") + m_sIconSet
+ _T("\\UnversionedIcon.ico"), m_regUnversioned
);
339 m_restart
= Restart_System
;
340 m_sOriginalIconSet
= m_sIconSet
;
343 return ISettingsPropPage::OnApply();