OSDN Git Service

Add .vs/ to .gitignore
[xkeymacs/xkeymacs.git] / xkeymacsdll / Commands.cpp
1 // Commands.cpp: implementation of the CCommands class\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "Commands.h"\r
6 #include "CmdTable.h"\r
7 #include "xkeymacsdll.h"\r
8 #include "Utils.h"\r
9 #include "../xkeymacs/resource.h"\r
10 #include <math.h>\r
11 #include <Imm.h>\r
12 \r
13 KbdMacro CCommands::m_KbdMacro;\r
14 OriginalWindowPosition CCommands::m_OriginalWindowPosition[MAX_WINDOW] = {'\0'};\r
15 CArray<CClipboardSnap *, CClipboardSnap *> CCommands::m_oClipboardData;\r
16 BOOL CCommands::m_bTemporarilyDisableXKeymacs = FALSE;\r
17 BOOL CCommands::m_bFirstFindDialog = FALSE;\r
18 BOOL CCommands::m_bC_ = FALSE;\r
19 int (*CCommands::m_LastKillCommand)() = NULL;\r
20 int (*CCommands::m_LastCommand)() = NULL;\r
21 SEARCH_DIRECTION CCommands::m_SearchDirection = NA;\r
22 BOOL CCommands::m_bC_u = FALSE;\r
23 BOOL CCommands::m_bNegativeNumericArgument = FALSE;\r
24 BOOL CCommands::m_bDefaultNumericArgument = TRUE;\r
25 BOOL CCommands::m_bM_x = FALSE;\r
26 BOOL CCommands::m_bM_ = FALSE;\r
27 BOOL CCommands::m_bC_x = FALSE;\r
28 BOOL CCommands::m_bSetMark = FALSE;\r
29 DWORD CCommands::m_nNumericArgument = 1;\r
30 BOOL CCommands::m_bIsSu = FALSE;\r
31 \r
32 void CCommands::DepressKey(BYTE bVk)\r
33 {\r
34         CXkeymacsDll::DepressKey(bVk);\r
35 }\r
36 \r
37 void CCommands::ReleaseKey(BYTE bVk)\r
38 {\r
39         CXkeymacsDll::ReleaseKey(bVk);\r
40 }\r
41 \r
42 void CCommands::Kdu(BYTE bVk1, BYTE bVk2, BYTE bVk3, BYTE bVk4)\r
43 {\r
44         UINT before = CXkeymacsDll::GetModifierState();\r
45         if (CXkeymacsDll::Get326Compatible() || CUtils::IsAtok())\r
46                 before &= ~SHIFT;\r
47         CXkeymacsDll::SetModifierState(0, before);\r
48 \r
49         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
50         if (bVk2)\r
51                 CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);\r
52         if (bVk3)\r
53                 CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);\r
54         if (bVk4)\r
55                 CXkeymacsDll::Kdu(bVk4, m_nNumericArgument);\r
56 \r
57         CXkeymacsDll::SetModifierState(before, 0);\r
58 }\r
59 \r
60 void CCommands::SdKduSu(BYTE bVk1, BYTE bVk2, BYTE bVk3, BYTE bVk4)\r
61 {\r
62         UINT before = CXkeymacsDll::GetModifierState();\r
63         CXkeymacsDll::SetModifierState(SHIFT, before);\r
64 \r
65         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
66         if (bVk2)\r
67                 CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);\r
68         if (bVk3)\r
69                 CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);\r
70         if (bVk4)\r
71                 CXkeymacsDll::Kdu(bVk4, m_nNumericArgument);\r
72 \r
73         if (!(before & SHIFT) && CUtils::IsShuriken()) {\r
74                 m_bIsSu = TRUE;\r
75                 before |= SHIFT;\r
76         }\r
77         CXkeymacsDll::SetModifierState(before, SHIFT);\r
78 }\r
79 \r
80 void CCommands::Su()\r
81 {\r
82         if (m_bIsSu) {\r
83                 ReleaseKey(VK_SHIFT);\r
84                 m_bIsSu = FALSE;\r
85         }\r
86 }\r
87 \r
88 void CCommands::CdKduCu(BYTE bVk1, BYTE bVk2)\r
89 {\r
90         UINT before = CXkeymacsDll::GetModifierState();\r
91         CXkeymacsDll::SetModifierState(CONTROL, before);\r
92 \r
93         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
94         if (bVk2)\r
95                 CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);\r
96 \r
97         CXkeymacsDll::SetModifierState(before, CONTROL);\r
98 }\r
99 \r
100 void CCommands::CdSdKduSuCu(BYTE bVk)\r
101 {\r
102         UINT before = CXkeymacsDll::GetModifierState();\r
103         CXkeymacsDll::SetModifierState(SHIFT | CONTROL, before);\r
104 \r
105         CXkeymacsDll::Kdu(bVk, m_nNumericArgument);\r
106 \r
107         CXkeymacsDll::SetModifierState(before, SHIFT | CONTROL);\r
108 }\r
109 \r
110 void CCommands::AdKduAu(BYTE bVk1, BYTE bVk2, BYTE bVk3)\r
111 {\r
112         UINT before = CXkeymacsDll::GetModifierState();\r
113         CXkeymacsDll::SetModifierState(META, before);\r
114 \r
115         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
116         if (bVk2)\r
117                 CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);\r
118         if (bVk3)\r
119                 CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);\r
120 \r
121         CXkeymacsDll::SetModifierState(before, META);\r
122 }\r
123 \r
124 void CCommands::AdSdKduSuAu(BYTE bVk1)\r
125 {\r
126         UINT before = CXkeymacsDll::GetModifierState();\r
127         CXkeymacsDll::SetModifierState(SHIFT | META, before);\r
128 \r
129         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
130 \r
131         CXkeymacsDll::SetModifierState(before, SHIFT | META);\r
132 }\r
133 \r
134 void CCommands::AdCdKduCuAu(BYTE bVk1)\r
135 {\r
136         UINT before = CXkeymacsDll::GetModifierState();\r
137         CXkeymacsDll::SetModifierState(CONTROL | META, before);\r
138 \r
139         CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);\r
140 \r
141         CXkeymacsDll::SetModifierState(before, CONTROL | META);\r
142 }\r
143 \r
144 // C-a: Home\r
145 int CCommands::BeginningOfLine()\r
146 {\r
147         int nNumericArgument = 1;\r
148         if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {\r
149                 nNumericArgument = m_nNumericArgument;\r
150                 if (m_bNegativeNumericArgument) {\r
151                         if (nNumericArgument) {\r
152                                 nNumericArgument *= -1;\r
153                         } else {\r
154                                 nNumericArgument = -1;\r
155                         }\r
156                 }\r
157         }\r
158         ClearNumericArgument();\r
159 \r
160         if (nNumericArgument <= 0) {\r
161                 nNumericArgument = -1 * nNumericArgument + 1;\r
162                 while (nNumericArgument--) {\r
163                         ReleaseKey(VK_CONTROL); // why?\r
164                         while (MoveCaret(VK_UP) != GOTO_HOOK);\r
165                 }\r
166                 ReleaseKey(VK_CONTROL); // why?\r
167                 while (MoveCaret(VK_HOME) != GOTO_HOOK);\r
168                 DepressKey(VK_CONTROL); // why?\r
169         } else if (nNumericArgument == 1) {\r
170                 return Reset(MoveCaret(VK_HOME));\r
171         } else if (2 <= nNumericArgument) {\r
172                 nNumericArgument -= 2;\r
173                 while (nNumericArgument--) {\r
174                         ReleaseKey(VK_CONTROL); // why?\r
175                         while (MoveCaret(VK_DOWN) != GOTO_HOOK);\r
176                 }\r
177                 ReleaseKey(VK_CONTROL); // why?\r
178                 while (MoveCaret(VK_END) != GOTO_HOOK);\r
179                 while (MoveCaret(VK_RIGHT) != GOTO_HOOK);\r
180                 DepressKey(VK_CONTROL); // why?\r
181         } else {\r
182                 ASSERT(0);\r
183         }\r
184         return Reset(GOTO_HOOK);\r
185 }\r
186 \r
187 // C-b: Left\r
188 int CCommands::BackwardChar()\r
189 {\r
190         if (m_bNegativeNumericArgument) {\r
191                 m_bNegativeNumericArgument = FALSE;\r
192                 return ForwardChar();\r
193         }\r
194 \r
195         return Reset(MoveCaret(VK_LEFT));\r
196 }\r
197 \r
198 // M-b: backward-word\r
199 int CCommands::BackwardWord()\r
200 {\r
201         if (m_bNegativeNumericArgument) {\r
202                 m_bNegativeNumericArgument = FALSE;\r
203                 return ForwardWord();\r
204         }\r
205 \r
206         return Reset(MoveCaret(VK_LEFT, TRUE));\r
207 }\r
208 \r
209 // C-e: End\r
210 int CCommands::EndOfLine()\r
211 {\r
212         int nNumericArgument = 1;\r
213         if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {\r
214                 nNumericArgument = m_nNumericArgument;\r
215                 if (m_bNegativeNumericArgument) {\r
216                         if (nNumericArgument) {\r
217                                 nNumericArgument *= -1;\r
218                         } else {\r
219                                 nNumericArgument = -1;\r
220                         }\r
221                 }\r
222         }\r
223         ClearNumericArgument();\r
224         if (nNumericArgument <= 0) {\r
225                 nNumericArgument *= -1;\r
226                 while (nNumericArgument--) {\r
227                         ReleaseKey(VK_CONTROL); // why?\r
228                         while (MoveCaret(VK_UP) != GOTO_HOOK);\r
229                 }\r
230                 ReleaseKey(VK_CONTROL); // why?\r
231                 while (MoveCaret(VK_HOME) != GOTO_HOOK);\r
232                 while (MoveCaret(VK_LEFT) != GOTO_HOOK);\r
233                 DepressKey(VK_CONTROL); // why?\r
234         } else if (nNumericArgument == 1) {\r
235                 return (MoveCaret(VK_END));\r
236         } else if (2 <= nNumericArgument) {\r
237                 --nNumericArgument;\r
238                 while (nNumericArgument--) {\r
239                         ReleaseKey(VK_CONTROL); // why?\r
240                         while (MoveCaret(VK_DOWN) != GOTO_HOOK);\r
241                 }\r
242                 ReleaseKey(VK_CONTROL); // why?\r
243                 while (MoveCaret(VK_END) != GOTO_HOOK);\r
244                 DepressKey(VK_CONTROL); // why?\r
245         } else {\r
246                 ASSERT(0);\r
247         }\r
248         return Reset(GOTO_HOOK);\r
249 }\r
250 \r
251 // C-f: Right\r
252 int CCommands::ForwardChar()\r
253 {\r
254 //      TCHAR szWindowText[WINDOW_TEXT_LENGTH] = {'\0'};\r
255 //      GetWindowText(GetForegroundWindow(), szWindowText, sizeof(szWindowText));\r
256 //      CUtils::Log("C-f: %s", szWindowText);\r
257 \r
258         if (m_bNegativeNumericArgument) {\r
259                 m_bNegativeNumericArgument = FALSE;\r
260                 return BackwardChar();\r
261         }\r
262 \r
263         return Reset(MoveCaret(VK_RIGHT));\r
264 }\r
265 \r
266 // M-f: forward-word\r
267 int CCommands::ForwardWord()\r
268 {\r
269         if (m_bNegativeNumericArgument) {\r
270                 m_bNegativeNumericArgument = FALSE;\r
271                 return BackwardWord();\r
272         }\r
273 \r
274         return Reset(MoveCaret(VK_RIGHT, TRUE));\r
275 }\r
276 \r
277 // C-n: Down\r
278 int CCommands::NextLine()\r
279 {\r
280 //      CUtils::Log(_T("C-n"));\r
281 \r
282         if (m_bNegativeNumericArgument) {\r
283                 m_bNegativeNumericArgument = FALSE;\r
284                 return PreviousLine();\r
285         }\r
286 \r
287         return Reset(MoveCaret(VK_DOWN));\r
288 }\r
289 \r
290 // C-o: open-line\r
291 int CCommands::OpenLine()\r
292 {\r
293         static const int DEFAULT_NUMERIC_ARGUMENT = -1;\r
294         static int nNumericArgument = DEFAULT_NUMERIC_ARGUMENT;\r
295 \r
296         if (nNumericArgument == DEFAULT_NUMERIC_ARGUMENT) {\r
297                 nNumericArgument = m_nNumericArgument;\r
298                 ClearNumericArgument();\r
299         }\r
300 \r
301         if (CUtils::IsHidemaru()\r
302          || CUtils::IsTuruKameMail()) {\r
303                 static int nStep = 0;\r
304 \r
305                 switch (nStep) {\r
306                 case 0:\r
307                         CdKduCu('M');\r
308                         nStep = 1;\r
309                         return Reset(GOTO_RECURSIVE);\r
310                 case 1:\r
311                         nStep = 0;\r
312                         Kdu(VK_UP, VK_END);\r
313                         if (--nNumericArgument) {\r
314                                 return Reset(GOTO_RECURSIVE);\r
315                         }\r
316                         break;\r
317                 }\r
318         } else {\r
319                 while (nNumericArgument--) {\r
320                         Kdu(VK_RETURN, VK_UP, VK_END);\r
321                 }\r
322         }\r
323 \r
324         nNumericArgument = DEFAULT_NUMERIC_ARGUMENT;\r
325         return Reset(GOTO_HOOK);\r
326 }\r
327 \r
328 // C-p: Up\r
329 int CCommands::PreviousLine()\r
330 {\r
331         if (m_bNegativeNumericArgument) {\r
332                 m_bNegativeNumericArgument = FALSE;\r
333                 return NextLine();\r
334         }\r
335 \r
336         return Reset(MoveCaret(VK_UP));\r
337 }\r
338 \r
339 // M-%\r
340 int CCommands::QueryReplace()\r
341 {\r
342         ClearNumericArgument();\r
343         if (CUtils::IsBecky()) {\r
344                 CdKduCu('Q', 'A');\r
345         } else if (CUtils::IsEclipse()\r
346                         || CUtils::IsInternetExplorer()\r
347                         || CUtils::IsLotusNotes()\r
348                         || CUtils::IsSleipnir()) {\r
349                 CdKduCu('F');\r
350         } else if (CUtils::IsAutla()\r
351                         || CUtils::IsBorlandCppBuilder()\r
352                         || CUtils::IseMemoPad()\r
353                         || CUtils::IsNami2000()\r
354                         || CUtils::IsStoryEditor()) {\r
355                 CdKduCu('R');\r
356         } else if (CUtils::IsEdLeaf()) {\r
357                 AdKduAu('E', 'E');\r
358         } else if (CUtils::IsPHPEditor()) {\r
359                 AdKduAu('S', 'F');\r
360         } else {\r
361                 CdKduCu('H');\r
362         }\r
363         return Reset(GOTO_HOOK);\r
364 }\r
365 \r
366 // C-M-%\r
367 int CCommands::QueryReplaceRegexp()\r
368 {\r
369         return QueryReplace();\r
370 }\r
371 \r
372 // M-<:\r
373 int CCommands::BeginningOfBuffer()\r
374 {\r
375         ClearNumericArgument();\r
376         return Reset(MoveCaret(VK_HOME, TRUE));\r
377 }\r
378 \r
379 // M->:\r
380 int CCommands::EndOfBuffer()\r
381 {\r
382         ClearNumericArgument();\r
383         return Reset(MoveCaret(VK_END, TRUE));\r
384 }\r
385 \r
386 // C-h: Back space\r
387 int CCommands::DeleteBackwardChar()\r
388 {\r
389         if (m_bNegativeNumericArgument) {\r
390                 m_bNegativeNumericArgument = FALSE;\r
391                 return DeleteChar();\r
392         }\r
393 \r
394         Kdu(VK_BACK);\r
395         m_bSetMark = FALSE;\r
396         return Reset(GOTO_HOOK);\r
397 }\r
398 \r
399 // C-d: Delete\r
400 int CCommands::DeleteChar()\r
401 {\r
402         if (m_bNegativeNumericArgument) {\r
403                 m_bNegativeNumericArgument = FALSE;\r
404                 return DeleteBackwardChar();\r
405         }\r
406 \r
407         m_bSetMark = FALSE;\r
408         Kdu(VK_DELETE);\r
409         return Reset(GOTO_HOOK);\r
410 }\r
411 \r
412 int CCommands::KillLineForAllFormat()\r
413 {\r
414         return KillLine(TRUE, KillLineForAllFormat);\r
415 }\r
416 \r
417 // C-k: Shift-End, Shift-Delete, if the cursor is not at EOL (is End Of Line)\r
418 //              Shift-Right, Cut, if the cursor is at EOL\r
419 int CCommands::KillLine()\r
420 {\r
421         return KillLine(FALSE);\r
422 }\r
423 \r
424 int CCommands::KillLine(BOOL bAllFormat, int (*pCommand)())\r
425 {\r
426         static BOOL bKeepAllFormat = FALSE;\r
427 \r
428         // Do not try to do these command at once.\r
429         // Clipboard has old data till you go out this function.\r
430         static int nStep = 0;\r
431         static int nPrevStep = 0;\r
432         static int nRepeat = 0;\r
433         static CString szClipboardText;\r
434         static BOOL bContinuous = FALSE;\r
435         static BOOL bTopOfFile = FALSE;\r
436 \r
437         if (nStep == nPrevStep) {\r
438                 ++nRepeat;\r
439         } else {\r
440                 nRepeat = 0;\r
441                 nPrevStep = nStep;\r
442         }\r
443 \r
444         switch (nStep) {\r
445         case 0:         // Clear Selection and get next character to confirm the cursor is at the EOF or not.\r
446 //              CUtils::Log(_T("C-k: 0"));\r
447                 bTopOfFile = FALSE;\r
448 \r
449                 if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {\r
450                         if (m_bNegativeNumericArgument || m_nNumericArgument == 0) {\r
451                                 // Shift+Up x -n Shift+Home Ctrl+X\r
452                                 SdKduSu(VK_UP);\r
453                                 ClearNumericArgument();\r
454                                 SdKduSu(VK_HOME);\r
455                         } else {\r
456                                 // Shift+Down x (n - 1) Shift+End Shift+Right Ctrl+X\r
457                                 --m_nNumericArgument;\r
458                                 SdKduSu(VK_DOWN);\r
459                                 ClearNumericArgument();\r
460                                 SdKduSu(VK_END, VK_RIGHT);\r
461                         }\r
462                         CdKduCu('X');\r
463                         nStep = 6;\r
464                         return Reset(GOTO_RECURSIVE);\r
465                 }\r
466 \r
467                 if (m_LastCommand == pCommand) {\r
468                         bContinuous = TRUE;\r
469                 } else {\r
470                         bContinuous = FALSE;\r
471                         if (m_bSetMark) {\r
472                                 m_bSetMark = FALSE;\r
473                                 DeactivateMark();\r
474                         }\r
475                 }\r
476 \r
477                 if (CUtils::IsDirector()\r
478                  || CUtils::IsEudora()) {\r
479                         nStep = 1;\r
480                         return Reset(GOTO_RECURSIVE);\r
481                 }\r
482 \r
483                 if (CUtils::IsLotus123()) {\r
484                         // C-k: Shift-End, Control-x\r
485                         SdKduSu(VK_END);\r
486                         CdKduCu('X');\r
487                         return Reset(GOTO_HOOK);\r
488                 }\r
489 \r
490                 CaptureClipboardData(0, CUtils::IsLotusNotes());\r
491 \r
492                 if (!CopyNextCharacter()) {\r
493 //                      CUtils::Log(_T("Error: CopyNextCharacter"));\r
494                         return Reset(GOTO_DO_NOTHING);\r
495                 }\r
496 \r
497                 nStep = 4;\r
498                 return Reset(GOTO_RECURSIVE);\r
499         case 1:         // Get back character to confirm the cursor is at the TOF or not only for Macromedia Director.\r
500 //              CUtils::Log(_T("C-k: 1"));\r
501                 nStep = 0;\r
502                 CaptureClipboardData();\r
503 \r
504                 if (!CopyBackCharacter()) {\r
505                         return Reset(GOTO_DO_NOTHING);\r
506                 }\r
507 \r
508                 nStep = 2;\r
509                 return Reset(GOTO_RECURSIVE);\r
510         case 2:         // Confirm the cursor is at the TOF or not only for Macromedia Director.\r
511                 {\r
512 //                      CUtils::Log(_T("C-k: 2"));\r
513                         nStep = 0;\r
514                         Su();\r
515 \r
516                         if (CUtils::IsTOF()) {\r
517                                 bTopOfFile = TRUE;\r
518                         }\r
519 \r
520                         // CopyBackCharacter move cursor right\r
521                         Kdu(VK_LEFT);\r
522                         RestoreClipboardData();\r
523 \r
524                         nStep = 3;\r
525                         return Reset(GOTO_RECURSIVE);\r
526                 }\r
527         case 3:         // Get next character to confirm the cursor is at the EOF or not.\r
528 //              CUtils::Log(_T("C-k: 3"));\r
529                 nStep = 0;\r
530 \r
531                 if (CUtils::IsLotus123()) {\r
532                         // C-k: Shift-End, Control-x\r
533                         SdKduSu(VK_END);\r
534                         CdKduCu('X');\r
535                         return Reset(GOTO_HOOK);\r
536                 }\r
537 \r
538                 CaptureClipboardData();\r
539 \r
540                 if (!CopyNextCharacter()) {\r
541 //                      CUtils::Log(_T("Error: CopyNextCharacter"));\r
542                         return Reset(GOTO_DO_NOTHING);\r
543                 }\r
544 \r
545                 nStep = 4;\r
546                 return Reset(GOTO_RECURSIVE);\r
547         case 4:         // Cut line\r
548 //              CUtils::Log(_T("C-k: 4"));\r
549                 nStep = 0;\r
550                 Su();\r
551 \r
552                 if ((CUtils::IsDirector()\r
553                   || CUtils::IsEudora())\r
554                  && !bTopOfFile) {\r
555                         // CopyNextCharacter move cursor left\r
556                         Kdu(VK_RIGHT);\r
557                 }\r
558 \r
559                 CUtils::GetClipboardText(szClipboardText);\r
560 //              CUtils::Log(_T("%x, %s"), szClipboardText.GetAt(0), szClipboardText);\r
561 \r
562                 if (szClipboardText.IsEmpty()) {        // EOF\r
563 //                      CUtils::Log(_T("C-k: EOF"));\r
564                         if (CUtils::IsLotusWordPro()\r
565                          || CUtils::IsMicrosoftFrontPage()\r
566                          || CUtils::IsMicrosoftWord()) {\r
567                                 SdKduSu(VK_RIGHT);\r
568                                 Cut_();\r
569                                 nStep = 5;\r
570                                 return Reset(GOTO_RECURSIVE);\r
571                         } else if (CUtils::IsLotusNotes()) {\r
572                                 Kdu(VK_END);\r
573                                 ReleaseKey(VK_CONTROL); // Why is it needed?\r
574                                 SdKduSu(VK_DOWN, VK_HOME);\r
575                                 Copy_();\r
576                                 DepressKey(VK_CONTROL); // Why is it needed?\r
577                                 nStep = 5;\r
578                                 return Reset(GOTO_RECURSIVE);\r
579                         } else {\r
580                                 // default\r
581                                 Kdu(VK_RIGHT);\r
582                                 RestoreClipboardData();\r
583 //                              CUtils::Log(_T("C-k: 4-1"));\r
584                                 return Reset(GOTO_HOOK);\r
585                         }\r
586                 }\r
587 \r
588                 if (szClipboardText.GetAt(0) != VK_RETURN) {\r
589 //                      CUtils::Log(_T("C-k: szClipboardText.GetAt(0) != VK_RETURN"));\r
590                         if (CUtils::IsDirector()) {\r
591                                 ReleaseKey(VK_CONTROL);\r
592                                 SdKduSu(VK_END);\r
593                                 Copy_();\r
594                                 DepressKey(VK_CONTROL);\r
595                         } else if (CUtils::IseMemoPad()\r
596                                         || CUtils::IsHidemaru() // Hidemaru clears mark after copy.\r
597                                         || CUtils::IsOpenOffice()\r
598                                         || CUtils::IsTuruKameMail()) {\r
599                                 SdKduSu(VK_END);\r
600                                 Cut_();\r
601                         } else if (CUtils::IsLotusWordPro()\r
602                                         || CUtils::IsMicrosoftWord()) {\r
603                                 SdKduSu(VK_END, VK_LEFT);\r
604                                 Cut_();\r
605                         } else {\r
606                                 SdKduSu(VK_END);\r
607                                 Copy_();\r
608                         }\r
609                 } else {        // EOL\r
610 //                      CUtils::Log(_T("C-k: EOL"));\r
611                         if (CUtils::IsDirector()) {\r
612                                 ReleaseKey(VK_CONTROL);\r
613                                 SdKduSu(VK_RIGHT);\r
614                                 Copy_();\r
615                                 DepressKey(VK_CONTROL);\r
616                         } else if (CUtils::IsEclipse()\r
617                                         || CUtils::IsStoryEditor()) {\r
618                                 SdKduSu(VK_RIGHT);\r
619                                 Copy_();\r
620                         } else if (CUtils::IseMemoPad()\r
621                                         || CUtils::IsHidemaru() // Hidemaru clears mark after copy.\r
622                                         || CUtils::IsOpenOffice()\r
623                                         || CUtils::IsTuruKameMail()) {\r
624                                 SdKduSu(VK_RIGHT);\r
625                                 Cut_();\r
626                         } else {\r
627                                 SdKduSu(VK_RIGHT);\r
628                                 Copy_();\r
629                         }\r
630                 }\r
631 \r
632                 nStep = 5;\r
633                 return Reset(GOTO_RECURSIVE);\r
634         case 5:         // input return if XKeymacs not only line but also line feed code and set the kill-line data on the clipboard.\r
635 //              CUtils::Log(_T("C-k: 5"));\r
636                 nStep = 0;\r
637 \r
638                 if (1000 < nRepeat) {\r
639 //                      CUtils::Log(_T("C-k: 5-1"));\r
640                         nStep = 6;\r
641                         return Reset(GOTO_RECURSIVE);\r
642                 }\r
643 \r
644 //              CUtils::Log(_T("C-k: 5-1-1"));\r
645                 Su();\r
646 //              CUtils::Log(_T("C-k: 5-1-2"));\r
647                 CaptureClipboardData(1, CUtils::IsLotusNotes());\r
648 //              CUtils::Log(_T("C-k: 5-1-3"));\r
649 \r
650 //              if (m_oClipboardData.GetSize() < 1 || m_oClipboardData[0] == NULL) {\r
651 ////                    CUtils::Log(_T("C-k: 5-2"));\r
652 //                      nStep = 6;\r
653 //                      return Reset(GOTO_RECURSIVE);\r
654 //              } else if (m_oClipboardData.GetSize() < 2 || m_oClipboardData[1] == NULL) {\r
655 ////                    CUtils::Log(_T("C-k: 5-3"));\r
656 //                      nStep = 5;\r
657 //                      return Reset(GOTO_RECURSIVE);\r
658 //              }\r
659 \r
660                 if (CUtils::IseMemoPad()\r
661                  || CUtils::IsHidemaru()        // Hidemaru clears mark after copy.\r
662                  || CUtils::IsLotusWordPro()\r
663                  || CUtils::IsMicrosoftWord ()\r
664                  || CUtils::IsOpenOffice()\r
665                  || CUtils::IsTuruKameMail()) {\r
666                         // do nothing\r
667 //                      CUtils::Log(_T("C-k: 5-4"));\r
668                 } else {\r
669                         // This changed will be required to avoid Thunderbird bug.\r
670                         // if (0 < FindReturnFromClipboardData(1) && !CUtils::IsExcel() && !CUtils::IsThunderbird()) {\r
671                         if (0 < FindReturnFromClipboardData(1) && !CUtils::IsExcel()) {\r
672 //                              CUtils::Log(_T("C-k: 5-5"));\r
673                                 SdKduSu(VK_LEFT);\r
674                                 Copy_();\r
675                                 nStep = 5;\r
676                                 return Reset(GOTO_RECURSIVE);\r
677                         } else {\r
678                                 Kdu(VK_DELETE);\r
679 //                              CUtils::Log(_T("C-k: 5-6"));\r
680                         }\r
681                 }\r
682 \r
683                 bKeepAllFormat = bAllFormat;\r
684                 if (!bKeepAllFormat\r
685                  && !m_oClipboardData[1]->IsAllMergeableFormat()) {\r
686 //                      CUtils::Log(_T("C-k: 5-7"));\r
687                         bKeepAllFormat = TRUE;\r
688                 }\r
689 \r
690                 if (bContinuous && !bKeepAllFormat) {\r
691 //                      CUtils::Log(_T("C-k: 5-8"));\r
692                         *m_oClipboardData[0] += *m_oClipboardData[1];\r
693                 } else {\r
694 //                      CUtils::Log(_T("C-k: 5-9"));\r
695                         *m_oClipboardData[0] = *m_oClipboardData[1];\r
696                 }\r
697                 RestoreClipboardData(0);\r
698 \r
699 //              CUtils::Log(_T("C-k: 5-10"));\r
700                 nStep = 6;\r
701                 return Reset(GOTO_RECURSIVE);\r
702         case 6:         // add data into kill-ring\r
703 //              CUtils::Log(_T("C-k: 6"));\r
704                 nStep = 0;\r
705                 Su();\r
706 \r
707                 if (bContinuous && bKeepAllFormat) {\r
708                         CXkeymacsDll::AddKillRing(FALSE);\r
709                 } else {\r
710                         CXkeymacsDll::AddKillRing();\r
711                 }\r
712                 return Reset(GOTO_HOOK);\r
713                 break;\r
714         }\r
715 \r
716         return Reset(GOTO_HOOK);\r
717 }\r
718 \r
719 // C-x u: C-/: C-_: Ctrl-Z\r
720 int CCommands::Undo()\r
721 {\r
722         if (CUtils::IsMicrosoftWord()) {\r
723                 UINT before = CXkeymacsDll::GetModifierState();\r
724                 CXkeymacsDll::SetModifierState(CONTROL, before);\r
725                 PostMessage(GetFocus(), WM_KEYDOWN, 'Z', 0);\r
726                 CXkeymacsDll::SetModifierState(before, CONTROL);\r
727         } else\r
728                 CdKduCu('Z');\r
729         return Reset(GOTO_HOOK);\r
730 }\r
731 \r
732 // C-x C-c: Alt-Space, Alt-C\r
733 int CCommands::SaveBuffersKillEmacs()\r
734 {\r
735         ClearNumericArgument();\r
736 \r
737         HWND hWnd = GetForegroundWindow();\r
738         if (hWnd) {\r
739                 OriginalWindowPosition *pPos = GetOriginalWindowPosition(hWnd);\r
740                 if (pPos && pPos->bMax[ROLL_UP_UNROLL]) {\r
741                         RollUpUnroll();\r
742                 }\r
743         }\r
744 \r
745         if (AppName::IsConsole()) {\r
746                 SystemMenu(CMD_CLOSE);\r
747         } else if (CUtils::IsExplorer()) {\r
748                 ReleaseKey(VK_CONTROL);\r
749                 AdKduAu(VK_F4);\r
750         } else if (CUtils::IsInternetExplorer()\r
751                         || CUtils::IsJavaW()) {\r
752                 AdKduAu(VK_F4);\r
753         } else {\r
754                 AdKduAu(VK_SPACE, 'C');\r
755         }\r
756         return Reset(GOTO_HOOK);\r
757 }\r
758 \r
759 // C-z: Alt-Space, Alt-N\r
760 int CCommands::IconifyOrDeiconifyFrame()\r
761 {\r
762         ClearNumericArgument();\r
763         if (AppName::IsConsole()) {\r
764                 SystemMenu(CMD_MINIMIZE);\r
765         } else {\r
766                 AdKduAu(VK_SPACE, 'N');\r
767         }\r
768         return Reset(GOTO_HOOK);\r
769 }\r
770 \r
771 int CCommands::Restore()\r
772 {\r
773         ClearNumericArgument();\r
774         if (CUtils::IsConsole()) {\r
775                 SystemMenu(CMD_RESTORE);\r
776         } else {\r
777                 AdKduAu(VK_SPACE, 'R');\r
778         }\r
779         return Reset(GOTO_HOOK);\r
780 }\r
781 \r
782 int CCommands::Move()\r
783 {\r
784         ClearNumericArgument();\r
785         if (CUtils::IsConsole()) {\r
786                 SystemMenu(CMD_MOVE);\r
787         } else {\r
788                 AdKduAu(VK_SPACE, 'M');\r
789         }\r
790         return Reset(GOTO_HOOK);\r
791 }\r
792 \r
793 int CCommands::Size()\r
794 {\r
795         ClearNumericArgument();\r
796         if (CUtils::IsConsole()) {\r
797                 SystemMenu(CMD_SIZE);\r
798         } else {\r
799                 AdKduAu(VK_SPACE, 'S');\r
800         }\r
801         return Reset(GOTO_HOOK);\r
802 }\r
803 \r
804 int CCommands::Minimize()\r
805 {\r
806         return IconifyOrDeiconifyFrame();\r
807 }\r
808 \r
809 int CCommands::Maximize()\r
810 {\r
811         ClearNumericArgument();\r
812 \r
813         HWND hWnd = GetForegroundWindow();\r
814         if (!hWnd) {\r
815                 return Reset(GOTO_HOOK);\r
816         }\r
817 \r
818         WINDOWPLACEMENT wndpl = {sizeof(WINDOWPLACEMENT)};\r
819         if (!GetWindowPlacement(hWnd, &wndpl)) {\r
820                 return Reset(GOTO_HOOK);\r
821         }\r
822 \r
823         if (wndpl.showCmd == SW_SHOWMAXIMIZED) {\r
824                 wndpl.showCmd = SW_RESTORE;\r
825         } else {\r
826                 wndpl.showCmd = SW_SHOWMAXIMIZED;\r
827         }\r
828 \r
829         SetWindowPlacement(hWnd, &wndpl);\r
830         return Reset(GOTO_HOOK);\r
831 }\r
832 \r
833 OriginalWindowPosition* CCommands::GetOriginalWindowPosition(HWND hWnd)\r
834 {\r
835         for (int i = 0; i < MAX_WINDOW; ++i) {\r
836                 if (m_OriginalWindowPosition[i].hWnd == hWnd) {\r
837                         return &m_OriginalWindowPosition[i];\r
838                 }\r
839         }\r
840 \r
841         for (int j = 0; j < MAX_WINDOW; ++j) {\r
842                 if (m_OriginalWindowPosition[j].hWnd == 0) {\r
843                         m_OriginalWindowPosition[j].hWnd = hWnd;\r
844                         memset(&m_OriginalWindowPosition[(j + 1) % MAX_WINDOW], 0, sizeof(OriginalWindowPosition));\r
845                         return &m_OriginalWindowPosition[j];\r
846                 }\r
847         }\r
848 \r
849         ASSERT(0);\r
850         return NULL;\r
851 }\r
852 \r
853 int CCommands::Maximize(MAXIMIZE_DIRECTION direction)\r
854 {\r
855         ClearNumericArgument();\r
856 \r
857         HWND hWnd = GetForegroundWindow();\r
858         if (!hWnd) {\r
859                 return Reset(GOTO_HOOK);\r
860         }\r
861 \r
862         RECT workarea = {'\0'};\r
863         if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0)) {\r
864                 return Reset(GOTO_HOOK);\r
865         }\r
866 \r
867         RECT window = {'\0'};\r
868         if (!GetWindowRect(hWnd, &window)) {\r
869                 return Reset(GOTO_HOOK);\r
870         }\r
871 \r
872         OriginalWindowPosition *pPos = GetOriginalWindowPosition(hWnd);\r
873         if (!pPos) {\r
874                 return Reset(GOTO_HOOK);\r
875         }\r
876 \r
877         int X = window.left;\r
878         int Y = window.top;\r
879         int nWidth = window.right - window.left;\r
880         int nHeight = window.bottom - window.top;\r
881 \r
882         switch (direction) {\r
883         case VERTICAL:\r
884                 if (pPos->bMax[direction]) {\r
885                         Y = pPos->nOriginalY;\r
886                         nHeight = pPos->nOriginalHeight;\r
887                 } else {\r
888                         pPos->nOriginalY = Y;\r
889                         pPos->nOriginalHeight = nHeight;\r
890 \r
891                         Y = workarea.top;\r
892                         nHeight = workarea.bottom - workarea.top;\r
893                 }\r
894                 break;\r
895         case HORIZONTAL:\r
896                 if (pPos->bMax[direction]) {\r
897                         X = pPos->nOriginalX;\r
898                         nWidth = pPos->nOriginalWidth;\r
899                 } else {\r
900                         pPos->nOriginalX = X;\r
901                         pPos->nOriginalWidth = nWidth;\r
902 \r
903                         X = workarea.left;\r
904                         nWidth = workarea.right - workarea.left;\r
905                 }\r
906                 break;\r
907         case ROLL_UP_UNROLL:\r
908                 if (pPos->bMax[direction]) {\r
909                         nHeight = pPos->nOriginalHeight;\r
910                 } else {\r
911                         pPos->nOriginalHeight = nHeight;\r
912 \r
913                         nHeight = 0x15;\r
914                 }\r
915                 break;\r
916         default:\r
917                 ASSERT(0);\r
918                 break;\r
919         }\r
920 \r
921         MoveWindow(hWnd, X, Y, nWidth, nHeight, TRUE);\r
922         pPos->bMax[direction] = !pPos->bMax[direction];\r
923         return Reset(GOTO_HOOK);\r
924 }\r
925 \r
926 int CCommands::MaximizeVertically()\r
927 {\r
928         return Maximize(VERTICAL);\r
929 }\r
930 \r
931 int CCommands::MaximizeHorizontally()\r
932 {\r
933         return Maximize(HORIZONTAL);\r
934 }\r
935 \r
936 // C-Space: \r
937 int CCommands::SetMarkCommand()\r
938 {\r
939         ClearNumericArgument();\r
940         if (m_bSetMark) {\r
941                 DeactivateMark();\r
942         }\r
943         m_bSetMark = TRUE;\r
944 \r
945         if (CUtils::IsConsole()) {\r
946                 SystemMenuEdit(CMD_MARK);\r
947         }\r
948 \r
949         return Reset(GOTO_HOOK);\r
950 }\r
951 \r
952 // C-g: Keyboard quit\r
953 int CCommands::KeyboardQuit()\r
954 {\r
955         ClearNumericArgument();\r
956         if (CUtils::IsFindDialog()) {\r
957                 Kdu(VK_ESCAPE);\r
958         }\r
959         if (m_bSetMark) {\r
960                 m_bSetMark = FALSE;\r
961                 DeactivateMark();\r
962         }\r
963         SetTemporarilyDisableXKeymacs(FALSE);\r
964         return Reset(GOTO_HOOK);\r
965 }\r
966 \r
967 DWORD CCommands::ClickCaret()\r
968 {\r
969         HWND hWnd = GetFocus();\r
970 \r
971         POINT CaretPos = {'\0'};\r
972         if (!GetCaretPos(&CaretPos)) {\r
973                 return GetLastError();\r
974         }\r
975 //      CUtils::Log(_T("client: x = %d, y = %d"), CaretPos.x, CaretPos.y);\r
976 \r
977         if (!ClientToScreen(hWnd, &CaretPos)) {\r
978                 return GetLastError();\r
979         }\r
980 //      CUtils::Log(_T("screen: x = %d, y = %d"), CaretPos.x, CaretPos.y);\r
981 \r
982         POINT Delta = {0, 1};\r
983         if (CUtils::IsSakuraEditor()) {\r
984                 Delta.x = 1;\r
985                 Delta.y = 29;   // OK: 29-42 NG: 28, 43\r
986         }\r
987 \r
988         const POINT clickPoint = {CaretPos.x + Delta.x, CaretPos.y + Delta.y};\r
989         return Click(&clickPoint);\r
990 }\r
991 \r
992 DWORD CCommands::DeactivateMark()\r
993 {\r
994         if (CUtils::IsOpenOffice() || CUtils::IsVisualStudio() || CUtils::IsVisualBasicEditor()) {\r
995                 // GetCaretPos always returen (x,y) = (0,0) on OpenOffice and Visual Studio, so ...\r
996                 // GetCaretPos always returen (x,y) = (-2199,*) on M$ Excel VBE, so ...\r
997                 Kdu(VK_ESCAPE);\r
998                 return ERROR_SUCCESS;   // i.e. return 0;\r
999         }\r
1000         if (CUtils::IsFlash() || CUtils::IsInternetExplorer() || CUtils::IsMicrosoftPowerPoint() ||\r
1001                         CUtils::IsMicrosoftWord() || CUtils::IsSleipnir() || CUtils::IsThunderbird() || CUtils::IsFirefox()) {\r
1002                 // GetCaretPos always returen (x,y) = (0,0) on M$ Word and Thunderbird, so ...\r
1003                 // GetCaretPos always returen start point on IE (and Sleipnir that uses IE), so ...\r
1004                 Kdu(VK_RIGHT);\r
1005                 return ERROR_SUCCESS;   // i.e. return 0;\r
1006         }\r
1007         if (CUtils::IsDirector()) {\r
1008                 // GetCaretPos always returen (x,y) = (0,0) on Macromedia Director, so ...\r
1009                 Kdu(VK_RIGHT, VK_LEFT);\r
1010                 return ERROR_SUCCESS;   // i.e. return 0;\r
1011         }\r
1012         if (CUtils::IsExplorer()) {\r
1013                 AdKduAu('E', 'A');\r
1014                 AdKduAu('E', 'I');\r
1015                 return ERROR_SUCCESS;   // i.e. return 0;\r
1016         }\r
1017         return ClickCaret();\r
1018 }\r
1019 \r
1020 // C-x C-f: Alt-F, Alt-O\r
1021 int CCommands::FindFile()\r
1022 {\r
1023         ClearNumericArgument();\r
1024         if (CUtils::IsFlash()\r
1025          || CUtils::IsSleipnir()) {\r
1026                 CdKduCu('O');\r
1027         } else if (CUtils::IsVisualStudio()) {\r
1028                 AdKduAu('F', 'O', 'F');\r
1029         } else {\r
1030                 AdKduAu('F', 'O');\r
1031         }\r
1032         return Reset(GOTO_HOOK);\r
1033 }\r
1034 \r
1035 // C-i: Tab\r
1036 int CCommands::TabToTabStop()\r
1037 {\r
1038         ClearNumericArgument();\r
1039         if (m_bSetMark) {\r
1040                 m_bSetMark = FALSE;\r
1041         }\r
1042         Kdu(VK_TAB);\r
1043         return Reset(GOTO_HOOK);\r
1044 }\r
1045 \r
1046 // C-m: Enter\r
1047 int CCommands::Newline()\r
1048 {\r
1049         Kdu(VK_RETURN);\r
1050         return Reset(GOTO_HOOK);\r
1051 }\r
1052 \r
1053 // C-x h: Ctrl-End, Ctrl-Shift-Home\r
1054 int CCommands::MarkWholeBuffer()\r
1055 {\r
1056         ClearNumericArgument();\r
1057         if (CUtils::IsConsole()) {\r
1058                 SystemMenuEdit(CMD_SELECT_ALL);\r
1059         } else if (CUtils::IsDreamweaver()\r
1060                         || CUtils::IsFireworks()\r
1061                         || CUtils::IsFlash()\r
1062                         || CUtils::IsIllustrator()\r
1063                         || CUtils::IsPaint()\r
1064                         || CUtils::IsPhotoshop()) {\r
1065                 CdKduCu('A');\r
1066         } else if (CUtils::IsExplorer()\r
1067                         || CUtils::IsReget()) {\r
1068                 Kdu(VK_END);\r
1069                 m_bSetMark = TRUE;\r
1070                 return Reset(MoveCaret(VK_HOME));\r
1071         } else {\r
1072                 CdKduCu(VK_END);\r
1073                 m_bSetMark = TRUE;\r
1074                 return Reset(MoveCaret(VK_HOME, TRUE));\r
1075         }\r
1076         return Reset(GOTO_HOOK);\r
1077 }\r
1078 \r
1079 // C-x C-p:\r
1080 int CCommands::MarkPage()\r
1081 {\r
1082         return MarkWholeBuffer();\r
1083 }\r
1084 \r
1085 // C-x C-s: Alt-F, Alt-S\r
1086 int CCommands::SaveBuffer()\r
1087 {\r
1088         ClearNumericArgument();\r
1089         if (CUtils::IsFlash()\r
1090          || CUtils::IsSleipnir()\r
1091          || CUtils::IsThunderbird()) {\r
1092                 CdKduCu('S');\r
1093                 return Reset(GOTO_HOOK);\r
1094         } else {\r
1095                 // default\r
1096                 AdKduAu('F', 'S');\r
1097                 return Reset(GOTO_HOOK);\r
1098         }\r
1099 }\r
1100 \r
1101 // C-v: Page Down\r
1102 int CCommands::ScrollUp()\r
1103 {\r
1104         if (m_bNegativeNumericArgument) {\r
1105                 m_bNegativeNumericArgument = FALSE;\r
1106                 return ScrollDown();\r
1107         }\r
1108 \r
1109         if (m_bDefaultNumericArgument) {\r
1110                 return Reset(MoveCaret(VK_NEXT));\r
1111         } else {\r
1112                 while (m_nNumericArgument--) {\r
1113                         SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);\r
1114                 }\r
1115         }\r
1116         return Reset(GOTO_HOOK);\r
1117 }\r
1118 \r
1119 // M-v: Page Up\r
1120 int CCommands::ScrollDown()\r
1121 {\r
1122         if (m_bNegativeNumericArgument) {\r
1123                 m_bNegativeNumericArgument = FALSE;\r
1124                 return ScrollUp();\r
1125         }\r
1126 \r
1127         if (m_bDefaultNumericArgument)\r
1128                 return Reset(MoveCaret(VK_PRIOR));\r
1129         while (m_nNumericArgument--)\r
1130                 SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);\r
1131         return Reset(GOTO_HOOK);\r
1132 }\r
1133 \r
1134 BOOL CCommands::bC_()\r
1135 {\r
1136         return m_bC_;\r
1137 }\r
1138 \r
1139 void CCommands::bC_(BOOL b)\r
1140 {\r
1141         m_bC_ = b;\r
1142 }\r
1143 \r
1144 BOOL CCommands::bC_x()\r
1145 {\r
1146         return m_bC_x;\r
1147 }\r
1148 \r
1149 void CCommands::bC_x(BOOL b)\r
1150 {\r
1151         m_bC_x = b;\r
1152 }\r
1153 \r
1154 BOOL CCommands::bM_x()\r
1155 {\r
1156         return m_bM_x;\r
1157 }\r
1158 \r
1159 void CCommands::bM_x(const BOOL b)\r
1160 {\r
1161         m_bM_x = b;\r
1162 \r
1163         if (b) {\r
1164                 CXkeymacsDll::SetM_xTip("");\r
1165         } else {\r
1166                 CXkeymacsDll::SetM_xTip(NULL);\r
1167         }\r
1168 }\r
1169 \r
1170 // C-x: only set flag\r
1171 int CCommands::C_x()\r
1172 {\r
1173         if (CXkeymacsDll::GetEnableCUA() && m_bSetMark) {\r
1174                 Cut();\r
1175         } else {\r
1176                 bC_x(TRUE);\r
1177         }\r
1178         return Reset(GOTO_HOOKX);\r
1179 }\r
1180 \r
1181 // C-x C-w: Alt-F, Alt-A\r
1182 int CCommands::WriteFile()\r
1183 {\r
1184         ClearNumericArgument();\r
1185         if (CUtils::IsSleipnir()) {\r
1186                 CdKduCu('S');\r
1187         } else if (CUtils::IsFlash()) {\r
1188                 CdSdKduSuCu('S');\r
1189         } else {\r
1190                 AdKduAu('F', 'A');\r
1191         }\r
1192         return Reset(GOTO_HOOK);\r
1193 }\r
1194 \r
1195 int CCommands::Paste()\r
1196 {\r
1197         ClearNumericArgument();\r
1198         m_bSetMark = FALSE;\r
1199         if (CUtils::IsConsole()) {\r
1200                 SystemMenuEdit(CMD_PASTE);\r
1201         } else {\r
1202                 CdKduCu('V');\r
1203         }\r
1204         return Reset(GOTO_HOOK);\r
1205 }\r
1206 \r
1207 // C-w: Ctrl-X\r
1208 int CCommands::KillRegion()\r
1209 {\r
1210         static int nStep = 0;\r
1211         switch (nStep) {\r
1212         case 0:\r
1213                 m_bSetMark = FALSE;\r
1214                 ClearNumericArgument();\r
1215                 CdKduCu('X');\r
1216                 if (CUtils::IsExplorer()) {\r
1217                         return Reset(GOTO_HOOK);\r
1218                 }\r
1219                 nStep = 1;\r
1220                 return Reset(GOTO_RECURSIVE);\r
1221         case 1:\r
1222                 nStep = 0;\r
1223                 CXkeymacsDll::AddKillRing();\r
1224                 return Reset(GOTO_HOOK);\r
1225         }\r
1226         // dummy\r
1227         return Reset(GOTO_HOOK);\r
1228 }\r
1229 \r
1230 // M-w: Ctrl-C\r
1231 int CCommands::KillRingSave()\r
1232 {\r
1233         static int nStep = 0;\r
1234         switch (nStep) {\r
1235         case 0:\r
1236                 ClearNumericArgument();\r
1237                 m_bSetMark = FALSE;\r
1238                 if (CUtils::IsConsole()) {\r
1239                         SystemMenuEdit(CMD_COPY);\r
1240                         return Reset(GOTO_HOOK);\r
1241                 } else if (CUtils::IsMicrosoftPowerPoint()) {   // PowerPoint did not want to deactivate-mark. Temporary code?\r
1242                         CdKduCu('X');\r
1243                 } else {\r
1244                         CdKduCu('C');\r
1245                 }\r
1246                 if (CUtils::IsExplorer()) {\r
1247                         return Reset(GOTO_HOOK);\r
1248                 }\r
1249                 nStep = 1;\r
1250                 return Reset(GOTO_RECURSIVE);\r
1251         case 1:\r
1252                 nStep = 0;\r
1253                 CXkeymacsDll::AddKillRing();\r
1254                 if (CUtils::IsMicrosoftPowerPoint()) {  // Because DeactivateMark move object like graph.\r
1255                         CdKduCu('V');\r
1256                 } else {\r
1257                         DeactivateMark();\r
1258                 }\r
1259                 return Reset(GOTO_HOOK);\r
1260         }\r
1261         // dummy\r
1262         return Reset(GOTO_HOOK);\r
1263 }\r
1264 \r
1265 // C-y: Ctrl-V\r
1266 int CCommands::Yank()\r
1267 {\r
1268         m_bSetMark = FALSE;\r
1269         if (CUtils::IsConsole()) {\r
1270                 SystemMenuEdit(CMD_PASTE);\r
1271         } else {\r
1272                 static CClipboardSnap* pSnap = NULL;\r
1273                 if (!m_bDefaultNumericArgument) {\r
1274                         DecreaseNumericArgument();\r
1275                         CXkeymacsDll::IncreaseKillRingIndex(m_nNumericArgument);\r
1276                         pSnap = CXkeymacsDll::GetKillRing(pSnap);\r
1277                 } else if (pSnap) {\r
1278                         pSnap = CXkeymacsDll::GetKillRing(pSnap);\r
1279                 } else {\r
1280                         if (CUtils::IsExcel() && m_LastKillCommand == KillRegion) {\r
1281                                 // do nothing to work C-w not Copy but Cut\r
1282                         } else if (CUtils::IsLotusNotes() && (m_LastKillCommand == KillRegion || m_LastKillCommand == KillRingSave)) {\r
1283                                 // do nothing\r
1284                         } else {\r
1285                                 pSnap = CXkeymacsDll::GetKillRing(pSnap, FALSE);\r
1286                         }\r
1287                 }\r
1288                 CdKduCu('V');\r
1289                 if (pSnap) {\r
1290                         return Reset(GOTO_RECURSIVE);\r
1291                 }\r
1292         }\r
1293         return Reset(GOTO_HOOK);\r
1294 }\r
1295 \r
1296 // M-y: yank-pop\r
1297 int CCommands::YankPop()\r
1298 {\r
1299         ClearNumericArgument();\r
1300 \r
1301         if (m_LastCommand == YankPop\r
1302          || m_LastCommand == Yank) {\r
1303                 static CClipboardSnap* pSnap = NULL;\r
1304                 if (!pSnap) {\r
1305                         CClipboardSnap* pOldSnap = NULL;\r
1306                         pOldSnap = CXkeymacsDll::GetKillRing(pOldSnap);\r
1307                         if (pOldSnap) {\r
1308                                 for (int i = 0; i < pOldSnap->GetCount(); ++i) {\r
1309                                         CdKduCu('Z');\r
1310                                 }\r
1311                         } else {\r
1312                                 CdKduCu('Z');\r
1313                         }\r
1314                         CXkeymacsDll::IncreaseKillRingIndex();\r
1315                 }\r
1316                 pSnap = CXkeymacsDll::GetKillRing(pSnap);\r
1317                 CdKduCu('V');\r
1318                 if (pSnap) {\r
1319                         return Reset(GOTO_RECURSIVE);\r
1320                 }\r
1321         }\r
1322 \r
1323         return Reset(GOTO_HOOK);\r
1324 }\r
1325 \r
1326 // M-!: cmd.exe/command.com\r
1327 int CCommands::ShellCommand()\r
1328 {\r
1329         TCHAR szShell[MAX_PATH];\r
1330         size_t len;\r
1331         !_tgetenv_s(&len, szShell, _T("XKEYMACS_SHELL")) && len != 0 && CUtils::Run(szShell) ||\r
1332                 !_tgetenv_s(&len, szShell, _T("COMSPEC")) && len != 0 && CUtils::Run(szShell);\r
1333         return Reset(GOTO_HOOK);\r
1334 }\r
1335 \r
1336 int CCommands::Ignore()\r
1337 {\r
1338         Reset();        // If you delete this line, Ignore() works as Enable/Disable XKeymacs only on Release build. Why?\r
1339         return Reset(GOTO_HOOK);\r
1340 }\r
1341 \r
1342 void CCommands::bM_(BOOL b)\r
1343 {\r
1344         m_bM_ = b;\r
1345 }\r
1346 \r
1347 BOOL CCommands::bM_()\r
1348 {\r
1349         return m_bM_;\r
1350 }\r
1351 \r
1352 // C-[\r
1353 int CCommands::Meta()\r
1354 {\r
1355         bM_(TRUE);\r
1356         return Reset(GOTO_HOOKX);\r
1357 }\r
1358 \r
1359 // Esc\r
1360 int CCommands::MetaEscape()\r
1361 {\r
1362         Meta();\r
1363         return Reset(GOTO_DO_NOTHING);\r
1364 }\r
1365 \r
1366 // Alt\r
1367 int CCommands::MetaAlt()\r
1368 {\r
1369         return Reset(GOTO_DO_NOTHING);\r
1370 }\r
1371 \r
1372 // C-0\r
1373 int CCommands::NumericArgument0()\r
1374 {\r
1375         return NumericArgument(0);\r
1376 }\r
1377 \r
1378 // C-1\r
1379 int CCommands::NumericArgument1()\r
1380 {\r
1381         return NumericArgument(1);\r
1382 }\r
1383 \r
1384 // C-2\r
1385 int CCommands::NumericArgument2()\r
1386 {\r
1387         return NumericArgument(2);\r
1388 }\r
1389 \r
1390 // C-3\r
1391 int CCommands::NumericArgument3()\r
1392 {\r
1393         return NumericArgument(3);\r
1394 }\r
1395 \r
1396 // C-4\r
1397 int CCommands::NumericArgument4()\r
1398 {\r
1399         return NumericArgument(4);\r
1400 }\r
1401 \r
1402 // C-5\r
1403 int CCommands::NumericArgument5()\r
1404 {\r
1405         return NumericArgument(5);\r
1406 }\r
1407 \r
1408 // C-6\r
1409 int CCommands::NumericArgument6()\r
1410 {\r
1411         return NumericArgument(6);\r
1412 }\r
1413 \r
1414 // C-7\r
1415 int CCommands::NumericArgument7()\r
1416 {\r
1417         return NumericArgument(7);\r
1418 }\r
1419 \r
1420 // C-8\r
1421 int CCommands::NumericArgument8()\r
1422 {\r
1423         return NumericArgument(8);\r
1424 }\r
1425 \r
1426 // C-9\r
1427 int CCommands::NumericArgument9()\r
1428 {\r
1429         return NumericArgument(9);\r
1430 }\r
1431 \r
1432 // C-#\r
1433 int CCommands::NumericArgument(int n)\r
1434 {\r
1435         if (m_bDefaultNumericArgument) {\r
1436                 m_nNumericArgument = n;\r
1437                 m_bDefaultNumericArgument = FALSE;\r
1438         } else {\r
1439                 m_nNumericArgument = m_nNumericArgument * 10 + n;\r
1440         }\r
1441         return Reset(GOTO_HOOK0_9);\r
1442 }\r
1443 \r
1444 // C--, M--\r
1445 int CCommands::NumericArgumentMinus()\r
1446 {\r
1447         m_bNegativeNumericArgument = !m_bNegativeNumericArgument;\r
1448         return Reset(GOTO_HOOK0_9);\r
1449 }\r
1450 \r
1451 // C-u\r
1452 int CCommands::UniversalArgument()\r
1453 {\r
1454         if (m_bC_u) {\r
1455                 m_nNumericArgument *= 4;\r
1456         } else {\r
1457                 m_nNumericArgument = 4;\r
1458                 m_bC_u = TRUE;\r
1459         }\r
1460         return Reset(GOTO_HOOKX);\r
1461 }\r
1462 \r
1463 // change function name and member variable name like bUniversalArgument()\r
1464 BOOL CCommands::bC_u()\r
1465 {\r
1466         return m_bC_u;\r
1467 }\r
1468 \r
1469 void CCommands::bC_u(BOOL b)\r
1470 {\r
1471         m_bC_u = b;\r
1472 }\r
1473 \r
1474 int CCommands::Repeat(BYTE bVk)\r
1475 {\r
1476         if (m_bDefaultNumericArgument) {\r
1477                 return Reset(GOTO_DO_NOTHING);\r
1478         } else {\r
1479                 CXkeymacsDll::Kdu(bVk, m_nNumericArgument);\r
1480                 return Reset(GOTO_HOOK);\r
1481         }\r
1482 }\r
1483 \r
1484 // C-l: Recenter\r
1485 int CCommands::Recenter()\r
1486 {\r
1487         if (CUtils::IsBecky()) {\r
1488                 static int nStep = 0;\r
1489                 RECT ClientRect = {'\0'};\r
1490                 GetClientRect(GetFocus(), &ClientRect);\r
1491                 static int gap = INT_MAX;\r
1492 \r
1493                 static POINT CaretPos = {'\0'};\r
1494                 GetCaretPos(&CaretPos);\r
1495 \r
1496                 switch (nStep) {\r
1497                 case 0:\r
1498                         nStep = 0;      // omaginai\r
1499                         if (CaretPos.y < ClientRect.bottom / 2) {\r
1500                                 SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);\r
1501                         } else if (ClientRect.bottom / 2 < CaretPos.y) {\r
1502                                 SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);\r
1503                         } else {\r
1504                                 gap = INT_MAX;\r
1505                                 return Reset(GOTO_HOOK);\r
1506                                 break;\r
1507                         }\r
1508 \r
1509                         Kdu(VK_DOWN);\r
1510                         nStep = 1;\r
1511                         return Reset(GOTO_RECURSIVE);\r
1512 \r
1513                 case 1:\r
1514                         nStep = 0;\r
1515                         // When a client screen can display 2n lines, the center line is (n + 1)th line.\r
1516                         int newgap = CaretPos.y - ClientRect.bottom / 2;\r
1517                         if (fabs((double)gap) <= fabs((double)newgap)) {\r
1518                                 if ((fabs((double)gap) == fabs((double)newgap)) && (gap != newgap) && newgap < 0) {\r
1519                                         SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);\r
1520                                 }\r
1521                                 gap = INT_MAX;\r
1522                                 return Reset(GOTO_HOOK);\r
1523                                 break;\r
1524                         }\r
1525 \r
1526                         gap = newgap;\r
1527                         return Reset(GOTO_RECURSIVE);\r
1528                 }\r
1529         } else if (CUtils::IsMicrosoftWord()\r
1530                         || CUtils::IsThunderbird()) {\r
1531                 RECT ClientRect = {'\0'};\r
1532                 GetClientRect(GetFocus(), &ClientRect);\r
1533 //              CUtils::Log(_T("top = %d, bottom = %d, left = %d, right = %d"), ClientRect.top, ClientRect.bottom, ClientRect.left, ClientRect.right);\r
1534 \r
1535                 POINT CaretPos = {'\0'};\r
1536                 GetCaretPos(&CaretPos);\r
1537 \r
1538                 static const int LENGTH_PER_SCROLL = 32;\r
1539 \r
1540                 if (CaretPos.y < ClientRect.bottom / 2) {\r
1541                         VScroll(SB_LINEUP, (ClientRect.bottom / 2 - CaretPos.y) / (LENGTH_PER_SCROLL / 2) + 1);\r
1542                 } else if (ClientRect.bottom / 2 < CaretPos.y) {\r
1543                         VScroll(SB_LINEDOWN, (CaretPos.y - ClientRect.bottom / 2) / (LENGTH_PER_SCROLL / 2));\r
1544                 }\r
1545 \r
1546                 return Reset(GOTO_HOOK);\r
1547         } else {\r
1548                 RECT ClientRect = {'\0'};\r
1549                 GetClientRect(GetFocus(), &ClientRect);\r
1550                 int gap = INT_MAX;\r
1551 \r
1552 //              CUtils::Log(_T("top = %d, bottom = %d, left = %d, right = %d"), ClientRect.top, ClientRect.bottom, ClientRect.left, ClientRect.right);\r
1553 \r
1554                 for (;;) {\r
1555                         POINT CaretPos = {'\0'};\r
1556                         GetCaretPos(&CaretPos);\r
1557 \r
1558                         if (CaretPos.y < ClientRect.bottom / 2) {\r
1559                                 VScroll(SB_LINEUP);\r
1560                         } else if (ClientRect.bottom / 2 < CaretPos.y) {\r
1561                                 VScroll(SB_LINEDOWN);\r
1562                         } else {\r
1563                                 break;\r
1564                         }\r
1565 \r
1566                         // When a client screen can display 2n lines, the center line is (n + 1)th line.\r
1567                         int newgap = CaretPos.y - ClientRect.bottom / 2;\r
1568                         if (fabs((double)gap) <= fabs((double)newgap)) {\r
1569                                 if ((fabs((double)gap) == fabs((double)newgap)) && (gap != newgap) && newgap < 0) {\r
1570                                         VScroll(SB_LINEUP);\r
1571                                 }\r
1572                                 break;\r
1573                         }\r
1574                         gap = newgap;\r
1575                 }\r
1576                 return Reset(GOTO_HOOK);\r
1577         }\r
1578         return Reset(GOTO_HOOK);\r
1579 }\r
1580 \r
1581 // C-t: Shift-Left, Shift-Delete, Right Shift-Insert, if the cursor is not at EOL (is End Of Line)\r
1582 //              Left, Shift-Right, Shift-Delete, Left, Shift-Insert, Right, if the cursor is at EOL\r
1583 int CCommands::TransposeChars()\r
1584 {\r
1585         ClearNumericArgument(); // tmp\r
1586 \r
1587         // Do not try to do these command at once.\r
1588         // Clipboard has old data till you go out this function.\r
1589         static int nStep = 0;\r
1590         switch (nStep) {\r
1591         case 0:         // Clear Selection\r
1592                 if (m_bSetMark) {\r
1593                         m_bSetMark = FALSE;\r
1594                         Kdu(VK_RIGHT, VK_LEFT);\r
1595                         nStep = 1;\r
1596                         return Reset(GOTO_RECURSIVE);\r
1597                 } else {\r
1598                         // Do nothing. Go to case 1:\r
1599                 }\r
1600         case 1:         // Get back character to confirm the cursor is at TOF or not.\r
1601                 nStep = 0;\r
1602                 CaptureClipboardData();\r
1603 \r
1604                 // simple version\r
1605                 if (CUtils::IsLotus123()) {\r
1606                         // C-t: Left, Shift-Right, Shift-Delete, Left, Shift-Insert, Right\r
1607                         Kdu(VK_LEFT);\r
1608                         SdKduSu(VK_RIGHT, VK_DELETE);\r
1609                         Kdu(VK_LEFT);\r
1610                         SdKduSu(VK_INSERT);\r
1611                         Kdu(VK_RIGHT);\r
1612                         nStep = 7;\r
1613                         return Reset(GOTO_RECURSIVE);\r
1614                 }\r
1615 \r
1616                 if (!CopyBackCharacter()) {\r
1617                         return Reset(GOTO_DO_NOTHING);\r
1618                 }\r
1619 \r
1620                 nStep = 2;\r
1621                 return Reset(GOTO_RECURSIVE);\r
1622         case 2:         // Get next character to confirm the cursor is at the EOF or not.\r
1623                 {\r
1624                         nStep = 0;\r
1625                         Su();\r
1626 \r
1627                         if (CUtils::IsTOF()) {\r
1628                                 Kdu(VK_LEFT);\r
1629                                 nStep = 7;\r
1630                                 return Reset(GOTO_RECURSIVE);\r
1631                         }\r
1632 \r
1633                         if (CUtils::IsDirector()) {\r
1634                                 // CopyBackCharacter move cursor right\r
1635                                 Kdu(VK_LEFT);\r
1636                                 ReleaseKey(VK_CONTROL);\r
1637                         }\r
1638 \r
1639                         if (CUtils::IsEudora()) {\r
1640                                 // CopyBackCharacter move cursor right\r
1641                                 Kdu(VK_LEFT);\r
1642                         }\r
1643 \r
1644                         if (!CopyNextCharacter()) {\r
1645                                 nStep = 7;\r
1646                                 return Reset(GOTO_RECURSIVE);\r
1647                         }\r
1648 \r
1649                         if (CUtils::IsDirector()) {\r
1650                                 DepressKey(VK_CONTROL);\r
1651                         }\r
1652 \r
1653                         nStep = 3;\r
1654                         return Reset(GOTO_RECURSIVE);\r
1655                 }\r
1656         case 3:         // Cut Left Character\r
1657                 {\r
1658                         nStep = 0;\r
1659                         Su();\r
1660 \r
1661                         CString szClipboardText;\r
1662                         CUtils::GetClipboardText(szClipboardText);\r
1663 //                      CUtils::Log(_T("%x, %d, %s"), szClipboardText.GetAt(0), szClipboardText.GetLength(), szClipboardText);\r
1664 \r
1665                         if (CUtils::IsDirector()\r
1666                          ||     CUtils::IsEudora()) {\r
1667                                 // CopyNextCharacter move cursor left\r
1668                                 Kdu(VK_RIGHT);\r
1669                         }\r
1670 \r
1671                         if (!szClipboardText.IsEmpty()\r
1672                          && szClipboardText.GetAt(0) != VK_RETURN) {\r
1673                                 if (CUtils::IseMemoPad()\r
1674                                  || CUtils::IsFlash()\r
1675                                  || CUtils::IsK2Editor()\r
1676                                  || CUtils::IsShuriken()) {\r
1677                                         SdKduSu(VK_LEFT);\r
1678                                         CdKduCu('X');\r
1679                                 } else if (CUtils::IsDirector()) {\r
1680                                         ReleaseKey(VK_CONTROL);\r
1681                                         SdKduSu(VK_LEFT);\r
1682                                         CdKduCu('X');\r
1683                                         Kdu(VK_RIGHT);\r
1684                                         DepressKey(VK_CONTROL);\r
1685                                 } else {\r
1686                                         SdKduSu(VK_LEFT, VK_DELETE);\r
1687                                 }\r
1688                                 nStep = 4;\r
1689                                 return Reset(GOTO_RECURSIVE);\r
1690                         } else {\r
1691                                 if (szClipboardText.IsEmpty()) {        // EOF\r
1692                                         if (CUtils::IsLotusNotes()\r
1693                                          || CUtils::IsLotusWordPro()\r
1694                                          || CUtils::IsMicrosoftFrontPage()\r
1695                                          || CUtils::IsMicrosoftWord()) {\r
1696                                                 // These applications say "EOL is EOF".\r
1697                                                 Kdu(VK_END);\r
1698                                         } else {\r
1699                                                 // default\r
1700                                                 Kdu(VK_RIGHT);\r
1701                                         }\r
1702                                 }\r
1703 \r
1704                                 nStep = 5;\r
1705                                 return Reset(GOTO_RECURSIVE);\r
1706                         }\r
1707                 }\r
1708         case 4:         // Paste the cut character\r
1709                 nStep = 0;\r
1710                 Su();\r
1711                 Kdu(VK_RIGHT);\r
1712                 if (CUtils::IsDirector()\r
1713                  || CUtils::IseMemoPad()\r
1714                  || CUtils::IsFlash()\r
1715                  || CUtils::IsK2Editor()\r
1716                  || CUtils::IsShuriken()) {\r
1717                         CdKduCu('V');\r
1718                 } else {\r
1719                         SdKduSu(VK_INSERT);\r
1720                 }\r
1721                 nStep = 7;\r
1722                 return Reset(GOTO_RECURSIVE);\r
1723         case 5:         // Cut character at the EOF.\r
1724                 nStep = 0;\r
1725                 if (CUtils::IsDirector()\r
1726                  || CUtils::IseMemoPad()\r
1727                  || CUtils::IsFlash()\r
1728                  || CUtils::IsK2Editor()\r
1729                  || CUtils::IsShuriken()) {\r
1730                         SdKduSu(VK_LEFT);\r
1731                         CdKduCu('X');\r
1732                 } else {\r
1733                         SdKduSu(VK_LEFT, VK_DELETE);\r
1734                 }\r
1735                 nStep = 6;\r
1736                 return Reset(GOTO_RECURSIVE);\r
1737         case 6:         // Paste the cut character near the EOF.\r
1738                 nStep = 0;\r
1739                 Su();\r
1740                 Kdu(VK_LEFT);\r
1741                 if (CUtils::IsDirector()\r
1742                  || CUtils::IseMemoPad()\r
1743                  || CUtils::IsFlash()\r
1744                  || CUtils::IsK2Editor()\r
1745                  || CUtils::IsShuriken()) {\r
1746                         DepressKey(VK_CONTROL);         // Why is this code needed?\r
1747                         CdKduCu('V');\r
1748                 } else {\r
1749                         SdKduSu(VK_INSERT);\r
1750                 }\r
1751                 Kdu(VK_RIGHT);\r
1752                 nStep = 7;\r
1753                 return Reset(GOTO_RECURSIVE);\r
1754         case 7:         // Set the original data on the clipboard.\r
1755                 nStep = 0;\r
1756                 Su();\r
1757                 RestoreClipboardData();\r
1758                 return Reset(GOTO_HOOK);\r
1759         }\r
1760         return Reset(GOTO_HOOK);\r
1761 }\r
1762 \r
1763 void CCommands::Cut_()\r
1764 {\r
1765         CdKduCu('X');\r
1766 }\r
1767 \r
1768 int CCommands::Cut()\r
1769 {\r
1770         ClearNumericArgument();\r
1771         m_bSetMark = FALSE;\r
1772         Cut_();\r
1773         return Reset(GOTO_HOOK);\r
1774 }\r
1775 \r
1776 void CCommands::Copy_()\r
1777 {\r
1778         if (CUtils::IsConsole()) {\r
1779                 SystemMenuEdit(CMD_COPY);\r
1780         } else if (CUtils::IsEclipse()\r
1781                         || CUtils::IsStoryEditor()) {\r
1782                 CdKduCu(VK_INSERT);\r
1783         } else {\r
1784                 CdKduCu('C');\r
1785         }\r
1786 }\r
1787 \r
1788 int CCommands::Copy()\r
1789 {\r
1790         ClearNumericArgument();\r
1791         m_bSetMark = FALSE;\r
1792         Copy_();\r
1793         return Reset(GOTO_HOOK);\r
1794 }\r
1795 \r
1796 // Copy next character of the cursor if the caret is NOT at end of the file\r
1797 // Move the caret to left if caret is at end of the file\r
1798 BOOL CCommands::CopyNextCharacter()\r
1799 {\r
1800         if (!CUtils::OpenClipboard()) {\r
1801                 ASSERT(0);\r
1802                 return FALSE;\r
1803         }\r
1804         if (!EmptyClipboard()) {\r
1805                 ASSERT(0);\r
1806                 return FALSE;\r
1807         }\r
1808         if (!CloseClipboard()) {\r
1809                 ASSERT(0);\r
1810                 return FALSE;\r
1811         }\r
1812 \r
1813         SdKduSu(VK_RIGHT);\r
1814         Copy_();\r
1815         Kdu(VK_LEFT);\r
1816 \r
1817         return TRUE;\r
1818 }\r
1819 \r
1820 BOOL CCommands::CopyBackCharacter()\r
1821 {\r
1822         if (!CUtils::OpenClipboard()) {\r
1823                 ASSERT(0);\r
1824                 return FALSE;\r
1825         }\r
1826         if (!EmptyClipboard()) {\r
1827                 ASSERT(0);\r
1828                 return FALSE;\r
1829         }\r
1830         if (!CloseClipboard()) {\r
1831                 ASSERT(0);\r
1832                 return FALSE;\r
1833         }\r
1834 \r
1835         SdKduSu(VK_LEFT);\r
1836         Copy_();\r
1837         Kdu(VK_RIGHT);\r
1838 \r
1839         return TRUE;\r
1840 }\r
1841 \r
1842 BOOL CCommands::CopyPreviousLine()\r
1843 {\r
1844         if (!CUtils::OpenClipboard()) {\r
1845                 ASSERT(0);\r
1846                 return FALSE;\r
1847         }\r
1848         if (!EmptyClipboard()) {\r
1849                 ASSERT(0);\r
1850                 return FALSE;\r
1851         }\r
1852         if (!CloseClipboard()) {\r
1853                 ASSERT(0);\r
1854                 return FALSE;\r
1855         }\r
1856 \r
1857         SdKduSu(VK_UP);\r
1858         Copy_();\r
1859 \r
1860         return TRUE;\r
1861 }\r
1862 \r
1863 BOOL CCommands::CopyCurrentLine()\r
1864 {\r
1865         if (!CUtils::OpenClipboard()) {\r
1866                 ASSERT(0);\r
1867                 return FALSE;\r
1868         }\r
1869         if (!EmptyClipboard()) {\r
1870                 ASSERT(0);\r
1871                 return FALSE;\r
1872         }\r
1873         if (!CloseClipboard()) {\r
1874                 ASSERT(0);\r
1875                 return FALSE;\r
1876         }\r
1877 \r
1878         SdKduSu(VK_HOME);\r
1879         Copy_();\r
1880 \r
1881         return TRUE;\r
1882 }\r
1883 \r
1884 void CCommands::DecreaseNumericArgument()\r
1885 {\r
1886         if (m_bNegativeNumericArgument) {\r
1887                 ++m_nNumericArgument;\r
1888         } else {\r
1889                 if (m_nNumericArgument == 0) {\r
1890                         ++m_nNumericArgument;\r
1891                         m_bNegativeNumericArgument = TRUE;\r
1892                 } else {\r
1893                         --m_nNumericArgument;\r
1894                 }\r
1895         }\r
1896 }\r
1897 \r
1898 void CCommands::ClearNumericArgument()\r
1899 {\r
1900         m_bDefaultNumericArgument = TRUE;\r
1901         m_nNumericArgument = 1;\r
1902         m_bNegativeNumericArgument = FALSE;\r
1903 }\r
1904 \r
1905 void CCommands::Reset()\r
1906 {\r
1907         Reset(GOTO_HOOK);\r
1908 }\r
1909 \r
1910 int CCommands::Reset(int rc)\r
1911 {\r
1912         switch(rc) {\r
1913         case GOTO_HOOK:\r
1914                 ClearNumericArgument();\r
1915                 m_bC_u = FALSE;\r
1916         case GOTO_HOOK0_9:\r
1917                 bC_(FALSE);\r
1918                 bC_x(FALSE);\r
1919                 bM_(FALSE);\r
1920                 bM_x(FALSE);\r
1921         case GOTO_HOOKX:\r
1922                 break;\r
1923 \r
1924         case GOTO_RECURSIVE:\r
1925                 break;\r
1926 \r
1927         case GOTO_DO_NOTHING:\r
1928                 break;\r
1929 \r
1930         default:\r
1931                 break;\r
1932         }\r
1933         return rc;\r
1934 }\r
1935 \r
1936 // C-q\r
1937 int CCommands::EnableOrDisableXKeymacs()\r
1938 {\r
1939         // dummy\r
1940         ASSERT(0);\r
1941         static int i = 0;       // If there is not this 2 line, EnableOrDisableXKeymacs, EnableXKeymacs and DisableXKeymacs has same function pointer.\r
1942         ++i;\r
1943         return Reset(GOTO_HOOK);\r
1944 }\r
1945 \r
1946 int CCommands::EnableXKeymacs()\r
1947 {\r
1948         // dummy\r
1949         ASSERT(0);\r
1950         static int i = 0;\r
1951         ++i;\r
1952         return Reset(GOTO_HOOK);\r
1953 }\r
1954 \r
1955 int CCommands::DisableXKeymacs()\r
1956 {\r
1957         // dummy\r
1958         ASSERT(0);\r
1959         static int i = 0;\r
1960         ++i;\r
1961         return Reset(GOTO_HOOK);\r
1962 }\r
1963 \r
1964 int CCommands::GetNumericArgument()\r
1965 {\r
1966         return m_nNumericArgument;\r
1967 }\r
1968 \r
1969 // C-r\r
1970 int CCommands::IsearchBackward()\r
1971 {\r
1972         return Search(BACKWARD);\r
1973 }\r
1974 \r
1975 // C-s\r
1976 int CCommands::IsearchForward()\r
1977 {\r
1978         return Search(FORWARD);\r
1979 }\r
1980 \r
1981 void CCommands::OpenFindDialog()\r
1982 {\r
1983         if (CUtils::IsAutla()\r
1984          || CUtils::IsBorlandCppBuilder()\r
1985          || CUtils::IsCodeWarrior()\r
1986          || CUtils::IsDana()\r
1987          || CUtils::IseMemoPad()\r
1988          || CUtils::IsJmEditor()\r
1989          || CUtils::IsK2Editor()\r
1990          || CUtils::IsOedit()\r
1991          || CUtils::IsOpenJane()\r
1992          || CUtils::IsPHPEditor()\r
1993          || CUtils::IsStoryEditor()\r
1994          || CUtils::IsTeraPad()) {\r
1995                 AdKduAu('S', 'F');\r
1996         } else if (CUtils::IsConsole()) {\r
1997                 SystemMenuEdit(CMD_FIND);\r
1998         } else if (CUtils::IsSakuraEditor()) {\r
1999                 AdKduAu('S', VK_RETURN);\r
2000         } else if (CUtils::IsNami2000()) {\r
2001                 AdKduAu('D', 'F');\r
2002         } else if (CUtils::IsVisualStudio()) {\r
2003                 AdKduAu('E', 'F', 'F');\r
2004         } else if (CUtils::IsDirector()) {\r
2005                 AdKduAu('E', 'F', 'T');\r
2006         } else if (CUtils::IsAdobeReader()) {\r
2007                 AdKduAu('E', 'S');\r
2008         } else if (CUtils::IsDWFM()\r
2009                         || CUtils::IsEggExplorer()\r
2010                         || CUtils::IsExplorer()\r
2011                         || CUtils::IsOutlookExpress()) {\r
2012                 Kdu(VK_F3);\r
2013         } else if (CUtils::IsHidemaru()\r
2014                         || CUtils::IsLunascape()\r
2015                         || CUtils::IsMicrosoftPowerPoint()\r
2016                         || CUtils::IsMozilla()\r
2017                         || CUtils::IsNetscape()\r
2018                         || CUtils::IsOpera()\r
2019                         || CUtils::IsSleipnir()) {\r
2020                 CdKduCu('F');\r
2021         } else if (CUtils::IsDreamweaver()\r
2022                         || CUtils::IsezHTML()\r
2023                         || CUtils::IsFlash()) {\r
2024                 DepressKey(VK_CONTROL);         // Why is this coad needed?\r
2025                 CdKduCu('F');\r
2026         } else if (CUtils::IsIPMessenger()) {\r
2027                 DepressKey(VK_CONTROL);\r
2028                 PostMessage(GetFocus(), WM_KEYDOWN, 'F', 0);\r
2029                 PostMessage(GetFocus(), WM_KEYUP, 'F', 0);\r
2030                 ReleaseKey(VK_CONTROL);\r
2031         } else {\r
2032                 // default\r
2033                 AdKduAu('E', 'F');\r
2034         }\r
2035 \r
2036         // Set Direction if Find dialog already exist\r
2037         if (CUtils::IsDWFM()\r
2038          || CUtils::IsEggExplorer()\r
2039          || CUtils::IsExplorer()\r
2040          || CUtils::IsFirefox()\r
2041          || CUtils::IsHidemaru()\r
2042          || CUtils::IsK2Editor()\r
2043          || CUtils::IsLotusWordPro()\r
2044          || CUtils::IsMicrosoftPowerPoint()\r
2045          || CUtils::IsMozilla()\r
2046          || CUtils::IsMSDN()\r
2047          || CUtils::IsNetscape()\r
2048          || CUtils::IsOpera()\r
2049          || CUtils::IsSakuraEditor()) {\r
2050         } else if (CUtils::IsInternetExplorer()\r
2051                         || CUtils::IsSleipnir()) {\r
2052                 // I want to set direction but IE does not allow me.\r
2053         } else {\r
2054                 SetSearchDirection();\r
2055         }\r
2056 }\r
2057 \r
2058 int CCommands::Search(SEARCH_DIRECTION direction)\r
2059 {\r
2060 //      CUtils::Log(_T("%s"), CUtils::GetApplicationName());\r
2061 \r
2062         if (CUtils::IsIllustrator()\r
2063          || CUtils::IsPaint()\r
2064          || CUtils::IsPhotoshop()) {\r
2065                 return Reset(GOTO_DO_NOTHING);\r
2066         }\r
2067 \r
2068         ClearNumericArgument();\r
2069 \r
2070         if ((direction != FORWARD) && (direction != BACKWARD)) {\r
2071                 ASSERT(0);\r
2072         }\r
2073 \r
2074         if (CUtils::IsVisualCpp()\r
2075          || CUtils::IsVisualStudio()) {\r
2076                 switch (direction) {\r
2077                 case FORWARD:\r
2078                         CdKduCu('I');\r
2079                         break;\r
2080                 case BACKWARD:\r
2081                         CdSdKduSuCu('I');\r
2082                         break;\r
2083                 default:\r
2084                         ASSERT(0);\r
2085                         break;\r
2086                 }\r
2087                 return Reset(GOTO_HOOK);\r
2088         }\r
2089 \r
2090         if (!CUtils::IsFindDialog()) {\r
2091 //              CUtils::Log(_T("Find Dialog is not."));\r
2092 \r
2093                 // F3 or Shift+F3\r
2094                 if (m_LastCommand == IsearchForward\r
2095                  || m_LastCommand == IsearchBackward) {\r
2096                         if (CUtils::IsBecky()\r
2097                          || CUtils::IsFirefox()\r
2098                          || CUtils::IsHidemaru()\r
2099                          || CUtils::IsPHPEditor()) {\r
2100                                 if (m_LastCommand == IsearchForward && direction != FORWARD\r
2101                                  || m_LastCommand == IsearchBackward && direction != BACKWARD) {\r
2102                                         // do nothing\r
2103                                 } else if (direction == FORWARD) {\r
2104                                         Kdu(VK_F3);\r
2105                                 } else if (direction == BACKWARD) {\r
2106                                         SdKduSu(VK_F3);\r
2107                                 }\r
2108                                 return Reset(GOTO_HOOK);\r
2109                         } else if (CUtils::IsBorlandCppBuilder()) {\r
2110                                 if (m_LastCommand == IsearchForward && direction != FORWARD\r
2111                                  || m_LastCommand == IsearchBackward && direction != BACKWARD) {\r
2112                                         AdKduAu('S', 'F');\r
2113                                         SetSearchDirection(direction);\r
2114                                         Kdu(VK_RETURN);\r
2115                                 } else {\r
2116                                         Kdu(VK_F3);\r
2117                                 }\r
2118                                 return Reset(GOTO_HOOK);\r
2119                         }\r
2120                 }\r
2121 \r
2122                 m_SearchDirection = direction;\r
2123                 if (CUtils::IsNotepadPP()) {\r
2124                         if (direction == FORWARD) // only forward incremental search supported\r
2125                                 AdCdKduCuAu('I');\r
2126                 } else if (CUtils::IsEclipse()) {\r
2127                         if (direction == FORWARD)\r
2128                                 CdKduCu('J');\r
2129                         else\r
2130                                 CdSdKduSuCu('J');\r
2131                 } else\r
2132                         OpenFindDialog();\r
2133         } else {\r
2134 //              CUtils::Log(_T("Find Dialog is opened."));\r
2135 \r
2136                 if (CUtils::IsHidemaru()\r
2137                  || CUtils::IsK2Editor()\r
2138                  || CUtils::IsOedit()\r
2139                  || CUtils::IsSakuraEditor()) {\r
2140                         BYTE bDirection = 0;\r
2141 \r
2142                         if (direction == FORWARD) {\r
2143                                 bDirection = GetDirectionForwardKey();\r
2144                         } else if (direction == BACKWARD) {\r
2145                                 bDirection = GetDirectionBackwardKey();\r
2146                         } else {\r
2147                                 ASSERT(0);\r
2148                         }\r
2149                         AdKduAu(bDirection);\r
2150                 } else if (CUtils::IsBorlandCppBuilder()) {\r
2151                         if (m_SearchDirection != direction) {\r
2152                                 SetSearchDirection(direction);\r
2153                         } else {\r
2154                                 Kdu(VK_RETURN);\r
2155                         }\r
2156                 } else if (CUtils::IsJmEditor()\r
2157                                 || CUtils::IsPHPEditor()) {\r
2158                         Kdu(VK_RETURN);\r
2159                 } else if (CUtils::IsAutla()) {\r
2160                         if (direction == FORWARD) {\r
2161                                 Kdu(VK_F3);\r
2162                         } else if (direction == BACKWARD) {\r
2163                                 SdKduSu(VK_F3);\r
2164                         } else {\r
2165                                 ASSERT(0);\r
2166                         }\r
2167                 } else {\r
2168                         if (m_SearchDirection != direction) {\r
2169                                 // Set Direction if Find dialog already exist\r
2170                                 if (CUtils::IsConsole()) {\r
2171                                         SetSearchDirection(BACKWARD);   // bad style\r
2172                                         m_SearchDirection = direction;\r
2173                                 } else {\r
2174                                         SetSearchDirection(direction);\r
2175                                 }\r
2176                                 return Reset(GOTO_HOOK);\r
2177                         }\r
2178 \r
2179                         // "Find Next(F)" if Find dialog already exist\r
2180                         if (CUtils::IsStoryEditor()) {\r
2181                                 AdKduAu('F');\r
2182                         } else {\r
2183                                 Kdu(VK_RETURN);\r
2184                         }\r
2185 \r
2186                         // open Find dialog again\r
2187                         CString szDialogTitle;\r
2188                         CUtils::GetFindDialogTitle(&szDialogTitle);\r
2189                         if (CUtils::IsNami2000()) {\r
2190                                 AdKduAu('D', 'F');\r
2191                                 SetSearchDirection();\r
2192                         } else if (CUtils::IsOutlook()\r
2193                                         && szDialogTitle.Compare(_T("\8c\9f\8dõ"))) {\r
2194                                 // Outlook (w/o Japanese version)\r
2195                                 AdKduAu('E', 'F');\r
2196                         } else if (CUtils::IsVisualCpp()) {\r
2197                                 CdKduCu('F');\r
2198                                 DepressKey(VK_CONTROL);         // Why is this need???\r
2199                         } else if (CUtils::IsCodeWarrior()\r
2200                                         || CUtils::IsDana()\r
2201                                         || CUtils::IsStoryEditor()\r
2202                                         || CUtils::IsTeraPad()) {\r
2203                                 AdKduAu('S', 'F');\r
2204                         } else if (CUtils::IsezHTML()) {\r
2205                                 CdKduCu('F');\r
2206                         }\r
2207 \r
2208                         // set cursor at end of FindWhat\r
2209                         if (CUtils::IsMozilla()\r
2210                          || CUtils::IsNetscape()) {\r
2211                                 // do nothing\r
2212                         } else if (CUtils::IsMicrosoftWord()) {\r
2213                                 UINT before = CXkeymacsDll::GetModifierState();\r
2214                                 CXkeymacsDll::SetModifierState(before & ~CONTROL, before);\r
2215                                 AdKduAu('N');\r
2216                                 Kdu(VK_ESCAPE);\r
2217                                 Kdu(VK_END);\r
2218                                 CXkeymacsDll::SetModifierState(before, before & ~CONTROL);\r
2219                         } else {\r
2220                                 AdKduAu(GetFindWhatKey());\r
2221                         }\r
2222                         Kdu(VK_END);\r
2223                 }\r
2224         }\r
2225         return Reset(GOTO_HOOK);\r
2226 }\r
2227 \r
2228 void CCommands::SetSearchDirection(SEARCH_DIRECTION direction)\r
2229 {\r
2230 //      CUtils::Log(_T("SetSearchDirection: %d"), direction);\r
2231         if ((direction != FORWARD) && (direction != BACKWARD)) {\r
2232                 return;\r
2233         }\r
2234 \r
2235         m_SearchDirection = direction;\r
2236 \r
2237         if (GetDirectionForwardKey() == 0 && GetDirectionBackwardKey() == 0) {\r
2238                 Kdu(VK_END);\r
2239                 return;\r
2240         } else if (CUtils::IsConsole()) {\r
2241                 if (direction == BACKWARD) {    // bad style\r
2242                         Kdu(VK_TAB, VK_TAB);\r
2243                         Kdu(VK_RIGHT);\r
2244                         SdKduSu(VK_TAB, VK_TAB);\r
2245                 }\r
2246         } else if (CUtils::IsMicrosoftWord()) {\r
2247                 UINT before = CXkeymacsDll::GetModifierState();\r
2248                 CXkeymacsDll::SetModifierState(before & ~CONTROL, before);\r
2249 \r
2250                 AdKduAu('M');\r
2251                 AdKduAu(0xBA);  // VK_OEM_1     Used for miscellaneous characters; it can vary by keyboard. \r
2252                                                 //                      Windows 2000/XP: For the US standard keyboard, the ';:' key\r
2253                 Kdu(VK_UP, VK_UP);\r
2254                 if (direction == BACKWARD) {\r
2255                         Kdu(VK_DOWN);\r
2256                 }\r
2257                 AdKduAu('N');\r
2258                 Kdu(VK_ESCAPE);\r
2259                 Kdu(VK_END);\r
2260 \r
2261                 CXkeymacsDll::SetModifierState(before, before & ~CONTROL);\r
2262         } else if (CUtils::IsLotusNotes()) {\r
2263                 BYTE bDirection = 0;\r
2264 \r
2265                 if (direction == FORWARD) {\r
2266                         bDirection = GetDirectionForwardKey();\r
2267                 } else if (direction == BACKWARD) {\r
2268                         bDirection = GetDirectionBackwardKey();\r
2269                 }\r
2270 \r
2271                 AdKduAu(GetSearchOptionKey(), bDirection, GetSearchOptionKey());\r
2272                 {\r
2273                         CString szDialogTitle;\r
2274                         CUtils::GetFindDialogTitle(&szDialogTitle);\r
2275 \r
2276                         if (!szDialogTitle.Compare(_T("\8c\9f\8dõ"))\r
2277                          || !szDialogTitle.Compare(_T("Find"))) {\r
2278                                 SdKduSu(VK_TAB);\r
2279                         } else {\r
2280                                 SdKduSu(VK_TAB, VK_TAB);\r
2281                         }\r
2282                 }\r
2283                 Kdu(VK_END);\r
2284         } else if (CUtils::IsBecky()) {\r
2285                 AdKduAu(GetDirectionForwardKey());\r
2286                 if (direction == BACKWARD) {\r
2287                         Kdu(VK_UP);\r
2288                 }\r
2289                 Kdu(VK_TAB, VK_TAB, VK_TAB, VK_TAB);\r
2290                 Kdu(VK_END);\r
2291         } else if (CUtils::IsMozilla()\r
2292                         || CUtils::IsNetscape()) {\r
2293                 Kdu(VK_TAB, VK_TAB, VK_TAB, VK_SPACE);\r
2294                 SdKduSu(VK_TAB, VK_TAB, VK_TAB);\r
2295         } else if (CUtils::IsezHTML()) {\r
2296                 BYTE bDirection = 0;\r
2297 \r
2298                 if (direction == FORWARD) {\r
2299                         bDirection = GetDirectionForwardKey();\r
2300                 } else if (direction == BACKWARD) {\r
2301                         bDirection = GetDirectionBackwardKey();\r
2302                 }\r
2303 \r
2304                 AdKduAu(bDirection);\r
2305                 SdKduSu(VK_TAB, VK_TAB, VK_TAB, VK_TAB);\r
2306         } else {\r
2307                 // default\r
2308                 BYTE bDirection = 0;\r
2309 \r
2310                 if (direction == FORWARD) {\r
2311                         bDirection = GetDirectionForwardKey();\r
2312                 } else if (direction == BACKWARD) {\r
2313                         bDirection = GetDirectionBackwardKey();\r
2314                 }\r
2315 \r
2316 //              CUtils::Log(_T("aSetSearchDirection: Direction = %c, FindWhatKey = %c"), bDirection, GetFindWhatKey());\r
2317                 AdKduAu(bDirection, GetFindWhatKey());\r
2318         }\r
2319 }\r
2320 \r
2321 // C-x C-j, C-o, C-\, C-BACKSLASH\r
2322 int CCommands::ToggleInputMethod()\r
2323 {\r
2324         SetInputMethodOpenStatus(TOGGLE_INPUT_METHOD);\r
2325         return Reset(GOTO_HOOK);\r
2326 }\r
2327 \r
2328 int CCommands::CompleteToggleInputMethod()\r
2329 {\r
2330         SetInputMethodOpenStatus(TOGGLE_INPUT_METHOD, TRUE);\r
2331         return Reset(GOTO_HOOK);\r
2332 }\r
2333 \r
2334 int CCommands::OpenInputMethod()\r
2335 {\r
2336         SetInputMethodOpenStatus(OPEN_INPUT_METHOD);\r
2337         return Reset(GOTO_HOOK);\r
2338 }\r
2339 \r
2340 int CCommands::CloseInputMethod()\r
2341 {\r
2342         SetInputMethodOpenStatus(CLOSE_INPUT_METHOD);\r
2343         return Reset(GOTO_HOOK);\r
2344 }\r
2345 \r
2346 int CCommands::CompleteCloseInputMethod()\r
2347 {\r
2348         SetInputMethodOpenStatus(CLOSE_INPUT_METHOD, TRUE);\r
2349         return Reset(GOTO_HOOK);\r
2350 }\r
2351 \r
2352 void CCommands::SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete)\r
2353 {\r
2354         ClearNumericArgument();\r
2355         HKL hKL = GetKeyboardLayout(0);\r
2356         if (CUtils::IsConsole()) {\r
2357                 Kdu(VK_KANJI);\r
2358         } else if (ImmIsIME(hKL)) {\r
2359                 // default\r
2360                 HWND hWnd = GetFocus();\r
2361                 HIMC hIMC = ImmGetContext(hWnd);\r
2362                 //CUtils::Log(_T(" do ime manip, %d, %d, %d, %p, %p"), status, isComplete, ImmGetOpenStatus(hIMC), hWnd, hIMC);\r
2363 \r
2364                 if (isComplete && ImmGetOpenStatus(hIMC)) {\r
2365                         ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);\r
2366                 }\r
2367 \r
2368                 switch (status) {\r
2369                 case CLOSE_INPUT_METHOD:\r
2370                         ImmSetOpenStatus(hIMC, FALSE);\r
2371                         break;\r
2372                 case OPEN_INPUT_METHOD:\r
2373                         ImmSetOpenStatus(hIMC, TRUE);\r
2374                         break;\r
2375                 case TOGGLE_INPUT_METHOD:\r
2376                         ImmSetOpenStatus(hIMC, !ImmGetOpenStatus(hIMC));\r
2377                         break;\r
2378                 default:\r
2379                         ASSERT(0);\r
2380                         break;\r
2381                 }\r
2382 \r
2383                 ImmReleaseContext(hWnd, hIMC);\r
2384         } else {\r
2385                 Kdu(VK_KANJI);\r
2386         }\r
2387 }\r
2388 \r
2389 // C-x k: Ctrl+F4\r
2390 int CCommands::KillBuffer()\r
2391 {\r
2392         CdKduCu(VK_F4);\r
2393         return Reset(GOTO_HOOK);\r
2394 }\r
2395 \r
2396 BOOL CCommands::IsKillCommand(int (*nFunctionPointer)())\r
2397 {\r
2398         for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
2399                 if (CmdTable::Command(nComID) == nFunctionPointer)\r
2400                         return !_tcsncmp(CmdTable::Name(nComID), _T("kill-"), 5);\r
2401         return FALSE;\r
2402 }\r
2403 \r
2404 void CCommands::SetLastCommand(int (__cdecl *LastCommand)(void))\r
2405 {\r
2406         m_LastCommand = LastCommand;\r
2407 \r
2408         if (IsKillCommand(LastCommand)) {\r
2409                 m_LastKillCommand = LastCommand;\r
2410         }\r
2411 }\r
2412 \r
2413 // M-d: \r
2414 int CCommands::KillWord()\r
2415 {\r
2416         if (CUtils::IsMicrosoftPowerPoint()\r
2417          || CUtils::IsThunderbird()) {\r
2418                 CdKduCu(VK_DELETE);\r
2419                 return Reset(GOTO_HOOK);\r
2420         }\r
2421 \r
2422         static int nStep = 0;\r
2423         static CString szClipboardText;\r
2424         static int nWhiteSpace = 0;\r
2425         switch (nStep) {\r
2426         case 0:\r
2427 //              CUtils::Log(_T("M-d: 0"));\r
2428                 ClearNumericArgument();\r
2429                 szClipboardText.Empty();\r
2430                 nWhiteSpace = 0;\r
2431                 CdSdKduSuCu(VK_RIGHT);\r
2432                 CdKduCu('X');\r
2433                 nStep = 1;\r
2434                 return Reset(GOTO_RECURSIVE);\r
2435         case 1:\r
2436                 {\r
2437 //                      CUtils::Log(_T("M-d: 1"));\r
2438                         nStep = 0;\r
2439                         CUtils::GetClipboardText(szClipboardText);\r
2440                         int nWordEnd = szClipboardText.GetLength();\r
2441                         int nFirstSpace = szClipboardText.Find(_T(' '));\r
2442 //                      CUtils::Log(_T("M-d: 1-1 _%s_%c"), szClipboardText, szClipboardText.GetAt(szClipboardText.GetLength() - 1));\r
2443                         if (nFirstSpace == 0) {\r
2444 //                              CUtils::Log(_T("M-d: 1-1-1"));\r
2445                                 nStep = 0;\r
2446                                 return Reset(GOTO_RECURSIVE);\r
2447                         } else if (0 < nFirstSpace) {\r
2448 //                              CUtils::Log(_T("M-d: 1-1-2"));\r
2449                                 nWordEnd = nFirstSpace; // (nFirstSpace + 1) - 1\r
2450                         }\r
2451                         int nFirstTab = szClipboardText.Find(_T('\t'));\r
2452                         if (nFirstTab == 0) {\r
2453 //                              CUtils::Log(_T("M-d: 1-2-1"));\r
2454                                 nStep = 0;\r
2455                                 return Reset(GOTO_RECURSIVE);\r
2456                         } else if (0 < nFirstTab && nFirstTab < nWordEnd) {\r
2457 //                              CUtils::Log(_T("M-d: 1-2-2"));\r
2458                                 nWordEnd = nFirstTab;   // (nFirstTab + 1) - 1\r
2459                         }\r
2460                         if (nWordEnd == szClipboardText.GetLength()) {\r
2461 //                              CUtils::Log(_T("M-d: 1-3-1"));\r
2462                                 nStep = 4;\r
2463                         } else {\r
2464 //                              CUtils::Log(_T("M-d: 1-3-2"));\r
2465                                 CString szEndWhiteSpace;\r
2466                                 nWhiteSpace = szClipboardText.GetLength() - nWordEnd;\r
2467                                 szEndWhiteSpace = szClipboardText.Right(nWhiteSpace);\r
2468                                 CUtils::SetClipboardText(szEndWhiteSpace);\r
2469                                 szClipboardText = szClipboardText.Left(nWordEnd);\r
2470                                 nStep = 2;\r
2471                         }\r
2472                         return Reset(GOTO_RECURSIVE);\r
2473                 }\r
2474         case 2:\r
2475 //              CUtils::Log(_T("M-d: 2"));\r
2476                 nStep = 0;\r
2477                 CdKduCu('V');\r
2478                 nStep = 3;\r
2479                 return Reset(GOTO_RECURSIVE);\r
2480         case 3:\r
2481 //              CUtils::Log(_T("M-d: 3"));\r
2482                 nStep = 0;\r
2483                 m_bDefaultNumericArgument = FALSE;\r
2484                 m_nNumericArgument = nWhiteSpace;\r
2485                 Kdu(VK_LEFT);\r
2486                 nStep = 4;\r
2487                 return Reset(GOTO_RECURSIVE);\r
2488         case 4:\r
2489 //              CUtils::Log(_T("M-d: 4"));\r
2490                 nStep = 0;\r
2491                 CUtils::SetClipboardText(szClipboardText);\r
2492                 nStep = 5;\r
2493                 return Reset(GOTO_RECURSIVE);\r
2494         case 5:\r
2495 //              CUtils::Log(_T("M-d: 5"));\r
2496                 nStep = 0;\r
2497                 CXkeymacsDll::AddKillRing();\r
2498                 m_bSetMark = FALSE;\r
2499                 return Reset(GOTO_HOOK);\r
2500         }\r
2501         // dummy\r
2502         return Reset(GOTO_HOOK);\r
2503 }\r
2504 \r
2505 // M-DEL\r
2506 int CCommands::BackwardKillWord()\r
2507 {\r
2508         CdSdKduSuCu(VK_LEFT);\r
2509         Cut_();\r
2510         return Reset(GOTO_HOOK);\r
2511 }\r
2512 \r
2513 // Select All\r
2514 int CCommands::SelectAll()\r
2515 {\r
2516         if (CUtils::IsConsole()) {\r
2517                 SystemMenuEdit(CMD_SELECT_ALL);\r
2518         } else {\r
2519                 CdKduCu('A');\r
2520         }\r
2521         return Reset(GOTO_HOOK);\r
2522 }\r
2523 \r
2524 // C-x (\r
2525 int CCommands::StartKbdMacro()\r
2526 {\r
2527         if (CUtils::IsMicrosoftWord())\r
2528                 AdKduAu('T', 'M', 'R');\r
2529         else if (CUtils::IsHidemaru())\r
2530                 SdKduSu(VK_F1);\r
2531         else {\r
2532                 if (bC_u())\r
2533                         m_KbdMacro.Call();\r
2534                 m_KbdMacro.Start();\r
2535                 CXkeymacsDll::SetKbMacro(&m_KbdMacro);\r
2536         }\r
2537         return Reset(GOTO_HOOK);\r
2538 }\r
2539 \r
2540 // C-x )\r
2541 int CCommands::EndKbdMacro()\r
2542 {\r
2543         if (CUtils::IsMicrosoftWord())\r
2544                 AdKduAu('T', 'M', 'R');\r
2545         else if (CUtils::IsHidemaru())\r
2546                 SdKduSu(VK_F1);\r
2547         else {\r
2548                 m_KbdMacro.End();\r
2549                 CXkeymacsDll::SetKbMacro(NULL);\r
2550         }\r
2551         return Reset(GOTO_HOOK);\r
2552 }\r
2553 \r
2554 // C-x e\r
2555 int CCommands::CallLastKbdMacro()\r
2556 {\r
2557         if (CUtils::IsMicrosoftWord())\r
2558                 AdKduAu('T', 'M', 'M');\r
2559         else if (CUtils::IsHidemaru()) {\r
2560                 int n = 1;\r
2561                 if (!m_bDefaultNumericArgument)\r
2562                         n = m_nNumericArgument;\r
2563                 ClearNumericArgument();\r
2564                 while (n--)\r
2565                         AdKduAu('M', 'P');\r
2566         } else {\r
2567                 EndKbdMacro();\r
2568                 while (m_nNumericArgument--)\r
2569                         m_KbdMacro.Call();\r
2570         }\r
2571         return Reset(GOTO_HOOK);\r
2572 }\r
2573 \r
2574 int CCommands::SwitchBetweenInputLocales()\r
2575 {\r
2576         UINT before = CXkeymacsDll::GetModifierState();\r
2577         CXkeymacsDll::SetModifierState(0, before);\r
2578 \r
2579         // Alt+Shift\r
2580         CXkeymacsDll::SetModifierState(SHIFT | META, 0);\r
2581         CXkeymacsDll::SetModifierState(0, SHIFT | META);\r
2582 \r
2583         CXkeymacsDll::SetModifierState(before, 0);\r
2584 \r
2585         return Reset(GOTO_HOOK);\r
2586 }\r
2587 \r
2588 // C-x b\r
2589 int CCommands::SwitchToBuffer()\r
2590 {\r
2591         ClearNumericArgument();\r
2592         // GetWindowInfo does not get information to find out if the window is MDI or SDI.\r
2593         CdKduCu(VK_TAB);\r
2594         return Reset(GOTO_HOOK);\r
2595 }\r
2596 \r
2597 int CCommands::C_()\r
2598 {\r
2599         return Reset(GOTO_HOOKX);\r
2600 }\r
2601 \r
2602 int CCommands::C_Eisu()\r
2603 {\r
2604         bC_(TRUE);\r
2605         return Reset(GOTO_HOOKX);\r
2606 }\r
2607 \r
2608 int CCommands::Escape()\r
2609 {\r
2610         ClearNumericArgument();\r
2611         Kdu(VK_ESCAPE);\r
2612         return Reset(GOTO_HOOK);\r
2613 }\r
2614 \r
2615 int CCommands::Tilde()\r
2616 {\r
2617         ClearNumericArgument();\r
2618         if (CXkeymacsDll::Is106Keyboard()) {\r
2619                 SdKduSu(0xDE);  // VK_OEM_7             Used for miscellaneous characters; it can vary by keyboard. \r
2620                 Su();                   //                              Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
2621         } else {\r
2622                 SdKduSu(0xC0);  // VK_OEM_3             Used for miscellaneous characters; it can vary by keyboard. \r
2623                 Su();                   //                              Windows 2000/XP: For the US standard keyboard, the '`~' key\r
2624         }\r
2625         return Reset(GOTO_HOOK);\r
2626 }\r
2627 \r
2628 int CCommands::BackQuote()\r
2629 {\r
2630         ClearNumericArgument();\r
2631         if (CXkeymacsDll::Is106Keyboard()) {\r
2632                 SdKduSu(0xC0);\r
2633                 Su();\r
2634         } else {\r
2635                 ReleaseKey(VK_SHIFT);\r
2636                 Kdu(0xC0);      // VK_OEM_3             Used for miscellaneous characters; it can vary by keyboard. \r
2637                                         //                              Windows 2000/XP: For the US standard keyboard, the '`~' key\r
2638         }\r
2639         return Reset(GOTO_HOOK);\r
2640 }\r
2641 \r
2642 BOOL CCommands::IsSetMark()\r
2643 {\r
2644         return m_bSetMark;\r
2645 }\r
2646 \r
2647 BYTE CCommands::GetFindWhatKey()\r
2648 {\r
2649         BYTE bFindWhat = 'N';\r
2650 \r
2651         if (CUtils::IsBecky()\r
2652          || CUtils::IsDana()\r
2653          || CUtils::IsEclipse()\r
2654          || CUtils::IsezHTML()\r
2655          || CUtils::IsLotusNotes()\r
2656          || CUtils::IsVisualBasicEditor()) {\r
2657                 bFindWhat = 'F';\r
2658         } else if (CUtils::IseMemoPad()) {\r
2659                 bFindWhat = 'K';\r
2660         } else if (CUtils::IsHidemaru()\r
2661                         || CUtils::IsJmEditor()) {\r
2662                 bFindWhat = 'S';\r
2663         } else if (CUtils::IsBorlandCppBuilder()\r
2664                         || CUtils::IsNami2000()\r
2665                         || CUtils::IsStoryEditor()\r
2666                         || CUtils::IsTeraPad()) {\r
2667                 bFindWhat = 'T';\r
2668         } else if (CUtils::IsAdobeReader()\r
2669                         || CUtils::IsAutla()\r
2670                         || CUtils::IsCodeWarrior()\r
2671                         || CUtils::IsFirefox()\r
2672                         || CUtils::IsFlash()\r
2673                         || CUtils::IsIPMessenger()\r
2674                         || CUtils::IsK2Editor()\r
2675                         || CUtils::IsOedit()\r
2676                         || CUtils::IsOpera()\r
2677                         || CUtils::IsOpenJane()\r
2678                         || CUtils::IsPHPEditor()\r
2679                         || CUtils::IsSakuraEditor()) {\r
2680                 bFindWhat = 0;\r
2681         }\r
2682 \r
2683         return bFindWhat;\r
2684 }\r
2685 \r
2686 BYTE CCommands::GetSearchOptionKey()\r
2687 {\r
2688         BYTE bSearchOption = 0;\r
2689 \r
2690         if (CUtils::IsLotusNotes()) {\r
2691                 bSearchOption = 'O';\r
2692         }\r
2693 \r
2694         return bSearchOption;\r
2695 }\r
2696 \r
2697 BYTE CCommands::GetDirectionForwardKey()\r
2698 {\r
2699         BYTE bDirectionForward = 'D';\r
2700         CString szDialogTitle;\r
2701         CUtils::GetFindDialogTitle(&szDialogTitle);\r
2702 \r
2703         if (CUtils::IsAdobeReader()\r
2704          || CUtils::IsAutla()\r
2705          || CUtils::IsCodeWarrior()\r
2706          || CUtils::IsDirector()\r
2707          || CUtils::IsDreamweaver()\r
2708          || CUtils::IsExcel()\r
2709          || CUtils::IsFirefox()\r
2710          || CUtils::IsFireworks()\r
2711          || CUtils::IsFlash()\r
2712          || CUtils::IsIPMessenger()\r
2713          || CUtils::IsJmEditor()\r
2714          || CUtils::IsLotus123()\r
2715          || CUtils::IsMicrosoftPowerPoint()\r
2716          || CUtils::IsOpera()\r
2717          || CUtils::IsOpenJane()\r
2718          || CUtils::IsStoryEditor()\r
2719          || CUtils::IsVisualBasicEditor()\r
2720          || CUtils::IsWordpad()) {\r
2721                 bDirectionForward = 0;\r
2722         } else if (CUtils::IsLotusNotes()\r
2723                         || CUtils::IsNami2000()\r
2724                         || CUtils::IsSakuraEditor()) {\r
2725                 bDirectionForward = 'D';\r
2726         } else if (CUtils::IsOedit()) {\r
2727                 bDirectionForward = 'F';\r
2728         } else if (CUtils::IsBecky()) {\r
2729                 if (!szDialogTitle.Compare(_T("\96{\95¶\93à\8c\9f\8dõ"))) {\r
2730                         bDirectionForward = 'O';\r
2731                 } else {\r
2732                         bDirectionForward = 0;\r
2733                 }\r
2734         } else if (CUtils::IsK2Editor()) {\r
2735                 bDirectionForward = 'L';\r
2736         } else if (CUtils::IseMemoPad()\r
2737                         || CUtils::IsHidemaru()) {\r
2738                 bDirectionForward = 'N';\r
2739         } else if (CUtils::IsEclipse()) {\r
2740                 bDirectionForward = 'O';\r
2741         }\r
2742 \r
2743         if (CUtils::IsOutlook()\r
2744          && !szDialogTitle.Compare(_T("Find"))) {\r
2745                 // Outlook (English version)\r
2746                 bDirectionForward = 0;\r
2747         }\r
2748 \r
2749         return bDirectionForward;\r
2750 }\r
2751 \r
2752 BYTE CCommands::GetDirectionBackwardKey()\r
2753 {\r
2754         BYTE bDirectionBackward = 'U';\r
2755         CString szDialogTitle;\r
2756         CUtils::GetFindDialogTitle(&szDialogTitle);\r
2757 \r
2758         if (CUtils::IsAdobeReader()\r
2759          || CUtils::IsAutla()\r
2760          || CUtils::IsCodeWarrior()\r
2761          || CUtils::IsDirector()\r
2762          || CUtils::IsDreamweaver()\r
2763          || CUtils::IsExcel()\r
2764          || CUtils::IsFirefox()\r
2765          || CUtils::IsFireworks()\r
2766          || CUtils::IsFlash()\r
2767          || CUtils::IsIPMessenger()\r
2768          || CUtils::IsJmEditor()\r
2769          || CUtils::IsLotus123()\r
2770          || CUtils::IsMicrosoftPowerPoint()\r
2771          || CUtils::IsOpera()\r
2772          || CUtils::IsOpenJane()\r
2773          || CUtils::IsStoryEditor()\r
2774          || CUtils::IsVisualBasicEditor()\r
2775          || CUtils::IsWordpad()) {\r
2776                 bDirectionBackward = 0;\r
2777         } else if (CUtils::IsBorlandCppBuilder()\r
2778                         || CUtils::IsEclipse()\r
2779                         || CUtils::IseMemoPad()\r
2780                         || CUtils::IsLotusNotes()\r
2781                         || CUtils::IsNami2000()) {\r
2782                 bDirectionBackward = 'B';\r
2783         } else if (CUtils::IsBecky()) {\r
2784                 if (!szDialogTitle.Compare(_T("\96{\95¶\93à\8c\9f\8dõ"))) {\r
2785                         bDirectionBackward = 'B';\r
2786                 } else {\r
2787                         bDirectionBackward = 0;\r
2788                 }\r
2789         } else if (CUtils::IsHidemaru()\r
2790                         || CUtils::IsOedit()) {\r
2791                 bDirectionBackward = 'P';\r
2792         } else if (CUtils::IsK2Editor()\r
2793                         || CUtils::IsSakuraEditor()) {\r
2794                 bDirectionBackward = 'U';\r
2795         }\r
2796 \r
2797         if (CUtils::IsOutlook()\r
2798          && !szDialogTitle.Compare(_T("Find"))) {\r
2799                 // Outlook (English version)\r
2800                 bDirectionBackward = 0;\r
2801         }\r
2802 \r
2803         return bDirectionBackward;\r
2804 }\r
2805 \r
2806 void CCommands::SetMark(BOOL bSetMark)\r
2807 {\r
2808         m_bSetMark = bSetMark;\r
2809 }\r
2810 \r
2811 GOTO CCommands::MoveCaret(BYTE bVk, BOOL bCtrl)\r
2812 {\r
2813         switch (bVk) {\r
2814         case VK_PRIOR:\r
2815         case VK_NEXT:\r
2816         case VK_END:\r
2817         case VK_HOME:\r
2818         case VK_LEFT:\r
2819         case VK_UP:\r
2820         case VK_RIGHT:\r
2821         case VK_DOWN:\r
2822                 break;\r
2823         default:\r
2824                 return CONTINUE;\r
2825         }\r
2826 \r
2827         struct {\r
2828                 BYTE bVk;\r
2829                 BOOL bCtrl;\r
2830                 DWORD time;\r
2831         } static last;\r
2832 \r
2833         const DWORD time = GetTickCount();\r
2834 //      CUtils::Log(_T("%d - %d = %d, %d, %d"), time, last.time, time - last.time, CXkeymacsDll::GetMaxKeyInterval(), CXkeymacsDll::GetAccelerate());\r
2835         if (CXkeymacsDll::GetAccelerate() && bVk == last.bVk && bCtrl == last.bCtrl && time - last.time < CXkeymacsDll::GetMaxKeyInterval()) {\r
2836                 NumericArgument(CXkeymacsDll::GetAccelerate());\r
2837         }\r
2838         last.bVk = bVk;\r
2839         last.bCtrl = bCtrl;\r
2840         last.time = time;\r
2841 \r
2842         if (bCtrl) {\r
2843                 if (m_bSetMark)\r
2844                         CdSdKduSuCu(bVk);\r
2845                 else\r
2846                         CdKduCu(bVk);\r
2847                 return GOTO_HOOK;\r
2848         }\r
2849         if (!m_bSetMark) {\r
2850                 Kdu(bVk);\r
2851                 return GOTO_HOOK;\r
2852         }\r
2853         if (CUtils::IsShuriken()) {\r
2854                 static UINT before;\r
2855                 static int nStep = 0;\r
2856                 switch (nStep) {\r
2857                 case 0:\r
2858                         before = CXkeymacsDll::GetModifierState();\r
2859                         CXkeymacsDll::SetModifierState(SHIFT, before);\r
2860                         CXkeymacsDll::Kdu(bVk, m_nNumericArgument);\r
2861                         CXkeymacsDll::SetModifierState(before | SHIFT, SHIFT);\r
2862                         nStep = 1;\r
2863                         return GOTO_RECURSIVE;\r
2864                 case 1:\r
2865                         nStep = 0;\r
2866                         if (!(before & SHIFT))\r
2867                                 ReleaseKey(VK_SHIFT);\r
2868                         return GOTO_HOOK;\r
2869                 }\r
2870         }\r
2871         SdKduSu(bVk);\r
2872         return GOTO_HOOK;\r
2873 }\r
2874 \r
2875 int CCommands::PassThrough()\r
2876 {\r
2877         Reset();        // Why?\r
2878         return Reset(GOTO_HOOK);\r
2879 }\r
2880 \r
2881 int CCommands::Redo()\r
2882 {\r
2883         if (CUtils::IsCorelDRAW()) {\r
2884                 CdSdKduSuCu('Z');\r
2885         } else {\r
2886                 CdKduCu('Y');\r
2887         }\r
2888         return Reset(GOTO_HOOK);\r
2889 }\r
2890 \r
2891 int CCommands::TemporarilyDisableXKeymacs()\r
2892 {\r
2893 //      CUtils::Log(_T("SetTemporarilyDisableXKeymacs"));\r
2894         SetTemporarilyDisableXKeymacs(TRUE);\r
2895         Reset();        // Why?\r
2896         return Reset(GOTO_HOOK);\r
2897 }\r
2898 \r
2899 BOOL CCommands::IsTemporarilyDisableXKeymacs()\r
2900 {\r
2901         return m_bTemporarilyDisableXKeymacs;\r
2902 }\r
2903 \r
2904 void CCommands::SetTemporarilyDisableXKeymacs(BOOL bTemporarilyDisableXKeymacs)\r
2905 {\r
2906         m_bTemporarilyDisableXKeymacs = bTemporarilyDisableXKeymacs;\r
2907         CXkeymacsDll::ShowHookState();\r
2908 }\r
2909 \r
2910 int CCommands::New()\r
2911 {\r
2912         ClearNumericArgument();\r
2913         m_bSetMark = FALSE;\r
2914         CdKduCu('N');\r
2915         return Reset(GOTO_HOOK);\r
2916 }\r
2917 \r
2918 int CCommands::Print()\r
2919 {\r
2920         ClearNumericArgument();\r
2921         m_bSetMark = FALSE;\r
2922         CdKduCu('P');\r
2923         return Reset(GOTO_HOOK);\r
2924 }\r
2925 \r
2926 int CCommands::Find()\r
2927 {\r
2928         ClearNumericArgument();\r
2929         m_bSetMark = FALSE;\r
2930         CdKduCu('F');\r
2931         return Reset(GOTO_HOOK);\r
2932 }\r
2933 \r
2934 int CCommands::FindNext()\r
2935 {\r
2936         ClearNumericArgument();\r
2937         m_bSetMark = FALSE;\r
2938         Kdu(VK_F3);\r
2939         return Reset(GOTO_HOOK);\r
2940 }\r
2941 \r
2942 int CCommands::SystemMenu(const CONSOLE_MENU nDown)\r
2943 {\r
2944 //      CUtils::Log(_T("SystemMenu"));\r
2945         if (!CUtils::IsConsole()) {\r
2946                 return ERROR_SUCCESS;\r
2947         }\r
2948 \r
2949         RECT consoleWindowRect = {'\0'};\r
2950         if (!GetWindowRect(GetForegroundWindow(), &consoleWindowRect)) {\r
2951                 return GetLastError();\r
2952         }\r
2953 //      CUtils::Log(_T("t = %d, l = %d"), consoleWindowRect.top, consoleWindowRect.left);\r
2954 \r
2955         const POINT clickPoint = {consoleWindowRect.left + 5, consoleWindowRect.top + 5};\r
2956         int rc = Click(&clickPoint);\r
2957         if (rc != ERROR_SUCCESS) {\r
2958                 return rc;\r
2959         }\r
2960 \r
2961         if (nDown != CMD_EDIT) {\r
2962                 for (int i = 0; i <= nDown; ++i) {\r
2963                         Kdu(VK_DOWN);\r
2964                 }\r
2965                 Kdu(VK_UP);\r
2966                 Kdu(VK_RETURN);\r
2967         }\r
2968         return ERROR_SUCCESS;   // i.e. return 0;\r
2969 }\r
2970 \r
2971 int CCommands::SystemMenuEdit(const CONSOLE_MENU_EDIT nDown)\r
2972 {\r
2973         if (!CUtils::IsConsole()) {\r
2974                 return ERROR_SUCCESS;\r
2975         }\r
2976 \r
2977         SystemMenu(CMD_EDIT);\r
2978         RECT consoleWindowRect = {'\0'};\r
2979         if (!GetWindowRect(GetForegroundWindow(), &consoleWindowRect)) {\r
2980                 return GetLastError();\r
2981         }\r
2982 \r
2983         const int y = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) * 6 + 20;    // y = A + B * 6 + 20\r
2984         const POINT clickPoint = {consoleWindowRect.left + 50, consoleWindowRect.top + y};      // 146 <= y <= 161 on W2K       (146 + 161 + 1) / 2 = 154 = 19 + 19 x 6 + 21\r
2985         int rc = Click(&clickPoint);                                                                                                            // 157 <= y <= 172 on WXP       (157 + 172 + 1) / 2 = 165 = 26 + 20 x 6 + 19\r
2986         if (rc != ERROR_SUCCESS) {\r
2987                 return rc;\r
2988         }\r
2989 \r
2990         for (int i = 0; i <= nDown; ++i) {\r
2991                 Kdu(VK_DOWN);\r
2992         }\r
2993         Kdu(VK_UP);     // Why? Because Mark did not work well only one VK_DOWN (or seven VK_DOWNs).\r
2994 \r
2995         Kdu(VK_RETURN);\r
2996         return ERROR_SUCCESS;   // i.e. return 0;\r
2997 }\r
2998 \r
2999 int CCommands::Click(const POINT *const pClickPoint)\r
3000 {\r
3001         BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU, FALSE);\r
3002 \r
3003         POINT CursorPos = {'\0'};\r
3004         if (!GetCursorPos(&CursorPos)) {\r
3005                 return GetLastError();\r
3006         }\r
3007 \r
3008         if (!SetCursorPos(pClickPoint->x, pClickPoint->y)) {\r
3009                 return GetLastError();\r
3010         }\r
3011         if (CUtils::IsConsole()\r
3012          && bIsAltDown) {\r
3013                 ReleaseKey(VK_MENU);\r
3014         }\r
3015         mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());\r
3016         mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());\r
3017         if (!SetCursorPos(CursorPos.x, CursorPos.y)) {\r
3018                 return GetLastError();\r
3019         }\r
3020         return ERROR_SUCCESS;\r
3021 }\r
3022 \r
3023 // C-x C-t\r
3024 int CCommands::TransposeLines()\r
3025 {\r
3026         static int nStep = 0;\r
3027         switch (nStep) {\r
3028         case 0:\r
3029                 nStep = 0;\r
3030 //              CUtils::Log(_T("C-x C-t: 0"));\r
3031                 Kdu(VK_END);\r
3032                 CaptureClipboardData();\r
3033                 nStep = 1;\r
3034                 return Reset(GOTO_RECURSIVE);\r
3035         case 1:\r
3036                 nStep = 0;\r
3037 //              CUtils::Log(_T("C-x C-t: 1"));\r
3038                 if (!CopyNextCharacter()) {\r
3039                         return Reset(GOTO_DO_NOTHING);\r
3040                 }\r
3041                 nStep = 2;\r
3042                 return Reset(GOTO_RECURSIVE);\r
3043         case 2:\r
3044                 nStep = 0;\r
3045 //              CUtils::Log(_T("C-x C-t: 2"));\r
3046                 Su();\r
3047                 if (CUtils::IsEOF()) {\r
3048                         Kdu(VK_END, VK_RETURN, VK_UP, VK_END);\r
3049                 }\r
3050                 Kdu(VK_HOME);\r
3051                 nStep = 3;\r
3052                 return Reset(GOTO_RECURSIVE);\r
3053         case 3:\r
3054                 nStep = 0;\r
3055 //              CUtils::Log(_T("C-x C-t: 3"));\r
3056                 if (!CopyBackCharacter()) {\r
3057                         return Reset(GOTO_DO_NOTHING);\r
3058                 }\r
3059                 nStep = 4;\r
3060                 return Reset(GOTO_RECURSIVE);\r
3061         case 4:\r
3062                 nStep = 0;\r
3063 //              CUtils::Log(_T("C-x C-t: 4"));\r
3064                 Su();\r
3065                 if (CUtils::IsTOF()) {  // TOF\r
3066                         Kdu(VK_DOWN, VK_END);\r
3067 //                      CUtils::Log(_T("C-x C-t: TOF"));\r
3068                         nStep = 5;\r
3069                 } else {\r
3070                         nStep = 7;\r
3071                 }\r
3072                 return Reset(GOTO_RECURSIVE);\r
3073         case 5:\r
3074                 nStep = 0;\r
3075 //              CUtils::Log(_T("C-x C-t: 5"));\r
3076                 if (!CopyNextCharacter()) {\r
3077                         return Reset(GOTO_DO_NOTHING);\r
3078                 }\r
3079                 nStep = 6;\r
3080                 return Reset(GOTO_RECURSIVE);\r
3081         case 6:\r
3082                 nStep = 0;\r
3083 //              CUtils::Log(_T("C-x C-t: 6"));\r
3084                 Su();\r
3085                 if (CUtils::IsEOF()) {\r
3086                         Kdu(VK_END, VK_RETURN, VK_UP, VK_END);\r
3087 //                      CUtils::Log(_T("C-x C-t: EOF2"));\r
3088                 }\r
3089                 nStep = 7;\r
3090                 return Reset(GOTO_RECURSIVE);\r
3091         case 7:\r
3092                 nStep = 0;\r
3093 //              CUtils::Log(_T("C-x C-t: 7"));\r
3094                 Kdu(VK_UP, VK_HOME);\r
3095                 SdKduSu(VK_DOWN);\r
3096                 CdKduCu('X');\r
3097                 nStep = 8;\r
3098                 return Reset(GOTO_RECURSIVE);\r
3099         case 8:\r
3100                 nStep = 0;\r
3101 //              CUtils::Log(_T("C-x C-t: 8"));\r
3102                 Su();\r
3103                 Kdu(VK_DOWN);\r
3104                 CdKduCu('V');\r
3105                 nStep = 9;\r
3106                 return Reset(GOTO_RECURSIVE);\r
3107         case 9:\r
3108                 nStep = 0;\r
3109 //              CUtils::Log(_T("C-x C-t: 9"));\r
3110                 RestoreClipboardData();\r
3111                 break;\r
3112         }\r
3113         return Reset(GOTO_HOOK);\r
3114 }\r
3115 \r
3116 void CCommands::CaptureClipboardData(const int nID, const BOOL bTextOnly)\r
3117 {\r
3118 //      CUtils::Log("CaptureClipboardData: 1");\r
3119         {\r
3120                 int nSize = nID + 1;\r
3121                 if (m_oClipboardData.GetSize() < nSize) {\r
3122 //                      CUtils::Log("CaptureClipboardData: 2");\r
3123                         try {\r
3124                                 m_oClipboardData.SetSize(nSize);\r
3125                         }\r
3126                         catch (CMemoryException* e) {\r
3127                                 e->Delete();\r
3128 //                              CUtils::Log("CaptureClipboardData: SetSize() threw an exception");\r
3129                         }\r
3130                 }\r
3131         }\r
3132 \r
3133 //      CUtils::Log("CaptureClipboardData: 3");\r
3134         if (!m_oClipboardData[nID]) {\r
3135 //              CUtils::Log("CaptureClipboardData: 4");\r
3136                 try {\r
3137                         CClipboardSnap *pSnap = new CClipboardSnap;\r
3138                         if (!pSnap) {\r
3139 //                              CUtils::Log("CaptureClipboardData: 5");\r
3140                                 return;\r
3141                         }\r
3142                         m_oClipboardData.SetAt(nID, pSnap);\r
3143                 }\r
3144                 catch (CMemoryException* e) {\r
3145                         e->Delete();\r
3146 //                      CUtils::Log("CaptureClipboardData: 'new' threw an exception");\r
3147                 }\r
3148         }\r
3149 \r
3150 //      CUtils::Log("CaptureClipboardData: 6: nID=%d, size=%d", nID, m_oClipboardData.GetSize());\r
3151         BOOL bCapture = m_oClipboardData[nID]->Capture(bTextOnly);\r
3152 //      CUtils::Log("CaptureClipboardData: 7");\r
3153         Sleep(0);       // for OpenOffice\r
3154         bCapture = m_oClipboardData[nID]->Capture(bTextOnly);   // for "office drawing shape format". Can CClipboardSnap care this problem?\r
3155 \r
3156 //      CUtils::Log("CaptureClipboardData: 8");\r
3157         if (!bCapture) {\r
3158 //              CUtils::Log(_T("Can not Capture in CaptureClipboardData"));\r
3159                 delete m_oClipboardData[nID];\r
3160 //              CUtils::Log("CaptureClipboardData: 9");\r
3161                 m_oClipboardData.SetAt(nID, NULL);\r
3162 //              CUtils::Log("CaptureClipboardData: 10");\r
3163         }\r
3164 }\r
3165 \r
3166 void CCommands::RestoreClipboardData(const int nID)\r
3167 {\r
3168         if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {\r
3169                 m_oClipboardData[nID]->Restore();\r
3170         }\r
3171 }\r
3172 \r
3173 int CCommands::FindReturnFromClipboardData(const int nID)\r
3174 {\r
3175         if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {\r
3176                 return m_oClipboardData[nID]->FindReturn();\r
3177         }\r
3178         return -1;\r
3179 }\r
3180 \r
3181 BOOL CCommands::IsEmptyClipboardData(const int nID)\r
3182 {\r
3183         if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {\r
3184                 return m_oClipboardData[nID]->IsEmpty();\r
3185         }\r
3186         return FALSE;\r
3187 }\r
3188 \r
3189 void CCommands::PrintFunctionName(int (*nFunctionPointer)())\r
3190 {\r
3191         for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
3192                 if (CmdTable::Command(nComID) == nFunctionPointer)\r
3193                         CUtils::Log(_T("m_LastCommand: %s"), CmdTable::Name(nComID));\r
3194 }\r
3195 \r
3196 int CCommands::CapsLock()\r
3197 {\r
3198         ClearNumericArgument();\r
3199         Kdu(VK_CAPITAL);\r
3200         return Reset(GOTO_HOOK);\r
3201 }\r
3202 \r
3203 int CCommands::Underscore()\r
3204 {\r
3205         ClearNumericArgument();\r
3206         if (CXkeymacsDll::Is106Keyboard()) {\r
3207                 SdKduSu(0xE2);  // VK_OEM_102   Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard\r
3208                 Su();\r
3209         } else {\r
3210                 SdKduSu(0xBD);  // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key\r
3211                 Su();\r
3212         }\r
3213         return Reset(GOTO_HOOK);\r
3214 }\r
3215 \r
3216 int CCommands::RollUpUnroll()\r
3217 {\r
3218         return Maximize(ROLL_UP_UNROLL);\r
3219 }\r
3220 \r
3221 int CCommands::Retop()\r
3222 {\r
3223         RECT ClientRect = {'\0'};\r
3224         GetClientRect(GetFocus(), &ClientRect);\r
3225 \r
3226         for (int i = 0; i < 0x10000; ++i) {\r
3227                 POINT CaretPos = {'\0'};\r
3228                 GetCaretPos(&CaretPos);\r
3229                 if (ClientRect.top + 10 < CaretPos.y) {\r
3230                         SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);\r
3231                 } else {\r
3232                         return Reset(GOTO_HOOK);\r
3233                 }\r
3234         }\r
3235 \r
3236         Kdu(VK_UP, VK_DOWN);\r
3237         return Reset(GOTO_HOOK);\r
3238 }\r
3239 \r
3240 int CCommands::OneShotModifierShift()\r
3241 {\r
3242         // dummy\r
3243         ASSERT(0);\r
3244         static int i = 0;\r
3245         ++i;\r
3246         return Reset(GOTO_HOOK);\r
3247 }\r
3248 \r
3249 int CCommands::OneShotModifierShiftRepeat()\r
3250 {\r
3251         // dummy\r
3252         ASSERT(0);\r
3253         static int i = 0;\r
3254         ++i;\r
3255         return Reset(GOTO_HOOK);\r
3256 }\r
3257 \r
3258 int CCommands::OneShotModifierCtrl()\r
3259 {\r
3260         // dummy\r
3261         ASSERT(0);\r
3262         static int i = 0;\r
3263         ++i;\r
3264         return Reset(GOTO_HOOK);\r
3265 }\r
3266 \r
3267 int CCommands::OneShotModifierCtrlRepeat()\r
3268 {\r
3269         // dummy\r
3270         ASSERT(0);\r
3271         static int i = 0;\r
3272         ++i;\r
3273         return Reset(GOTO_HOOK);\r
3274 }\r
3275 \r
3276 int CCommands::OneShotModifierAlt()\r
3277 {\r
3278         // dummy\r
3279         ASSERT(0);\r
3280         static int i = 0;\r
3281         ++i;\r
3282         return Reset(GOTO_HOOK);\r
3283 }\r
3284 \r
3285 int CCommands::OneShotModifierAltRepeat()\r
3286 {\r
3287         // dummy\r
3288         ASSERT(0);\r
3289         static int i = 0;\r
3290         ++i;\r
3291         return Reset(GOTO_HOOK);\r
3292 }\r
3293 \r
3294 int CCommands::CycleItems()\r
3295 {\r
3296         ClearNumericArgument();\r
3297         AdKduAu(VK_ESCAPE);\r
3298         return Reset(GOTO_HOOK);\r
3299 }\r
3300 \r
3301 int CCommands::CycleItemsInversely()\r
3302 {\r
3303         ClearNumericArgument();\r
3304         AdSdKduSuAu(VK_ESCAPE);\r
3305         return Reset(GOTO_HOOK);\r
3306 }\r
3307 \r
3308 // M-t\r
3309 int CCommands::TransposeWords()\r
3310 {\r
3311         static int nStep = 0;\r
3312         switch (nStep) {\r
3313         case 0:\r
3314                 nStep = 0;\r
3315 //              CUtils::Log(_T("M-t: 0"));\r
3316                 CdKduCu(VK_LEFT);\r
3317                 CaptureClipboardData();\r
3318                 nStep = 1;\r
3319                 return Reset(GOTO_RECURSIVE);\r
3320         case 1:\r
3321                 nStep = 0;\r
3322 //              CUtils::Log(_T("M-t: 1"));\r
3323                 CdSdKduSuCu(VK_RIGHT);\r
3324                 CdKduCu('X');\r
3325                 nStep = 2;\r
3326                 return Reset(GOTO_RECURSIVE);\r
3327         case 2:\r
3328                 nStep = 0;\r
3329 //              CUtils::Log(_T("M-t: 2"));\r
3330                 Su();\r
3331                 CdKduCu(VK_RIGHT);\r
3332                 CdKduCu('V');\r
3333                 Kdu(VK_LEFT);\r
3334                 nStep = 3;\r
3335                 return Reset(GOTO_RECURSIVE);\r
3336         case 3:\r
3337                 nStep = 0;\r
3338 //              CUtils::Log(_T("M-t: 3"));\r
3339                 RestoreClipboardData();\r
3340                 break;\r
3341         }\r
3342         return Reset(GOTO_HOOK);\r
3343 }\r
3344 \r
3345 LRESULT CCommands::VScroll(UINT nSBCode, const int nTimes)\r
3346 {\r
3347         if (CUtils::IsMicrosoftWord()\r
3348          || CUtils::IsThunderbird()) {\r
3349                 RECT ClientRect = {'\0'};\r
3350                 GetClientRect(GetFocus(), &ClientRect);\r
3351 \r
3352                 POINT righttop = {ClientRect.right, ClientRect.top};\r
3353                 ClientToScreen(GetFocus(), &righttop);\r
3354 //              CUtils::Log(_T("righttop: x = %d, y = %d"), righttop.x, righttop.y);\r
3355 \r
3356                 POINT rightbottom = {ClientRect.right, ClientRect.bottom};\r
3357                 ClientToScreen(GetFocus(), &rightbottom);\r
3358 //              CUtils::Log(_T("rightbottom: x = %d, y = %d"), rightbottom.x, rightbottom.y);\r
3359 \r
3360 //              POINT CursorPos = {'\0'};\r
3361 //              GetCursorPos(&CursorPos);\r
3362 //              CUtils::Log(_T("VScroll: x = %d, y = %d"), CursorPos.x, CursorPos.y);\r
3363 \r
3364                 POINT scrollpos = {'\0'};\r
3365 \r
3366                 switch (nSBCode) {\r
3367                 case SB_LINEUP:\r
3368                         if (CUtils::IsMicrosoftWord()) {\r
3369                                 scrollpos.x = righttop.x + 8;   // 0 to 16\r
3370                                 scrollpos.y = righttop.y - 9;   // 1 to 17\r
3371                         } else if (CUtils::IsThunderbird()) {\r
3372                                 scrollpos.x = righttop.x - 10;  // 2 to 18\r
3373                                 scrollpos.y = righttop.y + 8;   // 0 to 16\r
3374                         }\r
3375                         break;\r
3376                 case SB_LINEDOWN:\r
3377                         if (CUtils::IsMicrosoftWord()) {\r
3378                                 scrollpos.x = rightbottom.x + 8;        //  0 to 16\r
3379                                 scrollpos.y = rightbottom.y - 60;       // 52 to 68\r
3380                         } else if (CUtils::IsThunderbird()) {\r
3381                                 scrollpos.x = rightbottom.x - 10;       // 2 to 18\r
3382                                 scrollpos.y = rightbottom.y - 9;        // 1 to 17\r
3383                         }\r
3384                         break;\r
3385                 default:\r
3386                         return 1;\r
3387                 }\r
3388 \r
3389                 int i = 0;\r
3390                 for (i = 0; i < nTimes; ++i) {\r
3391                         Click(&scrollpos);\r
3392                 }\r
3393 \r
3394                 return 0;\r
3395         }\r
3396 \r
3397         return SendMessage(GetFocus(), WM_VSCROLL, nSBCode, NULL);\r
3398 }\r
3399 \r
3400 // M-q\r
3401 int CCommands::FillParagraph()\r
3402 {\r
3403         static const int nFillColumn = 70; // tmp\r
3404         static CString szClipboardText;\r
3405         static int nOldLineLength = 0;\r
3406 \r
3407         ClearNumericArgument(); // tmp\r
3408 \r
3409         static int nStep = 0;\r
3410         switch (nStep) {\r
3411         case 0:         // Clear Selection\r
3412 //              CUtils::Log(_T("M-q: 0"));\r
3413                 nStep = 0;\r
3414 \r
3415                 CaptureClipboardData();\r
3416                 if (m_bSetMark) {\r
3417                         m_bSetMark = FALSE;\r
3418                 }\r
3419                 Kdu(VK_HOME);\r
3420                 nOldLineLength = 0;\r
3421 \r
3422                 nStep = 1;\r
3423                 return Reset(GOTO_RECURSIVE);\r
3424         case 1:         // Copy previous line\r
3425 //              CUtils::Log(_T("M-q: 1"));\r
3426                 nStep = 0;\r
3427 \r
3428                 if (!CopyPreviousLine()) {\r
3429                         return Reset(GOTO_DO_NOTHING);\r
3430                 }\r
3431 \r
3432                 nStep = 2;\r
3433                 return Reset(GOTO_RECURSIVE);\r
3434         case 2:         // Check previous line to find TOP (top of paragraph)\r
3435 //              CUtils::Log(_T("M-q: 2"));\r
3436                 nStep = 0;\r
3437 \r
3438                 CUtils::GetClipboardText(szClipboardText);\r
3439 //              CUtils::Log(_T("M-q: 2-1: _%s_"), szClipboardText);\r
3440                 if (szClipboardText.IsEmpty()) {\r
3441                         // TOF\r
3442 //                      CUtils::Log(_T("M-q: 2: TOF"));\r
3443                         Kdu(VK_HOME);\r
3444                         nStep = 3;\r
3445                 } else if (szClipboardText == _T("\r\n")\r
3446                                 || szClipboardText == _T("\r")\r
3447                                 || szClipboardText == _T("\n")) {\r
3448                         // blank line i.e. top of paragraph\r
3449                         // UNIX: LF "\n"\r
3450                         // WINDOWS: CR LF "\r\n"\r
3451                         // MAC: CR "\r"\r
3452 //                      CUtils::Log(_T("M-q: 2: TOP"));\r
3453                         Kdu(VK_DOWN);\r
3454                         nStep = 3;\r
3455                 } else {\r
3456                         // middle of paragraph\r
3457 //                      CUtils::Log(_T("M-q: 2: MOP_%d_"), szClipboardText.GetLength());\r
3458 //                      CUtils::Log(_T("M-q: 2: MOP_%c(%d)%c(%d)"), szClipboardText.GetAt(0), szClipboardText.GetAt(0), szClipboardText.GetAt(1), szClipboardText.GetAt(1));\r
3459                         Kdu(VK_HOME);\r
3460                         nStep = 1;\r
3461                 }\r
3462 \r
3463                 return Reset(GOTO_RECURSIVE);\r
3464         case 3:         // Go to EOL to copy a current line at the next step\r
3465 //              CUtils::Log(_T("M-q: 3"));\r
3466                 nStep = 0;\r
3467 \r
3468                 Kdu(VK_END);\r
3469 \r
3470                 nStep = 4;\r
3471                 return Reset(GOTO_RECURSIVE);\r
3472         case 4:         // Copy a current line\r
3473 //              CUtils::Log(_T("M-q: 4"));\r
3474                 nStep = 0;\r
3475 \r
3476                 if (!CopyCurrentLine()) {\r
3477                         return Reset(GOTO_DO_NOTHING);\r
3478                 }\r
3479 \r
3480                 nStep = 5;\r
3481                 return Reset(GOTO_RECURSIVE);\r
3482         case 5:         // Just release shift\r
3483 //              CUtils::Log(_T("M-q: 5"));\r
3484                 nStep = 0;\r
3485 \r
3486                 ReleaseKey(VK_SHIFT);\r
3487 \r
3488                 nStep = 6;\r
3489                 return Reset(GOTO_RECURSIVE);\r
3490         case 6:         // Check current line and fill paragraph\r
3491 //              CUtils::Log(_T("M-q: 6"));\r
3492                 nStep = 0;\r
3493 \r
3494                 CUtils::GetClipboardText(szClipboardText);\r
3495                 if (szClipboardText.GetLength() == nOldLineLength + 1) {\r
3496 //                      CUtils::Log(_T("M-q: 6-1 Finished"));\r
3497                         Kdu(VK_END, VK_BACK, VK_RETURN);\r
3498                         nStep = 8;\r
3499                 } else if (szClipboardText.GetLength() < nFillColumn) {\r
3500 //                      CUtils::Log(_T("M-q: 6-2 This line is too small"));\r
3501                         Kdu(VK_END, VK_SPACE, VK_DELETE, VK_HOME);\r
3502                         nStep = 3;\r
3503                 } else {\r
3504 //                      CUtils::Log(_T("M-q: 6-3 %d_%s_%d"), szClipboardText.Left(nFillColumn).GetLength(), szClipboardText.Left(nFillColumn), szClipboardText.Left(nFillColumn).ReverseFind(_T(' ')));\r
3505                         const int offset = szClipboardText.Left(nFillColumn).ReverseFind(_T(' '));\r
3506                         if (offset == 0) {\r
3507 //                              CUtils::Log(_T("M-q: 6-3-1 TOL is space"));\r
3508                                 Kdu(VK_DELETE);\r
3509                         } else if (0 < offset) {\r
3510 //                              CUtils::Log(_T("M-q: 6-3-2"));\r
3511                                 ReleaseKey(VK_MENU); // FIXME\r
3512                                 for (int i = 0; i < offset; ++i) {\r
3513                                         Kdu(VK_RIGHT);\r
3514                                 }\r
3515                                 nStep = 7;\r
3516                                 return Reset(GOTO_RECURSIVE);\r
3517                         } else {\r
3518 //                              CUtils::Log(_T("M-q: 6-3-3 No space in first fill-column"));\r
3519                                 const int offset = szClipboardText.Find(_T(' '));\r
3520                                 if (offset < 0) {\r
3521                                         Kdu(VK_HOME, VK_DOWN);\r
3522                                 } else {\r
3523                                         ReleaseKey(VK_MENU); // FIXME\r
3524                                         for (int i = 0; i < offset; ++i) {\r
3525                                                 Kdu(VK_RIGHT);\r
3526                                         }\r
3527                                         nStep = 7;\r
3528                                         return Reset(GOTO_RECURSIVE);\r
3529                                 }\r
3530                         }\r
3531                         nStep = 3;\r
3532                 }\r
3533                 nOldLineLength = szClipboardText.GetLength();\r
3534 \r
3535                 return Reset(GOTO_RECURSIVE);\r
3536         case 7:         // Linefeed\r
3537 //              CUtils::Log(_T("M-q: 7"));\r
3538                 nStep = 0;\r
3539 \r
3540                 Kdu(VK_RETURN, VK_DELETE);\r
3541 \r
3542                 nStep = 3;\r
3543                 return Reset(GOTO_RECURSIVE);\r
3544         case 8:         // Restore clipboard data\r
3545 //              CUtils::Log(_T("M-q: 8"));\r
3546                 nStep = 0;\r
3547 \r
3548                 RestoreClipboardData();\r
3549 \r
3550                 return Reset(GOTO_HOOK);\r
3551         }\r
3552         return Reset(GOTO_HOOK);\r
3553 }\r
3554 \r
3555 // M-l\r
3556 int CCommands::DowncaseWord()\r
3557 {\r
3558         return CaseWord(DOWNCASE);\r
3559 }\r
3560 \r
3561 // M-u\r
3562 int CCommands::UpcaseWord()\r
3563 {\r
3564         return CaseWord(UPCASE);\r
3565 }\r
3566 \r
3567 // M-c\r
3568 int CCommands::CapitalizeWord()\r
3569 {\r
3570         return CaseWord(CAPITALIZE);\r
3571 }\r
3572 \r
3573 int CCommands::CaseWord(CASE_WORD nCase)\r
3574 {\r
3575         ClearNumericArgument(); // tmp\r
3576 \r
3577         // Do not try to do these command at once.\r
3578         // Clipboard has old data till you go out this function.\r
3579         static GOTO nNext = GOTO_HOOK;\r
3580         static int nStep = 0;\r
3581         static int nLastWhiteSpace = 0;\r
3582         static BOOL bFirstCharacter = TRUE;\r
3583         switch (nStep) {\r
3584         case 0:         // Clear Selection\r
3585                 nLastWhiteSpace = 0;\r
3586 \r
3587                 if (m_bSetMark) {\r
3588                         m_bSetMark = FALSE;\r
3589                         Kdu(VK_RIGHT, VK_LEFT);\r
3590                         nStep = 1;\r
3591                         return Reset(GOTO_RECURSIVE);\r
3592                 } else {\r
3593                         // Do nothing. Go to case 1:\r
3594                 }\r
3595         case 1:         // Get back character to confirm the cursor is at TOF or not.\r
3596                 nStep = 0;\r
3597 \r
3598                 CaptureClipboardData();\r
3599 \r
3600                 if (!CutFollowingWord()) {\r
3601                         return Reset(GOTO_DO_NOTHING);\r
3602                 }\r
3603 \r
3604                 nStep = 2;\r
3605                 return Reset(GOTO_RECURSIVE);\r
3606         case 2:\r
3607                 {\r
3608                         nStep = 0;\r
3609 \r
3610                         CString szClipboardText;\r
3611                         CUtils::GetClipboardText(szClipboardText);\r
3612 \r
3613                         CString szTrimmed = szClipboardText;\r
3614                         szTrimmed.TrimLeft();\r
3615                         if (szClipboardText.IsEmpty()) {\r
3616                                 nNext = GOTO_HOOK;\r
3617                                 RestoreClipboardData();\r
3618                                 return Reset(GOTO_HOOK);\r
3619                         } else if (szTrimmed.IsEmpty()) {\r
3620                                 if (nNext == GOTO_HOOK) {\r
3621                                         nNext = GOTO_RECURSIVE;\r
3622                                 } else {\r
3623                                         if (CUtils::IsHidemaru()) {\r
3624                                                 nLastWhiteSpace = 1;\r
3625                                         }\r
3626                                         nNext = GOTO_HOOK;\r
3627                                 }\r
3628                                 CUtils::SetClipboardText(szClipboardText);\r
3629                                 nStep = 3;\r
3630                                 return Reset(GOTO_RECURSIVE);\r
3631                         } else if (CUtils::IsHidemaru()) {\r
3632                                 nNext = GOTO_RECURSIVE;\r
3633                         } else {\r
3634                                 nNext = GOTO_HOOK;\r
3635                         }\r
3636 \r
3637                         switch (nCase) {\r
3638                         case DOWNCASE:\r
3639                                 szClipboardText.MakeLower();\r
3640                                 break;\r
3641                         case UPCASE:\r
3642                                 szClipboardText.MakeUpper();\r
3643                                 break;\r
3644                         case CAPITALIZE:\r
3645                                 {\r
3646                                         for (int i = 0; i < szClipboardText.GetLength(); ++i) {\r
3647                                                 if (_istspace(szClipboardText.GetAt(i))) {\r
3648                                                         continue;\r
3649                                                 } else if (bFirstCharacter) {\r
3650                                                         bFirstCharacter = FALSE;\r
3651                                                         if (_istlower(szClipboardText.GetAt(i))) {\r
3652                                                                 szClipboardText.SetAt(i, (TCHAR) toupper(szClipboardText.GetAt(i)));\r
3653                                                         }\r
3654                                                 } else {\r
3655                                                         if (_istupper(szClipboardText.GetAt(i))) {\r
3656                                                                 szClipboardText.SetAt(i, (TCHAR) tolower(szClipboardText.GetAt(i)));\r
3657                                                         }\r
3658                                                 }\r
3659                                         }\r
3660                                         break;\r
3661                                 }\r
3662                         default:\r
3663                                 ASSERT(0);\r
3664                         }\r
3665 \r
3666                         CUtils::SetClipboardText(szClipboardText);\r
3667 \r
3668                         nLastWhiteSpace = 0;\r
3669                         for (int j = szClipboardText.GetLength() - 1; !szClipboardText.IsEmpty() && 0 <= j; --j) {\r
3670                                 if (_istspace(szClipboardText.GetAt(j))) {\r
3671                                         ++nLastWhiteSpace;\r
3672                                 } else {\r
3673                                         break;\r
3674                                 }\r
3675                         }\r
3676 \r
3677                         nStep = 3;\r
3678                         return Reset(GOTO_RECURSIVE);\r
3679                 }\r
3680         case 3:\r
3681                 {\r
3682                         nStep = 0;\r
3683 \r
3684                         Paste();\r
3685 \r
3686                         for (int i = 0; i < nLastWhiteSpace; ++i) {\r
3687                                 Kdu(VK_LEFT);\r
3688                         }\r
3689 \r
3690                         nStep = 4;\r
3691                         return Reset(GOTO_RECURSIVE);\r
3692                 }\r
3693         case 4:\r
3694                 nStep = 0;\r
3695 \r
3696                 RestoreClipboardData();\r
3697 \r
3698                 if (nNext == GOTO_HOOK) {\r
3699                         bFirstCharacter = TRUE;\r
3700                 }\r
3701                 return Reset(nNext);\r
3702         }\r
3703 \r
3704         return Reset(GOTO_HOOK);\r
3705 }\r
3706 \r
3707 BOOL CCommands::CutFollowingWord()\r
3708 {\r
3709         if (!CUtils::OpenClipboard()) {\r
3710                 ASSERT(0);\r
3711                 return FALSE;\r
3712         }\r
3713         if (!EmptyClipboard()) {\r
3714                 ASSERT(0);\r
3715                 return FALSE;\r
3716         }\r
3717         if (!CloseClipboard()) {\r
3718                 ASSERT(0);\r
3719                 return FALSE;\r
3720         }\r
3721 \r
3722         if (CUtils::IsHidemaru()) {\r
3723                 // On Hidemaru, Cut_() does not work well after CdSdKduSuCu(). I do not know why.\r
3724                 SdKduSu(VK_RIGHT);\r
3725         } else {\r
3726                 CdSdKduSuCu(VK_RIGHT);\r
3727         }\r
3728         Cut_();\r
3729 \r
3730         return TRUE;\r
3731 }\r
3732 \r
3733 // M-x: execute-extended-command\r
3734 int CCommands::ExecuteExtendedCommand()\r
3735 {\r
3736 //      CUtils::Log(_T("ExecuteExtendedCommand"));\r
3737         bM_x(TRUE);\r
3738         return Reset(GOTO_HOOKX);\r
3739 }\r