2 #include "GitBlameLogList.h"
\r
4 #include "TortoiseGitBlameDoc.h"
\r
5 #include "TortoiseGitBlameView.h"
\r
7 #include "PathUtils.h"
\r
9 IMPLEMENT_DYNAMIC(CGitBlameLogList, CHintListCtrl)
\r
11 void CGitBlameLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect)
\r
13 POSITION pos = GetFirstSelectedItemPosition();
\r
14 int indexNext = GetNextSelectedItem(pos);
\r
20 GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));
\r
22 bool bOpenWith = false;
\r
24 procCmd+=_T("/path:\"");
\r
25 procCmd+=((CMainFrame*)::AfxGetApp()->GetMainWnd())->GetActiveView()->GetDocument()->GetPathName();
\r
27 procCmd+=_T(" /rev:")+this->m_logEntries[indexNext].m_CommitHash;
\r
29 procCmd+=_T(" /command:");
\r
34 procCmd+=_T("diff /udiff");
\r
40 CString tempfile=GetTempFile();
\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
54 GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
\r
55 GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));
\r
57 dlg.SetDiff(NULL,*r1,*r2);
\r
66 GitRev * r1 = &m_wcRev;
\r
67 GitRev * r2 = pSelLogEntry;
\r
69 dlg.SetDiff(NULL,*r1,*r2);
\r
72 //user clicked on the menu item "compare with working copy"
\r
73 //if (PromptShown())
\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
81 // CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
\r
86 procCmd+=CString(_T("diff \rev1:"))+CString(GIT_REV_ZERO)+CString(_T(" \rev2:"))+this->m_logEntries[indexNext].m_CommitHash;
\r
88 case ID_COMPAREWITHPREVIOUS:
\r
89 procCmd+=_T("prevdiff");
\r
91 case ID_COPYCLIPBOARD:
\r
93 CopySelectionToClipBoard();
\r
98 CopySelectionToClipBoard(TRUE);
\r
102 procCmd+=_T("export");
\r
104 case ID_CREATE_BRANCH:
\r
105 procCmd+=_T("branch");
\r
107 case ID_CREATE_TAG:
\r
108 procCmd+=_T("tag");
\r
110 case ID_SWITCHTOREV:
\r
111 procCmd+=_T("switch");
\r
115 //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);
\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
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
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
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
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
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
159 CString path = m_path.GetWinPathString();
\r
160 bool bGotSavePath = false;
\r
161 if ((GetSelectedCount() == 1)&&(!m_path.IsDirectory()))
\r
163 bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());
\r
167 CBrowseFolder folderBrowser;
\r
168 folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));
\r
169 bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);
\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
185 case ID_REVERTTOREV:
\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
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
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
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
217 case ID_BLAMECOMPARE:
\r
219 //user clicked on the menu item "compare with working copy"
\r
220 //now first get the revision which is selected
\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
228 CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);
\r
233 //user clicked on the menu item "compare and blame revisions"
\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
241 CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);
\r
244 case ID_BLAMEWITHPREVIOUS:
\r
246 //user clicked on the menu item "Compare and Blame with previous revision"
\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
254 CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);
\r
262 CProgressDlg progDlg;
\r
263 progDlg.SetTitle(IDS_APPNAME);
\r
264 progDlg.SetAnimation(IDR_DOWNLOAD);
\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
275 // try again, but with the selected revision as the peg revision
\r
276 if (!Cat(m_path, revSelected, revSelected, tempfile))
\r
279 SetAndClearProgressInfo((HWND)NULL);
\r
280 CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
\r
289 SetAndClearProgressInfo((HWND)NULL);
\r
290 SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
\r
293 ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);
\r
294 if ((ret <= HINSTANCE_ERROR)||bOpenWith)
\r
296 CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");
\r
297 cmd += tempfile.GetWinPathString() + _T(" ");
\r
298 CAppUtils::LaunchApplication(cmd, NULL, false);
\r
306 dlg.EndRev = revSelected;
\r
307 if (dlg.DoModal() == IDOK)
\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
315 if (dlg.m_bTextView)
\r
317 //open the default text editor for the result file
\r
318 CAppUtils::StartTextViewer(tempfile);
\r
322 CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");
\r
323 if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))
\r
331 CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
\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
348 m_nSearchIndex = GetSelectionMark();
\r
349 if (m_nSearchIndex < 0)
\r
350 m_nSearchIndex = 0;
\r
357 m_pFindDialog = new CFindReplaceDialog();
\r
358 m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this);
\r
362 case ID_REPOBROWSE:
\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
369 CAppUtils::LaunchApplication(sCmd, NULL, false);
\r
374 EditLogMessage(selIndex);
\r
377 case ID_EDITAUTHOR:
\r
379 EditAuthor(selEntries);
\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
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
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
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
422 case ID_VIEWPATHREV:
\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
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
447 if (CreateProcess(tortoiseProcPath, procCmd.GetBuffer(), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
\r
449 CloseHandle(process.hThread);
\r
450 CloseHandle(process.hProcess);
\r