1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016 - 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
), m_dwDefaultColumns(0) {};
46 void ReadSettings(DWORD defaultColumns
, DWORD hideColumns
, const CString
& containerName
, int ReadSettings
, 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 SetNames(UINT
* buff
, int size
);
57 int GetWidth(int column
, bool useDefaults
= false) const;
58 int GetVisibleWidth(int column
, bool useDefaults
) const;
59 void SetRightAlign(int column
) const;
61 /// switch columns on and off
62 void SetVisible(int column
, bool visible
);
64 /// tracking column modifications
65 void ColumnMoved(int column
, int position
);
67 manual: 0: automatic updates, 1: manual updates, 2: manual updates and set to optimal width, 3: reset manual adjusted state
69 void ColumnResized(int column
, int manual
= 0);
71 /// call these to update the user-prop list
72 /// (will also auto-insert /-remove new list columns)
74 /// don't clutter the context menu with irrelevant prop info
76 void RemoveUnusedProps();
78 /// bring everything back to its "natural" order
79 void ResetColumns(DWORD defaultColumns
);
81 void OnHeaderDblClick(NMHDR
* pNMHDR
, LRESULT
* pResult
)
83 LPNMHEADER header
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
84 if (header
&& (header
->iItem
>= 0) && (header
->iItem
< GetColumnCount()))
86 bool bShift
= !!(GetAsyncKeyState(VK_SHIFT
) & 0x8000);
87 ColumnResized(header
->iItem
, bShift
? 3 : 2);
92 void OnColumnResized(NMHDR
* pNMHDR
, LRESULT
* pResult
)
94 LPNMHEADER header
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
95 if (header
&& (header
->iItem
>= 0) && (header
->iItem
< GetColumnCount()))
96 ColumnResized(header
->iItem
, 1);
100 void OnColumnMoved(NMHDR
* pNMHDR
, LRESULT
* pResult
)
102 LPNMHEADER header
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
105 && (header
->iItem
>= 0)
106 && (header
->iItem
< GetColumnCount())
107 // only allow the reordering if the column was not moved left of the first
108 // visible item - otherwise the 'invisible' columns are not at the far left
109 // anymore and we get all kinds of redrawing problems.
111 && (header
->pitem
->iOrder
>= GetInvisibleCount()))
113 ColumnMoved(header
->iItem
, header
->pitem
->iOrder
);
117 void OnHdnBegintrack(NMHDR
* pNMHDR
, LRESULT
* pResult
)
119 LPNMHEADER phdr
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
121 if ((phdr
->iItem
< 0) || (phdr
->iItem
>= (int)itemName
.size()))
124 if (IsVisible(phdr
->iItem
))
129 int OnHdnItemchanging(NMHDR
* pNMHDR
, LRESULT
* pResult
)
131 LPNMHEADER phdr
= reinterpret_cast<LPNMHEADER
>(pNMHDR
);
133 if ((phdr
->iItem
< 0) || (phdr
->iItem
>= (int)itemName
.size()))
136 // visible columns may be modified
137 if (IsVisible(phdr
->iItem
))
140 // columns already marked as "invisible" internally may be (re-)sized to 0
141 if (phdr
->pitem
&& (phdr
->pitem
->mask
== HDI_WIDTH
) && (phdr
->pitem
->cxy
== 0))
144 if (phdr
->pitem
&& (phdr
->pitem
->mask
!= HDI_WIDTH
))
150 void OnContextMenuHeader(CWnd
* pWnd
, CPoint point
, bool isGroundEnable
= false);
153 void AddMenuItem(CMenu
* pop
)
155 UINT uCheckedFlags
= MF_STRING
| MF_ENABLED
| MF_CHECKED
;
156 UINT uUnCheckedFlags
= MF_STRING
| MF_ENABLED
;
158 for (int i
= 1; i
< (int)itemName
.size(); ++i
)
161 pop
->AppendMenu(IsVisible(i
)
169 DWORD m_dwDefaultColumns
;
171 /// initialization utilities
172 void ParseWidths(const CString
& widths
);
173 void SetStandardColumnVisibility(DWORD visibility
);
174 void ParseColumnOrder(const CString
& widths
);
176 /// map internal column order onto visible column order
177 /// (all invisibles in front)
179 std::vector
<int> GetGridColumnOrder() const;
180 void ApplyColumnOrder();
182 /// utilities used when writing data to the registry
183 DWORD
GetSelectedStandardColumns() const;
184 CString
GetWidthString() const;
185 CString
GetColumnOrderString() const;
187 /// our parent control and its data
190 /// where to store in the registry
191 CString registryPrefix
;
193 /// all columns in their "natural" order
196 int index
; ///< is a user prop when < GitSLC_USERPROPCOLOFFSET
199 bool relevant
; ///< set to @a visible, if no *shown* item has that property
203 std::vector
<ColumnInfo
> columns
;
205 /// user-defined properties
206 std::set
<CString
> itemProps
;
208 /// global column ordering including unused user props
209 std::vector
<int> columnOrder
;
211 std::vector
<int> itemName
;