OSDN Git Service

Merge X64 Build
[tortoisegit/TortoiseGitJp.git] / src / TortoiseGitBlame / LogListBlameAction.cpp
1 #include "stdafx.h"\r
2 #include "GitBlameLogList.h"\r
3 #include "GitRev.h"\r
4 #include "TortoiseGitBlameDoc.h"\r
5 #include "TortoiseGitBlameView.h"\r
6 #include "MainFrm.h"\r
7 #include "PathUtils.h"\r
8 \r
9 IMPLEMENT_DYNAMIC(CGitBlameLogList, CHintListCtrl)\r
10 \r
11 void CGitBlameLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect)\r
12 {       \r
13         POSITION pos = GetFirstSelectedItemPosition();\r
14         int indexNext = GetNextSelectedItem(pos);\r
15         if (indexNext < 0)\r
16                 return;\r
17 \r
18         CString  procCmd;\r
19 \r
20         GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));\r
21 \r
22         bool bOpenWith = false;\r
23 \r
24         procCmd+=_T("/path:\"");\r
25         procCmd+=((CMainFrame*)::AfxGetApp()->GetMainWnd())->GetActiveView()->GetDocument()->GetPathName();\r
26         procCmd+=_T("\" ");\r
27         procCmd+=_T(" /rev:")+this->m_logEntries[indexNext].m_CommitHash;\r
28 \r
29         procCmd+=_T(" /command:");\r
30 \r
31         switch (cmd)\r
32         {\r
33                 case ID_GNUDIFF1:\r
34                         procCmd+=_T("diff /udiff");\r
35                 break;\r
36 \r
37 #if 0\r
38                 case ID_GNUDIFF2:\r
39                         {\r
40                                 CString tempfile=GetTempFile();\r
41                                 CString cmd;\r
42                                 GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
43                                 GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
44                                 cmd.Format(_T("git.exe diff-tree -r -p --stat %s %s"),r1->m_CommitHash,r2->m_CommitHash);\r
45                                 g_Git.RunLogFile(cmd,tempfile);\r
46                                 CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r2->m_CommitHash.Left(6));\r
47 \r
48                         }\r
49                         break;\r
50 #endif\r
51 #if 0\r
52                 case ID_COMPARETWO:\r
53                         {\r
54                                 GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
55                                 GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
56                                 CFileDiffDlg dlg;\r
57                                 dlg.SetDiff(NULL,*r1,*r2);\r
58                                 dlg.DoModal();\r
59                                 \r
60                         }\r
61                         break;\r
62 #endif  \r
63 #if 0\r
64                 case ID_COMPARE:\r
65                         {\r
66                                 GitRev * r1 = &m_wcRev;\r
67                                 GitRev * r2 = pSelLogEntry;\r
68                                 CFileDiffDlg dlg;\r
69                                 dlg.SetDiff(NULL,*r1,*r2);\r
70                                 dlg.DoModal();\r
71 \r
72                                 //user clicked on the menu item "compare with working copy"\r
73                                 //if (PromptShown())\r
74                                 //{\r
75                                 //      GitDiff diff(this, m_hWnd, true);\r
76                                 //      diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
77                                 //      diff.SetHEADPeg(m_LogRevision);\r
78                                 //      diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);\r
79                                 //}\r
80                                 //else\r
81                                 //      CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
82                         }\r
83                         break;\r
84 #endif\r
85                 case ID_COMPARE:\r
86                         procCmd+=CString(_T("diff \rev1:"))+CString(GIT_REV_ZERO)+CString(_T(" \rev2:"))+this->m_logEntries[indexNext].m_CommitHash;\r
87                         break;\r
88                 case ID_COMPAREWITHPREVIOUS:\r
89                         procCmd+=_T("prevdiff");\r
90                         break;\r
91                 case ID_COPYCLIPBOARD:\r
92                         {\r
93                                 CopySelectionToClipBoard();\r
94                         }\r
95                         return;\r
96                 case ID_COPYHASH:\r
97                         {\r
98                                 CopySelectionToClipBoard(TRUE);\r
99                         }\r
100                         return;\r
101                 case ID_EXPORT:\r
102                         procCmd+=_T("export");\r
103                         break;\r
104                 case ID_CREATE_BRANCH:\r
105                         procCmd+=_T("branch");\r
106                         break;\r
107                 case ID_CREATE_TAG:\r
108                         procCmd+=_T("tag");\r
109                         break;\r
110                 case ID_SWITCHTOREV:\r
111                         procCmd+=_T("switch");\r
112                         break;\r
113 \r
114                 default:\r
115                         //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);\r
116                         return;\r
117 \r
118 #if 0\r
119         \r
120                 case ID_REVERTREV:\r
121                         {\r
122                                 // we need an URL to complete this command, so error out if we can't get an URL\r
123                                 if (pathURL.IsEmpty())\r
124                                 {\r
125                                         CString strMessage;\r
126                                         strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
127                                         CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
128                                         TRACE(_T("could not retrieve the URL of the folder!\n"));\r
129                                         break;          //exit\r
130                                 }\r
131                                 CString msg;\r
132                                 msg.Format(IDS_LOG_REVERT_CONFIRM, m_path.GetWinPath());\r
133                                 if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
134                                 {\r
135                                         CGitProgressDlg dlg;\r
136                                         dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
137                                         dlg.SetPathList(CTGitPathList(m_path));\r
138                                         dlg.SetUrl(pathURL);\r
139                                         dlg.SetSecondUrl(pathURL);\r
140                                         revisionRanges.AdjustForMerge(true);\r
141                                         dlg.SetRevisionRanges(revisionRanges);\r
142                                         dlg.SetPegRevision(m_LogRevision);\r
143                                         dlg.DoModal();\r
144                                 }\r
145                         }\r
146                         break;\r
147                 case ID_MERGEREV:\r
148                         {\r
149                                 // we need an URL to complete this command, so error out if we can't get an URL\r
150                                 if (pathURL.IsEmpty())\r
151                                 {\r
152                                         CString strMessage;\r
153                                         strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
154                                         CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
155                                         TRACE(_T("could not retrieve the URL of the folder!\n"));\r
156                                         break;          //exit\r
157                                 }\r
158 \r
159                                 CString path = m_path.GetWinPathString();\r
160                                 bool bGotSavePath = false;\r
161                                 if ((GetSelectedCount() == 1)&&(!m_path.IsDirectory()))\r
162                                 {\r
163                                         bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());\r
164                                 }\r
165                                 else\r
166                                 {\r
167                                         CBrowseFolder folderBrowser;\r
168                                         folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));\r
169                                         bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);\r
170                                 }\r
171                                 if (bGotSavePath)\r
172                                 {\r
173                                         CGitProgressDlg dlg;\r
174                                         dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
175                                         dlg.SetPathList(CTGitPathList(CTGitPath(path)));\r
176                                         dlg.SetUrl(pathURL);\r
177                                         dlg.SetSecondUrl(pathURL);\r
178                                         revisionRanges.AdjustForMerge(false);\r
179                                         dlg.SetRevisionRanges(revisionRanges);\r
180                                         dlg.SetPegRevision(m_LogRevision);\r
181                                         dlg.DoModal();\r
182                                 }\r
183                         }\r
184                         break;\r
185                 case ID_REVERTTOREV:\r
186                         {\r
187                                 // we need an URL to complete this command, so error out if we can't get an URL\r
188                                 if (pathURL.IsEmpty())\r
189                                 {\r
190                                         CString strMessage;\r
191                                         strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
192                                         CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
193                                         TRACE(_T("could not retrieve the URL of the folder!\n"));\r
194                                         break;          //exit\r
195                                 }\r
196 \r
197                                 CString msg;\r
198                                 msg.Format(IDS_LOG_REVERTTOREV_CONFIRM, m_path.GetWinPath());\r
199                                 if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
200                                 {\r
201                                         CGitProgressDlg dlg;\r
202                                         dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
203                                         dlg.SetPathList(CTGitPathList(m_path));\r
204                                         dlg.SetUrl(pathURL);\r
205                                         dlg.SetSecondUrl(pathURL);\r
206                                         GitRevRangeArray revarray;\r
207                                         revarray.AddRevRange(GitRev::REV_HEAD, revSelected);\r
208                                         dlg.SetRevisionRanges(revarray);\r
209                                         dlg.SetPegRevision(m_LogRevision);\r
210                                         dlg.DoModal();\r
211                                 }\r
212                         }\r
213                         break;\r
214         \r
215 \r
216         \r
217                 case ID_BLAMECOMPARE:\r
218                         {\r
219                                 //user clicked on the menu item "compare with working copy"\r
220                                 //now first get the revision which is selected\r
221                                 if (PromptShown())\r
222                                 {\r
223                                         GitDiff diff(this, this->m_hWnd, true);\r
224                                         diff.SetHEADPeg(m_LogRevision);\r
225                                         diff.ShowCompare(m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), false, true);\r
226                                 }\r
227                                 else\r
228                                         CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);\r
229                         }\r
230                         break;\r
231                 case ID_BLAMETWO:\r
232                         {\r
233                                 //user clicked on the menu item "compare and blame revisions"\r
234                                 if (PromptShown())\r
235                                 {\r
236                                         GitDiff diff(this, this->m_hWnd, true);\r
237                                         diff.SetHEADPeg(m_LogRevision);\r
238                                         diff.ShowCompare(CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
239                                 }\r
240                                 else\r
241                                         CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
242                         }\r
243                         break;\r
244                 case ID_BLAMEWITHPREVIOUS:\r
245                         {\r
246                                 //user clicked on the menu item "Compare and Blame with previous revision"\r
247                                 if (PromptShown())\r
248                                 {\r
249                                         GitDiff diff(this, this->m_hWnd, true);\r
250                                         diff.SetHEADPeg(m_LogRevision);\r
251                                         diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
252                                 }\r
253                                 else\r
254                                         CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
255                         }\r
256                         break;\r
257                 \r
258                 case ID_OPENWITH:\r
259                         bOpenWith = true;\r
260                 case ID_OPEN:\r
261                         {\r
262                                 CProgressDlg progDlg;\r
263                                 progDlg.SetTitle(IDS_APPNAME);\r
264                                 progDlg.SetAnimation(IDR_DOWNLOAD);\r
265                                 CString sInfoLine;\r
266                                 sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
267                                 progDlg.SetLine(1, sInfoLine, true);\r
268                                 SetAndClearProgressInfo(&progDlg);\r
269                                 progDlg.ShowModeless(m_hWnd);\r
270                                 CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path, revSelected);\r
271                                 bool bSuccess = true;\r
272                                 if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\r
273                                 {\r
274                                         bSuccess = false;\r
275                                         // try again, but with the selected revision as the peg revision\r
276                                         if (!Cat(m_path, revSelected, revSelected, tempfile))\r
277                                         {\r
278                                                 progDlg.Stop();\r
279                                                 SetAndClearProgressInfo((HWND)NULL);\r
280                                                 CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
281                                                 EnableOKButton();\r
282                                                 break;\r
283                                         }\r
284                                         bSuccess = true;\r
285                                 }\r
286                                 if (bSuccess)\r
287                                 {\r
288                                         progDlg.Stop();\r
289                                         SetAndClearProgressInfo((HWND)NULL);\r
290                                         SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
291                                         int ret = 0;\r
292                                         if (!bOpenWith)\r
293                                                 ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);\r
294                                         if ((ret <= HINSTANCE_ERROR)||bOpenWith)\r
295                                         {\r
296                                                 CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
297                                                 cmd += tempfile.GetWinPathString() + _T(" ");\r
298                                                 CAppUtils::LaunchApplication(cmd, NULL, false);\r
299                                         }\r
300                                 }\r
301                         }\r
302                         break;\r
303                 case ID_BLAME:\r
304                         {\r
305                                 CBlameDlg dlg;\r
306                                 dlg.EndRev = revSelected;\r
307                                 if (dlg.DoModal() == IDOK)\r
308                                 {\r
309                                         CBlame blame;\r
310                                         CString tempfile;\r
311                                         CString logfile;\r
312                                         tempfile = blame.BlameToTempFile(m_path, dlg.StartRev, dlg.EndRev, dlg.EndRev, logfile, _T(""), dlg.m_bIncludeMerge, TRUE, TRUE);\r
313                                         if (!tempfile.IsEmpty())\r
314                                         {\r
315                                                 if (dlg.m_bTextView)\r
316                                                 {\r
317                                                         //open the default text editor for the result file\r
318                                                         CAppUtils::StartTextViewer(tempfile);\r
319                                                 }\r
320                                                 else\r
321                                                 {\r
322                                                         CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");\r
323                                                         if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))\r
324                                                         {\r
325                                                                 break;\r
326                                                         }\r
327                                                 }\r
328                                         }\r
329                                         else\r
330                                         {\r
331                                                 CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
332                                         }\r
333                                 }\r
334                         }\r
335                         break;\r
336                 case ID_UPDATE:\r
337                         {\r
338                                 CString sCmd;\r
339                                 CString url = _T("tgit:")+pathURL;\r
340                                 sCmd.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),\r
341                                         (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
342                                         (LPCTSTR)m_path.GetWinPath(), (LONG)revSelected);\r
343                                 CAppUtils::LaunchApplication(sCmd, NULL, false);\r
344                         }\r
345                         break;\r
346                 case ID_FINDENTRY:\r
347                         {\r
348                                 m_nSearchIndex = GetSelectionMark();\r
349                                 if (m_nSearchIndex < 0)\r
350                                         m_nSearchIndex = 0;\r
351                                 if (m_pFindDialog)\r
352                                 {\r
353                                         break;\r
354                                 }\r
355                                 else\r
356                                 {\r
357                                         m_pFindDialog = new CFindReplaceDialog();\r
358                                         m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this);                                                                        \r
359                                 }\r
360                         }\r
361                         break;\r
362                 case ID_REPOBROWSE:\r
363                         {\r
364                                 CString sCmd;\r
365                                 sCmd.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),\r
366                                         (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
367                                         (LPCTSTR)pathURL, (LPCTSTR)revSelected.ToString());\r
368 \r
369                                 CAppUtils::LaunchApplication(sCmd, NULL, false);\r
370                         }\r
371                         break;\r
372                 case ID_EDITLOG:\r
373                         {\r
374                                 EditLogMessage(selIndex);\r
375                         }\r
376                         break;\r
377                 case ID_EDITAUTHOR:\r
378                         {\r
379                                 EditAuthor(selEntries);\r
380                         }\r
381                         break;\r
382                 case ID_REVPROPS:\r
383                         {\r
384                                 CEditPropertiesDlg dlg;\r
385                                 dlg.SetProjectProperties(&m_ProjectProperties);\r
386                                 CTGitPathList escapedlist;\r
387                                 dlg.SetPathList(CTGitPathList(CTGitPath(pathURL)));\r
388                                 dlg.SetRevision(revSelected);\r
389                                 dlg.RevProps(true);\r
390                                 dlg.DoModal();\r
391                         }\r
392                         break;\r
393                 \r
394                 case ID_EXPORT:\r
395                         {\r
396                                 CString sCmd;\r
397                                 sCmd.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),\r
398                                         (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
399                                         (LPCTSTR)pathURL, (LONG)revSelected);\r
400                                 CAppUtils::LaunchApplication(sCmd, NULL, false);\r
401                         }\r
402                         break;\r
403                 case ID_CHECKOUT:\r
404                         {\r
405                                 CString sCmd;\r
406                                 CString url = _T("tgit:")+pathURL;\r
407                                 sCmd.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),\r
408                                         (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
409                                         (LPCTSTR)url, (LONG)revSelected);\r
410                                 CAppUtils::LaunchApplication(sCmd, NULL, false);\r
411                         }\r
412                         break;\r
413                 case ID_VIEWREV:\r
414                         {\r
415                                 CString url = m_ProjectProperties.sWebViewerRev;\r
416                                 url = GetAbsoluteUrlFromRelativeUrl(url);\r
417                                 url.Replace(_T("%REVISION%"), revSelected.ToString());\r
418                                 if (!url.IsEmpty())\r
419                                         ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        \r
420                         }\r
421                         break;\r
422                 case ID_VIEWPATHREV:\r
423                         {\r
424                                 CString relurl = pathURL;\r
425                                 CString sRoot = GetRepositoryRoot(CTGitPath(relurl));\r
426                                 relurl = relurl.Mid(sRoot.GetLength());\r
427                                 CString url = m_ProjectProperties.sWebViewerPathRev;\r
428                                 url = GetAbsoluteUrlFromRelativeUrl(url);\r
429                                 url.Replace(_T("%REVISION%"), revSelected.ToString());\r
430                                 url.Replace(_T("%PATH%"), relurl);\r
431                                 if (!url.IsEmpty())\r
432                                         ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        \r
433                         }\r
434                         break;\r
435 #endif\r
436 \r
437                 } // switch (cmd)\r
438 \r
439 \r
440         STARTUPINFO startup;\r
441         PROCESS_INFORMATION process;\r
442         memset(&startup, 0, sizeof(startup));\r
443         startup.cb = sizeof(startup);\r
444         memset(&process, 0, sizeof(process));\r
445         CString tortoiseProcPath = CPathUtils::GetAppDirectory() + _T("TortoiseProc.exe");\r
446         \r
447         if (CreateProcess(tortoiseProcPath, procCmd.GetBuffer(), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
448         {\r
449                 CloseHandle(process.hThread);\r
450                 CloseHandle(process.hProcess);\r
451         }\r
452 }