1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2011-2016 - TortoiseGit
4 // Copyright (C) 2003-2008, 2011, 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"
23 #include "ShellUpdater.h"
25 #include "StringUtils.h"
26 #include "SetLookAndFeelPage.h"
28 #include "ShellCache.h"
30 extern MenuInfo menuInfo
[];
32 void InsertMenuItemToList(CListCtrl
*list
,CImageList
*imagelist
)
35 int iconWidth
= GetSystemMetrics(SM_CXSMICON
);
36 int iconHeight
= GetSystemMetrics(SM_CYSMICON
);
37 while(menuInfo
[i
].command
!= ShellMenuLastEntry
)
39 if ((menuInfo
[i
].command
!= ShellSeparator
&&
40 menuInfo
[i
].command
!= ShellSubMenu
&&
41 menuInfo
[i
].command
!= ShellSubMenuFile
&&
42 menuInfo
[i
].command
!= ShellSubMenuFolder
&&
43 menuInfo
[i
].command
!= ShellSubMenuLink
&&
44 menuInfo
[i
].command
!= ShellMenuMergeAbort
&&
45 menuInfo
[i
].command
!= ShellSubMenuMultiple
) &&
46 (i
== 0 || menuInfo
[i
- 1].menuID
!= menuInfo
[i
].menuID
))
48 auto hIcon
= CAppUtils::LoadIconEx(menuInfo
[i
].iconID
, iconWidth
, iconHeight
);
50 int nImage
= imagelist
-> Add(hIcon
);
53 temp
.LoadString(menuInfo
[i
].menuTextID
);
54 CStringUtils::RemoveAccelerators(temp
);
56 int nIndex
= list
->GetItemCount();
57 list
->InsertItem(nIndex
,temp
,nImage
);
58 list
->SetItemData(nIndex
,i
);
64 void SetMenuItemCheck(CListCtrl
*list
, unsigned __int64 mask
, CButton
*selectAll
)
66 bool allChecked
= true;
67 for(int i
=0;i
<list
->GetItemCount();i
++)
69 int data
= (int)list
->GetItemData(i
);
71 list
->SetCheck(i
,(menuInfo
[data
].menuID
& mask
) == menuInfo
[data
].menuID
);
72 if (!((menuInfo
[data
].menuID
& mask
) == menuInfo
[data
].menuID
))
77 selectAll
->SetCheck(BST_UNCHECKED
);
79 selectAll
->SetCheck(BST_CHECKED
);
81 selectAll
->SetCheck(BST_INDETERMINATE
);
84 unsigned __int64
GetMenuListMask(CListCtrl
* list
, CButton
* selectAll
= nullptr)
86 unsigned __int64 mask
= 0;
87 bool allChecked
= true;
89 for(int i
=0;i
<list
->GetItemCount();i
++)
93 int data
= (int)list
->GetItemData(i
);
94 mask
|= menuInfo
[data
].menuID
;
103 selectAll
->SetCheck(BST_UNCHECKED
);
105 selectAll
->SetCheck(BST_CHECKED
);
107 selectAll
->SetCheck(BST_INDETERMINATE
);
111 // Handles click on "select all" and returns the calculated mask
112 unsigned __int64
ClickedSelectAll(CListCtrl
*list
, CButton
*selectAll
)
114 UINT state
= (selectAll
->GetState() & 0x0003);
115 if (state
== BST_INDETERMINATE
)
117 // It is not at all useful to manually place the checkbox into the indeterminate state...
118 // We will force this on to the unchecked state
119 state
= BST_UNCHECKED
;
120 selectAll
->SetCheck(state
);
123 theApp
.DoWaitCursor(1);
125 for (int i
= 0; i
< list
->GetItemCount(); i
++)
126 list
->SetCheck(i
, state
== BST_CHECKED
);
128 unsigned __int64 mask
= GetMenuListMask(list
);
130 theApp
.DoWaitCursor(-1);
135 IMPLEMENT_DYNAMIC(CSetLookAndFeelPage
, ISettingsPropPage
)
136 CSetLookAndFeelPage::CSetLookAndFeelPage()
137 : ISettingsPropPage(CSetLookAndFeelPage::IDD
)
139 , m_bHideMenus(false)
142 m_regTopmenu
= cache
.menulayoutlow
;
143 m_regTopmenuhigh
= cache
.menulayouthigh
;
145 m_topmenu
= unsigned __int64(DWORD(m_regTopmenuhigh
))<<32;
146 m_topmenu
|= unsigned __int64(DWORD(m_regTopmenu
));
148 m_regHideMenus
= CRegDWORD(L
"Software\\TortoiseGit\\HideMenusForUnversionedItems", FALSE
);
149 m_bHideMenus
= m_regHideMenus
;
151 m_regNoContextPaths
= CRegString(L
"Software\\TortoiseGit\\NoContextPaths", L
"");
152 m_sNoContextPaths
= m_regNoContextPaths
;
153 m_sNoContextPaths
.Replace(L
"\n", L
"\r\n");
155 m_regEnableDragContextMenu
= CRegDWORD(L
"Software\\TortoiseGit\\EnableDragContextMenu", TRUE
);
156 m_bEnableDragContextMenu
= m_regEnableDragContextMenu
;
159 CSetLookAndFeelPage::~CSetLookAndFeelPage()
163 void CSetLookAndFeelPage::DoDataExchange(CDataExchange
* pDX
)
165 ISettingsPropPage::DoDataExchange(pDX
);
166 DDX_Control(pDX
, IDC_MENULIST
, m_cMenuList
);
167 DDX_Check(pDX
, IDC_HIDEMENUS
, m_bHideMenus
);
168 DDX_Text(pDX
, IDC_NOCONTEXTPATHS
, m_sNoContextPaths
);
169 DDX_Check(pDX
, IDC_ENABLEDRAGCONTEXTMENU
, m_bEnableDragContextMenu
);
173 BEGIN_MESSAGE_MAP(CSetLookAndFeelPage
, ISettingsPropPage
)
174 ON_NOTIFY(LVN_ITEMCHANGED
, IDC_MENULIST
, OnLvnItemchangedMenulist
)
175 ON_BN_CLICKED(IDC_SELECTALL
, OnBnClickedSelectall
)
176 ON_BN_CLICKED(IDC_RESTORE
, OnBnClickedRestoreDefaults
)
177 ON_BN_CLICKED(IDC_HIDEMENUS
, OnChange
)
178 ON_EN_CHANGE(IDC_NOCONTEXTPATHS
, &CSetLookAndFeelPage::OnEnChangeNocontextpaths
)
179 ON_BN_CLICKED(IDC_ENABLEDRAGCONTEXTMENU
, OnChange
)
183 BOOL
CSetLookAndFeelPage::OnInitDialog()
185 ISettingsPropPage::OnInitDialog();
187 AdjustControlSize(IDC_SELECTALL
);
188 AdjustControlSize(IDC_HIDEMENUS
);
189 AdjustControlSize(IDC_ENABLEDRAGCONTEXTMENU
);
191 m_tooltips
.AddTool(IDC_MENULIST
, IDS_SETTINGS_MENULAYOUT_TT
);
192 m_tooltips
.AddTool(IDC_HIDEMENUS
, IDS_SETTINGS_HIDEMENUS_TT
);
193 m_tooltips
.AddTool(IDC_NOCONTEXTPATHS
, IDS_SETTINGS_EXCLUDECONTEXTLIST_TT
);
194 m_tooltips
.AddTool(IDC_ENABLEDRAGCONTEXTMENU
, IDS_SETTINGS_ENABLEDRAGCONTEXTMENU_TT
);
196 m_cMenuList
.SetExtendedStyle(LVS_EX_CHECKBOXES
| (CRegDWORD(L
"Software\\TortoiseGit\\FullRowSelect", TRUE
) ? LVS_EX_FULLROWSELECT
: 0) | LVS_EX_DOUBLEBUFFER
);
198 m_cMenuList
.DeleteAllItems();
199 int c
= m_cMenuList
.GetHeaderCtrl()->GetItemCount() - 1;
201 m_cMenuList
.DeleteColumn(c
--);
202 m_cMenuList
.InsertColumn(0, L
"");
204 SetWindowTheme(m_hWnd
, L
"Explorer", nullptr);
206 m_cMenuList
.SetRedraw(false);
208 int iconWidth
= GetSystemMetrics(SM_CXSMICON
);
209 int iconHeight
= GetSystemMetrics(SM_CYSMICON
);
210 m_imgList
.Create(iconWidth
, iconHeight
, ILC_COLOR32
| ILC_MASK
, 4, 1);
214 InsertMenuItemToList(&m_cMenuList
,&m_imgList
);
215 SetMenuItemCheck(&m_cMenuList
, m_topmenu
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
219 m_cMenuList
.SetImageList(&m_imgList
, LVSIL_SMALL
);
221 int maxcol
= m_cMenuList
.GetHeaderCtrl()->GetItemCount() - 1;
223 for (col
= mincol
; col
<= maxcol
; col
++)
224 m_cMenuList
.SetColumnWidth(col
,LVSCW_AUTOSIZE_USEHEADER
);
225 m_cMenuList
.SetRedraw(true);
232 BOOL
CSetLookAndFeelPage::OnApply()
236 m_regTopmenu
= m_topmenu
& 0xFFFFFFFF;
237 m_regTopmenuhigh
= (m_topmenu
>> 32);
239 m_regTopmenu
.getErrorString();
240 m_sNoContextPaths
.Remove('\r');
241 if (!CStringUtils::EndsWith(m_sNoContextPaths
, L
'\n'))
242 m_sNoContextPaths
+= L
'\n';
244 Store(m_bHideMenus
, m_regHideMenus
);
245 Store(m_sNoContextPaths
, m_regNoContextPaths
);
246 Store(m_bEnableDragContextMenu
, m_regEnableDragContextMenu
);
248 m_sNoContextPaths
.Replace(L
"\n", L
"\r\n");
251 return ISettingsPropPage::OnApply();
254 void CSetLookAndFeelPage::OnBnClickedRestoreDefaults()
257 m_topmenu
= DEFAULTMENUTOPENTRIES
;
259 SetMenuItemCheck(&m_cMenuList
, m_topmenu
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
263 void CSetLookAndFeelPage::OnBnClickedSelectall()
270 m_topmenu
= ClickedSelectAll(&m_cMenuList
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
274 void CSetLookAndFeelPage::OnLvnItemchangedMenulist(NMHDR
* /*pNMHDR*/, LRESULT
*pResult
)
279 if (m_cMenuList
.GetItemCount() > 0)
280 m_topmenu
= GetMenuListMask(&m_cMenuList
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
284 void CSetLookAndFeelPage::OnChange()
289 void CSetLookAndFeelPage::OnEnChangeNocontextpaths()
295 #include "SetExtMenu.h"
297 IMPLEMENT_DYNAMIC(CSetExtMenu
, ISettingsPropPage
)
298 CSetExtMenu::CSetExtMenu()
299 : ISettingsPropPage(CSetExtMenu::IDD
)
305 m_regExtmenu
= shell
.menuextlow
;
306 m_regExtmenuhigh
= shell
.menuexthigh
;
308 m_extmenu
= unsigned __int64(DWORD(m_regExtmenuhigh
))<<32;
309 m_extmenu
|= unsigned __int64(DWORD(m_regExtmenu
));
312 CSetExtMenu::~CSetExtMenu()
316 void CSetExtMenu::DoDataExchange(CDataExchange
* pDX
)
318 ISettingsPropPage::DoDataExchange(pDX
);
319 DDX_Control(pDX
, IDC_MENULIST
, m_cMenuList
);
322 BEGIN_MESSAGE_MAP(CSetExtMenu
, ISettingsPropPage
)
323 ON_NOTIFY(LVN_ITEMCHANGED
, IDC_MENULIST
, OnLvnItemchangedMenulist
)
324 ON_BN_CLICKED(IDC_SELECTALL
, OnBnClickedSelectall
)
325 ON_BN_CLICKED(IDC_RESTORE
, OnBnClickedRestoreDefaults
)
328 BOOL
CSetExtMenu::OnInitDialog()
330 ISettingsPropPage::OnInitDialog();
332 AdjustControlSize(IDC_SELECTALL
);
334 m_tooltips
.AddTool(IDC_MENULIST
, IDS_SETTINGS_EXTMENULAYOUT_TT
);
335 //m_tooltips.AddTool(IDC_NOCONTEXTPATHS, IDS_SETTINGS_EXCLUDECONTEXTLIST_TT);
337 m_cMenuList
.SetExtendedStyle(LVS_EX_CHECKBOXES
| (CRegDWORD(L
"Software\\TortoiseGit\\FullRowSelect", TRUE
) ? LVS_EX_FULLROWSELECT
: 0) | LVS_EX_DOUBLEBUFFER
);
339 m_cMenuList
.DeleteAllItems();
340 int c
= m_cMenuList
.GetHeaderCtrl()->GetItemCount() - 1;
342 m_cMenuList
.DeleteColumn(c
--);
343 m_cMenuList
.InsertColumn(0, L
"");
345 SetWindowTheme(m_cMenuList
.GetSafeHwnd(), L
"Explorer", nullptr);
347 m_cMenuList
.SetRedraw(false);
349 int iconWidth
= GetSystemMetrics(SM_CXSMICON
);
350 int iconHeight
= GetSystemMetrics(SM_CYSMICON
);
351 m_imgList
.Create(iconWidth
, iconHeight
, ILC_COLOR32
| ILC_MASK
, 4, 1);
355 InsertMenuItemToList(&m_cMenuList
,&m_imgList
);
356 SetMenuItemCheck(&m_cMenuList
, m_extmenu
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
360 m_cMenuList
.SetImageList(&m_imgList
, LVSIL_SMALL
);
362 int maxcol
= m_cMenuList
.GetHeaderCtrl()->GetItemCount() - 1;
364 for (col
= mincol
; col
<= maxcol
; col
++)
365 m_cMenuList
.SetColumnWidth(col
,LVSCW_AUTOSIZE_USEHEADER
);
366 m_cMenuList
.SetRedraw(true);
373 BOOL
CSetExtMenu::OnApply()
377 m_regExtmenu
= (DWORD
)(m_extmenu
& 0xFFFFFFFF);
378 m_regExtmenuhigh
= (DWORD
)(m_extmenu
>> 32);
381 return ISettingsPropPage::OnApply();
384 void CSetExtMenu::OnBnClickedRestoreDefaults()
387 m_extmenu
= DEFAULTMENUEXTENTRIES
;
389 SetMenuItemCheck(&m_cMenuList
, m_extmenu
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
393 void CSetExtMenu::OnBnClickedSelectall()
400 m_extmenu
= ClickedSelectAll(&m_cMenuList
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
404 void CSetExtMenu::OnLvnItemchangedMenulist(NMHDR
* /*pNMHDR*/, LRESULT
*pResult
)
410 if (m_cMenuList
.GetItemCount() > 0)
411 m_extmenu
= GetMenuListMask(&m_cMenuList
, (CButton
*)GetDlgItem(IDC_SELECTALL
));
415 void CSetExtMenu::OnChange()