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.
21 #include "TortoiseProc.h"
22 #include "DirFileEnum.h"
23 #include "MessageBox.h"
24 #include ".\setoverlayicons.h"
25 #include "GitStatus.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
)
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);
72 m_sIconPath
+= _T("\\TortoiseOverlays\\Icons");
73 // list all the icon sets
74 CDirFileEnum
filefinder(m_sIconPath
);
77 while (filefinder
.NextFile(item
, &isDir
))
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
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
);
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
149 int index
= m_cIconSet
.GetCurSel();
152 // nothing selected. Shouldn't happen!
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
200 SecureZeroMemory(&sfi
, sizeof sfi
);
202 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
204 flags
|= SHGFI_SMALLICON
;
206 flags
|= SHGFI_LARGEICON
;
208 _T("Doesn't matter"),
209 FILE_ATTRIBUTE_DIRECTORY
,
213 int folderindex
= pImageList
->Add(sfi
.hIcon
); //folder
214 DestroyIcon(sfi
.hIcon
);
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
;
268 flags
|= SHGFI_SMALLICON
;
270 flags
|= SHGFI_LARGEICON
;
272 SecureZeroMemory(&sfi
, sizeof sfi
);
276 FILE_ATTRIBUTE_NORMAL
,
282 imageindex
= m_ImageList
.Add(sfi
.hIcon
);
284 imageindex
= m_ImageListBig
.Add(sfi
.hIcon
);
286 DestroyIcon(sfi
.hIcon
);
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
);
314 void CSetOverlayIcons::OnBnClickedSymbolradio()
316 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
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)
333 BOOL
CSetOverlayIcons::OnApply()
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
;
354 return ISettingsPropPage::OnApply();