Fixed issue #4126: Capitalize the first letter in the Push dialog
[TortoiseGit.git] / src / TortoiseProc / ColumnManager.h
blob8c3c012ac4f27e1c12f4105141bf191c10839ade
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016, 2019-2020, 2023 - 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.
20 #pragma once
22 /**
23 * \ingroup TortoiseProc
24 * Helper class for CGitStatusListCtrl that represents
25 * the columns visible and their order as well as
26 * persisting that data in the registry.
28 * It assigns logical index values to the (potential) columns:
29 * 0 .. GitSLC_NUMCOLUMNS-1 contain the standard attributes
31 * The column vector contains the columns that are actually
32 * available in the control.
35 class ColumnManager
37 public:
39 /// construction / destruction
41 ColumnManager(CListCtrl* control) : control(control) {};
42 ~ColumnManager() {};
44 /// registry access
46 void ReadSettings(DWORD defaultColumns, DWORD hideColumns, const CString& containerName, DWORD version, int maxsize, int* withlist = nullptr);
47 void WriteSettings() const;
49 /// read column definitions
51 int GetColumnCount() const; ///< total number of columns
52 bool IsVisible(int column) const;
53 int GetInvisibleCount() const;
54 bool IsRelevant(int column) const;
55 CString GetName(int column) const;
56 int GetColumnByName(int nameId) const;
57 int SetNames(UINT* buff, int size);
58 int GetWidth(int column, bool useDefaults = false) const;
59 int GetVisibleWidth(int column, bool useDefaults) const;
60 void SetRightAlign(int column) const;
62 /// switch columns on and off
63 void SetVisible(int column, bool visible);
65 /// tracking column modifications
66 void ColumnMoved(int column, int position);
67 /**
68 manual: 0: automatic updates, 1: manual updates, 2: manual updates and set to optimal width, 3: reset manual adjusted state
70 void ColumnResized(int column, int manual = 0);
72 /// call these to update the user-prop list
73 /// (will also auto-insert /-remove new list columns)
75 /// don't clutter the context menu with irrelevant prop info
77 void RemoveUnusedProps();
79 /// bring everything back to its "natural" order
80 void ResetColumns(DWORD defaultColumns);
82 void OnHeaderDblClick(NMHDR* pNMHDR, LRESULT* pResult)
84 LPNMHEADER header = reinterpret_cast<LPNMHEADER>(pNMHDR);
85 if (header && (header->iItem >= 0) && (header->iItem < GetColumnCount()))
87 bool bShift = !!(GetAsyncKeyState(VK_SHIFT) & 0x8000);
88 ColumnResized(header->iItem, bShift ? 3 : 2);
90 *pResult = 0;
93 void OnColumnResized(NMHDR* pNMHDR, LRESULT* pResult)
95 LPNMHEADER header = reinterpret_cast<LPNMHEADER>(pNMHDR);
96 if (header && (header->iItem >= 0) && (header->iItem < GetColumnCount()))
97 ColumnResized(header->iItem, 1);
98 *pResult = 0;
101 void OnColumnMoved(NMHDR* pNMHDR, LRESULT* pResult)
103 LPNMHEADER header = reinterpret_cast<LPNMHEADER>(pNMHDR);
104 *pResult = TRUE;
105 if (header
106 && (header->iItem >= 0)
107 && (header->iItem < GetColumnCount())
108 // only allow the reordering if the column was not moved left of the first
109 // visible item - otherwise the 'invisible' columns are not at the far left
110 // anymore and we get all kinds of redrawing problems.
111 && (header->pitem)
112 && (header->pitem->iOrder >= GetInvisibleCount()))
114 ColumnMoved(header->iItem, header->pitem->iOrder);
118 void OnHdnBegintrack(NMHDR* pNMHDR, LRESULT* pResult)
120 LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
121 *pResult = 0;
122 if (phdr->iItem < 0 || phdr->iItem >= static_cast<int>(itemName.size()))
123 return;
125 if (IsVisible(phdr->iItem))
126 return;
127 *pResult = 1;
130 int OnHdnItemchanging(NMHDR* pNMHDR, LRESULT* pResult)
132 LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
133 *pResult = 0;
134 if (phdr->iItem < 0 || phdr->iItem >= static_cast<int>(itemName.size()))
135 return 0;
137 // visible columns may be modified
138 if (IsVisible(phdr->iItem))
139 return 0;
141 // columns already marked as "invisible" internally may be (re-)sized to 0
142 if (phdr->pitem && (phdr->pitem->mask == HDI_WIDTH) && (phdr->pitem->cxy == 0))
143 return 0;
145 if (phdr->pitem && (phdr->pitem->mask != HDI_WIDTH))
146 return 0;
148 *pResult = 1;
149 return 1;
151 void OnContextMenuHeader(CWnd* pWnd, CPoint point, bool isGroundEnable = false);
152 void SetOnVisibilityChanged(std::function<void(int, bool)> onVisibilityChanged);
154 private:
155 void AddMenuItem(CMenu* pop)
157 UINT uCheckedFlags = MF_STRING | MF_ENABLED | MF_CHECKED;
158 UINT uUnCheckedFlags = MF_STRING | MF_ENABLED;
160 for (int i = 1; i < static_cast<int>(itemName.size()); ++i)
162 if (IsRelevant(i))
163 pop->AppendMenu(IsVisible(i)
164 ? uCheckedFlags
165 : uUnCheckedFlags
167 , GetName(i));
171 DWORD m_dwDefaultColumns = 0;
172 DWORD m_dwVersion = 0;
174 /// initialization utilities
175 void ParseWidths(const CString& widths);
176 void SetStandardColumnVisibility(DWORD visibility);
177 void ParseColumnOrder(const CString& widths);
179 /// map internal column order onto visible column order
180 /// (all invisibles in front)
182 std::vector<int> GetGridColumnOrder() const;
183 void ApplyColumnOrder();
185 /// utilities used when writing data to the registry
186 DWORD GetSelectedStandardColumns() const;
187 CString GetWidthString() const;
188 CString GetColumnOrderString() const;
190 /// our parent control and its data
191 CListCtrl* control = nullptr;
193 /// where to store in the registry
194 CString registryPrefix;
196 /// all columns in their "natural" order
197 struct ColumnInfo
199 int index; ///< is a user prop when < GitSLC_USERPROPCOLOFFSET
200 int width;
201 bool visible;
202 bool relevant; ///< set to @a visible, if no *shown* item has that property
203 bool adjusted;
206 std::function<void(int, bool)> onVisibilityChanged;
208 std::vector<ColumnInfo> columns;
210 /// user-defined properties
211 std::set<CString> itemProps;
213 /// global column ordering including unused user props
214 std::vector<int> columnOrder;
216 std::vector<int> itemName;