void CGitRefCompareList::OnContextMenuList(CWnd * /*pWnd*/, CPoint point) { int selIndex = GetSelectionMark(); if (selIndex < 0 || (size_t)selIndex >= m_RefList.size()) return; CString refName = m_RefList[selIndex].fullName; CString oldHash = m_RefList[selIndex].oldHash; CString newHash = m_RefList[selIndex].newHash; CIconMenu popup; popup.CreatePopupMenu(); CString logStr; if (!oldHash.IsEmpty()) { logStr.Format(IDS_SHOWLOG_OF, (LPCTSTR)oldHash); popup.AppendMenuIcon(IDGITRCL_OLDLOG, logStr, IDI_LOG); } if (!newHash.IsEmpty() && oldHash != newHash) { logStr.Format(IDS_SHOWLOG_OF, (LPCTSTR)newHash); popup.AppendMenuIcon(IDGITRCL_NEWLOG, logStr, IDI_LOG); } if (!oldHash.IsEmpty() && !newHash.IsEmpty() && oldHash != newHash) popup.AppendMenuIcon(IDGITRCL_COMPARE, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF); popup.AppendMenuIcon(IDGITRCL_REFLOG, IDS_MENUREFLOG, IDI_LOG); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this); AfxGetApp()->DoWaitCursor(1); switch (cmd) { case IDGITRCL_OLDLOG: case IDGITRCL_NEWLOG: { CString sCmd; sCmd.Format(L"/command:log /path:\"%s\" /endrev:\"%s\"", (LPCTSTR)g_Git.m_CurrentDir, cmd == IDGITRCL_OLDLOG ? (LPCTSTR)oldHash : (LPCTSTR)newHash); CAppUtils::RunTortoiseGitProc(sCmd); break; } case IDGITRCL_COMPARE: { CString sCmd; sCmd.Format(L"/command:showcompare /path:\"%s\" /revision1:\"%s\" /revision2:\"%s\"", (LPCTSTR)g_Git.m_CurrentDir, (LPCTSTR)oldHash, (LPCTSTR)newHash); if (!!(GetAsyncKeyState(VK_SHIFT) & 0x8000)) sCmd += L" /alternative"; CAppUtils::RunTortoiseGitProc(sCmd); break; } case IDGITRCL_REFLOG: { CString sCmd; sCmd.Format(L"/command:reflog /path:\"%s\" /ref:\"%s\"", (LPCTSTR)g_Git.m_CurrentDir, (LPCTSTR)refName); CAppUtils::RunTortoiseGitProc(sCmd); break; } } AfxGetApp()->DoWaitCursor(-1); }
BOOL CProgressDlg::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN) { if (pMsg->wParam == VK_ESCAPE) { // pressing the ESC key should close the dialog. But since we disabled the escape // key (so the user doesn't get the idea that he could simply undo an e.g. update) // this won't work. // So if the user presses the ESC key, change it to VK_RETURN so the dialog gets // the impression that the OK button was pressed. if ((!GetDlgItem(IDCANCEL)->IsWindowEnabled()) &&(GetDlgItem(IDOK)->IsWindowEnabled())&&(GetDlgItem(IDOK)->IsWindowVisible())) { // since we convert ESC to RETURN, make sure the OK button has the focus. GetDlgItem(IDOK)->SetFocus(); pMsg->wParam = VK_RETURN; } } } else if (pMsg->message == WM_CONTEXTMENU || pMsg->message == WM_RBUTTONDOWN) { CWnd * pWnd = (CWnd*) GetDlgItem(IDC_LOG); if (pWnd == GetFocus()) { CIconMenu popup; if (popup.CreatePopupMenu()) { popup.AppendMenuIcon(WM_COPY, IDS_SCIEDIT_COPY, IDI_COPYCLIP); if (m_Log.GetSelText().IsEmpty()) popup.EnableMenuItem(WM_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); popup.AppendMenu(MF_SEPARATOR); popup.AppendMenuIcon(EM_SETSEL, IDS_SCIEDIT_SELECTALL); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, pMsg->pt.x, pMsg->pt.y, this); switch (cmd) { case 0: // no command selected break; case EM_SETSEL: case WM_COPY: ::SendMessage(GetDlgItem(IDC_LOG)->GetSafeHwnd(), cmd, 0, -1); break; } return TRUE; } } } return __super::PreTranslateMessage(pMsg); }
void CChangedDlg::OnBnClickedStash() { CIconMenu popup; if (popup.CreatePopupMenu()) { popup.AppendMenuIcon(ID_STASH_SAVE, IDS_MENUSTASHSAVE, IDI_COMMIT); CTGitPath root = g_Git.m_CurrentDir; if (root.HasStashDir()) { popup.AppendMenuIcon(ID_STASH_POP, IDS_MENUSTASHPOP, IDI_RELOCATE); popup.AppendMenuIcon(ID_STASH_APPLY, IDS_MENUSTASHAPPLY, IDI_RELOCATE); popup.AppendMenuIcon(ID_STASH_LIST, IDS_MENUSTASHLIST, IDI_LOG); } POINT cursorPos; GetCursorPos(&cursorPos); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, cursorPos.x, cursorPos.y, this, 0); switch (cmd & 0xFFFF) { case ID_STASH_SAVE: CAppUtils::StashSave(); break; case ID_STASH_POP: CAppUtils::StashPop(2); break; case ID_STASH_APPLY: CAppUtils::StashApply(_T(""), false); break; case ID_STASH_LIST: { CRefLogDlg dlg; dlg.m_CurrentBranch = _T("refs/stash"); dlg.DoModal(); } break; default: return; } OnBnClickedRefresh(); } }
void CPropertiesWnd::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { CMFCPropertyGridProperty * pProperty = m_wndPropList.GetCurSel(); CString sMenuItemText; CIconMenu popup; if (pProperty && !pProperty->IsGroup() && popup.CreatePopupMenu()) { sMenuItemText.LoadString(IDS_SCIEDIT_COPY); popup.AppendMenu(MF_STRING | MF_ENABLED, WM_COPY, sMenuItemText); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); switch (cmd) { case 0: break; // no command selected case WM_COPY: CStringUtils::WriteAsciiStringToClipboard(pProperty->GetValue(), GetSafeHwnd()); break; } } }
void CGitProgressList::OnContextMenu(CWnd* pWnd, CPoint point) { if (m_options & ProgOptDryRun) return; // don't do anything in a dry-run. if (pWnd != this) return; int selIndex = GetSelectionMark(); if ((point.x == -1) && (point.y == -1)) { // Menu was invoked from the keyboard rather than by right-clicking CRect rect; GetItemRect(selIndex, &rect, LVIR_LABEL); ClientToScreen(&rect); point = rect.CenterPoint(); } if ((selIndex < 0) || m_bThreadRunning || GetSelectedCount() == 0) return; // entry is selected, thread has finished with updating so show the popup menu CIconMenu popup; if (!popup.CreatePopupMenu()) return; ContextMenuActionList actions; NotificationData* data = m_arData[selIndex]; if (data && GetSelectedCount() == 1) data->GetContextMenu(popup, actions); if (!actions.empty()) popup.AppendMenu(MF_SEPARATOR, NULL); actions.push_back([&]() { CString sLines; POSITION pos = GetFirstSelectedItemPosition(); while (pos) { int nItem = GetNextSelectedItem(pos); NotificationData* data = m_arData[nItem]; if (data) { sLines += data->sPathColumnText; sLines += _T("\r\n"); } } sLines.TrimRight(); if (!sLines.IsEmpty()) CStringUtils::WriteAsciiStringToClipboard(sLines, GetSafeHwnd()); }); popup.AppendMenuIcon(actions.size(), IDS_LOG_POPUP_COPYTOCLIPBOARD, IDI_COPYCLIP); if (actions.empty()) return; int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); if (cmd <= 0 || cmd > actions.size()) return; theApp.DoWaitCursor(1); actions.at(cmd - 1)(); theApp.DoWaitCursor(-1); }
void CPatchListCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { int selected=this->GetSelectedCount(); int index=0; POSITION pos=this->GetFirstSelectedItemPosition(); index=this->GetNextSelectedItem(pos); CIconMenu popup; if (popup.CreatePopupMenu()) { if(selected == 1) { if( m_ContextMenuMask&GetMenuMask(MENU_VIEWPATCH)) popup.AppendMenuIcon(MENU_VIEWPATCH, IDS_MENU_VIEWPATCH, 0); if( m_ContextMenuMask&GetMenuMask(MENU_VIEWWITHMERGE)) popup.AppendMenuIcon(MENU_VIEWWITHMERGE, IDS_MENU_VIEWWITHMERGE, 0); popup.SetDefaultItem(MENU_VIEWPATCH, FALSE); } if(selected >= 1) { if( m_ContextMenuMask&GetMenuMask(MENU_SENDMAIL)) popup.AppendMenuIcon(MENU_SENDMAIL, IDS_MENU_SENDMAIL, IDI_MENUSENDMAIL); if( m_ContextMenuMask&GetMenuMask(MENU_APPLY)) popup.AppendMenuIcon(MENU_APPLY, IDS_MENU_APPLY, 0); } int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); switch (cmd) { case MENU_VIEWPATCH: { CString path=GetItemText(index,0); CTGitPath gitpath; gitpath.SetFromWin(path); CAppUtils::StartUnifiedDiffViewer(path,gitpath.GetFilename()); break; } case MENU_VIEWWITHMERGE: { CString path=GetItemText(index,0); CTGitPath gitpath; gitpath.SetFromWin(path); CTGitPath dir; dir.SetFromGit(g_Git.m_CurrentDir); CAppUtils::StartExtPatch(gitpath,dir); break; } case MENU_SENDMAIL: { LaunchProc(_T("sendmail")); break; } case MENU_APPLY: { LaunchProc(_T("importpatch")); break; } default: break; } } }
void CFileDiffDlg::OnContextMenu(CWnd* pWnd, CPoint point) { if ((pWnd==0)||(pWnd != &m_cFileList)) return; if (m_cFileList.GetSelectedCount() == 0) return; // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_cFileList.GetItemRect(m_cFileList.GetSelectionMark(), &rect, LVIR_LABEL); m_cFileList.ClientToScreen(&rect); point = rect.CenterPoint(); } CIconMenu popup; if (popup.CreatePopupMenu()) { int firstEntry = -1; POSITION firstPos = m_cFileList.GetFirstSelectedItemPosition(); if (firstPos) firstEntry = m_cFileList.GetNextSelectedItem(firstPos); CString menuText; popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); popup.AppendMenuIcon(ID_GNUDIFFCOMPARE, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF); popup.AppendMenu(MF_SEPARATOR, NULL); if (!m_bIsBare) { menuText.Format(IDS_FILEDIFF_POPREVERTTOREV, (LPCTSTR)m_rev1.m_CommitHash.ToString().Left(g_Git.GetShortHASHLength())); popup.AppendMenuIcon(ID_REVERT1, menuText, IDI_REVERT); menuText.Format(IDS_FILEDIFF_POPREVERTTOREV, (LPCTSTR)m_rev2.m_CommitHash.ToString().Left(g_Git.GetShortHASHLength())); popup.AppendMenuIcon(ID_REVERT2, menuText, IDI_REVERT); popup.AppendMenu(MF_SEPARATOR, NULL); } popup.AppendMenuIcon(ID_LOG, IDS_FILEDIFF_LOG, IDI_LOG); if (firstEntry >= 0 && !m_arFilteredList[firstEntry]->IsDirectory()) { if (!m_bIsBare) { popup.AppendMenuIcon(ID_BLAME, IDS_FILEDIFF_POPBLAME, IDI_BLAME); popup.AppendMenu(MF_SEPARATOR, NULL); } popup.AppendMenuIcon(ID_EXPORT, IDS_FILEDIFF_POPEXPORT, IDI_EXPORT); } else if (firstEntry >= 0) popup.AppendMenuIcon(ID_LOGSUBMODULE, IDS_MENULOGSUBMODULE, IDI_LOG); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_SAVEAS, IDS_FILEDIFF_POPSAVELIST, IDI_SAVEAS); popup.AppendMenuIcon(ID_CLIPBOARD_PATH, IDS_STATUSLIST_CONTEXT_COPY, IDI_COPYCLIP); popup.AppendMenuIcon(ID_CLIPBOARD_ALL, IDS_STATUSLIST_CONTEXT_COPYEXT, IDI_COPYCLIP); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); m_bCancelled = false; switch (cmd) { case ID_COMPARE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, false); } } break; case ID_GNUDIFFCOMPARE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { CTGitPath *fd2 = m_arFilteredList[m_cFileList.GetNextSelectedItem(pos)]; CTGitPath *fd1 = fd2; if (fd2->m_Action & CTGitPath::LOGACTIONS_REPLACED) fd1 = new CTGitPath(fd2->GetGitOldPathString()); CAppUtils::StartShowUnifiedDiff(m_hWnd, *fd2, m_rev2.m_CommitHash.ToString(), *fd1, m_rev1.m_CommitHash.ToString()); if (fd1 != fd2) delete fd1; } } break; case ID_REVERT1: RevertSelectedItemToVersion(m_rev1.m_CommitHash.ToString()); break; case ID_REVERT2: RevertSelectedItemToVersion(m_rev2.m_CommitHash.ToString()); break; case ID_BLAME: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CAppUtils::LaunchTortoiseBlame(m_arFilteredList[index]->GetWinPathString(), m_rev1.m_CommitHash.ToString()); } } break; case ID_LOG: case ID_LOGSUBMODULE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CString sCmd = _T("/command:log"); if (sCmd == ID_LOGSUBMODULE) sCmd += _T(" /submodule"); sCmd += _T(" /path:\"") + m_arFilteredList[index]->GetWinPathString() + _T("\" "); sCmd += _T(" /endrev:") + m_rev1.m_CommitHash.ToString(); CAppUtils::RunTortoiseGitProc(sCmd); } } break; case ID_SAVEAS: { if (m_cFileList.GetSelectedCount() > 0) { CString temp; CTGitPath savePath; CString pathSave; if (!CAppUtils::FileOpenSave(pathSave, NULL, IDS_REPOBROWSE_SAVEAS, IDS_TEXTFILEFILTER, false, m_hWnd, _T(".txt"))) { break; } savePath = CTGitPath(pathSave); // now open the selected file for writing try { CStdioFile file(savePath.GetWinPathString(), CFile::typeBinary | CFile::modeReadWrite | CFile::modeCreate); if (m_path1.IsEmpty() && m_path2.IsEmpty()) temp.Format(IDS_FILEDIFF_CHANGEDLISTINTROROOT, (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)m_rev2.m_CommitHash.ToString()); else temp.Format(IDS_FILEDIFF_CHANGEDLISTINTRO, (LPCTSTR)m_path1.GetGitPathString(), (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)m_path2.GetGitPathString(), (LPCTSTR)m_rev2.m_CommitHash.ToString()); file.WriteString(temp + _T("\r\n")); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; file.WriteString(fd->GetGitPathString()); file.WriteString(_T("\r\n")); } file.Close(); } catch (CFileException* pE) { pE->ReportError(); } } } break; case ID_CLIPBOARD_PATH: { CopySelectionToClipboard(); } break; case ID_CLIPBOARD_ALL: { CopySelectionToClipboard(TRUE); } break; case ID_EXPORT: { // export all changed files to a folder CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; if (browseFolder.Show(GetSafeHwnd(), m_strExportDir) == CBrowseFolder::OK) { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; // we cannot export directories or folders if (fd->m_Action == CTGitPath::LOGACTIONS_DELETED || fd->IsDirectory()) continue; CPathUtils::MakeSureDirectoryPathExists(m_strExportDir + _T("\\") + fd->GetContainingDirectory().GetWinPathString()); CString filename = m_strExportDir + _T("\\") + fd->GetWinPathString(); if(m_rev1.m_CommitHash.ToString() == GIT_REV_ZERO) { if(!CopyFile(g_Git.CombinePath(fd), filename, false)) { MessageBox(CFormatMessageWrapper(), _T("TortoiseGit"), MB_OK | MB_ICONERROR); return; } } else { if(g_Git.GetOneFile(m_rev1.m_CommitHash, *fd, filename)) { CString out; out.Format(IDS_STATUSLIST_CHECKOUTFILEFAILED, (LPCTSTR)fd->GetGitPathString(), (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)filename); if (CMessageBox::Show(nullptr, g_Git.GetGitLastErr(out, CGit::GIT_CMD_GETONEFILE), _T("TortoiseGit"), 2, IDI_WARNING, CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2) return; } } } } } break; } } }
void CEditPropExternals::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { int selIndex = m_ExtList.GetSelectionMark(); if (selIndex < 0) return; // nothing selected, nothing to do with a context menu int selCount = m_ExtList.GetSelectedCount(); if (selCount <= 0) return; // nothing selected, nothing to do with a context menu // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_ExtList.GetItemRect(selIndex, &rect, LVIR_LABEL); m_ExtList.ClientToScreen(&rect); point = rect.CenterPoint(); } bool haveHead = true; POSITION pos = m_ExtList.GetFirstSelectedItemPosition(); while (pos) { int index = m_ExtList.GetNextSelectedItem(pos); if ((index >= 0)&&(index < (int)m_externals.size())) { if (m_externals[index].headrev == SVN_INVALID_REVNUM) { haveHead = false; break; } } } CIconMenu popup; if (popup.CreatePopupMenu()) { if (haveHead) popup.AppendMenuIcon(CMD_ADJUST, IDS_EDITPROPS_ADJUST_TO_HEAD); else popup.AppendMenuIcon(CMD_FETCH_AND_ADJUST, IDS_EDITPROPS_FETCH_AND_ADJUST_TO_HEAD); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RIGHTBUTTON, point.x, point.y, this, 0); switch (cmd) { case CMD_FETCH_AND_ADJUST: { SVN svn; svn.SetPromptParentWindow(m_hWnd); SVNInfo svnInfo; svnInfo.SetPromptParentWindow(m_hWnd); SVNLogHelper logHelper; CProgressDlg progDlg; progDlg.ShowModal(m_hWnd, TRUE); progDlg.SetTitle(IDS_EDITPROPS_PROG_FINDHEADTITLE); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_EDITPROPS_PROG_FINDHEADREVS))); DWORD count = 0; DWORD total = m_ExtList.GetSelectedCount(); POSITION p = m_ExtList.GetFirstSelectedItemPosition(); while (p) { int index = m_ExtList.GetNextSelectedItem(p); progDlg.SetProgress(count++, total); if ((index >= 0)&&(index < (int)m_externals.size())) { progDlg.SetLine(2, m_externals[index].url, true); if (m_externals[index].headrev == SVN_INVALID_REVNUM) { if (m_externals[index].root.IsEmpty()) { CTSVNPath path_ = m_externals[index].path; path_.AppendPathString(m_externals[index].targetDir); m_externals[index].root = svn.GetRepositoryRoot(path_); } auto fullurl = CTSVNPath(m_externals[index].fullurl); auto youngestRev = logHelper.GetYoungestRev(fullurl); if (!youngestRev.IsValid()) m_externals[index].headrev = svn.GetHEADRevision(fullurl, true); else m_externals[index].headrev = youngestRev; } } } progDlg.Stop(); } // intentional fall through case CMD_ADJUST: { POSITION p = m_ExtList.GetFirstSelectedItemPosition(); while (p) { int index = m_ExtList.GetNextSelectedItem(p); if ((index >= 0)&&(index < (int)m_externals.size())) { if (m_externals[index].headrev != SVN_INVALID_REVNUM) { if (m_externals[index].revision.kind == svn_opt_revision_number) { m_externals[index].revision.value.number = -1; m_externals[index].revision.kind = svn_opt_revision_unspecified; } m_externals[index].pegrevision.value.number = m_externals[index].headrev; m_externals[index].pegrevision.kind = svn_opt_revision_number; } } } m_ExtList.Invalidate(); } break; } } }
void CFileDiffDlg::OnContextMenu(CWnd* pWnd, CPoint point) { if ((pWnd==0)||(pWnd != &m_cFileList)) return; if (m_cFileList.GetSelectedCount() == 0) return; // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_cFileList.GetItemRect(m_cFileList.GetSelectionMark(), &rect, LVIR_LABEL); m_cFileList.ClientToScreen(&rect); point = rect.CenterPoint(); } CIconMenu popup; if (!popup.CreatePopupMenu()) return; popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); popup.AppendMenuIcon(ID_UNIFIEDDIFF, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF); popup.AppendMenuIcon(ID_BLAME, IDS_FILEDIFF_POPBLAME, IDI_BLAME); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_SAVEAS, IDS_FILEDIFF_POPSAVELIST, IDI_SAVEAS); popup.AppendMenuIcon(ID_CLIPBOARD, IDS_FILEDIFF_POPCLIPBOARD, IDI_COPYCLIP); popup.AppendMenuIcon(ID_EXPORT, IDS_FILEDIFF_POPEXPORT, IDI_EXPORT); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); m_bCancelled = false; switch (cmd) { case ID_COMPARE: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, false); } } break; case ID_UNIFIEDDIFF: { CTSVNPath diffFile = CTempFiles::Instance().GetTempFilePath(false); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CFileDiffDlg::FileDiff fd = m_arFilteredList[index]; CTSVNPath url1 = CTSVNPath(m_path1.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString()); CTSVNPath url2 = m_bDoPegDiff ? url1 : CTSVNPath(m_path2.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString()); if (m_bDoPegDiff) { PegDiff(url1, m_peg, m_rev1, m_rev2, CTSVNPath(), m_depth, m_bIgnoreancestry, false, true, CString(), true, diffFile); } else { Diff(url1, m_rev1, url2, m_rev2, CTSVNPath(), m_depth, m_bIgnoreancestry, false, true, CString(), true, diffFile); } } CAppUtils::StartUnifiedDiffViewer(diffFile, CString(), false); } break; case ID_BLAME: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, true); } } break; case ID_SAVEAS: if (m_cFileList.GetSelectedCount() > 0) { CTSVNPath savePath; CString pathSave; if (!CAppUtils::FileOpenSave(pathSave, NULL, IDS_REPOBROWSE_SAVEAS, IDS_COMMONFILEFILTER, false, m_hWnd)) { break; } savePath = CTSVNPath(pathSave); // now open the selected file for writing try { CStdioFile file(savePath.GetWinPathString(), CFile::typeBinary | CFile::modeReadWrite | CFile::modeCreate); CString temp; temp.FormatMessage(IDS_FILEDIFF_CHANGEDLISTINTRO, (LPCTSTR)m_path1.GetSVNPathString(), (LPCTSTR)m_rev1.ToString(), (LPCTSTR)m_path2.GetSVNPathString(), (LPCTSTR)m_rev2.ToString()); file.WriteString(temp + _T("\n")); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); FileDiff fd = m_arFilteredList[index]; file.WriteString(fd.path.GetSVNPathString()); file.WriteString(_T("\n")); } file.Close(); } catch (CFileException* pE) { pE->ReportError(); pE->Delete(); } } break; case ID_CLIPBOARD: CopySelectionToClipboard(); break; case ID_EXPORT: { // export all changed files to a folder CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; if (browseFolder.Show(GetSafeHwnd(), m_strExportDir) == CBrowseFolder::OK) { m_arSelectedFileList.RemoveAll(); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CFileDiffDlg::FileDiff fd = m_arFilteredList[index]; m_arSelectedFileList.Add(fd); } m_pProgDlg = new CProgressDlg(); InterlockedExchange(&m_bThreadRunning, TRUE); if (AfxBeginThread(ExportThreadEntry, this)==NULL) { InterlockedExchange(&m_bThreadRunning, FALSE); OnCantStartThread(); } } } break; } }
void CFileDiffDlg::OnContextMenu(CWnd* pWnd, CPoint point) { if ((pWnd==0)||(pWnd != &m_cFileList)) return; if (m_cFileList.GetSelectedCount() == 0) return; // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_cFileList.GetItemRect(m_cFileList.GetSelectionMark(), &rect, LVIR_LABEL); m_cFileList.ClientToScreen(&rect); point = rect.CenterPoint(); } CIconMenu popup; if (popup.CreatePopupMenu()) { popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); popup.AppendMenuIcon(ID_BLAME, IDS_FILEDIFF_POPBLAME, IDI_BLAME); popup.AppendMenuIcon(ID_LOG, IDS_FILEDIFF_LOG, IDI_LOG); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_EXPORT, IDS_FILEDIFF_POPEXPORT, IDI_EXPORT); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_SAVEAS, IDS_FILEDIFF_POPSAVELIST, IDI_SAVEAS); popup.AppendMenuIcon(ID_CLIPBOARD_PATH, IDS_STATUSLIST_CONTEXT_COPY, IDI_COPYCLIP); popup.AppendMenuIcon(ID_CLIPBOARD_ALL, IDS_STATUSLIST_CONTEXT_COPYEXT, IDI_COPYCLIP); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); m_bCancelled = false; switch (cmd) { case ID_COMPARE: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, false); } } break; case ID_BLAME: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CAppUtils::LaunchTortoiseBlame(m_arFilteredList[index]->GetWinPathString(), m_rev1.m_CommitHash.ToString()); } } break; case ID_LOG: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CString cmd = _T("/command:log"); cmd += _T(" /path:\"")+m_arFilteredList[index]->GetWinPathString()+_T("\" "); cmd += _T(" /endrev:")+m_rev1.m_CommitHash.ToString(); CAppUtils::RunTortoiseProc(cmd); } } break; case ID_SAVEAS: { if (m_cFileList.GetSelectedCount() > 0) { CString temp; CTGitPath savePath; CString pathSave; if (!CAppUtils::FileOpenSave(pathSave, NULL, IDS_REPOBROWSE_SAVEAS, IDS_COMMONFILEFILTER, false, m_hWnd)) { break; } savePath = CTGitPath(pathSave); // now open the selected file for writing try { CStdioFile file(savePath.GetWinPathString(), CFile::typeBinary | CFile::modeReadWrite | CFile::modeCreate); // temp.Format(IDS_FILEDIFF_CHANGEDLISTINTRO, (LPCTSTR)m_path1.GetGitPathString(), (LPCTSTR)m_rev1.ToString(), (LPCTSTR)m_path2.GetGitPathString(), (LPCTSTR)m_rev2.ToString()); file.WriteString(temp + _T("\n")); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; file.WriteString(fd->GetGitPathString()); file.WriteString(_T("\n")); } file.Close(); } catch (CFileException* pE) { pE->ReportError(); } } } break; case ID_CLIPBOARD_PATH: { CopySelectionToClipboard(); } break; case ID_CLIPBOARD_ALL: { CopySelectionToClipboard(TRUE); } break; case ID_EXPORT: { // export all changed files to a folder CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; if (browseFolder.Show(GetSafeHwnd(), m_strExportDir) == CBrowseFolder::OK) { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; // we cannot export directories or folders if (fd->m_Action == CTGitPath::LOGACTIONS_DELETED || fd->IsDirectory()) continue; CAppUtils::CreateMultipleDirectory(m_strExportDir + _T("\\") + fd->GetDirectory().GetWinPathString()); CString filename = m_strExportDir + _T("\\") + fd->GetWinPathString(); if(m_rev1.m_CommitHash.ToString() == GIT_REV_ZERO) { if(!CopyFile(g_Git.m_CurrentDir + _T("\\") + fd->GetWinPath(), filename, false)) { MessageBox(CFormatMessageWrapper(), _T("TortoiseGit"), MB_OK | MB_ICONERROR); return; } } else { if(g_Git.GetOneFile(m_rev1.m_CommitHash, *fd, filename)) { CString out; out.Format(_T("Fail checkout one file %s;%s"), m_rev1.m_CommitHash.ToString(), fd->GetWinPath()); CMessageBox::Show(NULL, out, _T("TortoiseGit"), MB_OK); return; } } } } } break; } } }