BrowseRefs: Context menu enhancements
[TortoiseGit.git] / src / TortoiseProc / ProgressDlg.cpp
bloba0c65f8281888ffa797545b46127ab3fa22ede5f
1 // ProgressDlg.cpp : implementation file
2 //
4 #include "stdafx.h"
5 #include "TortoiseProc.h"
6 #include "ProgressDlg.h"
7 #include "Git.h"
8 #include "atlconv.h"
9 // CProgressDlg dialog
11 IMPLEMENT_DYNAMIC(CProgressDlg, CResizableStandAloneDialog)
13 CProgressDlg::CProgressDlg(CWnd* pParent /*=NULL*/)
14 : CResizableStandAloneDialog(CProgressDlg::IDD, pParent), m_bShowCommand(true)
19 CProgressDlg::~CProgressDlg()
21 if(m_pThread != NULL)
23 delete m_pThread;
27 void CProgressDlg::DoDataExchange(CDataExchange* pDX)
29 CDialog::DoDataExchange(pDX);
30 DDX_Control(pDX, IDC_CURRENT, this->m_CurrentWork);
31 DDX_Control(pDX, IDC_TITLE_ANIMATE, this->m_Animate);
32 DDX_Control(pDX, IDC_RUN_PROGRESS, this->m_Progress);
33 DDX_Control(pDX, IDC_LOG, this->m_Log);
37 BEGIN_MESSAGE_MAP(CProgressDlg, CResizableStandAloneDialog)
38 ON_MESSAGE(MSG_PROGRESSDLG_UPDATE_UI, OnProgressUpdateUI)
39 ON_BN_CLICKED(IDOK, &CProgressDlg::OnBnClickedOk)
40 END_MESSAGE_MAP()
42 BOOL CProgressDlg::OnInitDialog()
44 CResizableStandAloneDialog::OnInitDialog();
46 AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, TOP_RIGHT);
47 AddAnchor(IDC_RUN_PROGRESS, TOP_LEFT,TOP_RIGHT);
48 AddAnchor(IDC_LOG, TOP_LEFT,BOTTOM_RIGHT);
50 AddAnchor(IDOK,BOTTOM_RIGHT);
51 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
53 m_Animate.Open(IDR_DOWNLOAD);
55 CString InitialText;
56 if ( !m_PreText.IsEmpty() )
58 InitialText = m_PreText + _T("\r\n");
60 if (m_bShowCommand && (!m_GitCmd.IsEmpty() ))
62 InitialText += m_GitCmd+_T("\r\n\r\n");
64 m_Log.SetWindowTextW(InitialText);
65 m_CurrentWork.SetWindowTextW(_T(""));
67 m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
68 if (m_pThread==NULL)
70 // ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));
72 else
74 m_pThread->m_bAutoDelete = FALSE;
75 m_pThread->ResumeThread();
78 if(!m_Title.IsEmpty())
79 this->SetWindowText(m_Title);
80 return TRUE;
83 UINT CProgressDlg::ProgressThreadEntry(LPVOID pVoid)
85 return ((CProgressDlg*)pVoid)->ProgressThread();
88 UINT CProgressDlg::ProgressThread()
90 PROCESS_INFORMATION pi;
91 HANDLE hRead;
93 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_START,0);
95 CString *pfilename;
96 if(m_LogFile.IsEmpty())
97 pfilename=NULL;
98 else
99 pfilename=&m_LogFile;
101 m_GitCmdList.push_back(m_GitCmd);
103 m_GitStatus =0;
105 for(int i=0;i<m_GitCmdList.size();i++)
107 if(m_GitCmdList[i].IsEmpty())
108 continue;
110 if (m_bShowCommand && m_GitCmdList[i]!= m_GitCmd)
112 CString str;
113 str+= m_GitCmdList[i]+_T("\r\n\r\n");
114 for(int j=0;j<str.GetLength();j++)
115 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]);
118 g_Git.RunAsync(this->m_GitCmdList[i],&pi, &hRead,pfilename);
120 DWORD readnumber;
121 char buffer[2];
122 CString output;
123 while(ReadFile(hRead,buffer,1,&readnumber,NULL))
125 buffer[readnumber]=0;
126 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,(TCHAR)buffer[0]);
129 CloseHandle(pi.hThread);
131 WaitForSingleObject(pi.hProcess, INFINITE);
133 DWORD status=0;
134 if(!GetExitCodeProcess(pi.hProcess,&status))
136 return GIT_ERROR_GET_EXIT_CODE;
138 m_GitStatus |= status;
141 CloseHandle(pi.hProcess);
143 CloseHandle(hRead);
145 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_END,0);
147 return 0;
150 LRESULT CProgressDlg::OnProgressUpdateUI(WPARAM wParam,LPARAM lParam)
152 if(wParam == MSG_PROGRESSDLG_START)
154 m_Animate.Play(0,-1,-1);
155 this->DialogEnableWindow(IDOK,FALSE);
157 if(wParam == MSG_PROGRESSDLG_END)
159 m_Animate.Stop();
160 m_Progress.SetPos(100);
161 this->DialogEnableWindow(IDOK,TRUE);
164 if(lParam != 0)
165 ParserCmdOutput((TCHAR)lParam);
167 return 0;
169 int CProgressDlg::FindPercentage(CString &log)
171 int s1=log.Find(_T('%'));
172 if(s1<0)
173 return -1;
175 int s2=s1-1;
176 for(int i=s1-1;i>=0;i--)
178 if(log[i]>=_T('0') && log[i]<=_T('9'))
179 s2=i;
180 else
181 break;
183 return _ttol(log.Mid(s2,s1-s2));
186 void CProgressDlg::ParserCmdOutput(TCHAR ch)
188 TRACE(_T("%c"),ch);
189 if( ch == _T('\r') || ch == _T('\n'))
191 TRACE(_T("End Char %s \r\n"),ch==_T('\r')?_T("lf"):_T(""));
192 TRACE(_T("End Char %s \r\n"),ch==_T('\n')?_T("cr"):_T(""));
194 CString text;
195 m_Log.GetWindowTextW(text);
196 if(ch == _T('\r'))
198 RemoveLastLine(text);
200 text+=_T("\r\n")+m_LogText;
201 m_Log.SetWindowTextW(text);
203 m_Log.LineScroll(m_Log.GetLineCount());
205 int s1=m_LogText.Find(_T(':'));
206 int s2=m_LogText.Find(_T('%'));
207 if(s1>0 && s2>0)
209 this->m_CurrentWork.SetWindowTextW(m_LogText.Left(s1));
210 int pos=FindPercentage(m_LogText);
211 TRACE(_T("Pos %d\r\n"),pos);
212 if(pos>0)
213 this->m_Progress.SetPos(pos);
216 m_LogText=_T("");
218 }else
220 m_LogText+=ch;
224 void CProgressDlg::RemoveLastLine(CString &str)
226 int start;
227 start=str.ReverseFind(_T('\n'));
228 if(start>0)
229 str=str.Left(start);
230 return;
232 // CProgressDlg message handlers
234 void CProgressDlg::OnBnClickedOk()
236 // TODO: Add your control notification handler code here
237 m_Log.GetWindowText(this->m_LogText);
238 OnOK();