OSDN Git Service

BrowseRefsDlg: Resizable
[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 \r
454 LONG CACEdit::OnUpdateFromList(UINT lParam, LONG /*wParam*/)\r
455 {\r
456         UpdateData(true);\r
457 \r
458         if(lParam == WM_KEYDOWN)\r
459         {\r
460                 HandleKey(VK_DOWN,true);\r
461         }\r
462         return 0;\r
463 }\r
464 \r
465 /*********************************************************************/\r
466 \r
467 void CACEdit::OnCloseList()\r
468 {\r
469         m_Liste.ShowWindow(false);\r
470 }\r
471 \r
472 /*********************************************************************/\r
473 \r
474 BOOL CACEdit::PreTranslateMessage(MSG* pMsg) \r
475 {\r
476         if(pMsg->message == WM_KEYDOWN)\r
477         {\r
478                 if(m_Liste.IsWindowVisible())\r
479                 {\r
480                         if(m_iType == _COMBOBOX_)\r
481                         {\r
482                                 if(pMsg->wParam == VK_DOWN || pMsg->wParam == VK_UP)\r
483                                         if(HandleKey(pMsg->wParam,false))\r
484                                                 return true;\r
485                         }\r
486 \r
487                         if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)\r
488                                 if(HandleKey(pMsg->wParam,false))\r
489                                         return true;\r
490                 }\r
491         }\r
492         return CWnd::PreTranslateMessage(pMsg);\r
493 }\r
494 \r
495 /*********************************************************************/\r
496 \r
497 void CACEdit::ReadDirectory(CString m_Dir)\r
498 {\r
499         CFileFind FoundFiles;\r
500         TCHAR ch;\r
501         CWaitCursor hg;\r
502 \r
503         // Wenn mittem im Pfad,\r
504         // vorheriges Verzeichnis einlesen.\r
505         if (m_Dir.Right(1) != _T('\\'))\r
506         {\r
507                 _tsplitpath(m_Dir, m_szDrive, m_szDir, m_szFname, m_szExt);\r
508                 m_Dir.Format(_T("%s%s"),m_szDrive, m_szDir);\r
509         }\r
510 \r
511         //ist hübscher\r
512         ch = (TCHAR)towupper(m_Dir.GetAt(0));\r
513         m_Dir.SetAt(0,ch);\r
514 \r
515         CString m_Name,m_File,m_Dir1 = m_Dir;   \r
516         if (m_Dir.Right(1) != _T('\\'))\r
517                 m_Dir += _T("\\");\r
518 \r
519         if(m_LastDirectory.CompareNoCase(m_Dir) == 0 && m_Liste.m_SearchList.GetSize())\r
520                 return;\r
521 \r
522         m_LastDirectory = m_Dir;\r
523         m_Dir += _T("*.*");\r
524 \r
525         BOOL bContinue = FoundFiles.FindFile(m_Dir);\r
526         if(bContinue)\r
527                 RemoveSearchAll();\r
528 \r
529         while (bContinue == TRUE)\r
530         {\r
531                 bContinue = FoundFiles.FindNextFile();\r
532                 m_File = FoundFiles.GetFileName();\r
533 \r
534                 if(FoundFiles.IsHidden() || FoundFiles.IsSystem())\r
535                         continue;\r
536                 if(FoundFiles.IsDirectory())\r
537                 {\r
538                         if(m_iMode & _MODE_ONLY_FILES)\r
539                                 continue;\r
540                         if(FoundFiles.IsDots())\r
541                                 continue;\r
542 \r
543                         if (m_File.Right(1) != _T('\\'))\r
544                                 m_File += _T("\\");\r
545                 }\r
546 \r
547                 if(!FoundFiles.IsDirectory())\r
548                         if(m_iMode & _MODE_ONLY_DIRS)\r
549                                 continue;\r
550 \r
551                 if(m_iMode & _MODE_FS_START_DIR_)\r
552                 {\r
553                         m_Name = m_File;\r
554                 }\r
555                 else\r
556                 {\r
557                         m_Name = m_Dir1;\r
558                         if (m_Name.Right(1) != _T('\\'))\r
559                                 m_Name += _T("\\");\r
560 \r
561                         m_Name += m_File;\r
562                 }\r
563 \r
564                 AddSearchString(m_Name);\r
565         }\r
566         FoundFiles.Close();\r
567         return;\r
568 \r
569 }\r
570 \r
571 /*********************************************************************/\r
572 \r
573 void CACEdit::SetStartDirectory(LPCTSTR lpszString)\r
574 {\r
575         if(m_iType == -1) {ASSERT(0); return;}\r
576 \r
577         if(m_iMode & _MODE_FS_START_DIR_)\r
578                 ReadDirectory(lpszString);\r
579 }\r
580 \r
581 /*********************************************************************\r
582 ** CComboBox \r
583 ** NEW:V1.1\r
584 *********************************************************************/\r
585 \r
586 int CACEdit::AddString( LPCTSTR lpszString )\r
587 {\r
588         if(m_iType == _COMBOBOX_)\r
589         {\r
590                 return ((CComboBox *)this)->AddString(lpszString);\r
591         }\r
592         return CB_ERR;\r
593 }\r
594 \r
595 /*********************************************************************/\r
596 \r
597 int CACEdit::SetDroppedWidth( UINT nWidth )\r
598 {\r
599         if(m_iType == _COMBOBOX_)\r
600         {\r
601                 return ((CComboBox *)this)->SetDroppedWidth(nWidth);\r
602         }\r
603         return CB_ERR;\r
604 }\r
605 \r
606 /*********************************************************************/\r
607 \r
608 int CACEdit::FindString( int nStartAfter, LPCTSTR lpszString )\r
609 {\r
610         if(m_iType == _COMBOBOX_)\r
611         {\r
612                 return ((CComboBox *)this)->FindString(nStartAfter,lpszString);\r
613         }\r
614         return CB_ERR;\r
615 }\r
616 \r
617 /*********************************************************************/\r
618 \r
619 int CACEdit::SelectString( int nStartAfter, LPCTSTR lpszString )\r
620 {\r
621         if(m_iType == _COMBOBOX_)\r
622         {\r
623                 return ((CComboBox *)this)->SelectString(nStartAfter,lpszString);\r
624         }\r
625         return CB_ERR;\r
626 }\r
627 \r
628 /*********************************************************************/\r
629 \r
630 void CACEdit::ShowDropDown(BOOL bShowIt)\r
631 {\r
632         if(m_iType == _COMBOBOX_)\r
633         {\r
634                 ((CComboBox *)this)->ShowDropDown(bShowIt);\r
635         }\r
636 }\r
637 \r
638 /*********************************************************************/\r
639 \r
640 void CACEdit::ResetContent()\r
641 {\r
642         if(m_iType == _COMBOBOX_)\r
643         {\r
644                 ((CComboBox *)this)->ResetContent();\r
645         }\r
646 }\r
647 \r
648 /*********************************************************************/\r
649 \r
650 int CACEdit::GetCurSel()\r
651 {\r
652         if(m_iType == _COMBOBOX_)\r
653         {\r
654                 return ((CComboBox *)this)->GetCurSel();\r
655         }\r
656         return CB_ERR;\r
657 }\r
658 \r
659 /*********************************************************************/\r
660 \r
661 int CACEdit::GetLBText( int nIndex, LPTSTR lpszText )\r
662 {\r
663         if(m_iType == _COMBOBOX_)\r
664         {\r
665                 return ((CComboBox *)this)->GetLBText(nIndex,lpszText);\r
666         }\r
667         return CB_ERR;\r
668 }\r
669 \r
670 /*********************************************************************/\r
671 \r
672 void CACEdit::GetLBText( int nIndex, CString& rString )\r
673 {\r
674         if(m_iType == _COMBOBOX_)\r
675         {\r
676                 ((CComboBox *)this)->GetLBText(nIndex,rString);\r
677         }\r
678 }\r
679 \r
680 /*********************************************************************/\r