OSDN Git Service

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