1 // ProgressDlg.cpp : implementation file
\r
5 #include "TortoiseProc.h"
\r
6 #include "ProgressDlg.h"
\r
9 // CProgressDlg dialog
\r
11 IMPLEMENT_DYNAMIC(CProgressDlg, CResizableStandAloneDialog)
\r
13 CProgressDlg::CProgressDlg(CWnd* pParent /*=NULL*/)
\r
14 : CResizableStandAloneDialog(CProgressDlg::IDD, pParent), m_bShowCommand(true), m_bAutoCloseOnSuccess(false), m_bAbort(false), m_bDone(false)
\r
17 m_bAltAbortPress=false;
\r
20 CProgressDlg::~CProgressDlg()
\r
22 if(m_pThread != NULL)
\r
28 void CProgressDlg::DoDataExchange(CDataExchange* pDX)
\r
30 CDialog::DoDataExchange(pDX);
\r
31 DDX_Control(pDX, IDC_CURRENT, this->m_CurrentWork);
\r
32 DDX_Control(pDX, IDC_TITLE_ANIMATE, this->m_Animate);
\r
33 DDX_Control(pDX, IDC_RUN_PROGRESS, this->m_Progress);
\r
34 DDX_Control(pDX, IDC_LOG, this->m_Log);
\r
38 BEGIN_MESSAGE_MAP(CProgressDlg, CResizableStandAloneDialog)
\r
39 ON_MESSAGE(MSG_PROGRESSDLG_UPDATE_UI, OnProgressUpdateUI)
\r
40 ON_BN_CLICKED(IDOK, &CProgressDlg::OnBnClickedOk)
\r
41 ON_BN_CLICKED(IDC_PROGRESS_BUTTON1,&CProgressDlg::OnBnClickedButton1)
\r
44 BOOL CProgressDlg::OnInitDialog()
\r
46 CResizableStandAloneDialog::OnInitDialog();
\r
48 AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, TOP_RIGHT);
\r
49 AddAnchor(IDC_RUN_PROGRESS, TOP_LEFT,TOP_RIGHT);
\r
50 AddAnchor(IDC_LOG, TOP_LEFT,BOTTOM_RIGHT);
\r
52 AddAnchor(IDOK,BOTTOM_RIGHT);
\r
53 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
\r
54 AddAnchor(IDC_PROGRESS_BUTTON1,BOTTOM_RIGHT);
\r
56 this->GetDlgItem(IDC_PROGRESS_BUTTON1)->ShowWindow(SW_HIDE);
\r
57 m_Animate.Open(IDR_DOWNLOAD);
\r
59 CString InitialText;
\r
60 if ( !m_PreText.IsEmpty() )
\r
62 InitialText = m_PreText + _T("\r\n");
\r
64 if (m_bShowCommand && (!m_GitCmd.IsEmpty() ))
\r
66 InitialText += m_GitCmd+_T("\r\n\r\n");
\r
68 m_Log.SetWindowTextW(InitialText);
\r
69 m_CurrentWork.SetWindowTextW(_T(""));
\r
71 m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
\r
72 if (m_pThread==NULL)
\r
74 // ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));
\r
78 m_pThread->m_bAutoDelete = FALSE;
\r
79 m_pThread->ResumeThread();
\r
82 if(!m_Title.IsEmpty())
\r
83 this->SetWindowText(m_Title);
\r
87 UINT CProgressDlg::ProgressThreadEntry(LPVOID pVoid)
\r
89 return ((CProgressDlg*)pVoid)->ProgressThread();
\r
92 UINT CProgressDlg::ProgressThread()
\r
94 PROCESS_INFORMATION pi;
\r
97 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_START,0);
\r
100 if(m_LogFile.IsEmpty())
\r
103 pfilename=&m_LogFile;
\r
105 m_GitCmdList.push_back(m_GitCmd);
\r
109 for(int i=0;i<m_GitCmdList.size();i++)
\r
111 if(m_GitCmdList[i].IsEmpty())
\r
114 if (m_bShowCommand && m_GitCmdList[i]!= m_GitCmd)
\r
117 str+= m_GitCmdList[i]+_T("\r\n\r\n");
\r
118 for(int j=0;j<str.GetLength();j++)
\r
119 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]);
\r
122 g_Git.RunAsync(this->m_GitCmdList[i],&pi, &hRead,pfilename);
\r
127 while(ReadFile(hRead,buffer,1,&readnumber,NULL))
\r
129 buffer[readnumber]=0;
\r
130 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,(TCHAR)buffer[0]);
\r
133 CloseHandle(pi.hThread);
\r
135 WaitForSingleObject(pi.hProcess, INFINITE);
\r
138 if(!GetExitCodeProcess(pi.hProcess,&status) || m_bAbort)
\r
140 CloseHandle(pi.hProcess);
\r
142 CloseHandle(hRead);
\r
144 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_FAILED,0);
\r
145 return GIT_ERROR_GET_EXIT_CODE;
\r
147 m_GitStatus |= status;
\r
150 CloseHandle(pi.hProcess);
\r
152 CloseHandle(hRead);
\r
154 this->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_END,0);
\r
159 LRESULT CProgressDlg::OnProgressUpdateUI(WPARAM wParam,LPARAM lParam)
\r
161 if(wParam == MSG_PROGRESSDLG_START)
\r
163 m_Animate.Play(0,-1,-1);
\r
164 this->DialogEnableWindow(IDOK,FALSE);
\r
166 if(wParam == MSG_PROGRESSDLG_END || wParam == MSG_PROGRESSDLG_FAILED)
\r
170 m_Progress.SetPos(100);
\r
171 this->DialogEnableWindow(IDOK,TRUE);
\r
173 if(wParam == MSG_PROGRESSDLG_END && m_GitStatus == 0)
\r
175 if(m_bAutoCloseOnSuccess)
\r
178 if(!m_changeAbortButtonOnSuccessTo.IsEmpty())
\r
180 GetDlgItem(IDC_PROGRESS_BUTTON1)->SetWindowText(m_changeAbortButtonOnSuccessTo);
\r
181 GetDlgItem(IDC_PROGRESS_BUTTON1)->ShowWindow(SW_SHOW);
\r
182 GetDlgItem(IDCANCEL)->ShowWindow(SW_HIDE);
\r
183 //Set default button is "close" rather than "push"
\r
184 this->SendMessage(WM_NEXTDLGCTL, (WPARAM)GetDlgItem(IDOK)->m_hWnd, TRUE);
\r
187 DialogEnableWindow(IDCANCEL, FALSE);
\r
190 DialogEnableWindow(IDCANCEL, FALSE);
\r
194 ParserCmdOutput((TCHAR)lParam);
\r
198 int CProgressDlg::FindPercentage(CString &log)
\r
200 int s1=log.Find(_T('%'));
\r
205 for(int i=s1-1;i>=0;i--)
\r
207 if(log[i]>=_T('0') && log[i]<=_T('9'))
\r
212 return _ttol(log.Mid(s2,s1-s2));
\r
215 void CProgressDlg::ParserCmdOutput(TCHAR ch)
\r
217 TRACE(_T("%c"),ch);
\r
218 if( ch == _T('\r') || ch == _T('\n'))
\r
220 TRACE(_T("End Char %s \r\n"),ch==_T('\r')?_T("lf"):_T(""));
\r
221 TRACE(_T("End Char %s \r\n"),ch==_T('\n')?_T("cr"):_T(""));
\r
224 m_Log.GetWindowTextW(text);
\r
227 RemoveLastLine(text);
\r
229 text+=_T("\r\n")+m_LogText;
\r
230 m_Log.SetWindowTextW(text);
\r
232 m_Log.LineScroll(m_Log.GetLineCount());
\r
234 int s1=m_LogText.Find(_T(':'));
\r
235 int s2=m_LogText.Find(_T('%'));
\r
238 this->m_CurrentWork.SetWindowTextW(m_LogText.Left(s1));
\r
239 int pos=FindPercentage(m_LogText);
\r
240 TRACE(_T("Pos %d\r\n"),pos);
\r
242 this->m_Progress.SetPos(pos);
\r
253 void CProgressDlg::RemoveLastLine(CString &str)
\r
256 start=str.ReverseFind(_T('\n'));
\r
258 str=str.Left(start);
\r
261 // CProgressDlg message handlers
\r
263 void CProgressDlg::OnBnClickedOk()
\r
265 // TODO: Add your control notification handler code here
\r
266 m_Log.GetWindowText(this->m_LogText);
\r
270 void CProgressDlg::OnBnClickedButton1()
\r
272 this->EndDialog(IDC_PROGRESS_BUTTON1);
\r
275 void CProgressDlg::OnCancel()
\r
279 CResizableStandAloneDialog::OnCancel();
\r