2 #include "GitBlameLogList.h"
4 #include "TortoiseGitBlameDoc.h"
5 #include "TortoiseGitBlameView.h"
9 IMPLEMENT_DYNAMIC(CGitBlameLogList
, CHintListCtrl
)
11 void CGitBlameLogList::hideUnimplementedCommands()
14 GetContextMenuBit(ID_COPYCLIPBOARD
) |
15 GetContextMenuBit(ID_COPYHASH
) |
16 GetContextMenuBit(ID_EXPORT
) |
17 GetContextMenuBit(ID_CREATE_BRANCH
) |
18 GetContextMenuBit(ID_CREATE_TAG
) |
19 GetContextMenuBit(ID_SWITCHTOREV
)
21 m_ContextMenuMask
|= GetContextMenuBit(ID_BLAME
);
24 void CGitBlameLogList::ContextMenuAction(int cmd
,int FirstSelect
, int LastSelect
,CMenu
* menu
)
26 POSITION pos
= GetFirstSelectedItemPosition();
27 int indexNext
= GetNextSelectedItem(pos
);
33 GitRev
* pSelLogEntry
= reinterpret_cast<GitRev
*>(m_arShownList
.GetAt(indexNext
));
35 bool bOpenWith
= false;
37 procCmd
+=_T(" /path:\"");
38 procCmd
+=((CMainFrame
*)::AfxGetApp()->GetMainWnd())->GetActiveView()->GetDocument()->GetPathName();
40 procCmd
+=_T(" /rev:")+this->m_logEntries
.GetGitRevAt(indexNext
).m_CommitHash
.ToString();
42 procCmd
+=_T(" /command:");
47 procCmd
+=_T("diff /udiff");
53 CString tempfile
=GetTempFile();
55 GitRev
* r1
= reinterpret_cast<GitRev
*>(m_arShownList
.GetAt(FirstSelect
));
56 GitRev
* r2
= reinterpret_cast<GitRev
*>(m_arShownList
.GetAt(LastSelect
));
57 cmd
.Format(_T("git.exe diff-tree -r -p --stat %s %s"),r1
->m_CommitHash
,r2
->m_CommitHash
);
58 g_Git
.RunLogFile(cmd
,tempfile
);
59 CAppUtils::StartUnifiedDiffViewer(tempfile
,r1
->m_CommitHash
.Left(6)+_T(":")+r2
->m_CommitHash
.Left(6));
67 GitRev
* r1
= reinterpret_cast<GitRev
*>(m_arShownList
.GetAt(FirstSelect
));
68 GitRev
* r2
= reinterpret_cast<GitRev
*>(m_arShownList
.GetAt(LastSelect
));
70 dlg
.SetDiff(NULL
,*r1
,*r2
);
79 GitRev
* r1
= &m_wcRev
;
80 GitRev
* r2
= pSelLogEntry
;
82 dlg
.SetDiff(NULL
,*r1
,*r2
);
85 //user clicked on the menu item "compare with working copy"
88 // GitDiff diff(this, m_hWnd, true);
89 // diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
90 // diff.SetHEADPeg(m_LogRevision);
91 // diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);
94 // CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
99 procCmd
+=CString(_T("diff \rev1:"))+CString(GIT_REV_ZERO
)+CString(_T(" \rev2:"))+this->m_logEntries
.GetGitRevAt(indexNext
).m_CommitHash
.ToString();
101 case ID_COMPAREWITHPREVIOUS
:
102 procCmd
+=_T("prevdiff");
104 case ID_COPYCLIPBOARD
:
106 CopySelectionToClipBoard();
111 CopySelectionToClipBoard(TRUE
);
115 procCmd
+=_T("export");
117 case ID_CREATE_BRANCH
:
118 procCmd
+=_T("branch");
124 procCmd
+=_T("switch");
127 procCmd
+=_T("blame");
128 procCmd
+=_T(" /endrev:") + this->m_logEntries
.GetGitRevAt(indexNext
).m_CommitHash
.ToString();
131 //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);
138 // we need an URL to complete this command, so error out if we can't get an URL
139 if (pathURL
.IsEmpty())
142 strMessage
.Format(IDS_ERR_NOURLOFFILE
, (LPCTSTR
)(m_path
.GetUIPathString()));
143 CMessageBox::Show(this->m_hWnd
, strMessage
, _T("TortoiseGit"), MB_ICONERROR
);
144 TRACE(_T("could not retrieve the URL of the folder!\n"));
148 msg
.Format(IDS_LOG_REVERT_CONFIRM
, m_path
.GetWinPath());
149 if (CMessageBox::Show(this->m_hWnd
, msg
, _T("TortoiseGit"), MB_YESNO
| MB_ICONQUESTION
) == IDYES
)
152 dlg
.SetCommand(CGitProgressDlg::GitProgress_Merge
);
153 dlg
.SetPathList(CTGitPathList(m_path
));
155 dlg
.SetSecondUrl(pathURL
);
156 revisionRanges
.AdjustForMerge(true);
157 dlg
.SetRevisionRanges(revisionRanges
);
158 dlg
.SetPegRevision(m_LogRevision
);
165 // we need an URL to complete this command, so error out if we can't get an URL
166 if (pathURL
.IsEmpty())
169 strMessage
.Format(IDS_ERR_NOURLOFFILE
, (LPCTSTR
)(m_path
.GetUIPathString()));
170 CMessageBox::Show(this->m_hWnd
, strMessage
, _T("TortoiseGit"), MB_ICONERROR
);
171 TRACE(_T("could not retrieve the URL of the folder!\n"));
175 CString path
= m_path
.GetWinPathString();
176 bool bGotSavePath
= false;
177 if ((GetSelectedCount() == 1)&&(!m_path
.IsDirectory()))
179 bGotSavePath
= CAppUtils::FileOpenSave(path
, NULL
, IDS_LOG_MERGETO
, IDS_COMMONFILEFILTER
, true, GetSafeHwnd());
183 CBrowseFolder folderBrowser
;
184 folderBrowser
.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO
)));
185 bGotSavePath
= (folderBrowser
.Show(GetSafeHwnd(), path
, path
) == CBrowseFolder::OK
);
190 dlg
.SetCommand(CGitProgressDlg::GitProgress_Merge
);
191 dlg
.SetPathList(CTGitPathList(CTGitPath(path
)));
193 dlg
.SetSecondUrl(pathURL
);
194 revisionRanges
.AdjustForMerge(false);
195 dlg
.SetRevisionRanges(revisionRanges
);
196 dlg
.SetPegRevision(m_LogRevision
);
203 // we need an URL to complete this command, so error out if we can't get an URL
204 if (pathURL
.IsEmpty())
207 strMessage
.Format(IDS_ERR_NOURLOFFILE
, (LPCTSTR
)(m_path
.GetUIPathString()));
208 CMessageBox::Show(this->m_hWnd
, strMessage
, _T("TortoiseGit"), MB_ICONERROR
);
209 TRACE(_T("could not retrieve the URL of the folder!\n"));
214 msg
.Format(IDS_LOG_REVERTTOREV_CONFIRM
, m_path
.GetWinPath());
215 if (CMessageBox::Show(this->m_hWnd
, msg
, _T("TortoiseGit"), MB_YESNO
| MB_ICONQUESTION
) == IDYES
)
218 dlg
.SetCommand(CGitProgressDlg::GitProgress_Merge
);
219 dlg
.SetPathList(CTGitPathList(m_path
));
221 dlg
.SetSecondUrl(pathURL
);
222 GitRevRangeArray revarray
;
223 revarray
.AddRevRange(GitRev::REV_HEAD
, revSelected
);
224 dlg
.SetRevisionRanges(revarray
);
225 dlg
.SetPegRevision(m_LogRevision
);
233 case ID_BLAMECOMPARE
:
235 //user clicked on the menu item "compare with working copy"
236 //now first get the revision which is selected
239 GitDiff
diff(this, this->m_hWnd
, true);
240 diff
.SetHEADPeg(m_LogRevision
);
241 diff
.ShowCompare(m_path
, GitRev::REV_BASE
, m_path
, revSelected
, GitRev(), false, true);
244 CAppUtils::StartShowCompare(m_hWnd
, m_path
, GitRev::REV_BASE
, m_path
, revSelected
, GitRev(), m_LogRevision
, false, false, true);
249 //user clicked on the menu item "compare and blame revisions"
252 GitDiff
diff(this, this->m_hWnd
, true);
253 diff
.SetHEADPeg(m_LogRevision
);
254 diff
.ShowCompare(CTGitPath(pathURL
), revSelected2
, CTGitPath(pathURL
), revSelected
, GitRev(), false, true);
257 CAppUtils::StartShowCompare(m_hWnd
, CTGitPath(pathURL
), revSelected2
, CTGitPath(pathURL
), revSelected
, GitRev(), m_LogRevision
, false, false, true);
260 case ID_BLAMEWITHPREVIOUS
:
262 //user clicked on the menu item "Compare and Blame with previous revision"
265 GitDiff
diff(this, this->m_hWnd
, true);
266 diff
.SetHEADPeg(m_LogRevision
);
267 diff
.ShowCompare(CTGitPath(pathURL
), revPrevious
, CTGitPath(pathURL
), revSelected
, GitRev(), false, true);
270 CAppUtils::StartShowCompare(m_hWnd
, CTGitPath(pathURL
), revPrevious
, CTGitPath(pathURL
), revSelected
, GitRev(), m_LogRevision
, false, false, true);
278 CProgressDlg progDlg
;
279 progDlg
.SetTitle(IDS_APPNAME
);
280 progDlg
.SetAnimation(IDR_DOWNLOAD
);
282 sInfoLine
.Format(IDS_PROGRESSGETFILEREVISION
, m_path
.GetWinPath(), (LPCTSTR
)revSelected
.ToString());
283 progDlg
.SetLine(1, sInfoLine
, true);
284 SetAndClearProgressInfo(&progDlg
);
285 progDlg
.ShowModeless(m_hWnd
);
286 CTGitPath tempfile
= CTempFiles::Instance().GetTempFilePath(false, m_path
, revSelected
);
287 bool bSuccess
= true;
288 if (!Cat(m_path
, GitRev(GitRev::REV_HEAD
), revSelected
, tempfile
))
291 // try again, but with the selected revision as the peg revision
292 if (!Cat(m_path
, revSelected
, revSelected
, tempfile
))
295 SetAndClearProgressInfo((HWND
)NULL
);
296 CMessageBox::Show(this->m_hWnd
, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR
);
305 SetAndClearProgressInfo((HWND
)NULL
);
306 SetFileAttributes(tempfile
.GetWinPath(), FILE_ATTRIBUTE_READONLY
);
309 ret
= (int)ShellExecute(this->m_hWnd
, NULL
, tempfile
.GetWinPath(), NULL
, NULL
, SW_SHOWNORMAL
);
310 if ((ret
<= HINSTANCE_ERROR
)||bOpenWith
)
312 CString cmd
= _T("RUNDLL32 Shell32,OpenAs_RunDLL ");
313 cmd
+= tempfile
.GetWinPathString() + _T(" ");
314 CAppUtils::LaunchApplication(cmd
, NULL
, false);
322 dlg
.EndRev
= revSelected
;
323 if (dlg
.DoModal() == IDOK
)
328 tempfile
= blame
.BlameToTempFile(m_path
, dlg
.StartRev
, dlg
.EndRev
, dlg
.EndRev
, logfile
, _T(""), dlg
.m_bIncludeMerge
, TRUE
, TRUE
);
329 if (!tempfile
.IsEmpty())
333 //open the default text editor for the result file
334 CAppUtils::StartTextViewer(tempfile
);
338 CString sParams
= _T("/path:\"") + m_path
.GetGitPathString() + _T("\" ");
339 if(!CAppUtils::LaunchTortoiseBlame(tempfile
, logfile
, CPathUtils::GetFileNameFromPath(m_path
.GetFileOrDirectoryName()),sParams
))
347 CMessageBox::Show(this->m_hWnd
, blame
.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR
);
355 CString url
= _T("tgit:")+pathURL
;
356 sCmd
.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),
357 (LPCTSTR
)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
358 (LPCTSTR
)m_path
.GetWinPath(), (LONG
)revSelected
);
359 CAppUtils::LaunchApplication(sCmd
, NULL
, false);
364 m_nSearchIndex
= GetSelectionMark();
365 if (m_nSearchIndex
< 0)
373 m_pFindDialog
= new CFindReplaceDialog();
374 m_pFindDialog
->Create(TRUE
, NULL
, NULL
, FR_HIDEUPDOWN
| FR_HIDEWHOLEWORD
, this);
381 sCmd
.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),
382 (LPCTSTR
)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
383 (LPCTSTR
)pathURL
, (LPCTSTR
)revSelected
.ToString());
385 CAppUtils::LaunchApplication(sCmd
, NULL
, false);
390 EditLogMessage(selIndex
);
395 EditAuthor(selEntries
);
400 CEditPropertiesDlg dlg
;
401 dlg
.SetProjectProperties(&m_ProjectProperties
);
402 CTGitPathList escapedlist
;
403 dlg
.SetPathList(CTGitPathList(CTGitPath(pathURL
)));
404 dlg
.SetRevision(revSelected
);
413 sCmd
.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),
414 (LPCTSTR
)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
415 (LPCTSTR
)pathURL
, (LONG
)revSelected
);
416 CAppUtils::LaunchApplication(sCmd
, NULL
, false);
422 CString url
= _T("tgit:")+pathURL
;
423 sCmd
.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),
424 (LPCTSTR
)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
425 (LPCTSTR
)url
, (LONG
)revSelected
);
426 CAppUtils::LaunchApplication(sCmd
, NULL
, false);
431 CString url
= m_ProjectProperties
.sWebViewerRev
;
432 url
= GetAbsoluteUrlFromRelativeUrl(url
);
433 url
.Replace(_T("%REVISION%"), revSelected
.ToString());
435 ShellExecute(this->m_hWnd
, _T("open"), url
, NULL
, NULL
, SW_SHOWDEFAULT
);
440 CString relurl
= pathURL
;
441 CString sRoot
= GetRepositoryRoot(CTGitPath(relurl
));
442 relurl
= relurl
.Mid(sRoot
.GetLength());
443 CString url
= m_ProjectProperties
.sWebViewerPathRev
;
444 url
= GetAbsoluteUrlFromRelativeUrl(url
);
445 url
.Replace(_T("%REVISION%"), revSelected
.ToString());
446 url
.Replace(_T("%PATH%"), relurl
);
448 ShellExecute(this->m_hWnd
, _T("open"), url
, NULL
, NULL
, SW_SHOWDEFAULT
);
457 PROCESS_INFORMATION process
;
458 memset(&startup
, 0, sizeof(startup
));
459 startup
.cb
= sizeof(startup
);
460 memset(&process
, 0, sizeof(process
));
461 CString tortoiseProcPath
= CPathUtils::GetAppDirectory() + _T("TortoiseProc.exe");
463 if (CreateProcess(tortoiseProcPath
, procCmd
.GetBuffer(), NULL
, NULL
, FALSE
, 0, 0, 0, &startup
, &process
))
465 CloseHandle(process
.hThread
);
466 CloseHandle(process
.hProcess
);