Revision | 29283 (tree) |
---|---|
Time | 2021-10-30 16:42:08 |
Author | stefankueng |
add a settings page to configure which menu entries should appear in the Win11 top menu
@@ -0,0 +1,131 @@ | ||
1 | +// TortoiseSVN - a Windows shell extension for easy version control | |
2 | + | |
3 | +// Copyright (C) 2021 - TortoiseSVN | |
4 | + | |
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. | |
9 | + | |
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. | |
14 | + | |
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. | |
18 | +// | |
19 | +#include "stdafx.h" | |
20 | +#include "Globals.h" | |
21 | +#include "StringUtils.h" | |
22 | +#include "LoadIconEx.h" | |
23 | +#include "SetWin11ContextMenu.h" | |
24 | + | |
25 | +IMPLEMENT_DYNAMIC(CSetWin11ContextMenu, ISettingsPropPage) | |
26 | +CSetWin11ContextMenu::CSetWin11ContextMenu() | |
27 | + : ISettingsPropPage(CSetWin11ContextMenu::IDD) | |
28 | + , m_bModified(false) | |
29 | + , m_bBlock(false) | |
30 | +{ | |
31 | + m_regTopMenu = CRegQWORD(L"Software\\TortoiseSVN\\ContextMenu11Entries", | |
32 | + static_cast<QWORD>(TSVNContextMenuEntries::Checkout | | |
33 | + TSVNContextMenuEntries::Update | | |
34 | + TSVNContextMenuEntries::Commit)); | |
35 | + m_topMenu = static_cast<TSVNContextMenuEntries>(static_cast<QWORD>(m_regTopMenu)); | |
36 | +} | |
37 | + | |
38 | +CSetWin11ContextMenu::~CSetWin11ContextMenu() | |
39 | +{ | |
40 | +} | |
41 | + | |
42 | +void CSetWin11ContextMenu::DoDataExchange(CDataExchange* pDX) | |
43 | +{ | |
44 | + ISettingsPropPage::DoDataExchange(pDX); | |
45 | + DDX_Control(pDX, IDC_MENULIST, m_cMenuList); | |
46 | +} | |
47 | + | |
48 | +BEGIN_MESSAGE_MAP(CSetWin11ContextMenu, ISettingsPropPage) | |
49 | + ON_NOTIFY(LVN_ITEMCHANGED, IDC_MENULIST, OnLvnItemchangedMenulist) | |
50 | +END_MESSAGE_MAP() | |
51 | + | |
52 | +BOOL CSetWin11ContextMenu::OnInitDialog() | |
53 | +{ | |
54 | + ISettingsPropPage::OnInitDialog(); | |
55 | + | |
56 | + m_tooltips.AddTool(IDC_MENULIST, IDS_SETTINGS_MENULAYOUT_TT); | |
57 | + | |
58 | + m_cMenuList.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); | |
59 | + | |
60 | + m_cMenuList.DeleteAllItems(); | |
61 | + int c = m_cMenuList.GetHeaderCtrl()->GetItemCount() - 1; | |
62 | + while (c >= 0) | |
63 | + m_cMenuList.DeleteColumn(c--); | |
64 | + m_cMenuList.InsertColumn(0, L""); | |
65 | + | |
66 | + SetWindowTheme(m_cMenuList.GetSafeHwnd(), L"Explorer", nullptr); | |
67 | + | |
68 | + m_cMenuList.SetRedraw(false); | |
69 | + | |
70 | + int iconWidth = GetSystemMetrics(SM_CXSMICON); | |
71 | + int iconHeight = GetSystemMetrics(SM_CYSMICON); | |
72 | + m_imgList.Create(iconWidth, iconHeight, ILC_COLOR16 | ILC_MASK, 4, 1); | |
73 | + | |
74 | + m_bBlock = true; | |
75 | + for (const auto& [menu, name, icon] : TSVNContextMenuEntriesVec) | |
76 | + { | |
77 | + InsertItem(name, icon, menu, iconWidth, iconHeight); | |
78 | + } | |
79 | + m_bBlock = false; | |
80 | + | |
81 | + m_cMenuList.SetImageList(&m_imgList, LVSIL_SMALL); | |
82 | + int minCol = 0; | |
83 | + int maxCol = m_cMenuList.GetHeaderCtrl()->GetItemCount() - 1; | |
84 | + for (int col = minCol; col <= maxCol; col++) | |
85 | + { | |
86 | + m_cMenuList.SetColumnWidth(col, LVSCW_AUTOSIZE_USEHEADER); | |
87 | + } | |
88 | + m_cMenuList.SetRedraw(true); | |
89 | + | |
90 | + UpdateData(FALSE); | |
91 | + | |
92 | + return TRUE; | |
93 | +} | |
94 | + | |
95 | +BOOL CSetWin11ContextMenu::OnApply() | |
96 | +{ | |
97 | + UpdateData(); | |
98 | + Store(static_cast<QWORD>(m_topMenu), m_regTopMenu); | |
99 | + | |
100 | + SetModified(FALSE); | |
101 | + return ISettingsPropPage::OnApply(); | |
102 | +} | |
103 | + | |
104 | +void CSetWin11ContextMenu::InsertItem(UINT nTextID, UINT nIconID, TSVNContextMenuEntries menu, int iconWidth, int iconHeight) | |
105 | +{ | |
106 | + auto hIcon = LoadIconEx(AfxGetResourceHandle(), MAKEINTRESOURCE(nIconID), iconWidth, iconHeight); | |
107 | + int nImage = m_imgList.Add(hIcon); | |
108 | + CString temp; | |
109 | + temp.LoadString(nTextID); | |
110 | + CStringUtils::RemoveAccelerators(temp); | |
111 | + int nIndex = m_cMenuList.GetItemCount(); | |
112 | + m_cMenuList.InsertItem(nIndex, temp, nImage); | |
113 | + m_cMenuList.SetCheck(nIndex, (m_topMenu & menu) != TSVNContextMenuEntries::None); | |
114 | +} | |
115 | + | |
116 | +void CSetWin11ContextMenu::OnLvnItemchangedMenulist(NMHDR* /*pNMHDR*/, LRESULT* pResult) | |
117 | +{ | |
118 | + if (m_bBlock) | |
119 | + return; | |
120 | + SetModified(TRUE); | |
121 | + if (m_cMenuList.GetItemCount() > 0) | |
122 | + { | |
123 | + int i = 0; | |
124 | + m_topMenu = TSVNContextMenuEntries::None; | |
125 | + for (const auto& [menu, name, icon] : TSVNContextMenuEntriesVec) | |
126 | + { | |
127 | + m_topMenu |= m_cMenuList.GetCheck(i++) ? menu : TSVNContextMenuEntries::None; | |
128 | + } | |
129 | + } | |
130 | + *pResult = 0; | |
131 | +} |
@@ -0,0 +1,64 @@ | ||
1 | +// TortoiseSVN - a Windows shell extension for easy version control | |
2 | + | |
3 | +// Copyright (C) 2021 - TortoiseSVN | |
4 | + | |
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. | |
9 | + | |
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. | |
14 | + | |
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. | |
18 | +// | |
19 | +#pragma once | |
20 | + | |
21 | +#include "SettingsPropPage.h" | |
22 | +#include "registry.h" | |
23 | +#include "Globals.h" | |
24 | + | |
25 | +/** | |
26 | + * \ingroup TortoiseProc | |
27 | + * Settings page for the Win11 top context menu. | |
28 | + */ | |
29 | +class CSetWin11ContextMenu : public ISettingsPropPage | |
30 | +{ | |
31 | + DECLARE_DYNAMIC(CSetWin11ContextMenu) | |
32 | + | |
33 | +public: | |
34 | + CSetWin11ContextMenu(); | |
35 | + ~CSetWin11ContextMenu() override; | |
36 | + | |
37 | + UINT GetIconID() override { return IDI_MISC; } | |
38 | + | |
39 | + // Dialog Data | |
40 | + enum | |
41 | + { | |
42 | + IDD = IDD_SETTINGSWIN11CONTEXTMENU | |
43 | + }; | |
44 | + | |
45 | +protected: | |
46 | + void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support | |
47 | + BOOL OnApply() override; | |
48 | + afx_msg void OnLvnItemchangedMenulist(NMHDR* pNMHDR, LRESULT* pResult); | |
49 | + | |
50 | + DECLARE_MESSAGE_MAP() | |
51 | +public: | |
52 | + BOOL OnInitDialog() override; | |
53 | + | |
54 | +private: | |
55 | + void InsertItem(UINT nTextID, UINT nIconID, TSVNContextMenuEntries dwFlags, int iconWidth, int iconHeight); | |
56 | + | |
57 | + CRegQWORD m_regTopMenu; | |
58 | + | |
59 | + CImageList m_imgList; | |
60 | + CListCtrl m_cMenuList; | |
61 | + BOOL m_bModified; | |
62 | + TSVNContextMenuEntries m_topMenu; | |
63 | + bool m_bBlock; | |
64 | +}; |
@@ -23,6 +23,8 @@ | ||
23 | 23 | #include "../../TSVNCache/CacheInterface.h" |
24 | 24 | #include "Theme.h" |
25 | 25 | #include "DarkModeHelper.h" |
26 | +#include "../../Utils/PathUtils.h" | |
27 | +#include "../../Utils/StringUtils.h" | |
26 | 28 | |
27 | 29 | #define BOTTOMMARG 32 |
28 | 30 |
@@ -32,7 +34,7 @@ | ||
32 | 34 | { |
33 | 35 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); |
34 | 36 | AddPropPages(); |
35 | - SetTheme(CTheme::Instance().IsDarkTheme()); | |
37 | + CSettings::SetTheme(CTheme::Instance().IsDarkTheme()); | |
36 | 38 | } |
37 | 39 | |
38 | 40 | CSettings::~CSettings() |
@@ -53,14 +55,27 @@ | ||
53 | 55 | |
54 | 56 | void CSettings::AddPropPages() |
55 | 57 | { |
56 | - m_pMainPage = new CSetMainPage(); | |
57 | - m_pOverlayPage = new CSetOverlayPage(); | |
58 | - m_pOverlaysPage = new CSetOverlayIcons(); | |
59 | - m_pOverlayHandlersPage = new CSetOverlayHandlers(); | |
60 | - m_pProxyPage = new CSetProxyPage(); | |
61 | - m_pProgsDiffPage = new CSettingsProgsDiff(); | |
62 | - m_pProgsMergePage = new CSettingsProgsMerge(); | |
63 | - m_pLookAndFeelPage = new CSetLookAndFeelPage(); | |
58 | + PWSTR pszPath = nullptr; | |
59 | + CString sysPath; | |
60 | + if (SHGetKnownFolderPath(FOLDERID_System, KF_FLAG_CREATE, nullptr, &pszPath) == S_OK) | |
61 | + { | |
62 | + sysPath = pszPath; | |
63 | + CoTaskMemFree(pszPath); | |
64 | + } | |
65 | + auto explorerVersion = CPathUtils::GetVersionFromFile(sysPath + L"\\shell32.dll"); | |
66 | + std::vector<int> versions; | |
67 | + stringtok(versions, explorerVersion, true, L"."); | |
68 | + bool isWin11OrLater = versions.size() > 3 && versions[2] >= 22000; | |
69 | + m_pMainPage = new CSetMainPage(); | |
70 | + m_pOverlayPage = new CSetOverlayPage(); | |
71 | + m_pOverlaysPage = new CSetOverlayIcons(); | |
72 | + m_pOverlayHandlersPage = new CSetOverlayHandlers(); | |
73 | + m_pProxyPage = new CSetProxyPage(); | |
74 | + m_pProgsDiffPage = new CSettingsProgsDiff(); | |
75 | + m_pProgsMergePage = new CSettingsProgsMerge(); | |
76 | + m_pLookAndFeelPage = new CSetLookAndFeelPage(); | |
77 | + if (isWin11OrLater) | |
78 | + m_pWin11ContextMenu = new CSetWin11ContextMenu(); | |
64 | 79 | m_pDialogsPage = new CSetDialogs(); |
65 | 80 | m_pMiscPage = new CSetMisc(); |
66 | 81 | m_pDialogs3Page = new SettingsDialogs3(); |
@@ -85,6 +100,8 @@ | ||
85 | 100 | SetPageIcon(m_pProgsDiffPage, m_pProgsDiffPage->GetIconID()); |
86 | 101 | SetPageIcon(m_pProgsMergePage, m_pProgsMergePage->GetIconID()); |
87 | 102 | SetPageIcon(m_pLookAndFeelPage, m_pLookAndFeelPage->GetIconID()); |
103 | + if (IsWindows10OrGreater()) | |
104 | + SetPageIcon(m_pWin11ContextMenu, m_pWin11ContextMenu->GetIconID()); | |
88 | 105 | SetPageIcon(m_pDialogsPage, m_pDialogsPage->GetIconID()); |
89 | 106 | SetPageIcon(m_pRevisionGraphPage, m_pRevisionGraphPage->GetIconID()); |
90 | 107 | SetPageIcon(m_pRevisionGraphColorsPage, m_pRevisionGraphColorsPage->GetIconID()); |
@@ -113,6 +130,7 @@ | ||
113 | 130 | AddPage(m_pProgsDiffPage); |
114 | 131 | AddPage(m_pProgsMergePage); |
115 | 132 | AddPage(m_pLookAndFeelPage); |
133 | + AddPage(m_pWin11ContextMenu); | |
116 | 134 | AddPage(m_pDialogsPage); |
117 | 135 | AddPage(m_pMiscPage); |
118 | 136 | AddPage(m_pDialogs3Page); |
@@ -138,6 +156,7 @@ | ||
138 | 156 | delete m_pProgsDiffPage; |
139 | 157 | delete m_pProgsMergePage; |
140 | 158 | delete m_pLookAndFeelPage; |
159 | + delete m_pWin11ContextMenu; | |
141 | 160 | delete m_pDialogsPage; |
142 | 161 | delete m_pRevisionGraphColorsPage; |
143 | 162 | delete m_pRevisionGraphPage; |
@@ -166,6 +185,7 @@ | ||
166 | 185 | restart |= m_pProgsDiffPage->GetRestart(); |
167 | 186 | restart |= m_pProgsMergePage->GetRestart(); |
168 | 187 | restart |= m_pLookAndFeelPage->GetRestart(); |
188 | + restart |= m_pWin11ContextMenu->GetRestart(); | |
169 | 189 | restart |= m_pDialogsPage->GetRestart(); |
170 | 190 | restart |= m_pRevisionGraphPage->GetRestart(); |
171 | 191 | restart |= m_pMiscPage->GetRestart(); |
@@ -26,6 +26,7 @@ | ||
26 | 26 | #include "SettingsProgsDiff.h" |
27 | 27 | #include "SettingsProgsMerge.h" |
28 | 28 | #include "SetLookAndFeelPage.h" |
29 | +#include "SetWin11ContextMenu.h" | |
29 | 30 | #include "SetDialogs.h" |
30 | 31 | #include "SettingsColors.h" |
31 | 32 | #include "SetMisc.h" |
@@ -78,6 +79,7 @@ | ||
78 | 79 | CSettingsProgsDiff* m_pProgsDiffPage; |
79 | 80 | CSettingsProgsMerge* m_pProgsMergePage; |
80 | 81 | CSetLookAndFeelPage* m_pLookAndFeelPage; |
82 | + CSetWin11ContextMenu* m_pWin11ContextMenu; | |
81 | 83 | CSetDialogs* m_pDialogsPage; |
82 | 84 | CSettingsRevisionGraph* m_pRevisionGraphPage; |
83 | 85 | CSettingsRevisionGraphColors* m_pRevisionGraphColorsPage; |