1 // DotXkeymacs.cpp: implementation of the CDotXkeymacs class.
\r
3 //////////////////////////////////////////////////////////////////////
\r
8 #include "DotXkeymacs.h"
\r
12 static char THIS_FILE[]=__FILE__;
\r
13 #define new DEBUG_NEW
\r
22 static const Language Languages[] = {
\r
23 { 0x0001, _T("Arabic") },
\r
24 { 0x0004, _T("Chinese") },
\r
25 { 0x0009, _T("English") },
\r
26 { 0x0401, _T("Arabic (Saudi Arabia)") },
\r
27 { 0x0402, _T("Bulgarian") },
\r
28 { 0x0403, _T("Catalan") },
\r
29 { 0x0404, _T("Chinese (Taiwan)") },
\r
30 { 0x0405, _T("Czech") },
\r
31 { 0x0406, _T("Danish") },
\r
32 { 0x0407, _T("German (Germany)") },
\r
33 { 0x0408, _T("Greek") },
\r
34 { 0x0409, _T("English (United States)") },
\r
35 { 0x040A, _T("Spanish (Traditional Sort)") },
\r
36 { 0x040B, _T("Finnish") },
\r
37 { 0x040C, _T("French (France)") },
\r
38 { 0x040D, _T("Hebrew") },
\r
39 { 0x040E, _T("Hungarian") },
\r
40 { 0x040F, _T("Icelandic") },
\r
41 { 0x0410, _T("Italian (Italy)") },
\r
42 { 0x0411, _T("Japanese") },
\r
43 { 0x0412, _T("Korean") },
\r
44 { 0x0413, _T("Dutch (Netherlands)") },
\r
45 { 0x0414, _T("Norwegian (Bokmal)") },
\r
46 { 0x0415, _T("Polish") },
\r
47 { 0x0416, _T("Portuguese (Brazil)") },
\r
48 { 0x0417, _T("Rhaeto-Romanic") },
\r
49 { 0x0418, _T("Romanian") },
\r
50 { 0x0419, _T("Russian") },
\r
51 { 0x041A, _T("Croatian") },
\r
52 { 0x041B, _T("Slovak") },
\r
53 { 0x041C, _T("Albanian") },
\r
54 { 0x041D, _T("Swedish") },
\r
55 { 0x041E, _T("Thai") },
\r
56 { 0x041F, _T("Turkish") },
\r
57 { 0x0420, _T("Urdu") },
\r
58 { 0x0421, _T("Indonesian") },
\r
59 { 0x0422, _T("Ukrainian") },
\r
60 { 0x0423, _T("Belarusian") },
\r
61 { 0x0424, _T("Slovenian") },
\r
62 { 0x0425, _T("Estonian") },
\r
63 { 0x0426, _T("Latvian") },
\r
64 { 0x0427, _T("Lithuanian") },
\r
65 { 0x0428, _T("Tajik") },
\r
66 { 0x0429, _T("Farsi") },
\r
67 { 0x042A, _T("Vietnamese") },
\r
68 { 0x042B, _T("Armenian") },
\r
69 { 0x042C, _T("Azeri (Latin)") },
\r
70 { 0x042D, _T("Basque") },
\r
71 { 0x042E, _T("Sorbian") },
\r
72 { 0x042F, _T("Macedonian (FYROM)") },
\r
73 { 0x0430, _T("Sutu") },
\r
74 { 0x0431, _T("Tsonga") },
\r
75 { 0x0432, _T("Tswana") },
\r
76 { 0x0434, _T("Xhosa") },
\r
77 { 0x0435, _T("Zulu") },
\r
78 { 0x0436, _T("Afrikaans") },
\r
79 { 0x0437, _T("Georgian") },
\r
80 { 0x0438, _T("Faeroese") },
\r
81 { 0x0439, _T("Hindi") },
\r
82 { 0x043A, _T("Maltese") },
\r
83 { 0x043C, _T("Gaelic") },
\r
84 { 0x043D, _T("Yiddish") },
\r
85 { 0x043E, _T("Malay (Malaysia)") },
\r
86 { 0x043F, _T("Kazakh") },
\r
87 { 0x0440, _T("Kyrgyz") },
\r
88 { 0x0441, _T("Swahili") },
\r
89 { 0x0442, _T("Turkmen") },
\r
90 { 0x0443, _T("Uzbek (Latin)") },
\r
91 { 0x0444, _T("Tatar") },
\r
92 { 0x0445, _T("Bengali") },
\r
93 { 0x0446, _T("Punjabi") },
\r
94 { 0x0447, _T("Gujarati") },
\r
95 { 0x0448, _T("Oriya") },
\r
96 { 0x0449, _T("Tamil") },
\r
97 { 0x044A, _T("Telugu") },
\r
98 { 0x044B, _T("Kannada") },
\r
99 { 0x044C, _T("Malayalam") },
\r
100 { 0x044D, _T("Assamese") },
\r
101 { 0x044E, _T("Marathi") },
\r
102 { 0x044F, _T("Sanskrit") },
\r
103 { 0x0450, _T("Mongolian") },
\r
104 { 0x0456, _T("Galician") },
\r
105 { 0x0457, _T("Konkani") },
\r
106 { 0x0458, _T("Manipuri") },
\r
107 { 0x0459, _T("Sindhi") },
\r
108 { 0x045A, _T("Syriac") },
\r
109 { 0x045B, _T("Sinhalese") },
\r
110 { 0x045C, _T("Cherokee") },
\r
111 { 0x045D, _T("Inuktitut") },
\r
112 { 0x045E, _T("Amharic") },
\r
113 { 0x045F, _T("Tamazight (Berber/Arabic)") },
\r
114 { 0x0460, _T("Kashmiri (Arabic)") },
\r
115 { 0x0461, _T("Nepali") },
\r
116 { 0x0462, _T("Frisian") },
\r
117 { 0x0463, _T("Pashto") },
\r
118 { 0x0464, _T("Filipino") },
\r
119 { 0x0465, _T("Dhivehi") },
\r
120 { 0x0466, _T("Edo") },
\r
121 { 0x0467, _T("Fulfulde") },
\r
122 { 0x0468, _T("Hausa") },
\r
123 { 0x0469, _T("Ibibio") },
\r
124 { 0x046A, _T("Yoruba") },
\r
125 { 0x0470, _T("Igbo") },
\r
126 { 0x0471, _T("Kanuri") },
\r
127 { 0x0472, _T("Oromo") },
\r
128 { 0x0473, _T("Tigrigna (Ethiopia)") },
\r
129 { 0x0475, _T("Hawaiian") },
\r
130 { 0x0476, _T("Latin") },
\r
131 { 0x0477, _T("Somali") },
\r
132 { 0x0478, _T("Yi") },
\r
133 { 0x0801, _T("Arabic (Iraq)") },
\r
134 { 0x0804, _T("Chinese (PRC)") },
\r
135 { 0x0807, _T("German (Switzerland)") },
\r
136 { 0x0809, _T("English (United Kingdom)") },
\r
137 { 0x080A, _T("Spanish (Mexico)") },
\r
138 { 0x080C, _T("French (Belgium)") },
\r
139 { 0x0810, _T("Italian (Switzerland)") },
\r
140 { 0x0813, _T("Dutch (Belgium)") },
\r
141 { 0x0814, _T("Norwegian (Nynorsk)") },
\r
142 { 0x0816, _T("Portuguese (Portugal)") },
\r
143 { 0x0818, _T("Romanian (Moldova)") },
\r
144 { 0x0819, _T("Russian (Moldova)") },
\r
145 { 0x081A, _T("Serbian (Latin)") },
\r
146 { 0x081D, _T("Swedish (Finland)") },
\r
147 { 0x082C, _T("Azeri (Cyrillic)") },
\r
148 { 0x0843, _T("Uzbek (Cyrillic)") },
\r
149 { 0x085F, _T("Tamazight (Latin)") },
\r
150 { 0x0873, _T("Tigrigna (Eritrea)") },
\r
151 { 0x0C01, _T("Arabic (Egypt)") },
\r
152 { 0x0C04, _T("Chinese (Hong Kong SAR)") },
\r
153 { 0x0C07, _T("German (Austria)") },
\r
154 { 0x0C09, _T("English (Australia)") },
\r
155 { 0x0C0A, _T("Spanish (International Sort)") },
\r
156 { 0x0C0C, _T("French (Canada)") },
\r
157 { 0x0C1A, _T("Serbian (Cyrillic)") },
\r
158 { 0x1001, _T("Arabic (Libya)") },
\r
159 { 0x1004, _T("Chinese (Singapore)") },
\r
160 { 0x1007, _T("German (Luxembourg)") },
\r
161 { 0x1009, _T("English (Canada)") },
\r
162 { 0x100A, _T("Spanish (Guatemala)") },
\r
163 { 0x100C, _T("French (Switzerland)") },
\r
164 { 0x1401, _T("Arabic (Algeria)") },
\r
165 { 0x1407, _T("German (Liechtenstein)") },
\r
166 { 0x1409, _T("English (New Zealand)") },
\r
167 { 0x140A, _T("Spanish (Costa Rica)") },
\r
168 { 0x140C, _T("French (Luxembourg)") },
\r
169 { 0x1801, _T("Arabic (Morocco)") },
\r
170 { 0x1809, _T("English (Ireland)") },
\r
171 { 0x180A, _T("Spanish (Panama)") },
\r
172 { 0x1C01, _T("Arabic (Tunisia)") },
\r
173 { 0x1C09, _T("English (South Africa)") },
\r
174 { 0x1C0A, _T("Spanish (Dominican Republic)") },
\r
175 { 0x2001, _T("Arabic (Oman)") },
\r
176 { 0x2009, _T("English (Jamaica)") },
\r
177 { 0x200A, _T("Spanish (Venezuela)") },
\r
178 { 0x2401, _T("Arabic (Yemen)") },
\r
179 { 0x240A, _T("Spanish (Colombia)") },
\r
180 { 0x2801, _T("Arabic (Syria)") },
\r
181 { 0x2809, _T("English (Belize)") },
\r
182 { 0x280A, _T("Spanish (Peru)") },
\r
183 { 0x2C01, _T("Arabic (Jordan)") },
\r
184 { 0x2C09, _T("English (Trinidad)") },
\r
185 { 0x2C0A, _T("Spanish (Argentina)") },
\r
186 { 0x3001, _T("Arabic (Lebanon)") },
\r
187 { 0x300A, _T("Spanish (Ecuador)") },
\r
188 { 0x3401, _T("Arabic (Kuwait)") },
\r
189 { 0x340A, _T("Spanish (Chile)") },
\r
190 { 0x3801, _T("Arabic (U.A.E.)") },
\r
191 { 0x380A, _T("Spanish (Uruguay)") },
\r
192 { 0x3C01, _T("Arabic (Bahrain)") },
\r
193 { 0x3C0A, _T("Spanish (Paraguay)") },
\r
194 { 0x4001, _T("Arabic (Qatar)") },
\r
195 { 0x400A, _T("Spanish (Bolivia)") },
\r
196 { 0x440A, _T("Spanish (El Salvador)") },
\r
197 { 0x480A, _T("Spanish (Honduras)") },
\r
198 { 0x4C0A, _T("Spanish (Nicaragua)") },
\r
199 { 0x500A, _T("Spanish (Puerto Rico)") },
\r
202 CObList CDotXkeymacs::m_oFunctionDefinition;
\r
203 int CDotXkeymacs::m_nIndex[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
204 const TCHAR CDotXkeymacs::m_szExt[] = _T("xkeymacs");
\r
206 void CDotXkeymacs::Load(LPCTSTR lpszFileName)
\r
208 CStdioFile oDotXkeymacs;
\r
209 if (oDotXkeymacs.Open(lpszFileName, CFile::modeRead | CFile::shareDenyWrite | CFile::typeText)) {
\r
211 while (oDotXkeymacs.ReadString(szRead)) {
\r
212 if (IsFunctionDefinition(szRead)) {
\r
213 CFunctionDefinition *pFunctionDefinition = new CFunctionDefinition(GetSymbol(szRead), GetDefinition(szRead));
\r
215 // Delete a listed definition which has the same symbol as a new one.
\r
216 for (POSITION currentPos, pos = m_oFunctionDefinition.GetHeadPosition(); (currentPos = pos) != NULL; ) {
\r
217 CFunctionDefinition *pCurrentDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetNext(pos);
\r
219 if (pCurrentDefinition->GetSymbol() == pFunctionDefinition->GetSymbol()) {
\r
220 CFunctionDefinition *pOverwritten = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(currentPos);
\r
221 m_oFunctionDefinition.RemoveAt(currentPos);
\r
222 delete pOverwritten;
\r
226 m_oFunctionDefinition.AddTail((CObject *)pFunctionDefinition);
\r
232 void CDotXkeymacs::LoadMainData(LPCTSTR lpszFileName)
\r
234 TCHAR szModuleFileName[MAX_PATH] = {'\0'};
\r
235 TCHAR szDrive[_MAX_DRIVE] = {'\0'};
\r
236 TCHAR szDir[_MAX_DIR] = {'\0'};
\r
238 if (GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName))) {
\r
239 _tsplitpath_s(szModuleFileName, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);
\r
242 TCHAR szOldPath[MAX_PATH] = {'\0'}; // This path is used by XKeymacs 3.22 and earlier
\r
243 _tmakepath_s(szOldPath, szDrive, szDir, lpszFileName, m_szExt);
\r
245 PathAppend(szDir, _T("etc"));
\r
246 TCHAR szPath[MAX_PATH] = {'\0'};
\r
247 _tmakepath_s(szPath, szDrive, szDir, lpszFileName, m_szExt);
\r
249 if (_trename(szOldPath, szPath)) { // try to move old file as backup when rename returns an error because files exist in both directorys
\r
250 TCHAR szBackupPath[MAX_PATH] = {'\0'};
\r
251 TCHAR szBackupFlag[_MAX_FNAME] = _T("~");
\r
252 _tcscat_s(szBackupFlag, lpszFileName);
\r
253 _tmakepath_s(szBackupPath, szDrive, szDir, szBackupFlag, m_szExt);
\r
254 (void)_trename(szOldPath, szBackupPath); // do nothing when a backup file has existed already
\r
260 void CDotXkeymacs::LoadUserData(LPCTSTR lpszFileName)
\r
262 TCHAR szPath[MAX_PATH] = {'\0'};
\r
263 if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, TRUE)) {
\r
264 _tmakepath_s(szPath, NULL, szPath, lpszFileName, m_szExt);
\r
269 void CDotXkeymacs::Load()
\r
271 static LPCTSTR szFileName = _T("dot");
\r
273 ClearFunctionDefinition();
\r
274 LoadMainData(GetLanguage()); // just for localization
\r
275 LoadMainData(szFileName);
\r
276 LoadUserData(szFileName); // overwrite main data
\r
279 BOOL CDotXkeymacs::IsFunctionDefinition(CString szFunctionDefinition)
\r
281 return !_tcsncmp(szFunctionDefinition, CString(MAKEINTRESOURCE(IDS_FSET)), _tcslen(CString(MAKEINTRESOURCE(IDS_FSET))));
\r
284 CString CDotXkeymacs::GetSymbol(CString szFunctionDefinition)
\r
286 const int nFirst = _tcslen(CString(MAKEINTRESOURCE(IDS_FSET))) + _tcslen(_T("'"));
\r
287 return szFunctionDefinition.Mid(nFirst, szFunctionDefinition.Find(_T(' '), nFirst) - nFirst);
\r
290 CString CDotXkeymacs::GetDefinition(CString szFunctionDefinition)
\r
292 const int nFirst = szFunctionDefinition.Find(_T(' '), _tcslen(CString(MAKEINTRESOURCE(IDS_FSET)))) + _tcslen(_T("'"));
\r
293 return szFunctionDefinition.Mid(nFirst, szFunctionDefinition.GetLength() - nFirst - _tcslen(_T(")")));
\r
296 void CDotXkeymacs::ClearFunctionDefinition()
\r
298 while (!m_oFunctionDefinition.IsEmpty()) {
\r
299 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetHead();
\r
300 delete pFunctionDefinition;
\r
301 pFunctionDefinition = NULL;
\r
302 m_oFunctionDefinition.RemoveHead();
\r
304 memset(m_nIndex, -1, sizeof(m_nIndex));
\r
307 int CDotXkeymacs::GetFunctionNumber()
\r
309 return m_oFunctionDefinition.GetCount();
\r
312 CString CDotXkeymacs::GetFunctionSymbol(int nIndex)
\r
314 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
318 if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {
\r
319 return pFunctionDefinition->GetSymbol();
\r
324 CString CDotXkeymacs::GetFunctionDefinition(int nIndex)
\r
326 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
330 if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {
\r
331 return pFunctionDefinition->GetDefinition();
\r
336 CString CDotXkeymacs::GetFunctionDefinition(CString szSymbol)
\r
338 for (POSITION pos = m_oFunctionDefinition.GetHeadPosition(); pos;) {
\r
339 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetNext(pos);
\r
340 if (!pFunctionDefinition->GetSymbol().Compare(szSymbol)) {
\r
341 return pFunctionDefinition->GetDefinition();
\r
345 return CString(_T("Undefined Command"));
\r
348 void CDotXkeymacs::ClearKey(int nIndex, int nAppID)
\r
350 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
354 if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {
\r
355 pFunctionDefinition->ClearKey(nAppID);
\r
358 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType) {
\r
359 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {
\r
360 if (m_nIndex[nAppID][nType][nKey] == nIndex) {
\r
361 m_nIndex[nAppID][nType][nKey] = -1;
\r
367 void CDotXkeymacs::SetKey(int nIndex, int nAppID, int nType, int nKey)
\r
369 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
373 if (CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex))) {
\r
374 pFunctionDefinition->SetKey(nAppID, nType, nKey);
\r
375 m_nIndex[nAppID][nType][nKey] = nIndex;
\r
379 int CDotXkeymacs::GetIndex(CString szSymbol)
\r
382 for (nIndex = 0; nIndex < m_oFunctionDefinition.GetCount(); ++nIndex) {
\r
383 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));
\r
384 if (!pFunctionDefinition->GetSymbol().Compare(szSymbol)) {
\r
391 int CDotXkeymacs::GetKeyNumber(int nIndex, int nAppID)
\r
393 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
397 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));
\r
398 return pFunctionDefinition->GetKeyNumber(nAppID);
\r
401 void CDotXkeymacs::GetKey(int nIndex, int nAppID, int nKeyID, int *pCommandType, int *pKey)
\r
403 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
407 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));
\r
408 pFunctionDefinition->GetKey(nAppID, nKeyID, pCommandType, pKey);
\r
411 int CDotXkeymacs::GetIndex(int nAppID, int nType, int nKey)
\r
413 return m_nIndex[nAppID][nType][nKey];
\r
416 void CDotXkeymacs::RemoveKey(const int nIndex, const int nAppID, const int nType, const int nKey)
\r
418 if (nIndex < 0 || m_oFunctionDefinition.GetCount() <= nIndex) {
\r
422 CFunctionDefinition *pFunctionDefinition = (CFunctionDefinition *)m_oFunctionDefinition.GetAt(m_oFunctionDefinition.FindIndex(nIndex));
\r
423 if (pFunctionDefinition) {
\r
424 pFunctionDefinition->RemoveKey(nAppID, nType, nKey);
\r
428 void CDotXkeymacs::RemoveKey(const int nAppID, const int nType, const int nKey)
\r
430 for (int nIndex = 0; nIndex < m_oFunctionDefinition.GetCount(); ++nIndex) {
\r
431 RemoveKey(nIndex, nAppID, nType, nKey);
\r
435 LPCTSTR CDotXkeymacs::GetLanguage()
\r
437 LPCTSTR szLanguage = _T("unknown");
\r
439 TCHAR lptstrFilename[MAX_PATH] = {'\0'};
\r
440 TCHAR windir[MAX_PATH] = "";
\r
442 _tgetenv_s(&len, windir, _T("windir"));
\r
443 _tmakepath_s(lptstrFilename, NULL, windir, _T("explorer"), _T("exe"));
\r
444 DWORD dwLen = GetFileVersionInfoSize(lptstrFilename, NULL);
\r
447 LPVOID lpData = malloc(dwLen);
\r
449 if (lpData && GetFileVersionInfo(lptstrFilename, NULL, dwLen, lpData)) {
\r
454 UINT cbTranslate = 0;
\r
456 if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate) && sizeof(Translate) <= cbTranslate) {
\r
457 for (int i = 0; i < _countof(Languages); ++i) {
\r
458 if (Languages[i].wLanguage == lpTranslate->wLanguage) {
\r
459 szLanguage = Languages[i].szLanguage;
\r