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.
20 #include "TortoiseProc.h"
21 #include "DirFileEnum.h"
22 #include "MessageBox.h"
23 #include ".\setoverlayicons.h"
24 #include "GitStatus.h"
26 #include "PathUtils.h"
27 #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
)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
;
126 m_sReadOnly
.LoadString(IDS_SETTINGS_READONLYNAME
);
127 m_sLocked
.LoadString(IDS_SETTINGS_LOCKEDNAME
);
130 theme
.SetWindowTheme(m_cIconList
.GetSafeHwnd(), L
"Explorer", NULL
);
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
150 int index
= m_cIconSet
.GetCurSel();
153 // nothing selected. Shouldn't happen!
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
201 SecureZeroMemory(&sfi
, sizeof sfi
);
203 UINT flags
= SHGFI_ICON
| SHGFI_USEFILEATTRIBUTES
;
205 flags
|= SHGFI_SMALLICON
;
207 flags
|= SHGFI_LARGEICON
;
209 _T("Doesn't matter"),
210 FILE_ATTRIBUTE_DIRECTORY
,
214 int folderindex
= pImageList
->Add(sfi
.hIcon
); //folder
215 DestroyIcon(sfi
.hIcon
);
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
;
269 flags
|= SHGFI_SMALLICON
;
271 flags
|= SHGFI_LARGEICON
;
273 SecureZeroMemory(&sfi
, sizeof sfi
);
277 FILE_ATTRIBUTE_NORMAL
,
283 imageindex
= m_ImageList
.Add(sfi
.hIcon
);
285 imageindex
= m_ImageListBig
.Add(sfi
.hIcon
);
287 DestroyIcon(sfi
.hIcon
);
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
);
315 void CSetOverlayIcons::OnBnClickedSymbolradio()
317 m_cIconList
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
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)
334 BOOL
CSetOverlayIcons::OnApply()
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
;
355 return ISettingsPropPage::OnApply();