--- /dev/null
+// GitLogList.cpp : implementation file\r
+//\r
+\r
+#include "stdafx.h"\r
+#include "TortoiseProc.h"\r
+#include "GitLogList.h"\r
+#include "GitRev.h"\r
+//#include "VssStyle.h"\r
+#include "IconMenu.h"\r
+// CGitLogList\r
+#include "cursor.h"\r
+#include "InputDlg.h"\r
+#include "PropDlg.h"\r
+#include "SVNProgressDlg.h"\r
+#include "ProgressDlg.h"\r
+//#include "RepositoryBrowser.h"\r
+//#include "CopyDlg.h"\r
+//#include "StatGraphDlg.h"\r
+#include "Logdlg.h"\r
+#include "MessageBox.h"\r
+#include "Registry.h"\r
+#include "AppUtils.h"\r
+#include "PathUtils.h"\r
+#include "StringUtils.h"\r
+#include "UnicodeUtils.h"\r
+#include "TempFile.h"\r
+//#include "GitInfo.h"\r
+//#include "GitDiff.h"\r
+#include "IconMenu.h"\r
+//#include "RevisionRangeDlg.h"\r
+//#include "BrowseFolder.h"\r
+//#include "BlameDlg.h"\r
+//#include "Blame.h"\r
+//#include "GitHelpers.h"\r
+#include "GitStatus.h"\r
+//#include "LogDlgHelper.h"\r
+//#include "CachedLogInfo.h"\r
+//#include "RepositoryInfo.h"\r
+//#include "EditPropertiesDlg.h"\r
+#include "FileDiffDlg.h"\r
+\r
+\r
+\r
+\r
+IMPLEMENT_DYNAMIC(CGitLogList, CHintListCtrl)\r
+\r
+CGitLogList::CGitLogList():CHintListCtrl()\r
+ ,m_regMaxBugIDColWidth(_T("Software\\TortoiseGit\\MaxBugIDColWidth"), 200)\r
+ ,m_nSearchIndex(0)\r
+{\r
+ // use the default GUI font, create a copy of it and\r
+ // change the copy to BOLD (leave the rest of the font\r
+ // the same)\r
+ HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);\r
+ LOGFONT lf = {0};\r
+ GetObject(hFont, sizeof(LOGFONT), &lf);\r
+ lf.lfWeight = FW_BOLD;\r
+ m_boldFont = CreateFontIndirect(&lf);\r
+\r
+}\r
+\r
+CGitLogList::~CGitLogList()\r
+{\r
+ DestroyIcon(m_hModifiedIcon);\r
+ DestroyIcon(m_hReplacedIcon);\r
+ DestroyIcon(m_hAddedIcon);\r
+ DestroyIcon(m_hDeletedIcon);\r
+ m_logEntries.ClearAll();\r
+\r
+ if (m_boldFont)\r
+ DeleteObject(m_boldFont);\r
+\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CGitLogList, CHintListCtrl)\r
+ ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawLoglist)\r
+ ON_NOTIFY(LVN_GETDISPINFO, 0, OnLvnGetdispinfoLoglist)\r
+ ON_WM_CONTEXTMENU()\r
+ ON_NOTIFY(NM_DBLCLK, 0, OnNMDblclkLoglist)\r
+ ON_NOTIFY(LVN_ODFINDITEM, IDC_LOGLIST, OnLvnOdfinditemLoglist)\r
+END_MESSAGE_MAP()\r
+\r
+int CGitLogList:: OnCreate(LPCREATESTRUCT lpCreateStruct)\r
+{\r
+ SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);\r
+ // load the icons for the action columns\r
+ m_hModifiedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONMODIFIED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
+ m_hReplacedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONREPLACED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
+ m_hAddedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONADDED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
+ m_hDeletedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONDELETED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
+\r
+ return CHintListCtrl::OnCreate(lpCreateStruct);\r
+}\r
+\r
+void CGitLogList::InsertGitColumn()\r
+{\r
+ CString temp;\r
+\r
+ int c = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;\r
+ \r
+ while (c>=0)\r
+ DeleteColumn(c--);\r
+ temp.LoadString(IDS_LOG_GRAPH);\r
+\r
+ InsertColumn(this->LOGLIST_GRAPH, temp);\r
+ \r
+#if 0 \r
+ // make the revision column right aligned\r
+ LVCOLUMN Column;\r
+ Column.mask = LVCF_FMT;\r
+ Column.fmt = LVCFMT_RIGHT;\r
+ SetColumn(0, &Column); \r
+#endif \r
+// CString log;\r
+// g_Git.GetLog(log);\r
+\r
+ temp.LoadString(IDS_LOG_ACTIONS);\r
+ InsertColumn(this->LOGLIST_ACTION, temp);\r
+ \r
+ temp.LoadString(IDS_LOG_MESSAGE);\r
+ InsertColumn(this->LOGLIST_MESSAGE, temp);\r
+ \r
+ temp.LoadString(IDS_LOG_AUTHOR);\r
+ InsertColumn(this->LOGLIST_AUTHOR, temp);\r
+ \r
+ temp.LoadString(IDS_LOG_DATE);\r
+ InsertColumn(this->LOGLIST_DATE, temp);\r
+ \r
+\r
+ if (m_bShowBugtraqColumn)\r
+ {\r
+// temp = m_ProjectProperties.sLabel;\r
+ if (temp.IsEmpty())\r
+ temp.LoadString(IDS_LOG_BUGIDS);\r
+ InsertColumn(this->LOGLIST_BUG, temp);\r
+\r
+ }\r
+ \r
+ SetRedraw(false);\r
+ ResizeAllListCtrlCols();\r
+ SetRedraw(true);\r
+\r
+}\r
+\r
+void CGitLogList::ResizeAllListCtrlCols()\r
+{\r
+\r
+ const int nMinimumWidth = ICONITEMBORDER+16*4;\r
+ int maxcol = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;\r
+ int nItemCount = GetItemCount();\r
+ TCHAR textbuf[MAX_PATH];\r
+ CHeaderCtrl * pHdrCtrl = (CHeaderCtrl*)(GetDlgItem(0));\r
+ if (pHdrCtrl)\r
+ {\r
+ for (int col = 0; col <= maxcol; col++)\r
+ {\r
+ HDITEM hdi = {0};\r
+ hdi.mask = HDI_TEXT;\r
+ hdi.pszText = textbuf;\r
+ hdi.cchTextMax = sizeof(textbuf);\r
+ pHdrCtrl->GetItem(col, &hdi);\r
+ int cx = GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin\r
+ for (int index = 0; index<nItemCount; ++index)\r
+ {\r
+ // get the width of the string and add 14 pixels for the column separator and margins\r
+ int linewidth = GetStringWidth(GetItemText(index, col)) + 14;\r
+ if (index < m_arShownList.GetCount())\r
+ {\r
+ GitRev * pCurLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index));\r
+ if ((pCurLogEntry)&&(pCurLogEntry->m_CommitHash == m_wcRev.m_CommitHash))\r
+ {\r
+ // set the bold font and ask for the string width again\r
+ SendMessage(WM_SETFONT, (WPARAM)m_boldFont, NULL);\r
+ linewidth = GetStringWidth(GetItemText(index, col)) + 14;\r
+ // restore the system font\r
+ SendMessage(WM_SETFONT, NULL, NULL);\r
+ }\r
+ }\r
+ if (index == 0)\r
+ {\r
+ // add the image size\r
+ CImageList * pImgList = GetImageList(LVSIL_SMALL);\r
+ if ((pImgList)&&(pImgList->GetImageCount()))\r
+ {\r
+ IMAGEINFO imginfo;\r
+ pImgList->GetImageInfo(0, &imginfo);\r
+ linewidth += (imginfo.rcImage.right - imginfo.rcImage.left);\r
+ linewidth += 3; // 3 pixels between icon and text\r
+ }\r
+ }\r
+ if (cx < linewidth)\r
+ cx = linewidth;\r
+ }\r
+ // Adjust columns "Actions" containing icons\r
+ if (col == this->LOGLIST_ACTION)\r
+ {\r
+ if (cx < nMinimumWidth)\r
+ {\r
+ cx = nMinimumWidth;\r
+ }\r
+ }\r
+ \r
+ if (col == this->LOGLIST_MESSAGE)\r
+ {\r
+ if (cx > LOGLIST_MESSAGE_MAX)\r
+ {\r
+ cx = LOGLIST_MESSAGE_MAX;\r
+ }\r
+\r
+ }\r
+ // keep the bug id column small\r
+ if ((col == 4)&&(m_bShowBugtraqColumn))\r
+ {\r
+ if (cx > (int)(DWORD)m_regMaxBugIDColWidth)\r
+ {\r
+ cx = (int)(DWORD)m_regMaxBugIDColWidth;\r
+ }\r
+ }\r
+\r
+ SetColumnWidth(col, cx);\r
+ }\r
+ }\r
+\r
+}\r
+\r
+\r
+void CGitLogList::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
+{\r
+\r
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );\r
+ // Take the default processing unless we set this to something else below.\r
+ *pResult = CDRF_DODEFAULT;\r
+\r
+ if (m_bNoDispUpdates)\r
+ return;\r
+\r
+ switch (pLVCD->nmcd.dwDrawStage)\r
+ {\r
+ case CDDS_PREPAINT:\r
+ {\r
+ *pResult = CDRF_NOTIFYITEMDRAW;\r
+ return;\r
+ }\r
+ break;\r
+ case CDDS_ITEMPREPAINT:\r
+ {\r
+ // This is the prepaint stage for an item. Here's where we set the\r
+ // item's text color. \r
+ \r
+ // Tell Windows to send draw notifications for each subitem.\r
+ *pResult = CDRF_NOTIFYSUBITEMDRAW;\r
+\r
+ COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);\r
+\r
+ if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+ {\r
+ GitRev* data = (GitRev*)m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec);\r
+ if (data)\r
+ {\r
+#if 0\r
+ if (data->bCopiedSelf)\r
+ {\r
+ // only change the background color if the item is not 'hot' (on vista with m_Themes enabled)\r
+ if (!m_Theme.IsAppm_Themed() || !m_bVista || ((pLVCD->nmcd.uItemState & CDIS_HOT)==0))\r
+ pLVCD->clrTextBk = GetSysColor(COLOR_MENU);\r
+ }\r
+\r
+ if (data->bCopies)\r
+ crText = m_Colors.GetColor(CColors::Modified);\r
+#endif\r
+// if ((data->childStackDepth)||(m_mergedRevs.find(data->Rev) != m_mergedRevs.end()))\r
+// crText = GetSysColor(COLOR_GRAYTEXT);\r
+// if (data->Rev == m_wcRev)\r
+// {\r
+// SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
+ // We changed the font, so we're returning CDRF_NEWFONT. This\r
+ // tells the control to recalculate the extent of the text.\r
+// *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
+// }\r
+ }\r
+ }\r
+ if (m_arShownList.GetCount() == (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+ {\r
+ if (m_bStrictStopped)\r
+ crText = GetSysColor(COLOR_GRAYTEXT);\r
+ }\r
+ // Store the color back in the NMLVCUSTOMDRAW struct.\r
+ pLVCD->clrText = crText;\r
+ return;\r
+ }\r
+ break;\r
+ case CDDS_ITEMPREPAINT|CDDS_ITEM|CDDS_SUBITEM:\r
+ {\r
+ if ((m_bStrictStopped)&&(m_arShownList.GetCount() == (INT_PTR)pLVCD->nmcd.dwItemSpec))\r
+ {\r
+ pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED|CDIS_FOCUS);\r
+ }\r
+ if (pLVCD->iSubItem == 1)\r
+ {\r
+ *pResult = CDRF_DODEFAULT;\r
+\r
+ if (m_arShownList.GetCount() <= (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+ return;\r
+\r
+ int nIcons = 0;\r
+ int iconwidth = ::GetSystemMetrics(SM_CXSMICON);\r
+ int iconheight = ::GetSystemMetrics(SM_CYSMICON);\r
+\r
+ GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec));\r
+\r
+ // Get the selected state of the\r
+ // item being drawn.\r
+ LVITEM rItem;\r
+ SecureZeroMemory(&rItem, sizeof(LVITEM));\r
+ rItem.mask = LVIF_STATE;\r
+ rItem.iItem = pLVCD->nmcd.dwItemSpec;\r
+ rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
+ GetItem(&rItem);\r
+\r
+ CRect rect;\r
+ GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+\r
+ // Fill the background\r
+ if (m_Theme.IsAppThemed() && m_bVista)\r
+ {\r
+ m_Theme.Open(m_hWnd, L"Explorer");\r
+ int state = LISS_NORMAL;\r
+ if (rItem.state & LVIS_SELECTED)\r
+ {\r
+ if (::GetFocus() == m_hWnd)\r
+ state |= LISS_SELECTED;\r
+ else\r
+ state |= LISS_SELECTEDNOTFOCUS;\r
+ }\r
+ else\r
+ {\r
+#if 0\r
+ if (pLogEntry->bCopiedSelf)\r
+ {\r
+ // unfortunately, the pLVCD->nmcd.uItemState does not contain valid\r
+ // information at this drawing stage. But we can check the whether the\r
+ // previous stage changed the background color of the item\r
+ if (pLVCD->clrTextBk == GetSysColor(COLOR_MENU))\r
+ {\r
+ HBRUSH brush;\r
+ brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));\r
+ if (brush)\r
+ {\r
+ ::FillRect(pLVCD->nmcd.hdc, &rect, brush);\r
+ ::DeleteObject(brush);\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ }\r
+\r
+ if (m_Theme.IsBackgroundPartiallyTransparent(LVP_LISTDETAIL, state))\r
+ m_Theme.DrawParentBackground(m_hWnd, pLVCD->nmcd.hdc, &rect);\r
+\r
+ m_Theme.DrawBackground(pLVCD->nmcd.hdc, LVP_LISTDETAIL, state, &rect, NULL);\r
+ }\r
+ else\r
+ {\r
+ HBRUSH brush;\r
+ if (rItem.state & LVIS_SELECTED)\r
+ {\r
+ if (::GetFocus() == m_hWnd)\r
+ brush = ::CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));\r
+ else\r
+ brush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));\r
+ }\r
+ else\r
+ {\r
+ //if (pLogEntry->bCopiedSelf)\r
+ // brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));\r
+ //else\r
+ brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));\r
+ }\r
+ if (brush == NULL)\r
+ return;\r
+\r
+ ::FillRect(pLVCD->nmcd.hdc, &rect, brush);\r
+ ::DeleteObject(brush);\r
+ }\r
+\r
+ // Draw the icon(s) into the compatible DC\r
+ if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_MODIFIED)\r
+ ::DrawIconEx(pLVCD->nmcd.hdc, rect.left + ICONITEMBORDER, rect.top, m_hModifiedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
+ nIcons++;\r
+\r
+ if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_ADDED)\r
+ ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hAddedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
+ nIcons++;\r
+\r
+ if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_DELETED)\r
+ ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hDeletedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
+ nIcons++;\r
+\r
+ if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_REPLACED)\r
+ ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hReplacedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
+ nIcons++;\r
+ *pResult = CDRF_SKIPDEFAULT;\r
+ return;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ *pResult = CDRF_DODEFAULT;\r
+\r
+}\r
+\r
+// CGitLogList message handlers\r
+\r
+void CGitLogList::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
+{\r
+ NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);\r
+\r
+ // Create a pointer to the item\r
+ LV_ITEM* pItem = &(pDispInfo)->item;\r
+\r
+ // Do the list need text information?\r
+ if (!(pItem->mask & LVIF_TEXT))\r
+ return;\r
+\r
+ // By default, clear text buffer.\r
+ lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
+\r
+ bool bOutOfRange = pItem->iItem >= ShownCountWithStopped();\r
+ \r
+ *pResult = 0;\r
+ if (m_bNoDispUpdates || m_bThreadRunning || bOutOfRange)\r
+ return;\r
+\r
+ // Which item number?\r
+ int itemid = pItem->iItem;\r
+ GitRev * pLogEntry = NULL;\r
+ if (itemid < m_arShownList.GetCount())\r
+ pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(pItem->iItem));\r
+ \r
+ // Which column?\r
+ switch (pItem->iSubItem)\r
+ {\r
+ case this->LOGLIST_GRAPH: //Graphic\r
+ if (pLogEntry)\r
+ {\r
+ }\r
+ break;\r
+ case this->LOGLIST_ACTION: //action -- no text in the column\r
+ break;\r
+ case this->LOGLIST_MESSAGE: //Message\r
+ if (pLogEntry)\r
+ lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_Subject, pItem->cchTextMax);\r
+ break;\r
+ case this->LOGLIST_AUTHOR: //Author\r
+ if (pLogEntry)\r
+ lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_AuthorName, pItem->cchTextMax);\r
+ break;\r
+ case this->LOGLIST_DATE: //Date\r
+ if (pLogEntry)\r
+ lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_AuthorDate.Format(_T("%Y-%m-%d %H:%M")), pItem->cchTextMax);\r
+ break;\r
+ \r
+ case 5:\r
+\r
+ break;\r
+ default:\r
+ ASSERT(false);\r
+ }\r
+}\r
+\r
+void CGitLogList::OnContextMenu(CWnd* pWnd, CPoint point)\r
+{\r
+\r
+ int selIndex = GetSelectionMark();\r
+ if (selIndex < 0)\r
+ return; // nothing selected, nothing to do with a context menu\r
+\r
+ // if the user selected the info text telling about not all revisions shown due to\r
+ // the "stop on copy/rename" option, we also don't show the context menu\r
+ if ((m_bStrictStopped)&&(selIndex == m_arShownList.GetCount()))\r
+ return;\r
+\r
+ // if the context menu is invoked through the keyboard, we have to use\r
+ // a calculated position on where to anchor the menu on\r
+ if ((point.x == -1) && (point.y == -1))\r
+ {\r
+ CRect rect;\r
+ GetItemRect(selIndex, &rect, LVIR_LABEL);\r
+ ClientToScreen(&rect);\r
+ point = rect.CenterPoint();\r
+ }\r
+ m_nSearchIndex = selIndex;\r
+ m_bCancelled = FALSE;\r
+\r
+ // calculate some information the context menu commands can use\r
+// CString pathURL = GetURLFromPath(m_path);\r
+\r
+ POSITION pos = GetFirstSelectedItemPosition();\r
+ int indexNext = GetNextSelectedItem(pos);\r
+ if (indexNext < 0)\r
+ return;\r
+\r
+ GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));\r
+#if 0\r
+ GitRev revSelected = pSelLogEntry->Rev;\r
+ GitRev revPrevious = git_revnum_t(revSelected)-1;\r
+ if ((pSelLogEntry->pArChangedPaths)&&(pSelLogEntry->pArChangedPaths->GetCount() <= 2))\r
+ {\r
+ for (int i=0; i<pSelLogEntry->pArChangedPaths->GetCount(); ++i)\r
+ {\r
+ LogChangedPath * changedpath = (LogChangedPath *)pSelLogEntry->pArChangedPaths->GetAt(i);\r
+ if (changedpath->lCopyFromRev)\r
+ revPrevious = changedpath->lCopyFromRev;\r
+ }\r
+ }\r
+ GitRev revSelected2;\r
+ if (pos)\r
+ {\r
+ PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));\r
+ revSelected2 = pLogEntry->Rev;\r
+ }\r
+ bool bAllFromTheSameAuthor = true;\r
+ CString firstAuthor;\r
+ CLogDataVector selEntries;\r
+ GitRev revLowest, revHighest;\r
+ GitRevRangeArray revisionRanges;\r
+ {\r
+ POSITION pos = GetFirstSelectedItemPosition();\r
+ PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));\r
+ revisionRanges.AddRevision(pLogEntry->Rev);\r
+ selEntries.push_back(pLogEntry);\r
+ firstAuthor = pLogEntry->sAuthor;\r
+ revLowest = pLogEntry->Rev;\r
+ revHighest = pLogEntry->Rev;\r
+ while (pos)\r
+ {\r
+ pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));\r
+ revisionRanges.AddRevision(pLogEntry->Rev);\r
+ selEntries.push_back(pLogEntry);\r
+ if (firstAuthor.Compare(pLogEntry->sAuthor))\r
+ bAllFromTheSameAuthor = false;\r
+ revLowest = (git_revnum_t(pLogEntry->Rev) > git_revnum_t(revLowest) ? revLowest : pLogEntry->Rev);\r
+ revHighest = (git_revnum_t(pLogEntry->Rev) < git_revnum_t(revHighest) ? revHighest : pLogEntry->Rev);\r
+ }\r
+ }\r
+\r
+#endif\r
+\r
+ int FirstSelect=-1, LastSelect=-1;\r
+ pos = GetFirstSelectedItemPosition();\r
+ FirstSelect = GetNextSelectedItem(pos);\r
+ while(pos)\r
+ {\r
+ LastSelect = GetNextSelectedItem(pos);\r
+ }\r
+ //entry is selected, now show the popup menu\r
+ CIconMenu popup;\r
+ if (popup.CreatePopupMenu())\r
+ {\r
+ if (GetSelectedCount() == 1)\r
+ {\r
+#if 0\r
+ if (!m_path.IsDirectory())\r
+ {\r
+ if (m_hasWC)\r
+ {\r
+ popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
+ popup.AppendMenuIcon(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
+ }\r
+ popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+ popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
+ popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
+ popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
+ popup.AppendMenuIcon(ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ }\r
+ else\r
+#endif \r
+ {\r
+ if (m_hasWC)\r
+ {\r
+ popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
+ // TODO:\r
+ // TortoiseMerge could be improved to take a /blame switch\r
+ // and then not 'cat' the files from a unified diff but\r
+ // blame then.\r
+ // But until that's implemented, the context menu entry for\r
+ // this feature is commented out.\r
+ //popup.AppendMenu(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
+ }\r
+ popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+ popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
+ popup.AppendMenuIcon(ID_BLAMEWITHPREVIOUS, IDS_LOG_POPUP_BLAMEWITHPREVIOUS, IDI_BLAME);\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ }\r
+\r
+// if (!m_ProjectProperties.sWebViewerRev.IsEmpty())\r
+// {\r
+// popup.AppendMenuIcon(ID_VIEWREV, IDS_LOG_POPUP_VIEWREV);\r
+// }\r
+// if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty())\r
+// {\r
+// popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
+// }\r
+// if ((!m_ProjectProperties.sWebViewerPathRev.IsEmpty())||\r
+// (!m_ProjectProperties.sWebViewerRev.IsEmpty()))\r
+// {\r
+// popup.AppendMenu(MF_SEPARATOR, NULL);\r
+// }\r
+\r
+// popup.AppendMenuIcon(ID_REPOBROWSE, IDS_LOG_BROWSEREPO, IDI_REPOBROWSE);\r
+// popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPY);\r
+// if (m_hasWC)\r
+// popup.AppendMenuIcon(ID_UPDATE, IDS_LOG_POPUP_UPDATE, IDI_UPDATE);\r
+ if (m_hasWC)\r
+ popup.AppendMenuIcon(ID_REVERTTOREV, IDS_LOG_POPUP_REVERTTOREV, IDI_REVERT);\r
+ if (m_hasWC)\r
+ popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
+// if (m_hasWC)\r
+// popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE);\r
+ popup.AppendMenuIcon(ID_CHECKOUT, IDS_MENUCHECKOUT, IDI_CHECKOUT);\r
+ popup.AppendMenuIcon(ID_EXPORT, IDS_MENUEXPORT, IDI_EXPORT);\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ }\r
+ else if (GetSelectedCount() >= 2)\r
+ {\r
+ bool bAddSeparator = false;\r
+ if (IsSelectionContinuous() || (GetSelectedCount() == 2))\r
+ {\r
+ popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);\r
+ }\r
+ if (GetSelectedCount() == 2)\r
+ {\r
+ popup.AppendMenuIcon(ID_BLAMETWO, IDS_LOG_POPUP_BLAMEREVS, IDI_BLAME);\r
+ popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);\r
+ bAddSeparator = true;\r
+ }\r
+ if (m_hasWC)\r
+ {\r
+ popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREVS, IDI_REVERT);\r
+// if (m_hasWC)\r
+// popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREVS, IDI_MERGE);\r
+ bAddSeparator = true;\r
+ }\r
+ if (bAddSeparator)\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ }\r
+#if 0\r
+// if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor))\r
+// {\r
+// popup.AppendMenuIcon(ID_EDITAUTHOR, IDS_LOG_POPUP_EDITAUTHOR);\r
+// }\r
+// if (GetSelectedCount() == 1)\r
+// {\r
+// popup.AppendMenuIcon(ID_EDITLOG, IDS_LOG_POPUP_EDITLOG);\r
+// popup.AppendMenuIcon(ID_REVPROPS, IDS_REPOBROWSE_SHOWREVPROP, IDI_PROPERTIES); // "Show Revision Properties"\r
+// popup.AppendMenu(MF_SEPARATOR, NULL);\r
+// }\r
+#endif\r
+ if (GetSelectedCount() != 0)\r
+ {\r
+ popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
+ }\r
+ popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
+\r
+ int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
+// DialogEnableWindow(IDOK, FALSE);\r
+// SetPromptApp(&theApp);\r
+ theApp.DoWaitCursor(1);\r
+ bool bOpenWith = false;\r
+\r
+ switch (cmd)\r
+ {\r
+ case ID_GNUDIFF1:\r
+ {\r
+ CString tempfile=GetTempFile();\r
+ CString cmd;\r
+ GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
+ cmd.Format(_T("git.cmd diff-tree -r -p --stat %s"),r1->m_CommitHash);\r
+ g_Git.RunLogFile(cmd,tempfile);\r
+ CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r1->m_Subject);\r
+ }\r
+ break;\r
+\r
+ case ID_GNUDIFF2:\r
+ {\r
+ CString tempfile=GetTempFile();\r
+ CString cmd;\r
+ GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
+ GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
+ cmd.Format(_T("git.cmd diff-tree -r -p --stat %s %s"),r1->m_CommitHash,r2->m_CommitHash);\r
+ g_Git.RunLogFile(cmd,tempfile);\r
+ CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r2->m_CommitHash.Left(6));\r
+\r
+ }\r
+ break;\r
+\r
+ case ID_COMPARETWO:\r
+ {\r
+ GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
+ GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
+ CFileDiffDlg dlg;\r
+ dlg.SetDiff(NULL,*r1,*r2);\r
+ dlg.DoModal();\r
+ \r
+ }\r
+ break;\r
+\r
+#if 0\r
+ case ID_GNUDIFF1:\r
+ {\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowUnifiedDiff(m_path, revPrevious, m_path, revSelected);\r
+ }\r
+ else\r
+ CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revPrevious, m_path, revSelected, GitRev(), m_LogRevision);\r
+ }\r
+ break;\r
+\r
+ case ID_GNUDIFF2:\r
+ {\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowUnifiedDiff(m_path, revSelected2, m_path, revSelected);\r
+ }\r
+ else\r
+ CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revSelected2, m_path, revSelected, GitRev(), m_LogRevision);\r
+ }\r
+ break;\r
+ case ID_REVERTREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+ CString msg;\r
+ msg.Format(IDS_LOG_REVERT_CONFIRM, m_path.GetWinPath());\r
+ if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(m_path));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ revisionRanges.AdjustForMerge(true);\r
+ dlg.SetRevisionRanges(revisionRanges);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ case ID_MERGEREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+\r
+ CString path = m_path.GetWinPathString();\r
+ bool bGotSavePath = false;\r
+ if ((GetSelectedCount() == 1)&&(!m_path.IsDirectory()))\r
+ {\r
+ bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());\r
+ }\r
+ else\r
+ {\r
+ CBrowseFolder folderBrowser;\r
+ folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));\r
+ bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);\r
+ }\r
+ if (bGotSavePath)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(CTGitPath(path)));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ revisionRanges.AdjustForMerge(false);\r
+ dlg.SetRevisionRanges(revisionRanges);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ case ID_REVERTTOREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+\r
+ CString msg;\r
+ msg.Format(IDS_LOG_REVERTTOREV_CONFIRM, m_path.GetWinPath());\r
+ if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(m_path));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ GitRevRangeArray revarray;\r
+ revarray.AddRevRange(GitRev::REV_HEAD, revSelected);\r
+ dlg.SetRevisionRanges(revarray);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ case ID_COPY:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+\r
+ CCopyDlg dlg;\r
+ dlg.m_URL = pathURL;\r
+ dlg.m_path = m_path;\r
+ dlg.m_CopyRev = revSelected;\r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ // should we show a progress dialog here? Copies are done really fast\r
+ // and without much network traffic.\r
+ if (!Copy(CTGitPathList(CTGitPath(pathURL)), CTGitPath(dlg.m_URL), dlg.m_CopyRev, dlg.m_CopyRev, dlg.m_sLogMessage))\r
+ CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ else\r
+ CMessageBox::Show(this->m_hWnd, IDS_LOG_COPY_SUCCESS, IDS_APPNAME, MB_ICONINFORMATION);\r
+ }\r
+ } \r
+ break;\r
+ case ID_COMPARE:\r
+ {\r
+ //user clicked on the menu item "compare with working copy"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, m_hWnd, true);\r
+ diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ }\r
+ break;\r
+ case ID_COMPARETWO:\r
+ {\r
+ GitRev r1 = revSelected;\r
+ GitRev r2 = revSelected2;\r
+ if (GetSelectedCount() > 2)\r
+ {\r
+ r1 = revHighest;\r
+ r2 = revLowest;\r
+ }\r
+ //user clicked on the menu item "compare revisions"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, m_hWnd, true);\r
+ diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), r2, CTGitPath(pathURL), r1);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), r2, CTGitPath(pathURL), r1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ }\r
+ break;\r
+ case ID_COMPAREWITHPREVIOUS:\r
+ {\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, m_hWnd, true);\r
+ diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ }\r
+ break;\r
+ case ID_BLAMECOMPARE:\r
+ {\r
+ //user clicked on the menu item "compare with working copy"\r
+ //now first get the revision which is selected\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ case ID_BLAMETWO:\r
+ {\r
+ //user clicked on the menu item "compare and blame revisions"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ case ID_BLAMEWITHPREVIOUS:\r
+ {\r
+ //user clicked on the menu item "Compare and Blame with previous revision"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ case ID_SAVEAS:\r
+ {\r
+ //now first get the revision which is selected\r
+ CString revFilename;\r
+ if (m_hasWC)\r
+ {\r
+ CString strWinPath = m_path.GetWinPathString();\r
+ int rfind = strWinPath.ReverseFind('.');\r
+ if (rfind > 0)\r
+ revFilename.Format(_T("%s-%ld%s"), (LPCTSTR)strWinPath.Left(rfind), (LONG)revSelected, (LPCTSTR)strWinPath.Mid(rfind));\r
+ else\r
+ revFilename.Format(_T("%s-%ld"), (LPCTSTR)strWinPath, revSelected);\r
+ }\r
+ if (CAppUtils::FileOpenSave(revFilename, NULL, IDS_LOG_POPUP_SAVE, IDS_COMMONFILEFILTER, false, m_hWnd))\r
+ {\r
+ CTGitPath tempfile;\r
+ tempfile.SetFromWin(revFilename);\r
+ CProgressDlg progDlg;\r
+ progDlg.SetTitle(IDS_APPNAME);\r
+ progDlg.SetAnimation(IDR_DOWNLOAD);\r
+ CString sInfoLine;\r
+ sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
+ progDlg.SetLine(1, sInfoLine, true);\r
+ SetAndClearProgressInfo(&progDlg);\r
+ progDlg.ShowModeless(m_hWnd);\r
+ if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\r
+ {\r
+ // try again with another peg revision\r
+ if (!Cat(m_path, revSelected, revSelected, tempfile))\r
+ {\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ EnableOKButton();\r
+ break;\r
+ }\r
+ }\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ }\r
+ }\r
+ break;\r
+ case ID_OPENWITH:\r
+ bOpenWith = true;\r
+ case ID_OPEN:\r
+ {\r
+ CProgressDlg progDlg;\r
+ progDlg.SetTitle(IDS_APPNAME);\r
+ progDlg.SetAnimation(IDR_DOWNLOAD);\r
+ CString sInfoLine;\r
+ sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
+ progDlg.SetLine(1, sInfoLine, true);\r
+ SetAndClearProgressInfo(&progDlg);\r
+ progDlg.ShowModeless(m_hWnd);\r
+ CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path, revSelected);\r
+ bool bSuccess = true;\r
+ if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\r
+ {\r
+ bSuccess = false;\r
+ // try again, but with the selected revision as the peg revision\r
+ if (!Cat(m_path, revSelected, revSelected, tempfile))\r
+ {\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ EnableOKButton();\r
+ break;\r
+ }\r
+ bSuccess = true;\r
+ }\r
+ if (bSuccess)\r
+ {\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
+ int ret = 0;\r
+ if (!bOpenWith)\r
+ ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);\r
+ if ((ret <= HINSTANCE_ERROR)||bOpenWith)\r
+ {\r
+ CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
+ cmd += tempfile.GetWinPathString() + _T(" ");\r
+ CAppUtils::LaunchApplication(cmd, NULL, false);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case ID_BLAME:\r
+ {\r
+ CBlameDlg dlg;\r
+ dlg.EndRev = revSelected;\r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ CBlame blame;\r
+ CString tempfile;\r
+ CString logfile;\r
+ tempfile = blame.BlameToTempFile(m_path, dlg.StartRev, dlg.EndRev, dlg.EndRev, logfile, _T(""), dlg.m_bIncludeMerge, TRUE, TRUE);\r
+ if (!tempfile.IsEmpty())\r
+ {\r
+ if (dlg.m_bTextView)\r
+ {\r
+ //open the default text editor for the result file\r
+ CAppUtils::StartTextViewer(tempfile);\r
+ }\r
+ else\r
+ {\r
+ CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");\r
+ if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case ID_UPDATE:\r
+ {\r
+ CString sCmd;\r
+ CString url = _T("tgit:")+pathURL;\r
+ sCmd.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)m_path.GetWinPath(), (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_FINDENTRY:\r
+ {\r
+ m_nSearchIndex = GetSelectionMark();\r
+ if (m_nSearchIndex < 0)\r
+ m_nSearchIndex = 0;\r
+ if (m_pFindDialog)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ m_pFindDialog = new CFindReplaceDialog();\r
+ m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this); \r
+ }\r
+ }\r
+ break;\r
+ case ID_REPOBROWSE:\r
+ {\r
+ CString sCmd;\r
+ sCmd.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)pathURL, (LPCTSTR)revSelected.ToString());\r
+\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_EDITLOG:\r
+ {\r
+ EditLogMessage(selIndex);\r
+ }\r
+ break;\r
+ case ID_EDITAUTHOR:\r
+ {\r
+ EditAuthor(selEntries);\r
+ }\r
+ break;\r
+ case ID_REVPROPS:\r
+ {\r
+ CEditPropertiesDlg dlg;\r
+ dlg.SetProjectProperties(&m_ProjectProperties);\r
+ CTGitPathList escapedlist;\r
+ dlg.SetPathList(CTGitPathList(CTGitPath(pathURL)));\r
+ dlg.SetRevision(revSelected);\r
+ dlg.RevProps(true);\r
+ dlg.DoModal();\r
+ }\r
+ break;\r
+ case ID_COPYCLIPBOARD:\r
+ {\r
+ CopySelectionToClipBoard();\r
+ }\r
+ break;\r
+ case ID_EXPORT:\r
+ {\r
+ CString sCmd;\r
+ sCmd.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)pathURL, (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_CHECKOUT:\r
+ {\r
+ CString sCmd;\r
+ CString url = _T("tgit:")+pathURL;\r
+ sCmd.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)url, (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_VIEWREV:\r
+ {\r
+ CString url = m_ProjectProperties.sWebViewerRev;\r
+ url = GetAbsoluteUrlFromRelativeUrl(url);\r
+ url.Replace(_T("%REVISION%"), revSelected.ToString());\r
+ if (!url.IsEmpty())\r
+ ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT); \r
+ }\r
+ break;\r
+ case ID_VIEWPATHREV:\r
+ {\r
+ CString relurl = pathURL;\r
+ CString sRoot = GetRepositoryRoot(CTGitPath(relurl));\r
+ relurl = relurl.Mid(sRoot.GetLength());\r
+ CString url = m_ProjectProperties.sWebViewerPathRev;\r
+ url = GetAbsoluteUrlFromRelativeUrl(url);\r
+ url.Replace(_T("%REVISION%"), revSelected.ToString());\r
+ url.Replace(_T("%PATH%"), relurl);\r
+ if (!url.IsEmpty())\r
+ ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT); \r
+ }\r
+ break;\r
+#endif\r
+ default:\r
+ break;\r
+ } // switch (cmd)\r
+ theApp.DoWaitCursor(-1);\r
+// EnableOKButton();\r
+ } // if (popup.CreatePopupMenu())\r
+\r
+}\r
+\r
+bool CGitLogList::IsSelectionContinuous()\r
+{\r
+ if ( GetSelectedCount()==1 )\r
+ {\r
+ // if only one revision is selected, the selection is of course\r
+ // continuous\r
+ return true;\r
+ }\r
+\r
+ POSITION pos = GetFirstSelectedItemPosition();\r
+ bool bContinuous = (m_arShownList.GetCount() == (INT_PTR)m_logEntries.size());\r
+ if (bContinuous)\r
+ {\r
+ int itemindex = GetNextSelectedItem(pos);\r
+ while (pos)\r
+ {\r
+ int nextindex = GetNextSelectedItem(pos);\r
+ if (nextindex - itemindex > 1)\r
+ {\r
+ bContinuous = false;\r
+ break;\r
+ }\r
+ itemindex = nextindex;\r
+ }\r
+ }\r
+ return bContinuous;\r
+}\r
+\r
+void CGitLogList::CopySelectionToClipBoard()\r
+{\r
+#if 0\r
+ CString sClipdata;\r
+ POSITION pos = GetFirstSelectedItemPosition();\r
+ if (pos != NULL)\r
+ {\r
+ CString sRev;\r
+ sRev.LoadString(IDS_LOG_REVISION);\r
+ CString sAuthor;\r
+ sAuthor.LoadString(IDS_LOG_AUTHOR);\r
+ CString sDate;\r
+ sDate.LoadString(IDS_LOG_DATE);\r
+ CString sMessage;\r
+ sMessage.LoadString(IDS_LOG_MESSAGE);\r
+ while (pos)\r
+ {\r
+ CString sLogCopyText;\r
+ CString sPaths;\r
+ PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));\r
+ LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;\r
+ for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount(); ++cpPathIndex)\r
+ {\r
+ LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
+ sPaths += cpath->GetAction() + _T(" : ") + cpath->sPath;\r
+ if (cpath->sCopyFromPath.IsEmpty())\r
+ sPaths += _T("\r\n");\r
+ else\r
+ {\r
+ CString sCopyFrom;\r
+ sCopyFrom.Format(_T(" (%s: %s, %s, %ld)\r\n"), CString(MAKEINTRESOURCE(IDS_LOG_COPYFROM)), \r
+ (LPCTSTR)cpath->sCopyFromPath, \r
+ (LPCTSTR)CString(MAKEINTRESOURCE(IDS_LOG_REVISION)), \r
+ (LPCTSTR)cpath->lCopyFromRev);\r
+ sPaths += sCopyFrom;\r
+ }\r
+ }\r
+ sPaths.Trim();\r
+ sLogCopyText.Format(_T("%s: %d\r\n%s: %s\r\n%s: %s\r\n%s:\r\n%s\r\n----\r\n%s\r\n\r\n"),\r
+ (LPCTSTR)sRev, pLogEntry->Rev,\r
+ (LPCTSTR)sAuthor, (LPCTSTR)pLogEntry->sAuthor,\r
+ (LPCTSTR)sDate, (LPCTSTR)pLogEntry->sDate,\r
+ (LPCTSTR)sMessage, (LPCTSTR)pLogEntry->sMessage,\r
+ (LPCTSTR)sPaths);\r
+ sClipdata += sLogCopyText;\r
+ }\r
+ CStringUtils::WriteAsciiStringToClipboard(sClipdata, GetSafeHwnd());\r
+ }\r
+#endif\r
+}\r
+\r
+void CGitLogList::DiffSelectedRevWithPrevious()\r
+{\r
+#if 0\r
+ if (m_bThreadRunning)\r
+ return;\r
+ UpdateLogInfoLabel();\r
+ int selIndex = m_LogList.GetSelectionMark();\r
+ if (selIndex < 0)\r
+ return;\r
+ int selCount = m_LogList.GetSelectedCount();\r
+ if (selCount != 1)\r
+ return;\r
+\r
+ // Find selected entry in the log list\r
+ POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
+ PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
+ long rev1 = pLogEntry->Rev;\r
+ long rev2 = rev1-1;\r
+ CTGitPath path = m_path;\r
+\r
+ // See how many files under the relative root were changed in selected revision\r
+ int nChanged = 0;\r
+ LogChangedPath * changed = NULL;\r
+ for (INT_PTR c = 0; c < pLogEntry->pArChangedPaths->GetCount(); ++c)\r
+ {\r
+ LogChangedPath * cpath = pLogEntry->pArChangedPaths->GetAt(c);\r
+ if (cpath && cpath -> sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0)\r
+ {\r
+ ++nChanged;\r
+ changed = cpath;\r
+ }\r
+ }\r
+\r
+ if (m_path.IsDirectory() && nChanged == 1) \r
+ {\r
+ // We're looking at the log for a directory and only one file under dir was changed in the revision\r
+ // Do diff on that file instead of whole directory\r
+ path.AppendPathString(changed->sPath.Mid(m_sRelativeRoot.GetLength()));\r
+ } \r
+\r
+ m_bCancelled = FALSE;\r
+ DialogEnableWindow(IDOK, FALSE);\r
+ SetPromptApp(&theApp);\r
+ theApp.DoWaitCursor(1);\r
+\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, m_hWnd, true);\r
+ diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(path, rev2, path, rev1);\r
+ }\r
+ else\r
+ {\r
+ CAppUtils::StartShowCompare(m_hWnd, path, rev2, path, rev1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ }\r
+\r
+ theApp.DoWaitCursor(-1);\r
+ EnableOKButton();\r
+#endif\r
+}\r
+\r
+void CGitLogList::OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
+{\r
+ LPNMLVFINDITEM pFindInfo = reinterpret_cast<LPNMLVFINDITEM>(pNMHDR);\r
+ *pResult = -1;\r
+ \r
+ if (pFindInfo->lvfi.flags & LVFI_PARAM)\r
+ return; \r
+ if ((pFindInfo->iStart < 0)||(pFindInfo->iStart >= m_arShownList.GetCount()))\r
+ return;\r
+ if (pFindInfo->lvfi.psz == 0)\r
+ return;\r
+#if 0\r
+ CString sCmp = pFindInfo->lvfi.psz;\r
+ CString sRev; \r
+ for (int i=pFindInfo->iStart; i<m_arShownList.GetCount(); ++i)\r
+ {\r
+ GitRev * pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(i));\r
+ sRev.Format(_T("%ld"), pLogEntry->Rev);\r
+ if (pFindInfo->lvfi.flags & LVFI_PARTIAL)\r
+ {\r
+ if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)\r
+ {\r
+ *pResult = i;\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (sCmp.Compare(sRev)==0)\r
+ {\r
+ *pResult = i;\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ if (pFindInfo->lvfi.flags & LVFI_WRAP)\r
+ {\r
+ for (int i=0; i<pFindInfo->iStart; ++i)\r
+ {\r
+ PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(i));\r
+ sRev.Format(_T("%ld"), pLogEntry->Rev);\r
+ if (pFindInfo->lvfi.flags & LVFI_PARTIAL)\r
+ {\r
+ if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)\r
+ {\r
+ *pResult = i;\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (sCmp.Compare(sRev)==0)\r
+ {\r
+ *pResult = i;\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ *pResult = -1;\r
+}\r
+\r
+int CGitLogList::FillGitLog()\r
+{\r
+ ClearText();\r
+\r
+ this->m_logEntries.ClearAll();\r
+ this->m_logEntries.ParserFromLog();\r
+ SetItemCountEx(this->m_logEntries.size());\r
+\r
+ this->m_arShownList.RemoveAll();\r
+\r
+ for(int i=0;i<m_logEntries.size();i++)\r
+ this->m_arShownList.Add(&m_logEntries[i]);\r
+\r
+ return 0;\r
+}\r
+\r
+BOOL CGitLogList::PreTranslateMessage(MSG* pMsg)\r
+{\r
+ // Skip Ctrl-C when copying text out of the log message or search filter\r
+ BOOL bSkipAccelerator = ( pMsg->message == WM_KEYDOWN && pMsg->wParam=='C' && (GetFocus()==GetDlgItem(IDC_MSGVIEW) || GetFocus()==GetDlgItem(IDC_SEARCHEDIT) ) && GetKeyState(VK_CONTROL)&0x8000 );\r
+ if (pMsg->message == WM_KEYDOWN && pMsg->wParam=='\r')\r
+ {\r
+ //if (GetFocus()==GetDlgItem(IDC_LOGLIST))\r
+ {\r
+ if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
+ {\r
+ DiffSelectedRevWithPrevious();\r
+ return TRUE;\r
+ }\r
+ }\r
+#if 0\r
+ if (GetFocus()==GetDlgItem(IDC_LOGMSG))\r
+ {\r
+ DiffSelectedFile();\r
+ return TRUE;\r
+ }\r
+#endif\r
+ }\r
+\r
+#if 0\r
+ if (m_hAccel && !bSkipAccelerator)\r
+ {\r
+ int ret = TranslateAccelerator(m_hWnd, m_hAccel, pMsg);\r
+ if (ret)\r
+ return TRUE;\r
+ }\r
+ \r
+#endif\r
+ //m_tooltips.RelayEvent(pMsg);\r
+ return __super::PreTranslateMessage(pMsg);\r
+}\r
+\r
+void CGitLogList::OnNMDblclkLoglist(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
+{\r
+ // a double click on an entry in the revision list has happened\r
+ *pResult = 0;\r
+\r
+ if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
+ DiffSelectedRevWithPrevious();\r
+}
\ No newline at end of file
, m_bShowedAll(false)\r
, m_bSelect(false)\r
, m_regLastStrict(_T("Software\\TortoiseGit\\LastLogStrict"), FALSE)\r
- , m_regMaxBugIDColWidth(_T("Software\\TortoiseGit\\MaxBugIDColWidth"), 200)\r
+ \r
, m_bSelectionMustBeContinuous(false)\r
, m_bShowBugtraqColumn(false)\r
, m_lowestRev(_T(""))\r
, m_bVista(false)\r
{\r
m_bFilterWithRegex = !!CRegDWORD(_T("Software\\TortoiseGit\\UseRegexFilter"), TRUE);\r
- // use the default GUI font, create a copy of it and\r
- // change the copy to BOLD (leave the rest of the font\r
- // the same)\r
- HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);\r
- LOGFONT lf = {0};\r
- GetObject(hFont, sizeof(LOGFONT), &lf);\r
- lf.lfWeight = FW_BOLD;\r
- m_boldFont = CreateFontIndirect(&lf);\r
+ \r
}\r
\r
CLogDlg::~CLogDlg()\r
{\r
InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
m_CurrentFilteredChangedArray.RemoveAll();\r
- m_logEntries.ClearAll();\r
+ \r
\r
if ( m_pStoreSelection )\r
{\r
delete m_pStoreSelection;\r
m_pStoreSelection = NULL;\r
}\r
- if (m_boldFont)\r
- DeleteObject(m_boldFont);\r
+ \r
}\r
\r
void CLogDlg::DoDataExchange(CDataExchange* pDX)\r
\r
// set up the columns\r
m_LogList.DeleteAllItems();\r
-#if 0\r
- int c = ((CHeaderCtrl*)(m_LogList.GetDlgItem(0)))->GetItemCount()-1;\r
- \r
- while (c>=0)\r
- m_LogList.DeleteColumn(c--);\r
- temp.LoadString(IDS_LOG_GRAPH);\r
-\r
- m_LogList.InsertColumn(this->LOGLIST_GRAPH, temp);\r
- \r
-#if 0 \r
- // make the revision column right aligned\r
- LVCOLUMN Column;\r
- Column.mask = LVCF_FMT;\r
- Column.fmt = LVCFMT_RIGHT;\r
- m_LogList.SetColumn(0, &Column); \r
-#endif \r
-// CString log;\r
-// g_Git.GetLog(log);\r
-\r
- temp.LoadString(IDS_LOG_ACTIONS);\r
- m_LogList.InsertColumn(this->LOGLIST_ACTION, temp);\r
- \r
- temp.LoadString(IDS_LOG_MESSAGE);\r
- m_LogList.InsertColumn(this->LOGLIST_MESSAGE, temp);\r
- \r
- temp.LoadString(IDS_LOG_AUTHOR);\r
- m_LogList.InsertColumn(this->LOGLIST_AUTHOR, temp);\r
- \r
- temp.LoadString(IDS_LOG_DATE);\r
- m_LogList.InsertColumn(this->LOGLIST_DATE, temp);\r
- \r
-\r
- if (m_bShowBugtraqColumn)\r
- {\r
- temp = m_ProjectProperties.sLabel;\r
- if (temp.IsEmpty())\r
- temp.LoadString(IDS_LOG_BUGIDS);\r
- m_LogList.InsertColumn(this->LOGLIST_BUG, temp);\r
\r
- }\r
- \r
- m_LogList.SetRedraw(false);\r
- ResizeAllListCtrlCols();\r
- m_LogList.SetRedraw(true);\r
-#endif\r
m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
m_ChangedFileListCtrl.DeleteAllItems();\r
- c = ((CHeaderCtrl*)(m_ChangedFileListCtrl.GetDlgItem(0)))->GetItemCount()-1;\r
+ int c = ((CHeaderCtrl*)(m_ChangedFileListCtrl.GetDlgItem(0)))->GetItemCount()-1;\r
while (c>=0)\r
m_ChangedFileListCtrl.DeleteColumn(c--);\r
temp.LoadString(IDS_PROGRS_ACTION);\r
{\r
// the dialog is used to select revisions\r
if (m_bSelectionMustBeContinuous)\r
- DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(IsSelectionContinuous()));\r
+ DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
else\r
DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
}\r
{\r
// the dialog is used to select revisions\r
if (m_bSelectionMustBeContinuous)\r
- DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(IsSelectionContinuous()));\r
+ DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
else\r
DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
}\r
m_DateTo.SetTime(&m_timTo);\r
#endif\r
DialogEnableWindow(IDC_GETALL, TRUE);\r
- m_LogList.ClearText();\r
-\r
- this->m_logEntries.ClearAll();\r
- this->m_logEntries.ParserFromLog();\r
- m_LogList.SetItemCountEx(this->m_logEntries.size());\r
-\r
- this->m_arShownList.RemoveAll();\r
-\r
- for(int i=0;i<m_logEntries.size();i++)\r
- this->m_arShownList.Add(&m_logEntries[i]);\r
+ m_LogList.FillGitLog();\r
\r
#if 0 \r
if (!m_bShowedAll)\r
InterlockedExchange(&m_bThreadRunning, FALSE);\r
m_LogList.RedrawItems(0, m_arShownList.GetCount());\r
m_LogList.SetRedraw(false);\r
- ResizeAllListCtrlCols();\r
+ m_LogList.ResizeAllListCtrlCols();\r
m_LogList.SetRedraw(true);\r
if ( m_pStoreSelection )\r
{\r
int selCount = m_LogList.GetSelectedCount();\r
if (pWnd == &m_LogList)\r
{\r
- ShowContextMenuForRevisions(pWnd, point);\r
+ //ShowContextMenuForRevisions(pWnd, point);\r
}\r
else if (pWnd == &m_ChangedFileListCtrl)\r
{\r
{\r
popup.AppendMenu(MF_SEPARATOR);\r
sMenuItemText.LoadString(IDS_LOG_POPUP_EDITLOG);\r
- popup.AppendMenu(MF_STRING | MF_ENABLED, ID_EDITAUTHOR, sMenuItemText);\r
+ popup.AppendMenu(MF_STRING | MF_ENABLED, CGitLogList::ID_EDITAUTHOR, sMenuItemText);\r
}\r
\r
int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
case WM_COPY:\r
::SendMessage(GetDlgItem(IDC_MSGVIEW)->GetSafeHwnd(), cmd, 0, -1);\r
break;\r
- case ID_EDITAUTHOR:\r
+ case CGitLogList::ID_EDITAUTHOR:\r
EditLogMessage(selIndex);\r
break;\r
}\r
EnableOKButton();\r
#endif\r
}\r
-\r
+#if 0\r
BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)\r
{\r
// Skip Ctrl-C when copying text out of the log message or search filter\r
m_tooltips.RelayEvent(pMsg);\r
return __super::PreTranslateMessage(pMsg);\r
}\r
+#endif\r
\r
BOOL CLogDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
{\r
\r
\r
m_LogList.DeleteAllItems();\r
- m_LogList.SetItemCountEx(ShownCountWithStopped());\r
- m_LogList.RedrawItems(0, ShownCountWithStopped());\r
+ m_LogList.SetItemCountEx(m_LogList.ShownCountWithStopped());\r
+ m_LogList.RedrawItems(0, m_LogList.ShownCountWithStopped());\r
m_LogList.SetRedraw(false);\r
- ResizeAllListCtrlCols();\r
+ m_LogList.ResizeAllListCtrlCols();\r
m_LogList.SetRedraw(true);\r
m_LogList.Invalidate();\r
if ( m_LogList.GetItemCount()==1 )\r
{\r
// if ((!bOneRev)||(IsDiffPossible(changedlogpaths[0], rev1)))\r
{\r
- popup.AppendMenuIcon(ID_DIFF, IDS_LOG_POPUP_DIFF, IDI_DIFF);\r
- popup.AppendMenuIcon(ID_BLAMEDIFF, IDS_LOG_POPUP_BLAMEDIFF, IDI_BLAME);\r
- popup.SetDefaultItem(ID_DIFF, FALSE);\r
- popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+ popup.AppendMenuIcon(CGitLogList::ID_DIFF, IDS_LOG_POPUP_DIFF, IDI_DIFF);\r
+ popup.AppendMenuIcon(CGitLogList::ID_BLAMEDIFF, IDS_LOG_POPUP_BLAMEDIFF, IDI_BLAME);\r
+ popup.SetDefaultItem(CGitLogList::ID_DIFF, FALSE);\r
+ popup.AppendMenuIcon(CGitLogList::ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
bEntryAdded = true;\r
}\r
// if (rev2 == rev1-1)\r
{\r
if (bEntryAdded)\r
popup.AppendMenu(MF_SEPARATOR, NULL);\r
- popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
- popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
- popup.AppendMenuIcon(ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
+ popup.AppendMenuIcon(CGitLogList::ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
+ popup.AppendMenuIcon(CGitLogList::ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
+ popup.AppendMenuIcon(CGitLogList::ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
popup.AppendMenu(MF_SEPARATOR, NULL);\r
if (m_hasWC)\r
- popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
- popup.AppendMenuIcon(ID_POPPROPS, IDS_REPOBROWSE_SHOWPROP, IDI_PROPERTIES); // "Show Properties"\r
- popup.AppendMenuIcon(ID_LOG, IDS_MENULOG, IDI_LOG); // "Show Log" \r
- popup.AppendMenuIcon(ID_GETMERGELOGS, IDS_LOG_POPUP_GETMERGELOGS, IDI_LOG); // "Show merge log"\r
- popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
+ popup.AppendMenuIcon(CGitLogList::ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
+ popup.AppendMenuIcon(CGitLogList::ID_POPPROPS, IDS_REPOBROWSE_SHOWPROP, IDI_PROPERTIES); // "Show Properties"\r
+ popup.AppendMenuIcon(CGitLogList::ID_LOG, IDS_MENULOG, IDI_LOG); // "Show Log" \r
+ popup.AppendMenuIcon(CGitLogList::ID_GETMERGELOGS, IDS_LOG_POPUP_GETMERGELOGS, IDI_LOG); // "Show merge log"\r
+ popup.AppendMenuIcon(CGitLogList::ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
bEntryAdded = true;\r
if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty())\r
{\r
popup.AppendMenu(MF_SEPARATOR, NULL);\r
- popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
+ popup.AppendMenuIcon(CGitLogList::ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
}\r
if (popup.GetDefaultItem(0,FALSE)==-1)\r
- popup.SetDefaultItem(ID_OPEN, FALSE);\r
+ popup.SetDefaultItem(CGitLogList::ID_OPEN, FALSE);\r
}\r
}\r
else if (changedlogpaths.size())\r
{\r
// more than one entry is selected\r
- popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE);\r
+ popup.AppendMenuIcon(CGitLogList::ID_SAVEAS, IDS_LOG_POPUP_SAVE);\r
bEntryAdded = true;\r
}\r
\r
\r
switch (cmd)\r
{\r
- case ID_DIFF:\r
+ case CGitLogList::ID_DIFF:\r
{\r
DoDiffFromLog(selIndex, rev1, rev2, false, false);\r
}\r
if (GetFocus() == &m_ChangedFileListCtrl)\r
CopyChangedSelectionToClipBoard();\r
else\r
- CopySelectionToClipBoard();\r
+ m_LogList.CopySelectionToClipBoard();\r
}\r
\r
CString CLogDlg::GetAbsoluteUrlFromRelativeUrl(const CString& url)\r