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.
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.
39 /// construction / destruction
41 ColumnManager(CListCtrl
* control
) : control(control
) {};
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
);
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);
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);
101 void OnColumnMoved(NMHDR
* pNMHDR
, LRESULT
* pResult
)
103 LPNMHEADER header
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
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.
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
);
122 if (phdr
->iItem
< 0 || phdr
->iItem
>= static_cast<int>(itemName
.size()))
125 if (IsVisible(phdr
->iItem
))
130 int OnHdnItemchanging(NMHDR
* pNMHDR
, LRESULT
* pResult
)
132 LPNMHEADER phdr
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
134 if (phdr
->iItem
< 0 || phdr
->iItem
>= static_cast<int>(itemName
.size()))
137 // visible columns may be modified
138 if (IsVisible(phdr
->iItem
))
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))
145 if (phdr
->pitem
&& (phdr
->pitem
->mask
!= HDI_WIDTH
))
151 void OnContextMenuHeader(CWnd
* pWnd
, CPoint point
, bool isGroundEnable
= false);
152 void SetOnVisibilityChanged(std::function
<void(int, bool)> onVisibilityChanged
);
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
)
163 pop
->AppendMenu(IsVisible(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
199 int index
; ///< is a user prop when < GitSLC_USERPROPCOLOFFSET
202 bool relevant
; ///< set to @a visible, if no *shown* item has that property
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
;