4 * @brief Implementation file for CDirColsDlg
6 * @date Created: 2003-08-19
11 #include "DirColsDlg.h"
18 /////////////////////////////////////////////////////////////////////////////
22 * @brief Default dialog constructor.
23 * @param [in] pParent Dialog's parent component (window).
25 CDirColsDlg::CDirColsDlg(CWnd* pParent /*= nullptr*/)
26 : CTrDialog(CDirColsDlg::IDD, pParent)
28 , m_showAdditionalProperties(false)
33 * @brief Handle dialog data exchange between controls and variables.
35 void CDirColsDlg::DoDataExchange(CDataExchange* pDX)
37 CTrDialog::DoDataExchange(pDX);
38 //{{AFX_DATA_MAP(CDirColsDlg)
39 DDX_Control(pDX, IDC_COLDLG_LIST, m_listColumns);
43 BEGIN_MESSAGE_MAP(CDirColsDlg, CTrDialog)
44 //{{AFX_MSG_MAP(CDirColsDlg)
45 ON_BN_CLICKED(IDC_UP, OnUp)
46 ON_BN_CLICKED(IDC_DOWN, OnDown)
47 ON_BN_CLICKED(IDC_COLDLG_ADDITIONAL_PROPERTIES, OnAdditionalProperties)
48 ON_BN_CLICKED(IDC_COLDLG_DEFAULTS, OnDefaults)
50 ON_NOTIFY(LVN_ITEMCHANGED, IDC_COLDLG_LIST, OnLvnItemchangedColdlgList)
53 /////////////////////////////////////////////////////////////////////////////
54 // CDirColsDlg message handlers
57 * @brief Initialize listcontrol in dialog.
59 void CDirColsDlg::InitList()
61 const int lpx = CClientDC(this).GetDeviceCaps(LOGPIXELSX);
62 auto pointToPixel = [lpx](int point) { return MulDiv(point, lpx, 72); };
64 // Show selection across entire row.
65 // Also enable infotips.
66 m_listColumns.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
67 m_listColumns.InsertColumn(0, _T(""), LVCFMT_LEFT, pointToPixel(148));
71 * @brief Dialog initialisation. Load column lists.
73 BOOL CDirColsDlg::OnInitDialog()
75 CTrDialog::OnInitDialog();
79 EnableDlgItem(IDC_COLDLG_ADDITIONAL_PROPERTIES, false);
82 return TRUE; // return TRUE unless you set the focus to a control
83 // EXCEPTION: OCX Property Pages should return FALSE
87 * @brief Load listboxes on screen from column array.
89 void CDirColsDlg::LoadLists()
91 for (ColumnArray::iterator iter = m_cols.begin(); iter != m_cols.end(); ++iter)
93 const column & c = *iter;
94 int x = m_listColumns.InsertItem(m_listColumns.GetItemCount(),
96 m_listColumns.SetItemData(x, c.log_col);
98 m_listColumns.SetCheck(x, TRUE);
100 SortArrayToLogicalOrder();
102 // Set first item to selected state
107 * @brief Select item in list.
108 * @param [in] index Index of item to select.
110 void CDirColsDlg::SelectItem(int index)
112 m_listColumns.SetItemState(index, LVIS_SELECTED, LVIS_SELECTED);
116 * @brief Load listboxes on screen from defaults column array
118 void CDirColsDlg::LoadDefLists()
120 for (ColumnArray::iterator iter = m_defCols.begin(); iter != m_defCols.end(); ++iter)
122 const column & c = *iter;
123 int x = m_listColumns.InsertItem(m_listColumns.GetItemCount(),
125 m_listColumns.SetItemData(x, c.log_col);
127 m_listColumns.SetCheck(x, TRUE);
129 SortArrayToLogicalOrder();
132 * @brief Sort m_cols so that it is in logical column order.
134 void CDirColsDlg::SortArrayToLogicalOrder()
136 std::sort(m_cols.begin(), m_cols.end(), &CompareColumnsByLogicalOrder);
140 * @brief Compare column order of two columns.
141 * @param [in] el1 First column to compare.
142 * @param [in] el2 Second column to compare.
143 * @return Column order.
145 bool CDirColsDlg::CompareColumnsByLogicalOrder( const column & el1, const column & el2 )
147 return el1.log_col < el2.log_col;
151 * @brief Move column name in the list.
152 * @param [in] index Index of column to move.
153 * @param [in] newIndex New index for the column to move.
155 void CDirColsDlg::MoveItem(int index, int newIndex)
157 // Get current column data
158 String text = m_listColumns.GetItemText(index, 0);
159 bool checked = !!m_listColumns.GetCheck(index);
160 UINT state = m_listColumns.GetItemState(index, LVIS_SELECTED);
161 DWORD_PTR data = m_listColumns.GetItemData(index);
164 m_listColumns.DeleteItem(index);
166 // Insert column in new index
167 m_listColumns.InsertItem(newIndex, text.c_str());
168 m_listColumns.SetItemState(newIndex, state, LVIS_SELECTED);
169 m_listColumns.SetItemData(newIndex, data);
171 m_listColumns.SetCheck(newIndex);
175 * @brief Move selected items one position up or down.
176 * @param [in] bUp If `true` items are moved up,
177 * if `false` items are moved down.
179 void CDirColsDlg::MoveSelectedItems(bool bUp)
182 POSITION pos = m_listColumns.GetFirstSelectedItemPosition();
184 while (pos != nullptr)
186 int ind = m_listColumns.GetNextSelectedItem(pos);
187 int newInd = bUp ? ind - 1: ind + 1;
189 // Remember first item
192 MoveItem(ind, newInd);
194 m_listColumns.EnsureVisible(firstInd, FALSE);
198 * @brief Move selected items up in list.
200 void CDirColsDlg::OnUp()
202 MoveSelectedItems(true);
206 * @brief Move selected items down (in show list)
208 void CDirColsDlg::OnDown()
210 MoveSelectedItems(false);
214 * @brief Close this dialog and show Additional Properties dialog
216 void CDirColsDlg::OnAdditionalProperties()
218 m_showAdditionalProperties = true;
223 * @brief Move hidden columns as last items in the list.
225 void CDirColsDlg::SanitizeOrder()
227 // Find last visible column.
228 int i = m_listColumns.GetItemCount() - 1;
231 if (m_listColumns.GetCheck(i))
235 // Move all hidden columns below last visible column.
236 for (int j = i; j >= 0; j--)
238 if (!m_listColumns.GetCheck(j))
247 * @brief User clicked ok, so we update m_cols and close.
249 void CDirColsDlg::OnOK()
253 size_t colssize = m_cols.size();
254 for (int i = 0; i < m_listColumns.GetItemCount(); i++)
256 bool checked = !!m_listColumns.GetCheck(i);
257 DWORD_PTR data = m_listColumns.GetItemData(i);
258 assert(data < colssize);
261 column& col1 = m_cols[data];
273 * @brief Empty lists and load default columns and order.
275 void CDirColsDlg::OnDefaults()
277 m_listColumns.DeleteAllItems();
283 * @brief Update description when selected item changes.
285 void CDirColsDlg::OnLvnItemchangedColdlgList(NMHDR *pNMHDR, LRESULT *pResult)
287 POSITION pos = m_listColumns.GetFirstSelectedItemPosition();
291 int ind = m_listColumns.GetNextSelectedItem(pos);
292 DWORD_PTR data = m_listColumns.GetItemData(ind);
294 ColumnArray::size_type j;
295 for (j = 0; j < m_cols.size(); j++)
297 if (static_cast<DWORD_PTR>(m_cols[j].log_col) == data)
300 SetDlgItemText(IDC_COLDLG_DESC, m_cols[j].desc);
302 // Disable Up/Down -buttons when first/last items are selected.
303 EnableDlgItem(IDC_UP, ind != 0);
304 EnableDlgItem(IDC_DOWN,
305 ind != m_listColumns.GetItemCount() - static_cast<int>(m_listColumns.GetSelectedCount()));
308 // Disable the "OK" button when no items are checked.
309 bool bChecked = false;
310 for (int i = 0; i < m_listColumns.GetItemCount(); i++)
311 if (!!m_listColumns.GetCheck(i))
316 EnableDlgItem(IDOK, bChecked);