2 * @file DirAdditionalPropertiesDlg.cpp
4 * @brief Implementation file for CDirAdditionalPropertiesDlg
8 #include "DirAdditionalPropertiesDlg.h"
9 #include "PropertySystem.h"
17 /////////////////////////////////////////////////////////////////////////////
18 // CDirAdditionalPropertiesDlg dialog
21 * @brief Default dialog constructor.
22 * @param [in] pParent Dialog's parent component (window).
24 CDirAdditionalPropertiesDlg::CDirAdditionalPropertiesDlg(const std::vector<String>& canonicalNames, CWnd* pParent /*= nullptr*/)
25 : CTrDialog(CDirAdditionalPropertiesDlg::IDD, pParent)
26 , m_canonicalNames(canonicalNames)
32 * @brief Handle dialog data exchange between controls and variables.
34 void CDirAdditionalPropertiesDlg::DoDataExchange(CDataExchange* pDX)
36 CTrDialog::DoDataExchange(pDX);
37 //{{AFX_DATA_MAP(CDirAdditionalPropertiesDlg)
38 DDX_Control(pDX, IDC_PROPS_TREEVIEW, m_treeProps);
39 DDX_Control(pDX, IDC_PROPS_LISTVIEW, m_listProps);
43 BEGIN_MESSAGE_MAP(CDirAdditionalPropertiesDlg, CTrDialog)
44 //{{AFX_MSG_MAP(CDirAdditionalPropertiesDlg)
45 ON_BN_CLICKED(IDC_PROPS_ADD, OnAdd)
46 ON_COMMAND_RANGE(IDC_PROPS_DEL, IDC_PROPS_DELALL, OnDelete)
47 ON_NOTIFY(NM_DBLCLK, IDC_PROPS_TREEVIEW, OnDblClkTreeView)
48 ON_NOTIFY(TVN_KEYDOWN, IDC_PROPS_TREEVIEW, OnKeyDownTreeView)
49 ON_NOTIFY(LVN_KEYDOWN, IDC_PROPS_LISTVIEW, OnKeyDownListView)
53 Node& CDirAdditionalPropertiesDlg::MakeNode(Node& parentNode, const std::vector<StringView>& path, std::vector<StringView>::iterator it)
55 for (auto& node : parentNode.childNodes)
61 return MakeNode(node, path, it);
65 Node& node = parentNode.childNodes.emplace_back();
66 node.selected = false;
71 node.hItem = m_treeProps.InsertItem(tr(ucr::toUTF8(node.name)).c_str(), parentNode.hItem);
72 return MakeNode(node, path, it);
74 node.canonicalName = strutils::join(path.begin(), path.end(), _T("."));
75 PropertySystem ps({ node.canonicalName });
76 std::vector<String> displayNames;
77 ps.GetDisplayNames(displayNames);
78 node.displayName = displayNames[0];
79 node.hItem = m_treeProps.InsertItem(node.displayName.c_str(), parentNode.hItem);
80 m_treeProps.SetItemData(node.hItem, reinterpret_cast<DWORD_PTR>(&node));
84 void CDirAdditionalPropertiesDlg::LoadList()
86 m_root.hItem = TVI_ROOT;
87 PropertySystem ps(PropertySystem::VIEWABLE);
88 for (const auto& canonicalName : ps.GetCanonicalNames())
90 PropertySystem ps2({ canonicalName });
91 std::vector<String> displayNames;
92 ps2.GetDisplayNames(displayNames);
93 if (!displayNames[0].empty())
95 auto path = strutils::split(canonicalName, '.');
96 Node& node = MakeNode(m_root, path, path.begin());
97 if (std::count(m_canonicalNames.begin(), m_canonicalNames.end(), canonicalName) > 0)
99 for (HTREEITEM hItem = m_treeProps.GetParentItem(node.hItem); hItem; hItem = m_treeProps.GetParentItem(hItem))
100 m_treeProps.Expand(hItem, TVE_EXPAND);
101 node.selected = true;
102 m_treeProps.SetItemState(node.hItem, TVIS_BOLD, TVIS_BOLD);
103 m_listProps.InsertItem(LVIF_TEXT|LVIF_PARAM,
104 m_listProps.GetItemCount(), node.displayName.c_str(),
105 0, 0, 0, reinterpret_cast<LPARAM>(&node));
109 if (!m_root.childNodes.empty())
110 m_treeProps.SelectItem(m_root.childNodes.front().hItem);
113 /////////////////////////////////////////////////////////////////////////////
114 // CDirAdditionalPropertiesDlg message handlers
116 BOOL CDirAdditionalPropertiesDlg::OnInitDialog()
118 CTrDialog::OnInitDialog();
121 m_listProps.GetClientRect(&rc);
122 m_listProps.InsertColumn(0, _T(""), LVCFMT_LEFT, rc.Width());
125 return TRUE; // return TRUE unless you set the focus to a control
126 // EXCEPTION: OCX Property Pages should return FALSE
129 void CDirAdditionalPropertiesDlg::OnAdd()
131 HTREEITEM hItem = m_treeProps.GetSelectedItem();
134 Node* pNode = reinterpret_cast<Node*>(m_treeProps.GetItemData(hItem));
135 if (pNode && !pNode->selected)
137 pNode->selected = true;
138 m_treeProps.SetItemState(pNode->hItem, TVIS_BOLD, TVIS_BOLD);
139 m_listProps.InsertItem(LVIF_TEXT|LVIF_PARAM,
140 m_listProps.GetItemCount(), pNode->displayName.c_str(),
141 0, 0, 0, reinterpret_cast<LPARAM>(pNode));
146 void CDirAdditionalPropertiesDlg::OnDelete(UINT nId)
148 for (int i = m_listProps.GetItemCount() - 1; i >= 0; --i)
150 if (nId == IDC_PROPS_DELALL || m_listProps.GetItemState(i, LVIS_SELECTED) != 0)
152 Node* pNode = reinterpret_cast<Node*>(m_listProps.GetItemData(i));
155 pNode->selected = false;
156 m_treeProps.SetItemState(pNode->hItem, 0, TVIS_BOLD);
157 m_listProps.DeleteItem(i);
163 void CDirAdditionalPropertiesDlg::OnDblClkTreeView(NMHDR* pNMHDR, LRESULT* pResult)
165 HTREEITEM hItem = m_treeProps.GetSelectedItem();
168 Node* pNode = reinterpret_cast<Node*>(m_treeProps.GetItemData(hItem));
173 for (int i = 0; i < m_listProps.GetItemCount(); ++i)
175 bool selected = (pNode == reinterpret_cast<Node*>(m_listProps.GetItemData(i)));
176 m_listProps.SetItemState(i, selected ? LVIS_SELECTED : 0, LVIS_SELECTED);
178 OnDelete(IDC_PROPS_DEL);
189 void CDirAdditionalPropertiesDlg::OnKeyDownTreeView(NMHDR* pNMHDR, LRESULT* pResult)
191 NMTVKEYDOWN* pNMKEY = reinterpret_cast<NMTVKEYDOWN*>(pNMHDR);
192 if (pNMKEY->wVKey == VK_SPACE)
194 OnDblClkTreeView(pNMHDR, pResult);
203 void CDirAdditionalPropertiesDlg::OnKeyDownListView(NMHDR* pNMHDR, LRESULT* pResult)
205 NMLVKEYDOWN* pNMKEY = reinterpret_cast<NMLVKEYDOWN*>(pNMHDR);
206 if (pNMKEY->wVKey == VK_DELETE)
208 OnDelete(IDC_PROPS_DEL);
217 void CDirAdditionalPropertiesDlg::OnOK()
220 m_canonicalNames.clear();
221 for (int i = 0; i < m_listProps.GetItemCount(); ++i)
223 Node* pNode = reinterpret_cast<Node*>(m_listProps.GetItemData(i));
225 m_canonicalNames.push_back(pNode->canonicalName);