OSDN Git Service

Add a solution file and project files for Microsoft Visual Studio 10.0.
[xkeymacs/xkeymacs.git] / xkeymacs / dotxkeymacs.cpp
1 // DotXkeymacs.cpp: implementation of the CDotXkeymacs class.\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "stdafx.h"\r
6 #include <direct.h>\r
7 #include <Shlwapi.h>\r
8 #include "xkeymacs.h"\r
9 #include "DotXkeymacs.h"\r
10 \r
11 #ifdef _DEBUG\r
12 #undef THIS_FILE\r
13 static char THIS_FILE[]=__FILE__;\r
14 #define new DEBUG_NEW\r
15 #endif\r
16 \r
17 #pragma data_seg(".xkmcs")\r
18         CObList         CDotXkeymacs::m_oFunctionDefinition;\r
19         int                     CDotXkeymacs::m_nIndex[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
20         const TCHAR     CDotXkeymacs::m_szExt[] = _T("xkeymacs");\r
21 #pragma data_seg()\r
22 \r
23 //////////////////////////////////////////////////////////////////////\r
24 // Construction/Destruction\r
25 //////////////////////////////////////////////////////////////////////\r
26 \r
27 CDotXkeymacs::CDotXkeymacs()\r
28 {\r
29 \r
30 }\r
31 \r
32 CDotXkeymacs::~CDotXkeymacs()\r
33 {\r
34 \r
35 }\r
36 \r
37 void CDotXkeymacs::Load(LPCTSTR lpszFileName)\r
38 {\r
39         CStdioFile oDotXkeymacs;\r
40         if (oDotXkeymacs.Open(lpszFileName, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeRead | CFile::shareDenyWrite | CFile::typeText)) {\r
41                 CString szRead;\r
42                 while (oDotXkeymacs.ReadString(szRead)) {\r
43                         if (IsFunctionDefinition(szRead)) {\r
44                                 CFunctionDefinition *pFunctionDefinition = new CFunctionDefinition(GetSymbol(szRead), GetDefinition(szRead));\r
45 \r
46                                 // Delete a listed definition which has the same symbol as a new one.\r
47                                 for (POSITION currentPos, pos = m_oFunctionDefinition.GetHeadPosition(); (currentPos = pos) != NULL; ) {\r
48                                         CFunctionDefinition *pCurrentDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetNext(pos);\r
49 \r
50                                         if (pCurrentDefinition->GetSymbol() == pFunctionDefinition->GetSymbol()) {\r
51                                                 CFunctionDefinition *pOverwritten = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(currentPos);\r
52                                                 m_oFunctionDefinition.RemoveAt(currentPos);\r
53                                                 delete pOverwritten;\r
54                                         }\r
55                                 }\r
56 \r
57                                 m_oFunctionDefinition.AddTail((CObject *)pFunctionDefinition);\r
58                         }\r
59                 }\r
60         }\r
61 }\r
62 \r
63 void CDotXkeymacs::LoadMainData(LPCTSTR lpszFileName)\r
64 {\r
65         TCHAR szModuleFileName[MAX_PATH] = {'\0'};\r
66         TCHAR szDrive[_MAX_DRIVE] = {'\0'};\r
67         TCHAR szDir[_MAX_DIR] = {'\0'};\r
68 \r
69         if (GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName))) {\r
70                 _tsplitpath(szModuleFileName, szDrive, szDir, NULL, NULL);\r
71         }\r
72 \r
73         TCHAR szOldPath[MAX_PATH] = {'\0'};     // This path is used by XKeymacs 3.22 and earlier\r
74         _tmakepath(szOldPath, szDrive, szDir, lpszFileName, m_szExt);\r
75 \r
76         PathAppend(szDir, _T("etc"));\r
77         TCHAR szEtc[MAX_PATH] = {'\0'};\r
78         _tmakepath(szEtc, szDrive, szDir, NULL, NULL);\r
79         (void)_tmkdir(szEtc);   // make etc directory if needed\r
80 \r
81         TCHAR szPath[MAX_PATH] = {'\0'};\r
82         _tmakepath(szPath, szDrive, szDir, lpszFileName, m_szExt);\r
83 \r
84         if (_trename(szOldPath, szPath)) {                      // try to move old file as backup when rename returns an error because files exist in both directorys\r
85                 TCHAR szBackupPath[MAX_PATH] = {'\0'};\r
86                 TCHAR szBackupFlag[_MAX_FNAME] = _T("~");\r
87                 _tmakepath(szBackupPath, szDrive, szDir, _tcscat(szBackupFlag, lpszFileName), m_szExt);\r
88                 (void)_trename(szOldPath, szBackupPath);        // do nothing when a backup file has existed already\r
89         }\r
90 \r
91         Load(szPath);\r
92 }\r
93 \r
94 void CDotXkeymacs::LoadUserData(LPCTSTR lpszFileName)\r
95 {\r
96         TCHAR szPath[MAX_PATH] = {'\0'};\r
97         if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, TRUE)) {\r
98                 _tmakepath(szPath, NULL, szPath, lpszFileName, m_szExt);\r
99                 Load(szPath);\r
100         }\r
101 }\r
102 \r
103 void CDotXkeymacs::Load()\r
104 {\r
105         static LPCTSTR szFileName = _T("dot");\r
106 \r
107         ClearFunctionDefinition();\r
108         LoadMainData(GetLanguage());    // just for localization\r
109         LoadMainData(szFileName);\r
110         LoadUserData(szFileName);       // overwrite main data\r
111 }\r
112 \r
113 BOOL CDotXkeymacs::IsFunctionDefinition(CString szFunctionDefinition)\r
114 {\r
115         return !_tcsncmp(szFunctionDefinition, CString(MAKEINTRESOURCE(IDS_FSET)), _tcslen(CString(MAKEINTRESOURCE(IDS_FSET))));\r
116 }\r
117 \r
118 CString CDotXkeymacs::GetSymbol(CString szFunctionDefinition)\r
119 {\r
120         const int nFirst = _tcslen(CString(MAKEINTRESOURCE(IDS_FSET))) + _tcslen(_T("'"));\r
121         return szFunctionDefinition.Mid(nFirst, szFunctionDefinition.Find(_T(' '), nFirst) - nFirst);\r
122 }\r
123 \r
124 CString CDotXkeymacs::GetDefinition(CString szFunctionDefinition)\r
125 {\r
126         const int nFirst = szFunctionDefinition.Find(_T(' '), _tcslen(CString(MAKEINTRESOURCE(IDS_FSET)))) + _tcslen(_T("'"));\r
127         return szFunctionDefinition.Mid(nFirst, szFunctionDefinition.GetLength() - nFirst - _tcslen(_T(")")));\r
128 }\r
129 \r
130 void CDotXkeymacs::ClearFunctionDefinition()\r
131 {\r
132         while (!m_oFunctionDefinition.IsEmpty()) {\r
133                 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetHead();\r
134                 delete pFunctionDefinition;\r
135                 pFunctionDefinition = NULL;\r
136                 m_oFunctionDefinition.RemoveHead();\r
137         }\r
138         memset(m_nIndex, -1, sizeof(m_nIndex));\r
139 }\r
140 \r
141 int CDotXkeymacs::GetFunctionNumber()\r
142 {\r
143         return m_oFunctionDefinition.GetCount();\r
144 }\r
145 \r
146 CString CDotXkeymacs::GetFunctionSymbol(int nIndex)\r
147 {\r
148         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
149                 return CString();\r
150         }\r
151 \r
152         if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {\r
153                 return pFunctionDefinition->GetSymbol();\r
154         }\r
155         return CString();\r
156 }\r
157 \r
158 CString CDotXkeymacs::GetFunctionDefinition(int nIndex)\r
159 {\r
160         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
161                 return CString();\r
162         }\r
163 \r
164         if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {\r
165                 return pFunctionDefinition->GetDefinition();\r
166         }\r
167         return CString();\r
168 }\r
169 \r
170 CString CDotXkeymacs::GetFunctionDefinition(CString szSymbol)\r
171 {\r
172         for (POSITION pos = m_oFunctionDefinition.GetHeadPosition(); pos;) {\r
173                 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetNext(pos);\r
174                 if (!pFunctionDefinition->GetSymbol().Compare(szSymbol)) {\r
175                         return pFunctionDefinition->GetDefinition();\r
176                 }\r
177         }\r
178 \r
179         return CString(_T("Undefined Command"));\r
180 }\r
181 \r
182 void CDotXkeymacs::ClearKey(int nIndex, int nApplicationID)\r
183 {\r
184         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
185                 return;\r
186         }\r
187 \r
188         if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {\r
189                 pFunctionDefinition->ClearKey(nApplicationID);\r
190         }\r
191 \r
192         for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
193                 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
194                         if (m_nIndex[nApplicationID][nCommandType][nKey] == nIndex) {\r
195                                 m_nIndex[nApplicationID][nCommandType][nKey] = -1;\r
196                         }\r
197                 }\r
198         }\r
199 }\r
200 \r
201 void CDotXkeymacs::SetKey(int nIndex, int nApplicationID, int nCommandType, int nKey)\r
202 {\r
203         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
204                 return;\r
205         }\r
206 \r
207         if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {\r
208                 pFunctionDefinition->SetKey(nApplicationID, nCommandType, nKey);\r
209                 m_nIndex[nApplicationID][nCommandType][nKey] = nIndex;\r
210         }\r
211 }\r
212 \r
213 int CDotXkeymacs::GetIndex(CString szSymbol)\r
214 {\r
215         int nIndex = 0;\r
216         for (nIndex = 0; nIndex < m_oFunctionDefinition.GetCount(); ++nIndex) {\r
217                 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));\r
218                 if (!pFunctionDefinition->GetSymbol().Compare(szSymbol)) {\r
219                         return nIndex;\r
220                 }\r
221         }\r
222         return -1;\r
223 }\r
224 \r
225 int CDotXkeymacs::GetKeyNumber(int nIndex, int nApplicationID)\r
226 {\r
227         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
228                 return 0;\r
229         }\r
230 \r
231         CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));\r
232         return pFunctionDefinition->GetKeyNumber(nApplicationID);\r
233 }\r
234 \r
235 void CDotXkeymacs::GetKey(int nIndex, int nApplicationID, int nKeyID, int *pCommandType, int *pKey)\r
236 {\r
237         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
238                 return;\r
239         }\r
240 \r
241         CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));\r
242         pFunctionDefinition->GetKey(nApplicationID, nKeyID, pCommandType, pKey);\r
243 }\r
244 \r
245 int CDotXkeymacs::GetIndex(int nApplicationID, int nCommandType, int nKey)\r
246 {\r
247         return m_nIndex[nApplicationID][nCommandType][nKey];\r
248 }\r
249 \r
250 void CDotXkeymacs::RemoveKey(const int nIndex, const int nApplicationID, const int nCommandType, const int nKey)\r
251 {\r
252         if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {\r
253                 return;\r
254         }\r
255 \r
256         CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));\r
257         if (pFunctionDefinition) {\r
258                 pFunctionDefinition->RemoveKey(nApplicationID, nCommandType, nKey);\r
259         }\r
260 }\r
261 \r
262 void CDotXkeymacs::RemoveKey(const int nApplicationID, const int nCommandType, const int nKey)\r
263 {\r
264         for (int nIndex = 0; nIndex < m_oFunctionDefinition.GetCount(); ++nIndex) {\r
265                 RemoveKey(nIndex, nApplicationID, nCommandType, nKey);\r
266         }\r
267 }\r
268 \r
269 LPCTSTR CDotXkeymacs::GetLanguage()\r
270 {\r
271         LPCTSTR szLanguage = _T("unknown");\r
272 \r
273         TCHAR lptstrFilename[MAX_PATH] = {'\0'};\r
274         _tmakepath(lptstrFilename, NULL, _tgetenv(_T("windir")), _T("explorer"), _T("exe"));\r
275         DWORD dwLen = GetFileVersionInfoSize(lptstrFilename, NULL);\r
276 \r
277         if (dwLen) {\r
278                 LPVOID lpData = malloc(dwLen);\r
279 \r
280                 if (lpData && GetFileVersionInfo(lptstrFilename, NULL, dwLen, lpData)) {\r
281                         Translate_t *lpTranslate;\r
282                         UINT cbTranslate = 0;\r
283 \r
284                         if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate) && sizeof(Translate_t) <= cbTranslate) {\r
285                                 for (int i = 0; i < sizeof(Languages)/sizeof(Languages[0]); ++i) {\r
286                                         if (Languages[i].wLanguage == lpTranslate->wLanguage) {\r
287                                                 szLanguage = Languages[i].szLanguage;\r
288                                                 break;\r
289                                         }\r
290                                 }\r
291                         }\r
292                 }\r
293 \r
294                 free(lpData);\r
295         }\r
296 \r
297         return szLanguage;\r
298 }\r