OSDN Git Service

Fix a bug where the headers of CPropertiesList can't show properly.
[xkeymacs/xkeymacs.git] / xkeymacs / propertieslist.cpp
1 // PropertiesList.cpp : implementation file\r
2 //\r
3 \r
4 #include "stdafx.h"\r
5 #include "xkeymacs.h"\r
6 #include "Profile.h"\r
7 #include "Properties.h"\r
8 #include "PropertiesList.h"\r
9 \r
10 #ifdef _DEBUG\r
11 #define new DEBUG_NEW\r
12 #undef THIS_FILE\r
13 static char THIS_FILE[] = __FILE__;\r
14 #endif\r
15 \r
16 /////////////////////////////////////////////////////////////////////////////\r
17 // CPropertiesList property page\r
18 \r
19 BOOL CPropertiesList::m_bSortAscending = TRUE;\r
20 \r
21 IMPLEMENT_DYNCREATE(CPropertiesList, CPropertyPage)\r
22 \r
23 CPropertiesList::CPropertiesList() : CPropertyPage(CPropertiesList::IDD)\r
24 {\r
25         //{{AFX_DATA_INIT(CPropertiesList)\r
26                 // NOTE: the ClassWizard will add member initialization here\r
27         //}}AFX_DATA_INIT\r
28 }\r
29 \r
30 CPropertiesList::~CPropertiesList()\r
31 {\r
32 }\r
33 \r
34 void CPropertiesList::DoDataExchange(CDataExchange* pDX)\r
35 {\r
36         CPropertyPage::DoDataExchange(pDX);\r
37         //{{AFX_DATA_MAP(CPropertiesList)\r
38         DDX_Control(pDX, IDC_PROPERTIES_LIST, m_cPropertiesList);\r
39         //}}AFX_DATA_MAP\r
40 }\r
41 \r
42 \r
43 BEGIN_MESSAGE_MAP(CPropertiesList, CPropertyPage)\r
44         //{{AFX_MSG_MAP(CPropertiesList)\r
45         ON_WM_CREATE()\r
46         ON_NOTIFY(LVN_COLUMNCLICK, IDC_PROPERTIES_LIST, OnColumnclickPropertiesList)\r
47         //}}AFX_MSG_MAP\r
48 END_MESSAGE_MAP()\r
49 \r
50 /////////////////////////////////////////////////////////////////////////////\r
51 // CPropertiesList message handlers\r
52 \r
53 BOOL CPropertiesList::OnSetActive() \r
54 {\r
55         // TODO: Add your specialized code here and/or call the base class\r
56         m_pProperties->EnableControl(LIST_TAB);\r
57         SetDialogData(m_pProperties->GetCurrentApplication());\r
58 \r
59         return CPropertyPage::OnSetActive();\r
60 }\r
61 \r
62 void CPropertiesList::SetDialogData(CString szApplicationName)\r
63 {\r
64         UpdateDialogData(szApplicationName, FALSE);\r
65 }\r
66 \r
67 void CPropertiesList::UpdateDialogData(CString szApplicationName, BOOL bSaveAndValidate)\r
68 {\r
69         if (bSaveAndValidate) { // GetDialogData\r
70                 UpdateData();\r
71         }\r
72 \r
73         if (!bSaveAndValidate) {        // SetDialogData\r
74                 m_cPropertiesList.DeleteAllItems();\r
75                 m_nCategoryWidth = 0;\r
76                 m_nCommandWidth = 0;\r
77                 m_nKeyWidth = 0;\r
78 \r
79                 for (int nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
80                         CString szCommandName = CXkeymacsData::GetCommandName(nCommandID);\r
81                         if (szCommandName.IsEmpty()) {\r
82                                 break;\r
83                         }\r
84 \r
85                         CString szCategory(MAKEINTRESOURCE(CXkeymacsData::GetCategoryID(nCommandID)));\r
86                         if (szCategory.IsEmpty()) {\r
87                                 continue;\r
88                         }\r
89 \r
90                         BOOL bInserted = FALSE;\r
91                         for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
92                                 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
93                                         if (nCommandID == CProfile::GetCommandID(m_pProperties->GetApplicationID(), nCommandType, nKey)) {\r
94                                                 CString szKey;\r
95                                                 szKey.Format(_T("%s%s"), CProfile::CommandType2String(nCommandType), CProfile::Key2String(nKey));\r
96 \r
97                                                 InsertItem(szCategory, szCommandName, szKey);\r
98 \r
99                                                 bInserted = TRUE;\r
100                                         }\r
101                                 }\r
102                         }\r
103                         if (!bInserted) {\r
104                                 InsertItem(szCategory, szCommandName, _T(""));\r
105                         }\r
106                 }\r
107 \r
108                 SortItem(m_nSelectedColumn);\r
109                 m_cPropertiesList.SetColumnWidth(0, m_nCategoryWidth + 0x20);\r
110                 m_cPropertiesList.SetColumnWidth(1, m_nCommandWidth + 0x20);\r
111                 m_cPropertiesList.SetColumnWidth(2, m_nKeyWidth + 0x20);\r
112         }\r
113 \r
114         if (!bSaveAndValidate) {        // SetDialogData\r
115                 UpdateData(FALSE);\r
116         }\r
117 }\r
118 \r
119 void CPropertiesList::GetDialogData()\r
120 {\r
121         UpdateDialogData(m_pProperties->GetCurrentApplication(), TRUE);\r
122 }\r
123 \r
124 int CPropertiesList::OnCreate(LPCREATESTRUCT lpCreateStruct) \r
125 {\r
126         if (CPropertyPage::OnCreate(lpCreateStruct) == -1)\r
127                 return -1;\r
128 \r
129         // TODO: Add your specialized creation code here\r
130         m_pProperties = (CProperties *)GetParent()->GetParent();\r
131 \r
132         return 0;\r
133 }\r
134 \r
135 BOOL CPropertiesList::OnKillActive() \r
136 {\r
137         // TODO: Add your specialized code here and/or call the base class\r
138         GetDialogData();\r
139 \r
140         return CPropertyPage::OnKillActive();\r
141 }\r
142 \r
143 void CPropertiesList::EnableControl()\r
144 {\r
145         BOOL bEnable = m_pProperties->IsEnableControl();\r
146 \r
147         m_cPropertiesList.EnableWindow(bEnable);\r
148 }\r
149 \r
150 BOOL CPropertiesList::OnInitDialog() \r
151 {\r
152         CPropertyPage::OnInitDialog();\r
153 \r
154         // TODO: Add extra initialization here\r
155         DWORD dwStyle = m_cPropertiesList.GetExtendedStyle();\r
156         dwStyle |= LVS_EX_FULLROWSELECT;\r
157         m_cPropertiesList.SetExtendedStyle(dwStyle);\r
158 \r
159         m_nSelectedColumn = 0;\r
160         m_bSortAscending = TRUE;\r
161 \r
162         m_cPropertiesList.InsertColumn(0, CString(MAKEINTRESOURCE(IDS_CATEGORY)), LVCFMT_LEFT);\r
163         m_cPropertiesList.InsertColumn(1, CString(MAKEINTRESOURCE(IDS_COMMAND)), LVCFMT_LEFT);\r
164         m_cPropertiesList.InsertColumn(2, CString(MAKEINTRESOURCE(IDS_KEY)), LVCFMT_LEFT);\r
165 \r
166         return TRUE;  // return TRUE unless you set the focus to a control\r
167                       // EXCEPTION: OCX Property Pages should return FALSE\r
168 }\r
169 \r
170 int CALLBACK CPropertiesList::SortCategory(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)\r
171 {\r
172         return Sort(lParam1, lParam2, lParamSort, SORT_CATEGORY);\r
173 }\r
174 \r
175 int CALLBACK CPropertiesList::SortCommand(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)\r
176 {\r
177         return Sort(lParam1, lParam2, lParamSort, SORT_COMMAND);\r
178 }\r
179 \r
180 int CALLBACK CPropertiesList::SortKey(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)\r
181 {\r
182         return Sort(lParam1, lParam2, lParamSort, SORT_KEY);\r
183 }\r
184 \r
185 void CPropertiesList::OnColumnclickPropertiesList(NMHDR* pNMHDR, LRESULT* pResult) \r
186 {\r
187         NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;\r
188         // TODO: Add your control notification handler code here\r
189         if (m_nSelectedColumn == pNMListView->iSubItem) {\r
190                 m_bSortAscending = !m_bSortAscending;\r
191         } else {\r
192                 m_nSelectedColumn = pNMListView->iSubItem;\r
193                 m_bSortAscending = TRUE;\r
194         }\r
195 \r
196         for (int nItem = 0; nItem < m_cPropertiesList.GetItemCount(); ++nItem) {\r
197                 m_cPropertiesList.SetItemData(nItem, nItem);\r
198         }\r
199 \r
200         SortItem(pNMListView->iSubItem);\r
201 \r
202         *pResult = 0;\r
203 }\r
204 \r
205 void CPropertiesList::DisplayIndicator()\r
206 {\r
207         CHeaderCtrl *pHeaderCtrl = m_cPropertiesList.GetHeaderCtrl();\r
208 \r
209         for (int nItemCount = 0; nItemCount < pHeaderCtrl->GetItemCount(); ++nItemCount) {\r
210                 HDITEM hditem;\r
211                 if (nItemCount == m_nSelectedColumn) {\r
212                         hditem.mask = HDI_FORMAT | HDI_BITMAP;\r
213                         hditem.fmt = HDF_STRING | HDF_BITMAP | HDF_BITMAP_ON_RIGHT;\r
214                         const int IDB_SORT = m_bSortAscending ? IDB_SORT_ASCENDING : IDB_SORT_DESCENDING;\r
215                         hditem.hbm = (HBITMAP)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_SORT), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);\r
216                         pHeaderCtrl->SetItem(nItemCount, &hditem);\r
217                 } else {\r
218                         hditem.mask = HDI_FORMAT;\r
219                         hditem.fmt = HDF_STRING;\r
220                         hditem.hbm = NULL;\r
221                         pHeaderCtrl->SetItem(nItemCount, &hditem);\r
222                 }\r
223         }\r
224 }\r
225 \r
226 void CPropertiesList::SortItem(int nColumn)\r
227 {\r
228         switch (nColumn) {\r
229         case 0:\r
230                 m_cPropertiesList.SortItems(CPropertiesList::SortCategory, (LPARAM) &m_cPropertiesList);\r
231                 break;\r
232         case 1:\r
233                 m_cPropertiesList.SortItems(CPropertiesList::SortCommand, (LPARAM) &m_cPropertiesList);\r
234                 break;\r
235         case 2:\r
236                 m_cPropertiesList.SortItems(CPropertiesList::SortKey, (LPARAM) &m_cPropertiesList);\r
237                 break;\r
238         default:\r
239                 m_cPropertiesList.SortItems(CPropertiesList::SortCategory, (LPARAM) &m_cPropertiesList);\r
240                 break;\r
241         }\r
242 \r
243         DisplayIndicator();\r
244 }\r
245 \r
246 void CPropertiesList::InsertItem(LPCTSTR szCategory, LPCTSTR szCommandName, LPCTSTR szKey)\r
247 {\r
248         int nItem = m_cPropertiesList.InsertItem(m_cPropertiesList.GetItemCount(), szCategory);\r
249         m_cPropertiesList.SetItemData(nItem, nItem);\r
250         m_cPropertiesList.SetItemText(nItem, 1, szCommandName);\r
251         m_cPropertiesList.SetItemText(nItem, 2, szKey);\r
252 \r
253         m_nCategoryWidth = __max(m_nCategoryWidth, m_cPropertiesList.GetStringWidth(szCategory));\r
254         m_nCommandWidth = __max(m_nCommandWidth, m_cPropertiesList.GetStringWidth(szCommandName));\r
255         m_nKeyWidth = __max(m_nKeyWidth, m_cPropertiesList.GetStringWidth(szKey));\r
256 }\r
257 \r
258 int CPropertiesList::Sort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort, SORT_TYPE sortType)\r
259 {\r
260         CListCtrl *pListCtrl = (CListCtrl *) lParamSort;\r
261 \r
262         CString szCategory1 = pListCtrl->GetItemText(lParam1, 0);\r
263         CString szCommand1 = pListCtrl->GetItemText(lParam1, 1);\r
264         CString szKey1 = pListCtrl->GetItemText(lParam1, 2);\r
265 \r
266         CString szCategory2 = pListCtrl->GetItemText(lParam2, 0);\r
267         CString szCommand2 = pListCtrl->GetItemText(lParam2, 1);\r
268         CString szKey2 = pListCtrl->GetItemText(lParam2, 2);\r
269 \r
270         int rc = 0;\r
271         switch (sortType) {\r
272         case SORT_CATEGORY:\r
273                 rc = rc ? rc : _tcscmp(szCategory1, szCategory2);\r
274                 // Do NOT write break; here.\r
275         case SORT_COMMAND:\r
276                 rc = rc ? rc : _tcscmp(szCommand1, szCommand2);\r
277                 // Do NOT write break; here.\r
278         case SORT_KEY:\r
279                 if (!rc) {\r
280                         rc = rc ? rc : _tcscmp(szKey1, szKey2);\r
281                         if (szKey1.IsEmpty() && !szKey2.IsEmpty()) {\r
282                                 rc = 1;\r
283                         } else if (!szKey1.IsEmpty() && szKey2.IsEmpty()) {\r
284                                 rc = -1;\r
285                         }\r
286                 }\r
287                 break;\r
288         default:\r
289                 break;\r
290         }\r
291         return m_bSortAscending ? rc : rc * -1;\r
292 }\r