OSDN Git Service

Fix Show Log boundary show more than 1 log item when using --boundary & -n1
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / ProgressDlg.cpp
1 // ProgressDlg.cpp : implementation file\r
2 //\r
3 \r
4 #include "stdafx.h"\r
5 #include "TortoiseProc.h"\r
6 #include "ProgressDlg.h"\r
7 #include "Git.h"\r
8 #include "atlconv.h"\r
9 // CProgressDlg dialog\r
10 \r
11 IMPLEMENT_DYNAMIC(CProgressDlg, CResizableStandAloneDialog)\r
12 \r
13 CProgressDlg::CProgressDlg(CWnd* pParent /*=NULL*/)\r
14         : CResizableStandAloneDialog(CProgressDlg::IDD, pParent)\r
15 {\r
16 \r
17 }\r
18 \r
19 CProgressDlg::~CProgressDlg()\r
20 {\r
21         if(m_pThread != NULL)\r
22         {\r
23                 delete m_pThread;\r
24         }\r
25 }\r
26 \r
27 void CProgressDlg::DoDataExchange(CDataExchange* pDX)\r
28 {\r
29         CDialog::DoDataExchange(pDX);\r
30         DDX_Control(pDX, IDC_CURRENT, this->m_CurrentWork);\r
31         DDX_Control(pDX, IDC_TITLE_ANIMATE, this->m_Animate);\r
32         DDX_Control(pDX, IDC_RUN_PROGRESS, this->m_Progress);\r
33         DDX_Control(pDX, IDC_LOG, this->m_Log);\r
34 }\r
35 \r
36 \r
37 BEGIN_MESSAGE_MAP(CProgressDlg, CResizableStandAloneDialog)\r
38 END_MESSAGE_MAP()\r
39 \r
40 BOOL CProgressDlg::OnInitDialog()\r
41 {\r
42         CResizableStandAloneDialog::OnInitDialog();\r
43 \r
44         AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, TOP_RIGHT);\r
45         AddAnchor(IDC_RUN_PROGRESS, TOP_LEFT,TOP_RIGHT);\r
46         AddAnchor(IDC_LOG, TOP_LEFT,BOTTOM_RIGHT);\r
47 \r
48         AddAnchor(IDOK,BOTTOM_RIGHT);\r
49         AddAnchor(IDCANCEL,BOTTOM_RIGHT);\r
50 \r
51         m_Animate.Open(IDR_DOWNLOAD);\r
52         \r
53         m_Log.SetWindowTextW(this->m_GitCmd+_T("\r\n\r\n"));\r
54         m_CurrentWork.SetWindowTextW(_T(""));\r
55 \r
56         m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
57         if (m_pThread==NULL)\r
58         {\r
59 //              ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
60         }\r
61         else\r
62         {\r
63                 m_pThread->m_bAutoDelete = FALSE;\r
64                 m_pThread->ResumeThread();\r
65         }\r
66         return TRUE;\r
67 }\r
68 \r
69 UINT CProgressDlg::ProgressThreadEntry(LPVOID pVoid)\r
70 {\r
71         return ((CProgressDlg*)pVoid)->ProgressThread();\r
72 }\r
73 \r
74 UINT CProgressDlg::ProgressThread()\r
75 {\r
76         PROCESS_INFORMATION pi;\r
77         HANDLE hRead;\r
78 \r
79         m_Animate.Play(0,-1,-1);\r
80 \r
81         CString *pfilename;\r
82         if(m_LogFile.IsEmpty())\r
83                 pfilename=NULL;\r
84         else\r
85                 pfilename=&m_LogFile;\r
86 \r
87         g_Git.RunAsync(this->m_GitCmd,&pi, &hRead,pfilename);\r
88         this->DialogEnableWindow(IDOK,FALSE);\r
89 \r
90         DWORD readnumber;\r
91         char buffer[2];\r
92         CString output;\r
93         while(ReadFile(hRead,buffer,1,&readnumber,NULL))\r
94         {\r
95                 buffer[readnumber]=0;\r
96                 ParserCmdOutput((TCHAR)buffer[0]);\r
97         }\r
98 \r
99         CloseHandle(pi.hThread);\r
100 \r
101         WaitForSingleObject(pi.hProcess, INFINITE);\r
102         m_GitStatus =0;\r
103 \r
104         if(!GetExitCodeProcess(pi.hProcess,&m_GitStatus))\r
105         {\r
106                 return GIT_ERROR_GET_EXIT_CODE;\r
107         }\r
108 \r
109         CloseHandle(pi.hProcess);\r
110 \r
111         CloseHandle(hRead);\r
112 \r
113         m_Progress.SetPos(100);\r
114         this->DialogEnableWindow(IDOK,TRUE);\r
115 \r
116         m_Animate.Stop();\r
117         return 0;\r
118 }\r
119 \r
120 int CProgressDlg::FindPercentage(CString &log)\r
121 {\r
122         int s1=log.Find(_T('%'));\r
123         if(s1<0)\r
124                 return -1;\r
125 \r
126         int s2=s1-1;\r
127         for(int i=s1-1;i>=0;i--)\r
128         {\r
129                 if(log[i]>=_T('0') && log[i]<=_T('9'))\r
130                         s2=i;\r
131                 else\r
132                         break;\r
133         }\r
134         return _ttol(log.Mid(s2,s1-s2));\r
135 }\r
136 \r
137 void CProgressDlg::ParserCmdOutput(TCHAR ch)\r
138 {\r
139         TRACE(_T("%c"),ch);\r
140         if( ch == _T('\r') || ch == _T('\n'))\r
141         {\r
142                 TRACE(_T("End Char %s \r\n"),ch==_T('\r')?_T("lf"):_T(""));\r
143                 TRACE(_T("End Char %s \r\n"),ch==_T('\n')?_T("cr"):_T(""));\r
144 \r
145                 CString text;\r
146                 m_Log.GetWindowTextW(text);\r
147                 if(ch == _T('\r'))\r
148                 {\r
149                         RemoveLastLine(text);\r
150                 }\r
151                 text+=_T("\r\n")+m_LogText;\r
152                 m_Log.SetWindowTextW(text);\r
153                 \r
154                 m_Log.LineScroll(m_Log.GetLineCount());\r
155 \r
156                 int s1=m_LogText.Find(_T(':'));\r
157                 int s2=m_LogText.Find(_T('%'));\r
158                 if(s1>0 && s2>0)\r
159                 {\r
160                         this->m_CurrentWork.SetWindowTextW(m_LogText.Left(s1));\r
161                         int pos=FindPercentage(m_LogText);\r
162                         TRACE(_T("Pos %d\r\n"),pos);\r
163                         if(pos>0)\r
164                                 this->m_Progress.SetPos(pos);\r
165                 }\r
166 \r
167                 m_LogText=_T("");\r
168 \r
169         }else\r
170         {\r
171                 m_LogText+=ch;\r
172         }\r
173 \r
174 }\r
175 void CProgressDlg::RemoveLastLine(CString &str)\r
176 {\r
177         int start;\r
178         start=str.ReverseFind(_T('\n'));\r
179         if(start>0);\r
180                 str=str.Left(start);\r
181         return;\r
182 }\r
183 // CProgressDlg message handlers\r