OSDN Git Service

3d9445d5b2eaf8a72c85a16ad990b19b1846e53d
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / SyncDlg.cpp
1 // TortoiseGit - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2008-2009 - TortoiseGit\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 \r
20 // SyncDlg.cpp : implementation file\r
21 //\r
22 \r
23 #include "stdafx.h"\r
24 #include "TortoiseProc.h"\r
25 #include "SyncDlg.h"\r
26 #include "progressdlg.h"\r
27 #include "MessageBox.h"\r
28 #include "ImportPatchDlg.h"\r
29 #include "PathUtils.h"\r
30 #include "RebaseDlg.h"\r
31 \r
32 // CSyncDlg dialog\r
33 \r
34 IMPLEMENT_DYNAMIC(CSyncDlg, CResizableStandAloneDialog)\r
35 \r
36 CSyncDlg::CSyncDlg(CWnd* pParent /*=NULL*/)\r
37         : CResizableStandAloneDialog(CSyncDlg::IDD, pParent)\r
38 {\r
39         m_pTooltip=&this->m_tooltips;\r
40         m_bInited=false;\r
41         m_CmdOutCurrentPos=0;\r
42         m_bAutoLoadPuttyKey = CAppUtils::IsSSHPutty();\r
43 }\r
44 \r
45 CSyncDlg::~CSyncDlg()\r
46 {\r
47 }\r
48 \r
49 void CSyncDlg::DoDataExchange(CDataExchange* pDX)\r
50 {\r
51         CDialog::DoDataExchange(pDX);\r
52         DDX_Check(pDX, IDC_CHECK_PUTTY_KEY, m_bAutoLoadPuttyKey);\r
53         DDX_Check(pDX, IDC_CHECK_FORCE,m_bForce);\r
54         DDX_Control(pDX, IDC_COMBOBOXEX_URL, m_ctrlURL);\r
55         DDX_Control(pDX, IDC_BUTTON_TABCTRL, m_ctrlDumyButton);\r
56         DDX_Control(pDX, IDC_BUTTON_PULL, m_ctrlPull);\r
57         DDX_Control(pDX, IDC_BUTTON_PUSH, m_ctrlPush);\r
58         DDX_Control(pDX, IDC_STATIC_STATUS, m_ctrlStatus);\r
59         DDX_Control(pDX, IDC_PROGRESS_SYNC, m_ctrlProgress);\r
60         DDX_Control(pDX, IDC_ANIMATE_SYNC, m_ctrlAnimate);\r
61         DDX_Control(pDX, IDC_BUTTON_SUBMODULE,m_ctrlSubmodule);\r
62         BRANCH_COMBOX_DDX;\r
63 }\r
64 \r
65 \r
66 BEGIN_MESSAGE_MAP(CSyncDlg, CResizableStandAloneDialog)\r
67         ON_BN_CLICKED(IDC_BUTTON_PULL, &CSyncDlg::OnBnClickedButtonPull)\r
68         ON_BN_CLICKED(IDC_BUTTON_PUSH, &CSyncDlg::OnBnClickedButtonPush)\r
69         ON_BN_CLICKED(IDC_BUTTON_APPLY, &CSyncDlg::OnBnClickedButtonApply)\r
70         ON_BN_CLICKED(IDC_BUTTON_EMAIL, &CSyncDlg::OnBnClickedButtonEmail)\r
71         ON_BN_CLICKED(IDC_BUTTON_MANAGE, &CSyncDlg::OnBnClickedButtonManage)\r
72         BRANCH_COMBOX_EVENT\r
73         ON_NOTIFY(CBEN_ENDEDIT, IDC_COMBOBOXEX_URL, &CSyncDlg::OnCbenEndeditComboboxexUrl)\r
74         ON_CBN_EDITCHANGE(IDC_COMBOBOXEX_URL, &CSyncDlg::OnCbnEditchangeComboboxexUrl)\r
75         ON_MESSAGE(MSG_PROGRESSDLG_UPDATE_UI, OnProgressUpdateUI)\r
76         ON_BN_CLICKED(IDC_BUTTON_COMMIT, &CSyncDlg::OnBnClickedButtonCommit)\r
77         ON_BN_CLICKED(IDC_BUTTON_SUBMODULE, &CSyncDlg::OnBnClickedButtonSubmodule)\r
78 END_MESSAGE_MAP()\r
79 \r
80 \r
81 void CSyncDlg::EnableControlButton(bool bEnabled)\r
82 {\r
83         GetDlgItem(IDC_BUTTON_PULL)->EnableWindow(bEnabled);\r
84         GetDlgItem(IDC_BUTTON_PUSH)->EnableWindow(bEnabled);\r
85         GetDlgItem(IDC_BUTTON_APPLY)->EnableWindow(bEnabled);\r
86         GetDlgItem(IDC_BUTTON_EMAIL)->EnableWindow(bEnabled);\r
87         GetDlgItem(IDOK)->EnableWindow(bEnabled);\r
88         GetDlgItem(IDC_BUTTON_SUBMODULE)->EnableWindow(bEnabled);\r
89 }\r
90 // CSyncDlg message handlers\r
91 \r
92 void CSyncDlg::OnBnClickedButtonPull()\r
93 {\r
94         // TODO: Add your control notification handler code here\r
95         int CurrentEntry;\r
96         CurrentEntry = this->m_ctrlPull.GetCurrentEntry();                   \r
97         this->m_regPullButton = CurrentEntry;\r
98 \r
99 \r
100         this->m_bAbort=false;\r
101         this->m_GitCmdList.clear();\r
102 \r
103         this->UpdateData();\r
104         UpdateCombox();\r
105 \r
106         m_oldHash = g_Git.GetHash(CString(_T("HEAD")));\r
107 \r
108         if( CurrentEntry == 0)\r
109         {\r
110                 if( g_Git.GetHash(this->m_strLocalBranch) != m_oldHash)\r
111                 {\r
112                         CMessageBox::Show(NULL,_T("Pull require local branch must be current branch"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
113                         return;                                                 \r
114                 }\r
115         }\r
116 \r
117         if(this->m_strURL.IsEmpty())\r
118         {\r
119                 CMessageBox::Show(NULL,_T("URL can't Empty"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
120                 return;\r
121         }\r
122 \r
123         if(this->m_bAutoLoadPuttyKey)\r
124         {\r
125                 CAppUtils::LaunchPAgent(NULL,&this->m_strURL);\r
126         }\r
127 \r
128         this->SwitchToRun();\r
129 \r
130         CString force;\r
131         if(this->m_bForce)\r
132                 force = _T(" --force ");\r
133 \r
134         CString cmd;\r
135 \r
136         ShowTab(IDC_CMD_LOG);\r
137 \r
138         this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,false);\r
139         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);\r
140         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CONFLICT-1,false);\r
141 \r
142         this->GetDlgItem(IDC_BUTTON_COMMIT)->ShowWindow(SW_HIDE);\r
143 \r
144         ///Pull \r
145         if(CurrentEntry == 0) //Pull\r
146         {\r
147                 cmd.Format(_T("git.exe pull %s \"%s\" %s"),\r
148                                 force,\r
149                                 m_strURL,\r
150                                 this->m_strRemoteBranch);\r
151 \r
152                 m_CurrentCmd = GIT_COMMAND_PULL;\r
153                 m_GitCmdList.push_back(cmd);\r
154 \r
155                 m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
156                 if (m_pThread==NULL)\r
157                 {\r
158                 //              ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
159                 }\r
160                 else\r
161                 {\r
162                         m_pThread->m_bAutoDelete = TRUE;\r
163                         m_pThread->ResumeThread();\r
164                 }\r
165 \r
166         }\r
167 \r
168         ///Fetch\r
169         if(CurrentEntry == 1 || CurrentEntry ==2 ) //Fetch\r
170         {\r
171                 cmd.Format(_T("git.exe fetch %s \"%s\" %s"),\r
172                                 force,\r
173                                 m_strURL,\r
174                                 this->m_strRemoteBranch);\r
175                 if(CurrentEntry == 1) \r
176                         m_CurrentCmd = GIT_COMMAND_FETCH;\r
177                 else\r
178                         m_CurrentCmd = GIT_COMMAND_FETCHANDREBASE;\r
179                 m_GitCmdList.push_back(cmd);\r
180 \r
181                 m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
182                 if (m_pThread==NULL)\r
183                 {\r
184                 //              ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
185                 }\r
186                 else\r
187                 {\r
188                         m_pThread->m_bAutoDelete = TRUE;\r
189                         m_pThread->ResumeThread();\r
190                 }\r
191         }\r
192 \r
193 \r
194         \r
195 }\r
196 \r
197 void CSyncDlg::PullComplete()\r
198 {\r
199         EnableControlButton(true);\r
200         SwitchToInput();\r
201         this->FetchOutList(true);\r
202 \r
203         CString newhash;\r
204         newhash = g_Git.GetHash(CString(_T("HEAD")));\r
205 \r
206         \r
207 \r
208         if( this ->m_GitCmdStatus )\r
209         {\r
210                 CTGitPathList list;\r
211                 if(g_Git.ListConflictFile(list))\r
212                 {\r
213                         this->m_ctrlCmdOut.SetSel(-1,-1);\r
214                         this->m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));\r
215 \r
216                         this->ShowTab(IDC_CMD_LOG);\r
217                         return;\r
218                 }\r
219 \r
220                 if(list.GetCount()>0)\r
221                 {\r
222                         this->m_ConflictFileList.Clear();       \r
223                         CTGitPathList list;\r
224                         CTGitPath path;\r
225                         list.AddPath(path);\r
226 \r
227                         this->m_ConflictFileList.GetStatus(&list,true);\r
228                         this->m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED,\r
229                                                                           CTGitPath::LOGACTIONS_UNMERGED);\r
230                         \r
231                         this->ShowTab(IDC_IN_CONFLICT);\r
232 \r
233                         this->GetDlgItem(IDC_BUTTON_COMMIT)->ShowWindow(SW_NORMAL);\r
234                 }\r
235                 else\r
236                         this->ShowTab(IDC_CMD_LOG);\r
237 \r
238         }else\r
239         {\r
240                 if(newhash == this->m_oldHash)\r
241                 {\r
242                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);\r
243                         this->m_InLogList.ShowText(_T("No commits get after pull"));\r
244                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);\r
245                 }\r
246                 else\r
247                 {\r
248                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,true);\r
249                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);\r
250                         \r
251                         this->AddDiffFileList(&m_InChangeFileList,&m_arInChangeList,newhash,m_oldHash);\r
252                 \r
253                         m_InLogList.FillGitLog(NULL,CGit::      LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE,\r
254                                 &this->m_oldHash,&newhash);\r
255                 }\r
256                 this->ShowTab(IDC_IN_LOGLIST);\r
257         }\r
258 }\r
259 \r
260 void CSyncDlg::FetchComplete()\r
261 {\r
262         EnableControlButton(true);\r
263         SwitchToInput();\r
264         this->FetchOutList(true);\r
265 \r
266         ShowTab(IDC_CMD_LOG);\r
267         if( (!this->m_GitCmdStatus) && this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)\r
268         {\r
269                 CRebaseDlg dlg;\r
270                 dlg.m_PostButtonTexts.Add(_T("Email &Patch..."));\r
271                 int response = dlg.DoModal();\r
272                 if(response == IDOK)\r
273                 {\r
274                         return ;\r
275                 }\r
276 \r
277                 if(response == IDC_REBASE_POST_BUTTON)\r
278                 {\r
279                         CString cmd,out;\r
280                         cmd.Format(_T("git.exe  format-patch -o \"%s\" %s..%s"),\r
281                                         g_Git.m_CurrentDir,\r
282                                         dlg.m_Upstream,dlg.m_Branch);\r
283                         if(g_Git.Run(cmd,&out,CP_ACP))\r
284                         {\r
285                                 CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
286                                 return ;\r
287                         }\r
288 \r
289                         CAppUtils::SendPatchMail(cmd,out);\r
290                 }\r
291         }\r
292 }\r
293 \r
294 void CSyncDlg::OnBnClickedButtonPush()\r
295 {\r
296         // TODO: Add your control notification handler code here\r
297         this->UpdateData();\r
298         UpdateCombox();\r
299 \r
300         if(this->m_strURL.IsEmpty())\r
301         {\r
302                 CMessageBox::Show(NULL,_T("URL can't Empty"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
303                 return;\r
304         }\r
305 \r
306         this->m_regPushButton=this->m_ctrlPush.GetCurrentEntry();\r
307         this->SwitchToRun();\r
308         this->m_bAbort=false;\r
309         this->m_GitCmdList.clear();\r
310 \r
311         ShowTab(IDC_CMD_LOG);\r
312 \r
313         CString cmd;\r
314         CString tags;\r
315         CString force;\r
316         CString all;\r
317 \r
318 \r
319 \r
320         switch (m_ctrlPush.GetCurrentEntry())\r
321         {\r
322         case 1:\r
323                 tags = _T(" --tags ");\r
324                 break;\r
325         case 2:\r
326                 all = _T(" --all ");\r
327                 break;\r
328         }\r
329 \r
330         if(this->m_bForce)\r
331                 force = _T(" --force ");\r
332 \r
333         cmd.Format(_T("git.exe push %s %s %s \"%s\" %s"),\r
334                                 tags,force,all,\r
335                                 m_strURL,\r
336                                 m_strLocalBranch);\r
337 \r
338         if (!m_strRemoteBranch.IsEmpty())\r
339         {\r
340                 cmd += _T(":") + m_strRemoteBranch;\r
341         }\r
342         \r
343         m_GitCmdList.push_back(cmd);\r
344 \r
345         m_CurrentCmd = GIT_COMMAND_PUSH;\r
346 \r
347         if(this->m_bAutoLoadPuttyKey)\r
348         {\r
349                 CAppUtils::LaunchPAgent(NULL,&this->m_strURL);\r
350         }\r
351 \r
352         m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
353         if (m_pThread==NULL)\r
354         {\r
355 //              ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
356         }\r
357         else\r
358         {\r
359                 m_pThread->m_bAutoDelete = TRUE;\r
360                 m_pThread->ResumeThread();\r
361         }\r
362         \r
363 }\r
364 \r
365 void CSyncDlg::OnBnClickedButtonApply()\r
366 {\r
367         // TODO: Add your control notification handler code here\r
368         CString oldhash;\r
369         oldhash=g_Git.GetHash(CString(_T("HEAD")));\r
370         \r
371         CImportPatchDlg dlg;\r
372         CString cmd,output;\r
373 \r
374         if(dlg.DoModal() == IDOK)\r
375         {\r
376                 int err=0;\r
377                 for(int i=0;i<dlg.m_PathList.GetCount();i++)\r
378                 {                       \r
379                         cmd.Format(_T("git.exe am \"%s\""),dlg.m_PathList[i].GetGitPathString());\r
380                         \r
381                         if(g_Git.Run(cmd,&output,CP_ACP))\r
382                         {\r
383                                 CMessageBox::Show(NULL,output,_T("TortoiseGit"),MB_OK);\r
384 \r
385                                 err=1;\r
386                                 break;\r
387                         }\r
388                         this->m_ctrlCmdOut.SetSel(-1,-1);\r
389                         this->m_ctrlCmdOut.ReplaceSel(cmd+_T("\n"));\r
390                         this->m_ctrlCmdOut.SetSel(-1,-1);\r
391                         this->m_ctrlCmdOut.ReplaceSel(output);\r
392                 }\r
393                 \r
394 \r
395                 CString newhash=g_Git.GetHash(CString(_T("HEAD")));             \r
396 \r
397                 this->m_InLogList.Clear();\r
398                 this->m_InChangeFileList.Clear();\r
399 \r
400                 if(newhash == oldhash)\r
401                 {\r
402                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);\r
403                         this->m_InLogList.ShowText(_T("No commits get from patch"));\r
404                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);\r
405 \r
406                 }else\r
407                 {\r
408                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,true);\r
409                         this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);\r
410                         \r
411                         this->AddDiffFileList(&m_InChangeFileList,&m_arInChangeList,newhash,oldhash);\r
412                         m_InLogList.FillGitLog(NULL,CGit::      LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE,\r
413                                 &oldhash,&newhash);\r
414 \r
415                         this->FetchOutList(true);\r
416 \r
417                 }\r
418 \r
419                 this->m_ctrlTabCtrl.ShowTab(IDC_CMD_LOG-1,true);\r
420 \r
421                 if(err)\r
422                 {\r
423                         this->ShowTab(IDC_CMD_LOG);\r
424 \r
425                 }else\r
426                 {\r
427                         this->ShowTab(IDC_IN_LOGLIST);\r
428                 }\r
429         }\r
430 }\r
431 \r
432 void CSyncDlg::OnBnClickedButtonEmail()\r
433 {\r
434         // TODO: Add your control notification handler code here\r
435         CString cmd,out;\r
436         \r
437         this->m_strLocalBranch = this->m_ctrlLocalBranch.GetString();\r
438         this->m_ctrlRemoteBranch.GetWindowText(this->m_strRemoteBranch);\r
439         this->m_ctrlURL.GetWindowText(this->m_strURL);\r
440         m_strURL=m_strURL.Trim();\r
441         m_strRemoteBranch=m_strRemoteBranch.Trim();\r
442         \r
443         cmd.Format(_T("git.exe  format-patch -o \"%s\" %s..%s"),\r
444                                         g_Git.m_CurrentDir,\r
445                                         m_strURL+_T('/')+m_strRemoteBranch,m_strLocalBranch);\r
446         \r
447         if(g_Git.Run(cmd,&out,CP_ACP))\r
448         {\r
449                 CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
450                 return ;\r
451         }\r
452 \r
453         CAppUtils::SendPatchMail(cmd,out);      \r
454 \r
455 }\r
456 void CSyncDlg::ShowProgressCtrl(bool bShow)\r
457 {\r
458         int b=bShow?SW_NORMAL:SW_HIDE;\r
459         this->m_ctrlAnimate.ShowWindow(b);\r
460         this->m_ctrlProgress.ShowWindow(b);\r
461         this->m_ctrlAnimate.Open(IDR_DOWNLOAD);\r
462         if(b == SW_NORMAL)\r
463                 this->m_ctrlAnimate.Play(0,-1,-1);\r
464         else\r
465                 this->m_ctrlAnimate.Stop();\r
466 }\r
467 void CSyncDlg::ShowInputCtrl(bool bShow)\r
468 {\r
469         int b=bShow?SW_NORMAL:SW_HIDE;\r
470         this->m_ctrlURL.ShowWindow(b);\r
471         this->m_ctrlLocalBranch.ShowWindow(b);\r
472         this->m_ctrlRemoteBranch.ShowWindow(b);\r
473         this->GetDlgItem(IDC_BUTTON_LOCAL_BRANCH)->ShowWindow(b);\r
474         this->GetDlgItem(IDC_BUTTON_REMOTE_BRANCH)->ShowWindow(b);\r
475         this->GetDlgItem(IDC_STATIC_LOCAL_BRANCH)->ShowWindow(b);\r
476         this->GetDlgItem(IDC_STATIC_REMOTE_BRANCH)->ShowWindow(b);\r
477         this->GetDlgItem(IDC_BUTTON_MANAGE)->ShowWindow(b);\r
478         this->GetDlgItem(IDC_CHECK_PUTTY_KEY)->ShowWindow(b);\r
479         this->GetDlgItem(IDC_CHECK_FORCE)->ShowWindow(b);\r
480         this->GetDlgItem(IDC_STATIC_REMOTE_URL)->ShowWindow(b);\r
481         \r
482 }\r
483 BOOL CSyncDlg::OnInitDialog()\r
484 {\r
485         CResizableStandAloneDialog::OnInitDialog();\r
486 \r
487         /*\r
488         this->m_ctrlAnimate.ShowWindow(SW_NORMAL);\r
489         this->m_ctrlAnimate.Open(IDR_DOWNLOAD);\r
490         this->m_ctrlAnimate.Play(0,-1,-1);\r
491     */\r
492 \r
493         // ------------------ Create Tabctrl -----------\r
494         CWnd *pwnd=this->GetDlgItem(IDC_BUTTON_TABCTRL);\r
495         CRect rectDummy;\r
496         pwnd->GetWindowRect(&rectDummy);\r
497         this->ScreenToClient(rectDummy);\r
498 \r
499         if (!m_ctrlTabCtrl.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, IDC_SYNC_TAB))\r
500         {\r
501                 TRACE0("Failed to create output tab window\n");\r
502                 return FALSE;      // fail to create\r
503         }\r
504         m_ctrlTabCtrl.SetResizeMode(CMFCTabCtrl::RESIZE_NO);\r
505 \r
506         // -------------Create Command Log Ctrl ---------\r
507         DWORD dwStyle;\r
508         dwStyle= ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL |WS_VSCROLL  ;\r
509 \r
510         if( !m_ctrlCmdOut.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_CMD_LOG))\r
511         {\r
512                 TRACE0("Failed to create Log commits window\n");\r
513                 return FALSE;      // fail to create\r
514         }\r
515 \r
516         m_ctrlTabCtrl.InsertTab(&m_ctrlCmdOut,_T("Log"),-1);\r
517         \r
518         //m_ctrlCmdOut.ReplaceSel(_T("Hello"));\r
519 \r
520         //----------  Create in coming list ctrl -----------\r
521         dwStyle =LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;;\r
522 \r
523         if( !m_InLogList.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_IN_LOGLIST))\r
524         {\r
525                 TRACE0("Failed to create output commits window\n");\r
526                 return FALSE;      // fail to create\r
527 \r
528         }\r
529 \r
530         m_ctrlTabCtrl.InsertTab(&m_InLogList,_T("In Commits"),-1);\r
531 \r
532         m_InLogList.InsertGitColumn();\r
533 \r
534         //----------- Create In Change file list -----------\r
535         dwStyle = LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP |LVS_SINGLESEL |WS_CHILD | WS_VISIBLE;\r
536         \r
537         if( !m_InChangeFileList.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_IN_CHANGELIST))\r
538         {\r
539                 TRACE0("Failed to create output change files window\n");\r
540                 return FALSE;      // fail to create\r
541         }\r
542         m_ctrlTabCtrl.InsertTab(&m_InChangeFileList,_T("In ChangeList"),-1);\r
543 \r
544         m_InChangeFileList.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |SVNSLC_COLADD|SVNSLC_COLDEL , _T("OutSyncDlg"),\r
545                                     (CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_COMPARETWO)|\r
546                                                         CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_GNUDIFF2)),false);\r
547 \r
548 \r
549         //---------- Create Conflict List Ctrl -----------------\r
550         dwStyle = LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP |LVS_SINGLESEL |WS_CHILD | WS_VISIBLE;\r
551         \r
552         if( !m_ConflictFileList.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_IN_CONFLICT))\r
553         {\r
554                 TRACE0("Failed to create output change files window\n");\r
555                 return FALSE;      // fail to create\r
556         }\r
557         m_ctrlTabCtrl.InsertTab(&m_ConflictFileList,_T("Conflict"),-1);\r
558 \r
559         m_ConflictFileList.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |SVNSLC_COLADD|SVNSLC_COLDEL , _T("OutSyncDlg"),\r
560                                     (CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_COMPARETWO)|\r
561                                                         CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_GNUDIFF2)|\r
562                                                         SVNSLC_POPCONFLICT|SVNSLC_POPRESOLVE),false);\r
563 \r
564 \r
565         //----------  Create Commit Out List Ctrl---------------\r
566                         \r
567         dwStyle =LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;;\r
568 \r
569         if( !m_OutLogList.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_OUT_LOGLIST))\r
570         {\r
571                 TRACE0("Failed to create output commits window\n");\r
572                 return FALSE;      // fail to create\r
573 \r
574         }\r
575 \r
576         m_ctrlTabCtrl.InsertTab(&m_OutLogList,_T("Out Commits"),-1);\r
577         \r
578 \r
579         m_OutLogList.InsertGitColumn();\r
580 \r
581         //------------- Create Change File List Control ----------------\r
582 \r
583         dwStyle = LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP |LVS_SINGLESEL |WS_CHILD | WS_VISIBLE;\r
584         \r
585         if( !m_OutChangeFileList.Create(dwStyle,rectDummy,&m_ctrlTabCtrl,IDC_OUT_CHANGELIST))\r
586         {\r
587                 TRACE0("Failed to create output change files window\n");\r
588                 return FALSE;      // fail to create\r
589         }\r
590         m_ctrlTabCtrl.InsertTab(&m_OutChangeFileList,_T("Out ChangeList"),-1);\r
591 \r
592         m_OutChangeFileList.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |SVNSLC_COLADD|SVNSLC_COLDEL , _T("OutSyncDlg"),\r
593                                     (CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_COMPARETWO)|\r
594                                                         CGitStatusListCtrl::GetContextMenuBit(CGitStatusListCtrl::IDSVNLC_GNUDIFF2)),false);\r
595 \r
596         this->m_tooltips.Create(this);\r
597 \r
598         AddAnchor(IDC_SYNC_TAB,TOP_LEFT,BOTTOM_RIGHT);\r
599 \r
600         AddAnchor(IDC_GROUP_INFO,TOP_LEFT,TOP_RIGHT);\r
601         AddAnchor(IDC_COMBOBOXEX_URL,TOP_LEFT,TOP_RIGHT);\r
602         AddAnchor(IDC_BUTTON_MANAGE,TOP_RIGHT);\r
603         AddAnchor(IDC_BUTTON_PULL,BOTTOM_LEFT);\r
604         AddAnchor(IDC_BUTTON_PUSH,BOTTOM_LEFT);\r
605         AddAnchor(IDC_BUTTON_SUBMODULE,BOTTOM_LEFT);\r
606         AddAnchor(IDC_BUTTON_APPLY,BOTTOM_RIGHT);\r
607         AddAnchor(IDC_BUTTON_EMAIL,BOTTOM_RIGHT);\r
608         AddAnchor(IDC_PROGRESS_SYNC,TOP_LEFT,TOP_RIGHT);\r
609         AddAnchor(IDOK,BOTTOM_RIGHT);\r
610         AddAnchor(IDHELP,BOTTOM_RIGHT);\r
611         AddAnchor(IDC_STATIC_STATUS,BOTTOM_LEFT);\r
612         AddAnchor(IDC_ANIMATE_SYNC,TOP_LEFT);\r
613         AddAnchor(IDC_BUTTON_COMMIT,BOTTOM_LEFT);\r
614 \r
615         BRANCH_COMBOX_ADD_ANCHOR();\r
616 \r
617         this->GetDlgItem(IDC_BUTTON_COMMIT)->ShowWindow(SW_HIDE);\r
618 \r
619         CString WorkingDir=g_Git.m_CurrentDir;\r
620         WorkingDir.Replace(_T(':'),_T('_'));\r
621         m_RegKeyRemoteBranch = CString(_T("Software\\TortoiseGit\\History\\SyncBranch\\"))+WorkingDir;\r
622 \r
623 \r
624         this->AddOthersToAnchor();\r
625         // TODO:  Add extra initialization here\r
626 \r
627         this->m_ctrlPush.AddEntry(CString(_T("Pus&h")));\r
628         this->m_ctrlPush.AddEntry(CString(_T("Push ta&gs")));\r
629         ///this->m_ctrlPush.AddEntry(CString(_T("Push All")));\r
630 \r
631         this->m_ctrlPull.AddEntry(CString(_T("&Pull")));\r
632         this->m_ctrlPull.AddEntry(CString(_T("Fetc&h")));\r
633         this->m_ctrlPull.AddEntry(CString(_T("Fetch&&Re&base")));\r
634 \r
635         this->m_ctrlSubmodule.AddEntry(CString(_T("Submodule Update")));\r
636         this->m_ctrlSubmodule.AddEntry(CString(_T("Submodule Init")));\r
637         this->m_ctrlSubmodule.AddEntry(CString(_T("Submodule Sync")));\r
638         \r
639         WorkingDir.Replace(_T(':'),_T('_'));\r
640 \r
641         CString regkey ;\r
642         regkey.Format(_T("Software\\TortoiseGit\\TortoiseProc\\Sync\\%s"),WorkingDir);\r
643 \r
644         this->m_regPullButton = CRegDWORD(regkey+_T("\\Pull"),0);\r
645         this->m_regPushButton = CRegDWORD(regkey+_T("\\Push"),0);\r
646         this->m_regSubmoduleButton = CRegDWORD(regkey+_T("\\Submodule"));\r
647 \r
648         this->m_ctrlPull.SetCurrentEntry(this->m_regPullButton);\r
649         this->m_ctrlPush.SetCurrentEntry(this->m_regPushButton);\r
650         this->m_ctrlSubmodule.SetCurrentEntry(this->m_regSubmoduleButton);\r
651 \r
652         CString str;\r
653         this->GetWindowText(str);\r
654         str += _T(" - ") + g_Git.m_CurrentDir;\r
655         this->SetWindowText(str);\r
656 \r
657         EnableSaveRestore(_T("SyncDlg"));\r
658 \r
659         this->m_ctrlURL.LoadHistory(CString(_T("Software\\TortoiseGit\\History\\SyncURL\\"))+WorkingDir, _T("url"));\r
660 \r
661         STRING_VECTOR list;\r
662         \r
663         if(!g_Git.GetRemoteList(list))\r
664         {       \r
665                 for(unsigned int i=0;i<list.size();i++)\r
666                 {\r
667                         m_ctrlURL.AddString(list[i]);\r
668                 }\r
669         }       \r
670         m_ctrlURL.SetCurSel(0);\r
671         m_ctrlRemoteBranch.SetCurSel(0);\r
672 \r
673         this->LoadBranchInfo();\r
674 \r
675         this->m_bInited=true;\r
676         FetchOutList();\r
677         \r
678         m_ctrlTabCtrl.ShowTab(IDC_CMD_LOG-1,false);\r
679         m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,false);\r
680         m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);\r
681         m_ctrlTabCtrl.ShowTab(IDC_IN_CONFLICT-1,false);\r
682                 \r
683         return TRUE;  // return TRUE unless you set the focus to a control\r
684         // EXCEPTION: OCX Property Pages should return FALSE\r
685 }\r
686 \r
687 void CSyncDlg::OnBnClickedButtonManage()\r
688 {\r
689         // TODO: Add your control notification handler code here\r
690         CAppUtils::LaunchRemoteSetting();\r
691 }\r
692 \r
693 BOOL CSyncDlg::PreTranslateMessage(MSG* pMsg)\r
694 {\r
695         // TODO: Add your specialized code here and/or call the base class\r
696         m_tooltips.RelayEvent(pMsg);\r
697         return __super::PreTranslateMessage(pMsg);\r
698 }\r
699 void CSyncDlg::FetchOutList(bool force)\r
700 {\r
701         if(!m_bInited)\r
702                 return;\r
703         m_OutChangeFileList.Clear();\r
704         this->m_OutLogList.Clear();\r
705 \r
706         CString remote;\r
707         this->m_ctrlURL.GetWindowText(remote);\r
708         CString remotebranch;\r
709         this->m_ctrlRemoteBranch.GetWindowText(remotebranch);\r
710         remotebranch=remote+_T("/")+remotebranch;\r
711 \r
712         if(IsURL())\r
713         {\r
714                 CString str;\r
715                 str=_T("Don't know what will push befause you enter URL");\r
716                 m_OutLogList.ShowText(str);\r
717                 this->m_ctrlTabCtrl.ShowTab(m_OutChangeFileList.GetDlgCtrlID()-1,FALSE);\r
718                 m_OutLocalBranch.Empty();\r
719                 m_OutRemoteBranch.Empty();\r
720 \r
721                 this->GetDlgItem(IDC_BUTTON_EMAIL)->EnableWindow(FALSE);\r
722                 return ;\r
723         \r
724         }else if(g_Git.GetHash(remotebranch).GetLength()<40)\r
725         {\r
726                 CString str;\r
727                 str.Format(_T("Don't know what will push befause unkown \"%s\""),remotebranch);\r
728                 m_OutLogList.ShowText(str);\r
729                 this->m_ctrlTabCtrl.ShowTab(m_OutChangeFileList.GetDlgCtrlID()-1,FALSE);\r
730                 m_OutLocalBranch.Empty();\r
731                 m_OutRemoteBranch.Empty();\r
732 \r
733                 this->GetDlgItem(IDC_BUTTON_EMAIL)->EnableWindow(FALSE);\r
734                 return ;\r
735         }\r
736         else\r
737         {\r
738                 CString localbranch;\r
739                 localbranch=this->m_ctrlLocalBranch.GetString();\r
740 \r
741                 if(localbranch != m_OutLocalBranch || m_OutRemoteBranch != remotebranch || force)\r
742                 {\r
743                         m_OutLogList.ClearText();\r
744                         m_OutLogList.FillGitLog(NULL,CGit::     LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE,\r
745                                 &remotebranch,&localbranch);\r
746                         \r
747                         CString str;\r
748                         if(m_OutLogList.GetItemCount() == 0)\r
749                         {                       \r
750                                 str.Format(_T("No commits ahead \"%s\""),remotebranch);\r
751                                 m_OutLogList.ShowText(str);\r
752                                 this->m_ctrlStatus.SetWindowText(str);\r
753                                 this->m_ctrlTabCtrl.ShowTab(m_OutChangeFileList.GetDlgCtrlID()-1,FALSE);\r
754                                 this->GetDlgItem(IDC_BUTTON_EMAIL)->EnableWindow(FALSE);\r
755                         }\r
756                         else\r
757                         {\r
758                                 str.Format(_T("%d commits ahead \"%s\""),m_OutLogList.GetItemCount(),remotebranch);\r
759                                 this->m_ctrlStatus.SetWindowText(str);\r
760 \r
761                                 AddDiffFileList(&m_OutChangeFileList,&m_arOutChangeList,localbranch,remotebranch);\r
762                                 \r
763                                 this->m_ctrlTabCtrl.ShowTab(m_OutChangeFileList.GetDlgCtrlID()-1,TRUE);\r
764                                 this->GetDlgItem(IDC_BUTTON_EMAIL)->EnableWindow(TRUE);\r
765                         }\r
766                 }\r
767                 this->m_OutLocalBranch=localbranch;\r
768                 this->m_OutRemoteBranch=remotebranch;\r
769         }\r
770 \r
771 }\r
772 \r
773 bool CSyncDlg::IsURL()\r
774 {\r
775         CString str;\r
776         this->m_ctrlURL.GetWindowText(str);\r
777         if(str.Find(_T('\\'))>=0 || str.Find(_T('/'))>=0)\r
778                 return true;\r
779         else\r
780                 return false;\r
781 }\r
782 void CSyncDlg::OnCbenEndeditComboboxexUrl(NMHDR *pNMHDR, LRESULT *pResult)\r
783 {\r
784         // TODO: Add your control notification handler code here\r
785         *pResult = 0;\r
786 }\r
787 \r
788 void CSyncDlg::OnCbnEditchangeComboboxexUrl()\r
789 {\r
790         this->FetchOutList();\r
791         // TODO: Add your control notification handler code here\r
792 }\r
793 \r
794 UINT CSyncDlg::ProgressThread()\r
795 {\r
796         m_GitCmdStatus=CProgressDlg::RunCmdList(this,m_GitCmdList,true,NULL,&this->m_bAbort);\r
797         return 0;\r
798 }\r
799 \r
800 \r
801 LRESULT CSyncDlg::OnProgressUpdateUI(WPARAM wParam,LPARAM lParam)\r
802 {\r
803         if(wParam == MSG_PROGRESSDLG_START)\r
804         {\r
805                 m_ctrlAnimate.Play(0,-1,-1);\r
806                 this->m_ctrlProgress.SetPos(0);\r
807         }\r
808 \r
809         if(wParam == MSG_PROGRESSDLG_END || wParam == MSG_PROGRESSDLG_FAILED)\r
810         {\r
811                 //m_bDone = true;\r
812                 m_ctrlAnimate.Stop();\r
813                 m_ctrlProgress.SetPos(100);\r
814                 //this->DialogEnableWindow(IDOK,TRUE);\r
815 \r
816                 //if(wParam == MSG_PROGRESSDLG_END)\r
817                 if(this->m_CurrentCmd == GIT_COMMAND_PUSH )\r
818                 {\r
819                         EnableControlButton(true);\r
820                         SwitchToInput();\r
821                         this->FetchOutList(true);\r
822                 }\r
823                 if(this->m_CurrentCmd == GIT_COMMAND_PULL )\r
824                 {\r
825                         PullComplete();\r
826                 }\r
827                 if(this->m_CurrentCmd == GIT_COMMAND_FETCH || this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)\r
828                 {\r
829                         FetchComplete();\r
830                 }\r
831                 if(this->m_CurrentCmd == GIT_COMMAND_SUBMODULE)\r
832                 {\r
833                         //this->m_ctrlCmdOut.SetSel(-1,-1);\r
834                         //this->m_ctrlCmdOut.ReplaceSel(_T("Done\r\n"));\r
835                         //this->m_ctrlCmdOut.SetSel(-1,-1);\r
836                         EnableControlButton(true);\r
837                         SwitchToInput();\r
838                 }\r
839         }\r
840 \r
841         if(lParam != 0)\r
842                 ParserCmdOutput((TCHAR)lParam);\r
843 \r
844         return 0;\r
845 }\r
846 \r
847 \r
848 void CSyncDlg::ParserCmdOutput(TCHAR ch)\r
849 {\r
850         //TRACE(_T("%c"),ch);\r
851         int linenum;\r
852         int index;\r
853         linenum = this->m_ctrlCmdOut.GetLineCount();\r
854 \r
855         if( ch == _T('\r') )\r
856         {\r
857                 if(linenum>0)\r
858                         m_CmdOutCurrentPos = this->m_ctrlCmdOut.LineIndex(linenum-1);\r
859                 else\r
860                         m_CmdOutCurrentPos = 0;\r
861 \r
862                 //TRACE(_T("line %d - %d\n"),index,m_ctrlCmdOut.GetTextLength());\r
863         }else\r
864                 m_CmdOutCurrentPos++;\r
865                 \r
866         this->m_ctrlCmdOut.SetSel(m_CmdOutCurrentPos,m_CmdOutCurrentPos+1);\r
867         \r
868         if( ch != _T('\r') )\r
869                 this->m_ctrlCmdOut.ReplaceSel(CString(ch));\r
870         \r
871         int firstline = m_ctrlCmdOut.GetFirstVisibleLine();\r
872         if( linenum - firstline > 4 )\r
873                 this->m_ctrlCmdOut.LineScroll(linenum - firstline -4);\r
874 \r
875         if( ch == _T('\r') || ch == _T('\n') )\r
876         {\r
877                 int s1=m_LogText.Find(_T(':'));\r
878                 int s2=m_LogText.Find(_T('%'));\r
879                 if(s1>0 && s2>0)\r
880                 {\r
881                         //      this->m_CurrentWork.SetWindowTextW(m_LogText.Left(s1));\r
882                         int pos=CProgressDlg::FindPercentage(m_LogText);\r
883                         TRACE(_T("Pos %d\r\n"),pos);\r
884                         if(pos>0)\r
885                                 this->m_ctrlProgress.SetPos(pos);\r
886                 }\r
887                 m_LogText=_T("");       \r
888         }\r
889         m_LogText+=ch;\r
890 \r
891 }\r
892 void CSyncDlg::OnBnClickedButtonCommit()\r
893 {\r
894         // TODO: Add your control notification handler code here\r
895     CString proc=CPathUtils::GetAppDirectory();\r
896     proc += _T("TortoiseProc.exe /command:commit");\r
897     proc += _T(" /path:\"");\r
898     proc += g_Git.m_CurrentDir;\r
899     \r
900         CAppUtils::LaunchApplication(proc,IDS_ERROR_CANNON_FIND_TORTOISEPROC,false);\r
901 }\r
902 \r
903 void CSyncDlg::OnOK()\r
904 {\r
905         // TODO: Add your specialized code here and/or call the base class\r
906         UpdateCombox();\r
907         m_ctrlURL.SaveHistory();\r
908         SaveHistory();\r
909         __super::OnOK();\r
910 }\r
911 \r
912 void CSyncDlg::OnBnClickedButtonSubmodule()\r
913 {\r
914         // TODO: Add your control notification handler code here\r
915                 // TODO: Add your control notification handler code here\r
916         this->UpdateData();\r
917         UpdateCombox();\r
918 \r
919         this->m_regSubmoduleButton = this->m_ctrlSubmodule.GetCurrentEntry();\r
920 \r
921         this->SwitchToRun();\r
922         \r
923         this->m_bAbort=false;\r
924         this->m_GitCmdList.clear();\r
925 \r
926         ShowTab(IDC_CMD_LOG);\r
927 \r
928         CString cmd;\r
929 \r
930         switch (m_ctrlSubmodule.GetCurrentEntry())\r
931         {\r
932         case 0:\r
933                 cmd=_T("git.exe submodule update");\r
934                 break;\r
935         case 1:\r
936                 cmd=_T("git.exe submodule init");\r
937                 break;\r
938         case 2:\r
939                 cmd=_T("git.exe submodule sync");\r
940                 break;\r
941         }\r
942 \r
943         \r
944         m_GitCmdList.push_back(cmd);\r
945 \r
946         m_CurrentCmd = GIT_COMMAND_SUBMODULE;\r
947 \r
948         m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
949         if (m_pThread==NULL)\r
950         {\r
951 //              ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
952         }\r
953         else\r
954         {\r
955                 m_pThread->m_bAutoDelete = TRUE;\r
956                 m_pThread->ResumeThread();\r
957         }\r
958 \r
959 }\r