OSDN Git Service

Sync Dialog Scroll the correct line number
[tortoisegit/TortoiseGitJp.git] / src / Utils / ACEdit.cpp
1 // ACEdit.cpp: Implementierungsdatei\r
2 //\r
3 \r
4 #include "stdafx.h"\r
5 #include "ACEdit.h"\r
6 #include  <io.h>\r
7 \r
8 \r
9 #ifdef _DEBUG\r
10 #define new DEBUG_NEW\r
11 #undef THIS_FILE\r
12 static char THIS_FILE[] = __FILE__;\r
13 #endif\r
14 \r
15 #define _EDIT_ 1\r
16 #define _COMBOBOX_ 2\r
17 \r
18 /////////////////////////////////////////////////////////////////////////////\r
19 // CACEdit\r
20 \r
21 CACEdit::CACEdit()\r
22 {\r
23         m_iMode = _MODE_STANDARD_;\r
24         m_iType = -1;\r
25         m_pEdit = NULL;\r
26         m_CursorMode = false;\r
27         m_PrefixChar = 0;\r
28 }\r
29 \r
30 /*********************************************************************/\r
31 \r
32 CACEdit::~CACEdit()\r
33 {\r
34         DestroyWindow();\r
35 }\r
36 \r
37 /*********************************************************************/\r
38 \r
39 BEGIN_MESSAGE_MAP(CACEdit, CWnd)\r
40         //{{AFX_MSG_MAP(CACEdit)\r
41         ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)\r
42         ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)\r
43         ON_WM_KEYDOWN()\r
44         ON_CONTROL_REFLECT(EN_CHANGE, OnChange)\r
45         ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnChange)\r
46         ON_CONTROL_REFLECT(CBN_DROPDOWN, OnCloseList)\r
47         //}}AFX_MSG_MAP\r
48         ON_MESSAGE(ENAC_UPDATE,OnUpdateFromList)\r
49 END_MESSAGE_MAP()\r
50 \r
51 /*********************************************************************/\r
52 \r
53 void CACEdit::SetMode(int iMode)\r
54 {\r
55         if(m_iType == -1)\r
56                 Init();\r
57 \r
58         m_iMode = iMode;\r
59 \r
60         /*\r
61         ** Vers. 1.1\r
62         ** NEW: _MODE_CURSOR_O_LIST_\r
63         */\r
64         if(iMode == _MODE_CURSOR_O_LIST_)\r
65                 m_iMode |= _MODE_STANDARD_;\r
66 \r
67         if(iMode & _MODE_FILESYSTEM_)\r
68                 m_SeparationStr = _T("\\");\r
69 \r
70         // Vers. 1.2\r
71         if(iMode & _MODE_FIND_ALL_)\r
72         {\r
73                 m_Liste.m_lMode |= _MODE_FIND_ALL_;\r
74         }\r
75 }\r
76 \r
77 /*********************************************************************/\r
78 \r
79 void CACEdit::Init()\r
80 {\r
81         CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,\r
82                 0,(HBRUSH) (COLOR_WINDOW), 0);\r
83         CRect rcWnd,rcWnd1;\r
84         GetWindowRect(rcWnd);\r
85 \r
86         VERIFY(m_Liste.CreateEx(WS_EX_TOOLWINDOW,\r
87                 szClassName,NULL,\r
88                 WS_THICKFRAME | WS_CHILD | WS_BORDER |\r
89                 WS_CLIPSIBLINGS | WS_OVERLAPPED,\r
90                 CRect(rcWnd.left, rcWnd.top +20, rcWnd.left+ 200, rcWnd.top+200),\r
91                 GetDesktopWindow(), \r
92                 0x3E8, NULL));\r
93 \r
94         CString m_ClassName;\r
95         ::GetClassName(GetSafeHwnd(), m_ClassName.GetBuffer(32), 32);\r
96         m_ClassName.ReleaseBuffer();\r
97 \r
98         if (m_ClassName.Compare(_T("Edit")) == 0)\r
99         {\r
100                 m_iType = _EDIT_;\r
101         }\r
102         else\r
103         {\r
104                 if (m_ClassName.Compare(_T("ComboBox")) == 0)\r
105                 {\r
106                         m_iType = _COMBOBOX_;\r
107 \r
108                         m_pEdit = (CEdit*)GetWindow(GW_CHILD);\r
109                         VERIFY(m_pEdit);\r
110                         ::GetClassName(m_pEdit->GetSafeHwnd(), m_ClassName.GetBuffer(32), 32);\r
111                         m_ClassName.ReleaseBuffer();\r
112                         VERIFY(m_ClassName.Compare(_T("Edit")) == 0);\r
113                 }\r
114         }\r
115 \r
116         if(m_iType == -1)\r
117         {\r
118                 ASSERT(0);\r
119                 return;\r
120         }\r
121 \r
122         m_Liste.Init(this);\r
123 }\r
124 \r
125 /*********************************************************************/\r
126 \r
127 void CACEdit::AddSearchStrings(LPCTSTR Strings[])\r
128 {\r
129         int i = 0;\r
130         LPCTSTR str;\r
131         if(m_iType == -1) {ASSERT(0); return;}\r
132 \r
133         m_Liste.RemoveAll();\r
134 \r
135         do\r
136         {\r
137                 str = Strings[i];\r
138                 if(str)\r
139                 {\r
140                         m_Liste.AddSearchString(str);\r
141                 }\r
142 \r
143                 i++;\r
144         }\r
145         while(str);\r
146 \r
147         m_Liste.SortSearchList();\r
148 }\r
149 \r
150 /*********************************************************************/\r
151 \r
152 void CACEdit::AddSearchString(LPCTSTR lpszString)\r
153 {\r
154         if(m_iType == -1) {ASSERT(0); return;} \r
155 \r
156         m_Liste.AddSearchString(lpszString);\r
157 }\r
158 \r
159 /*********************************************************************/\r
160 \r
161 void CACEdit::RemoveSearchAll()\r
162 {\r
163         if(m_iType == -1) {ASSERT(0); return;}\r
164 \r
165         m_Liste.RemoveAll();    \r
166 }\r
167 \r
168 /*********************************************************************/\r
169 \r
170 void CACEdit::OnKillfocus() \r
171 {\r
172         if(m_Liste.GetSafeHwnd()) // fix Vers 1.1\r
173                 m_Liste.ShowWindow(false);\r
174 }\r
175 \r
176 /*********************************************************************/\r
177 \r
178 void CACEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)\r
179 {\r
180         if(!HandleKey(nChar,false))\r
181                 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);\r
182 }\r
183 \r
184 /*********************************************************************/\r
185 \r
186 bool CACEdit::HandleKey(UINT nChar, bool m_bFromChild)\r
187 {\r
188         if (nChar == VK_ESCAPE ||nChar == VK_RETURN)\r
189         {\r
190                 m_Liste.ShowWindow(false);\r
191                 return true;\r
192         }\r
193 \r
194         if (nChar == VK_DOWN || nChar == VK_UP \r
195                 || nChar == VK_PRIOR || nChar == VK_NEXT\r
196                 || nChar == VK_HOME || nChar == VK_END) \r
197         {\r
198                 /*\r
199                 ** Vers. 1.1\r
200                 ** NEW: _MODE_CURSOR_O_LIST_\r
201                 */\r
202                 if(!m_Liste.IsWindowVisible() && (m_iMode & _MODE_CURSOR_O_LIST_))\r
203                 {\r
204                         GetWindowText(m_EditText);\r
205                         if(m_EditText.IsEmpty())\r
206                         {\r
207                                 m_Liste.CopyList();\r
208                                 return true;\r
209                         }       \r
210                 }\r
211 \r
212                 if(m_Liste.IsWindowVisible())\r
213                 {\r
214                         int pos;\r
215 \r
216 \r
217                         if(m_iMode & _MODE_STANDARD_ \r
218                                 || m_iMode & _MODE_FILESYSTEM_\r
219                                 || m_iMode & _MODE_FS_START_DIR_)\r
220                         {\r
221                                 m_CursorMode = true;\r
222 \r
223                                 if(!m_bFromChild)\r
224                                         m_EditText = m_Liste.GetNextString(nChar);\r
225                                 else\r
226                                         m_EditText = m_Liste.GetString();\r
227 \r
228                                 if(m_iMode & _MODE_FILESYSTEM_)\r
229                                 {\r
230                                         if (m_EditText.Right(1) == _T('\\'))\r
231                                                 m_EditText = m_EditText.Mid(0,m_EditText.GetLength()-1);\r
232                                 }\r
233 \r
234                                 m_Liste.SelectItem(-1);\r
235                                 SetWindowText(m_EditText);\r
236                                 pos = m_EditText.GetLength();\r
237 \r
238                                 if(m_iType == _COMBOBOX_)\r
239                                 {\r
240                                         m_pEdit->SetSel(pos,pos,true);\r
241                                         m_pEdit->SetModify(true);\r
242                                 }\r
243 \r
244                                 if(m_iType == _EDIT_)\r
245                                 {\r
246                                         ((CEdit*)this)->SetSel(pos,pos,true);\r
247                                         ((CEdit*)this)->SetModify(true);\r
248                                 }\r
249 \r
250                                 GetParent()->SendMessage(ENAC_UPDATE, WM_KEYDOWN, GetDlgCtrlID());\r
251                                 m_CursorMode = false;\r
252                                 return true;\r
253                         }\r
254 \r
255                         if(m_iMode & _MODE_SEPARATION_)\r
256                         {\r
257                                 CString m_Text,m_Left,m_Right;\r
258                                 int left,right,pos=0,len;\r
259 \r
260                                 m_CursorMode = true;\r
261 \r
262                                 GetWindowText(m_EditText);\r
263 \r
264                                 if(m_iType == _EDIT_)\r
265                                         pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));\r
266 \r
267                                 if(m_iType == _COMBOBOX_)\r
268                                         pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());\r
269 \r
270                                 left  = FindSepLeftPos(pos-1,true);\r
271                                 right = FindSepRightPos(pos);\r
272 \r
273                                 m_Text = m_EditText.Left(left);\r
274 \r
275                                 if(!m_bFromChild)\r
276                                         m_Text += m_Liste.GetNextString(nChar);\r
277                                 else\r
278                                         m_Text += m_Liste.GetString();\r
279 \r
280                                 m_Liste.SelectItem(-1);\r
281                                 m_Text += m_EditText.Mid(right);\r
282                                 len = m_Liste.GetString().GetLength();\r
283 \r
284                                 m_Text += this->m_SeparationStr;\r
285 \r
286                                 SetWindowText(m_Text);\r
287                                 GetParent()->SendMessage(ENAC_UPDATE, WM_KEYDOWN, GetDlgCtrlID());\r
288 \r
289                                 right = FindSepLeftPos2(pos-1);\r
290                                 left -= right;\r
291                                 len += right;\r
292 \r
293                                 left+=m_SeparationStr.GetLength();\r
294 \r
295                                 if(m_iType == _EDIT_)\r
296                                 {\r
297                                         ((CEdit*)this)->SetModify(true);\r
298                                         ((CEdit*)this)->SetSel(left+len,left+len,false);\r
299                                 }\r
300 \r
301                                 if(m_iType == _COMBOBOX_)\r
302                                 {\r
303                                         m_pEdit->SetModify(true);\r
304                                         m_pEdit->SetSel(left,left+len,true);\r
305                                 }\r
306 \r
307                                 m_CursorMode = false;\r
308                                 return true;\r
309                         }\r
310                 }\r
311         }\r
312         return false;\r
313 }\r
314 \r
315 /*********************************************************************/\r
316 \r
317 void CACEdit::OnChange() \r
318 {\r
319         CString m_Text;\r
320         int pos=0,len;\r
321 \r
322         if(m_iType == -1) \r
323         {ASSERT(0); return;}\r
324 \r
325         GetWindowText(m_EditText);\r
326         len = m_EditText.GetLength();\r
327         //----------------------------------------------\r
328         if(m_iMode & _MODE_FILESYSTEM_ || m_iMode & _MODE_FS_START_DIR_)\r
329         {\r
330                 if(!m_CursorMode)\r
331                 {\r
332                         if(m_iType == _EDIT_)\r
333                                 pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));\r
334 \r
335                         if(m_iType == _COMBOBOX_)\r
336                                 pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());\r
337 \r
338                         if(m_iMode & _MODE_FS_START_DIR_)\r
339                         {\r
340                                 if(len)\r
341                                         m_Liste.FindString(-1,m_EditText);\r
342                                 else\r
343                                         m_Liste.ShowWindow(false);\r
344                         }\r
345                         else\r
346                         {\r
347                                 if(len > 2 && pos == len)\r
348                                 {                       \r
349                                         if(_taccess(m_EditText,0) == 0)\r
350                                         {\r
351                                                 ReadDirectory(m_EditText);\r
352                                         }\r
353                                         m_Liste.FindString(-1,m_EditText);\r
354                                 }\r
355                                 else\r
356                                         m_Liste.ShowWindow(false);\r
357                         }\r
358                 } // m_CursorMode\r
359         }\r
360         //----------------------------------------------        \r
361         if(m_iMode & _MODE_SEPARATION_)\r
362         {\r
363                 if(!m_CursorMode)\r
364                 {\r
365                         if(m_iType == _EDIT_)\r
366                                 pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));\r
367 \r
368                         if(m_iType == _COMBOBOX_)\r
369                                 pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());\r
370 \r
371                         int left,right;\r
372                         left  = FindSepLeftPos(pos-1);\r
373                         right = FindSepRightPos(pos);\r
374                         m_Text = m_EditText.Mid(left,right-left);\r
375                         m_Liste.FindString(-1,m_Text);\r
376                 }\r
377         }\r
378         //----------------------------------------------\r
379         if(m_iMode & _MODE_STANDARD_)\r
380         {\r
381                 if(!m_CursorMode)\r
382                         m_Liste.FindString(-1,m_EditText);\r
383         }\r
384         //----------------------------------------------\r
385         GetParent()->SendMessage(ENAC_UPDATE, EN_UPDATE, GetDlgCtrlID());\r
386 }\r
387 \r
388 /*********************************************************************/\r
389 \r
390 int CACEdit::FindSepLeftPos(int pos,bool m_bIncludePrefix)\r
391 {\r
392         int len = m_EditText.GetLength(); \r
393         TCHAR ch;\r
394         int i;\r
395 \r
396         if(pos >= len && len != 1)\r
397                 pos =  len -1;\r
398 \r
399         for(i = pos; i >= 0 ; i--)\r
400         {\r
401                 ch = m_EditText.GetAt(i);\r
402                 if(m_PrefixChar == ch)\r
403                         return i + (m_bIncludePrefix ? 1 : 0);\r
404                 if(m_SeparationStr.Find(ch) != -1)\r
405                         break;\r
406         }\r
407 \r
408         return  i + 1;\r
409 }\r
410 \r
411 /*********************************************************************/\r
412 \r
413 int CACEdit::FindSepLeftPos2(int pos)\r
414 {\r
415         int len = m_EditText.GetLength(); \r
416         TCHAR ch;\r
417 \r
418         if(pos >= len && len != 1)\r
419                 pos =  len -1;\r
420 \r
421         if(len == 1)\r
422                 return 0;\r
423 \r
424         for(int i = pos; i >= 0 ; i--)\r
425         {\r
426                 ch = m_EditText.GetAt(i);\r
427                 if(m_PrefixChar == ch)\r
428                         return 1;\r
429         }\r
430 \r
431         return  0;\r
432 }\r
433 \r
434 /*********************************************************************/\r
435 \r
436 int CACEdit::FindSepRightPos(int pos)\r
437 {\r
438         int len = m_EditText.GetLength(); \r
439         TCHAR ch;\r
440         int i;\r
441 \r
442         for(i = pos; i < len ; i++)\r
443         {\r
444                 ch = m_EditText.GetAt(i);\r
445                 if(m_SeparationStr.Find(ch) != -1)\r
446                         break;\r
447         }\r
448 \r
449         return i;\r
450 }\r
451 \r
452 /*********************************************************************/\r
453 LRESULT CACEdit::OnUpdateFromList(WPARAM lParam, LPARAM /*wParam*/)\r
454 {\r
455         UpdateData(true);\r
456 \r
457         if(lParam == WM_KEYDOWN)\r
458         {\r
459                 HandleKey(VK_DOWN,true);\r
460         }\r
461         return 0;\r
462 }\r
463 \r
464 /*********************************************************************/\r
465 \r
466 void CACEdit::OnCloseList()\r
467 {\r
468         m_Liste.ShowWindow(false);\r
469 }\r
470 \r
471 /*********************************************************************/\r
472 \r
473 BOOL CACEdit::PreTranslateMessage(MSG* pMsg) \r
474 {\r
475         if(pMsg->message == WM_KEYDOWN)\r
476         {\r
477                 if(m_Liste.IsWindowVisible())\r
478                 {\r
479                         if(m_iType == _COMBOBOX_)\r
480                         {\r
481                                 if(pMsg->wParam == VK_DOWN || pMsg->wParam == VK_UP)\r
482                                         if(HandleKey(pMsg->wParam,false))\r
483                                                 return true;\r
484                         }\r
485 \r
486                         if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)\r
487                                 if(HandleKey(pMsg->wParam,false))\r
488                                         return true;\r
489                 }\r
490         }\r
491         return CWnd::PreTranslateMessage(pMsg);\r
492 }\r
493 \r
494 /*********************************************************************/\r
495 \r
496 void CACEdit::ReadDirectory(CString m_Dir)\r
497 {\r
498         CFileFind FoundFiles;\r
499         TCHAR ch;\r
500         CWaitCursor hg;\r
501 \r
502         // Wenn mittem im Pfad,\r
503         // vorheriges Verzeichnis einlesen.\r
504         if (m_Dir.Right(1) != _T('\\'))\r
505         {\r
506                 _tsplitpath(m_Dir, m_szDrive, m_szDir, m_szFname, m_szExt);\r
507                 m_Dir.Format(_T("%s%s"),m_szDrive, m_szDir);\r
508         }\r
509 \r
510         //ist hübscher\r
511         ch = (TCHAR)towupper(m_Dir.GetAt(0));\r
512         m_Dir.SetAt(0,ch);\r
513 \r
514         CString m_Name,m_File,m_Dir1 = m_Dir;   \r
515         if (m_Dir.Right(1) != _T('\\'))\r
516                 m_Dir += _T("\\");\r
517 \r
518         if(m_LastDirectory.CompareNoCase(m_Dir) == 0 && m_Liste.m_SearchList.GetSize())\r
519                 return;\r
520 \r
521         m_LastDirectory = m_Dir;\r
522         m_Dir += _T("*.*");\r
523 \r
524         BOOL bContinue = FoundFiles.FindFile(m_Dir);\r
525         if(bContinue)\r
526                 RemoveSearchAll();\r
527 \r
528         while (bContinue == TRUE)\r
529         {\r
530                 bContinue = FoundFiles.FindNextFile();\r
531                 m_File = FoundFiles.GetFileName();\r
532 \r
533                 if(FoundFiles.IsHidden() || FoundFiles.IsSystem())\r
534                         continue;\r
535                 if(FoundFiles.IsDirectory())\r
536                 {\r
537                         if(m_iMode & _MODE_ONLY_FILES)\r
538                                 continue;\r
539                         if(FoundFiles.IsDots())\r
540                                 continue;\r
541 \r
542                         if (m_File.Right(1) != _T('\\'))\r
543                                 m_File += _T("\\");\r
544                 }\r
545 \r
546                 if(!FoundFiles.IsDirectory())\r
547                         if(m_iMode & _MODE_ONLY_DIRS)\r
548                                 continue;\r
549 \r
550                 if(m_iMode & _MODE_FS_START_DIR_)\r
551                 {\r
552                         m_Name = m_File;\r
553                 }\r
554                 else\r
555                 {\r
556                         m_Name = m_Dir1;\r
557                         if (m_Name.Right(1) != _T('\\'))\r
558                                 m_Name += _T("\\");\r
559 \r
560                         m_Name += m_File;\r
561                 }\r
562 \r
563                 AddSearchString(m_Name);\r
564         }\r
565         FoundFiles.Close();\r
566         return;\r
567 \r
568 }\r
569 \r
570 /*********************************************************************/\r
571 \r
572 void CACEdit::SetStartDirectory(LPCTSTR lpszString)\r
573 {\r
574         if(m_iType == -1) {ASSERT(0); return;}\r
575 \r
576         if(m_iMode & _MODE_FS_START_DIR_)\r
577                 ReadDirectory(lpszString);\r
578 }\r
579 \r
580 /*********************************************************************\r
581 ** CComboBox \r
582 ** NEW:V1.1\r
583 *********************************************************************/\r
584 \r
585 int CACEdit::AddString( LPCTSTR lpszString )\r
586 {\r
587         if(m_iType == _COMBOBOX_)\r
588         {\r
589                 return ((CComboBox *)this)->AddString(lpszString);\r
590         }\r
591         return CB_ERR;\r
592 }\r
593 \r
594 /*********************************************************************/\r
595 \r
596 int CACEdit::SetDroppedWidth( UINT nWidth )\r
597 {\r
598         if(m_iType == _COMBOBOX_)\r
599         {\r
600                 return ((CComboBox *)this)->SetDroppedWidth(nWidth);\r
601         }\r
602         return CB_ERR;\r
603 }\r
604 \r
605 /*********************************************************************/\r
606 \r
607 int CACEdit::FindString( int nStartAfter, LPCTSTR lpszString )\r
608 {\r
609         if(m_iType == _COMBOBOX_)\r
610         {\r
611                 return ((CComboBox *)this)->FindString(nStartAfter,lpszString);\r
612         }\r
613         return CB_ERR;\r
614 }\r
615 \r
616 /*********************************************************************/\r
617 \r
618 int CACEdit::SelectString( int nStartAfter, LPCTSTR lpszString )\r
619 {\r
620         if(m_iType == _COMBOBOX_)\r
621         {\r
622                 return ((CComboBox *)this)->SelectString(nStartAfter,lpszString);\r
623         }\r
624         return CB_ERR;\r
625 }\r
626 \r
627 /*********************************************************************/\r
628 \r
629 void CACEdit::ShowDropDown(BOOL bShowIt)\r
630 {\r
631         if(m_iType == _COMBOBOX_)\r
632         {\r
633                 ((CComboBox *)this)->ShowDropDown(bShowIt);\r
634         }\r
635 }\r
636 \r
637 /*********************************************************************/\r
638 \r
639 void CACEdit::ResetContent()\r
640 {\r
641         if(m_iType == _COMBOBOX_)\r
642         {\r
643                 ((CComboBox *)this)->ResetContent();\r
644         }\r
645 }\r
646 \r
647 /*********************************************************************/\r
648 \r
649 int CACEdit::GetCurSel()\r
650 {\r
651         if(m_iType == _COMBOBOX_)\r
652         {\r
653                 return ((CComboBox *)this)->GetCurSel();\r
654         }\r
655         return CB_ERR;\r
656 }\r
657 \r
658 /*********************************************************************/\r
659 \r
660 int CACEdit::GetLBText( int nIndex, LPTSTR lpszText )\r
661 {\r
662         if(m_iType == _COMBOBOX_)\r
663         {\r
664                 return ((CComboBox *)this)->GetLBText(nIndex,lpszText);\r
665         }\r
666         return CB_ERR;\r
667 }\r
668 \r
669 /*********************************************************************/\r
670 \r
671 void CACEdit::GetLBText( int nIndex, CString& rString )\r
672 {\r
673         if(m_iType == _COMBOBOX_)\r
674         {\r
675                 ((CComboBox *)this)->GetLBText(nIndex,rString);\r
676         }\r
677 }\r
678 \r
679 /*********************************************************************/\r