fixed the ContextMenuStash.png screenshot
[TortoiseGit.git] / src / Utils / ACEdit.cpp
blob49cc49234d2c2ba2218649ef7b6a84fbb278754d
1 // ACEdit.cpp: Implementierungsdatei
2 //
4 #include "stdafx.h"
5 #include "ACEdit.h"
6 #include <io.h>
9 #ifdef _DEBUG
10 #define new DEBUG_NEW
11 #undef THIS_FILE
12 static char THIS_FILE[] = __FILE__;
13 #endif
15 #define _EDIT_ 1
16 #define _COMBOBOX_ 2
18 /////////////////////////////////////////////////////////////////////////////
19 // CACEdit
21 CACEdit::CACEdit()
23 m_iMode = _MODE_STANDARD_;
24 m_iType = -1;
25 m_pEdit = NULL;
26 m_CursorMode = false;
27 m_PrefixChar = 0;
30 /*********************************************************************/
32 CACEdit::~CACEdit()
34 DestroyWindow();
37 /*********************************************************************/
39 BEGIN_MESSAGE_MAP(CACEdit, CWnd)
40 //{{AFX_MSG_MAP(CACEdit)
41 ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
42 ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)
43 ON_WM_KEYDOWN()
44 ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
45 ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnChange)
46 ON_CONTROL_REFLECT(CBN_DROPDOWN, OnCloseList)
47 //}}AFX_MSG_MAP
48 ON_MESSAGE(ENAC_UPDATE,OnUpdateFromList)
49 END_MESSAGE_MAP()
51 /*********************************************************************/
53 void CACEdit::SetMode(int iMode)
55 if(m_iType == -1)
56 Init();
58 m_iMode = iMode;
61 ** Vers. 1.1
62 ** NEW: _MODE_CURSOR_O_LIST_
64 if(iMode == _MODE_CURSOR_O_LIST_)
65 m_iMode |= _MODE_STANDARD_;
67 if(iMode & _MODE_FILESYSTEM_)
68 m_SeparationStr = _T("\\");
70 // Vers. 1.2
71 if(iMode & _MODE_FIND_ALL_)
73 m_Liste.m_lMode |= _MODE_FIND_ALL_;
77 /*********************************************************************/
79 void CACEdit::Init()
81 CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,
82 0,(HBRUSH) (COLOR_WINDOW), 0);
83 CRect rcWnd,rcWnd1;
84 GetWindowRect(rcWnd);
86 VERIFY(m_Liste.CreateEx(WS_EX_TOOLWINDOW,
87 szClassName,NULL,
88 WS_THICKFRAME | WS_CHILD | WS_BORDER |
89 WS_CLIPSIBLINGS | WS_OVERLAPPED,
90 CRect(rcWnd.left, rcWnd.top +20, rcWnd.left+ 200, rcWnd.top+200),
91 GetDesktopWindow(),
92 0x3E8, NULL));
94 CString m_ClassName;
95 ::GetClassName(GetSafeHwnd(), m_ClassName.GetBuffer(32), 32);
96 m_ClassName.ReleaseBuffer();
98 if (m_ClassName.Compare(_T("Edit")) == 0)
100 m_iType = _EDIT_;
102 else
104 if (m_ClassName.Compare(_T("ComboBox")) == 0)
106 m_iType = _COMBOBOX_;
108 m_pEdit = (CEdit*)GetWindow(GW_CHILD);
109 VERIFY(m_pEdit);
110 ::GetClassName(m_pEdit->GetSafeHwnd(), m_ClassName.GetBuffer(32), 32);
111 m_ClassName.ReleaseBuffer();
112 VERIFY(m_ClassName.Compare(_T("Edit")) == 0);
116 if(m_iType == -1)
118 ASSERT(0);
119 return;
122 m_Liste.Init(this);
125 /*********************************************************************/
127 void CACEdit::AddSearchStrings(LPCTSTR Strings[])
129 int i = 0;
130 LPCTSTR str;
131 if(m_iType == -1) {ASSERT(0); return;}
133 m_Liste.RemoveAll();
137 str = Strings[i];
138 if(str)
140 m_Liste.AddSearchString(str);
143 i++;
145 while(str);
147 m_Liste.SortSearchList();
150 /*********************************************************************/
152 void CACEdit::AddSearchString(LPCTSTR lpszString)
154 if(m_iType == -1) {ASSERT(0); return;}
156 m_Liste.AddSearchString(lpszString);
159 /*********************************************************************/
161 void CACEdit::RemoveSearchAll()
163 if(m_iType == -1) {ASSERT(0); return;}
165 m_Liste.RemoveAll();
168 /*********************************************************************/
170 void CACEdit::OnKillfocus()
172 if(m_Liste.GetSafeHwnd()) // fix Vers 1.1
173 m_Liste.ShowWindow(false);
176 /*********************************************************************/
178 void CACEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
180 if(!HandleKey(nChar,false))
181 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
184 /*********************************************************************/
186 bool CACEdit::HandleKey(UINT nChar, bool m_bFromChild)
188 if (nChar == VK_ESCAPE ||nChar == VK_RETURN)
190 m_Liste.ShowWindow(false);
191 return true;
194 if (nChar == VK_DOWN || nChar == VK_UP
195 || nChar == VK_PRIOR || nChar == VK_NEXT
196 || nChar == VK_HOME || nChar == VK_END)
199 ** Vers. 1.1
200 ** NEW: _MODE_CURSOR_O_LIST_
202 if(!m_Liste.IsWindowVisible() && (m_iMode & _MODE_CURSOR_O_LIST_))
204 GetWindowText(m_EditText);
205 if(m_EditText.IsEmpty())
207 m_Liste.CopyList();
208 return true;
212 if(m_Liste.IsWindowVisible())
214 int pos;
217 if(m_iMode & _MODE_STANDARD_
218 || m_iMode & _MODE_FILESYSTEM_
219 || m_iMode & _MODE_FS_START_DIR_)
221 m_CursorMode = true;
223 if(!m_bFromChild)
224 m_EditText = m_Liste.GetNextString(nChar);
225 else
226 m_EditText = m_Liste.GetString();
228 if(m_iMode & _MODE_FILESYSTEM_)
230 if (m_EditText.Right(1) == _T('\\'))
231 m_EditText = m_EditText.Mid(0,m_EditText.GetLength()-1);
234 m_Liste.SelectItem(-1);
235 SetWindowText(m_EditText);
236 pos = m_EditText.GetLength();
238 if(m_iType == _COMBOBOX_)
240 m_pEdit->SetSel(pos,pos,true);
241 m_pEdit->SetModify(true);
244 if(m_iType == _EDIT_)
246 ((CEdit*)this)->SetSel(pos,pos,true);
247 ((CEdit*)this)->SetModify(true);
250 GetParent()->SendMessage(ENAC_UPDATE, WM_KEYDOWN, GetDlgCtrlID());
251 m_CursorMode = false;
252 return true;
255 if(m_iMode & _MODE_SEPARATION_)
257 CString m_Text,m_Left,m_Right;
258 int left,right,pos=0,len;
260 m_CursorMode = true;
262 GetWindowText(m_EditText);
264 if(m_iType == _EDIT_)
265 pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));
267 if(m_iType == _COMBOBOX_)
268 pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());
270 left = FindSepLeftPos(pos-1,true);
271 right = FindSepRightPos(pos);
273 m_Text = m_EditText.Left(left);
275 if(!m_bFromChild)
276 m_Text += m_Liste.GetNextString(nChar);
277 else
278 m_Text += m_Liste.GetString();
280 m_Liste.SelectItem(-1);
281 m_Text += m_EditText.Mid(right);
282 len = m_Liste.GetString().GetLength();
284 m_Text += this->m_SeparationStr;
286 SetWindowText(m_Text);
287 GetParent()->SendMessage(ENAC_UPDATE, WM_KEYDOWN, GetDlgCtrlID());
289 right = FindSepLeftPos2(pos-1);
290 left -= right;
291 len += right;
293 left+=m_SeparationStr.GetLength();
295 if(m_iType == _EDIT_)
297 ((CEdit*)this)->SetModify(true);
298 ((CEdit*)this)->SetSel(left+len,left+len,false);
301 if(m_iType == _COMBOBOX_)
303 m_pEdit->SetModify(true);
304 m_pEdit->SetSel(left,left+len,true);
307 m_CursorMode = false;
308 return true;
312 return false;
315 /*********************************************************************/
317 void CACEdit::OnChange()
319 CString m_Text;
320 int pos=0,len;
322 if(m_iType == -1)
323 {ASSERT(0); return;}
325 GetWindowText(m_EditText);
326 len = m_EditText.GetLength();
327 //----------------------------------------------
328 if(m_iMode & _MODE_FILESYSTEM_ || m_iMode & _MODE_FS_START_DIR_)
330 if(!m_CursorMode)
332 if(m_iType == _EDIT_)
333 pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));
335 if(m_iType == _COMBOBOX_)
336 pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());
338 if(m_iMode & _MODE_FS_START_DIR_)
340 if(len)
341 m_Liste.FindString(-1,m_EditText);
342 else
343 m_Liste.ShowWindow(false);
345 else
347 if(len > 2 && pos == len)
349 if(_taccess(m_EditText,0) == 0)
351 ReadDirectory(m_EditText);
353 m_Liste.FindString(-1,m_EditText);
355 else
356 m_Liste.ShowWindow(false);
358 } // m_CursorMode
360 //----------------------------------------------
361 if(m_iMode & _MODE_SEPARATION_)
363 if(!m_CursorMode)
365 if(m_iType == _EDIT_)
366 pos = LOWORD(((CEdit*)this)->CharFromPos(GetCaretPos()));
368 if(m_iType == _COMBOBOX_)
369 pos = m_pEdit->CharFromPos(m_pEdit->GetCaretPos());
371 int left,right;
372 left = FindSepLeftPos(pos-1);
373 right = FindSepRightPos(pos);
374 m_Text = m_EditText.Mid(left,right-left);
375 m_Liste.FindString(-1,m_Text);
378 //----------------------------------------------
379 if(m_iMode & _MODE_STANDARD_)
381 if(!m_CursorMode)
382 m_Liste.FindString(-1,m_EditText);
384 //----------------------------------------------
385 GetParent()->SendMessage(ENAC_UPDATE, EN_UPDATE, GetDlgCtrlID());
388 /*********************************************************************/
390 int CACEdit::FindSepLeftPos(int pos,bool m_bIncludePrefix)
392 int len = m_EditText.GetLength();
393 TCHAR ch;
394 int i;
396 if(pos >= len && len != 1)
397 pos = len -1;
399 for(i = pos; i >= 0 ; i--)
401 ch = m_EditText.GetAt(i);
402 if(m_PrefixChar == ch)
403 return i + (m_bIncludePrefix ? 1 : 0);
404 if(m_SeparationStr.Find(ch) != -1)
405 break;
408 return i + 1;
411 /*********************************************************************/
413 int CACEdit::FindSepLeftPos2(int pos)
415 int len = m_EditText.GetLength();
416 TCHAR ch;
418 if(pos >= len && len != 1)
419 pos = len -1;
421 if(len == 1)
422 return 0;
424 for(int i = pos; i >= 0 ; i--)
426 ch = m_EditText.GetAt(i);
427 if(m_PrefixChar == ch)
428 return 1;
431 return 0;
434 /*********************************************************************/
436 int CACEdit::FindSepRightPos(int pos)
438 int len = m_EditText.GetLength();
439 TCHAR ch;
440 int i;
442 for(i = pos; i < len ; i++)
444 ch = m_EditText.GetAt(i);
445 if(m_SeparationStr.Find(ch) != -1)
446 break;
449 return i;
452 /*********************************************************************/
453 LRESULT CACEdit::OnUpdateFromList(WPARAM lParam, LPARAM /*wParam*/)
455 UpdateData(true);
457 if(lParam == WM_KEYDOWN)
459 HandleKey(VK_DOWN,true);
461 return 0;
464 /*********************************************************************/
466 void CACEdit::OnCloseList()
468 m_Liste.ShowWindow(false);
471 /*********************************************************************/
473 BOOL CACEdit::PreTranslateMessage(MSG* pMsg)
475 if(pMsg->message == WM_KEYDOWN)
477 if(m_Liste.IsWindowVisible())
479 if(m_iType == _COMBOBOX_)
481 if(pMsg->wParam == VK_DOWN || pMsg->wParam == VK_UP)
482 if(HandleKey(pMsg->wParam,false))
483 return true;
486 if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
487 if(HandleKey(pMsg->wParam,false))
488 return true;
491 return CWnd::PreTranslateMessage(pMsg);
494 /*********************************************************************/
496 void CACEdit::ReadDirectory(CString m_Dir)
498 CFileFind FoundFiles;
499 TCHAR ch;
500 CWaitCursor hg;
502 // Wenn mittem im Pfad,
503 // vorheriges Verzeichnis einlesen.
504 if (m_Dir.Right(1) != _T('\\'))
506 _tsplitpath(m_Dir, m_szDrive, m_szDir, m_szFname, m_szExt);
507 m_Dir.Format(_T("%s%s"),m_szDrive, m_szDir);
510 //ist hübscher
511 ch = (TCHAR)towupper(m_Dir.GetAt(0));
512 m_Dir.SetAt(0,ch);
514 CString m_Name,m_File,m_Dir1 = m_Dir;
515 if (m_Dir.Right(1) != _T('\\'))
516 m_Dir += _T("\\");
518 if(m_LastDirectory.CompareNoCase(m_Dir) == 0 && m_Liste.m_SearchList.GetSize())
519 return;
521 m_LastDirectory = m_Dir;
522 m_Dir += _T("*.*");
524 BOOL bContinue = FoundFiles.FindFile(m_Dir);
525 if(bContinue)
526 RemoveSearchAll();
528 while (bContinue == TRUE)
530 bContinue = FoundFiles.FindNextFile();
531 m_File = FoundFiles.GetFileName();
533 if(FoundFiles.IsHidden() || FoundFiles.IsSystem())
534 continue;
535 if(FoundFiles.IsDirectory())
537 if(m_iMode & _MODE_ONLY_FILES)
538 continue;
539 if(FoundFiles.IsDots())
540 continue;
542 if (m_File.Right(1) != _T('\\'))
543 m_File += _T("\\");
546 if(!FoundFiles.IsDirectory())
547 if(m_iMode & _MODE_ONLY_DIRS)
548 continue;
550 if(m_iMode & _MODE_FS_START_DIR_)
552 m_Name = m_File;
554 else
556 m_Name = m_Dir1;
557 if (m_Name.Right(1) != _T('\\'))
558 m_Name += _T("\\");
560 m_Name += m_File;
563 AddSearchString(m_Name);
565 FoundFiles.Close();
566 return;
570 /*********************************************************************/
572 void CACEdit::SetStartDirectory(LPCTSTR lpszString)
574 if(m_iType == -1) {ASSERT(0); return;}
576 if(m_iMode & _MODE_FS_START_DIR_)
577 ReadDirectory(lpszString);
580 /*********************************************************************
581 ** CComboBox
582 ** NEW:V1.1
583 *********************************************************************/
585 int CACEdit::AddString( LPCTSTR lpszString )
587 if(m_iType == _COMBOBOX_)
589 return ((CComboBox *)this)->AddString(lpszString);
591 return CB_ERR;
594 /*********************************************************************/
596 int CACEdit::SetDroppedWidth( UINT nWidth )
598 if(m_iType == _COMBOBOX_)
600 return ((CComboBox *)this)->SetDroppedWidth(nWidth);
602 return CB_ERR;
605 /*********************************************************************/
607 int CACEdit::FindString( int nStartAfter, LPCTSTR lpszString )
609 if(m_iType == _COMBOBOX_)
611 return ((CComboBox *)this)->FindString(nStartAfter,lpszString);
613 return CB_ERR;
616 /*********************************************************************/
618 int CACEdit::SelectString( int nStartAfter, LPCTSTR lpszString )
620 if(m_iType == _COMBOBOX_)
622 return ((CComboBox *)this)->SelectString(nStartAfter,lpszString);
624 return CB_ERR;
627 /*********************************************************************/
629 void CACEdit::ShowDropDown(BOOL bShowIt)
631 if(m_iType == _COMBOBOX_)
633 ((CComboBox *)this)->ShowDropDown(bShowIt);
637 /*********************************************************************/
639 void CACEdit::ResetContent()
641 if(m_iType == _COMBOBOX_)
643 ((CComboBox *)this)->ResetContent();
647 /*********************************************************************/
649 int CACEdit::GetCurSel()
651 if(m_iType == _COMBOBOX_)
653 return ((CComboBox *)this)->GetCurSel();
655 return CB_ERR;
658 /*********************************************************************/
660 int CACEdit::GetLBText( int nIndex, LPTSTR lpszText )
662 if(m_iType == _COMBOBOX_)
664 return ((CComboBox *)this)->GetLBText(nIndex,lpszText);
666 return CB_ERR;
669 /*********************************************************************/
671 void CACEdit::GetLBText( int nIndex, CString& rString )
673 if(m_iType == _COMBOBOX_)
675 ((CComboBox *)this)->GetLBText(nIndex,rString);
679 /*********************************************************************/