OSDN Git Service

Log Dlg Statbutton work'
authorFrank Li <lznuaa@gmail.com>
Tue, 30 Dec 2008 05:12:20 +0000 (13:12 +0800)
committerFrank Li <lznuaa@gmail.com>
Tue, 30 Dec 2008 05:12:20 +0000 (13:12 +0800)
src/TortoiseProc/GitLogList.cpp
src/TortoiseProc/GitLogList.h
src/TortoiseProc/LogDlg.cpp
src/TortoiseProc/LogDlg.h
src/TortoiseProc/LogDlgHelper.h
src/TortoiseProc/StatGraphDlg.h
src/TortoiseProc/TortoiseProc.vcproj

index c23d479..5a4d822 100644 (file)
-// GitLogList.cpp : implementation file
-//
-/*
-       Description: qgit revision list view
-
-       Author: Marco Costalba (C) 2005-2007
-
-       Copyright: See COPYING file that comes with this distribution
-
-*/
-#include "stdafx.h"
-#include "TortoiseProc.h"
-#include "GitLogList.h"
-#include "GitRev.h"
-//#include "VssStyle.h"
-#include "IconMenu.h"
-// CGitLogList
-#include "cursor.h"
-#include "InputDlg.h"
-#include "PropDlg.h"
-#include "SVNProgressDlg.h"
-#include "ProgressDlg.h"
-//#include "RepositoryBrowser.h"
-//#include "CopyDlg.h"
-//#include "StatGraphDlg.h"
-#include "Logdlg.h"
-#include "MessageBox.h"
-#include "Registry.h"
-#include "AppUtils.h"
-#include "PathUtils.h"
-#include "StringUtils.h"
-#include "UnicodeUtils.h"
-#include "TempFile.h"
-//#include "GitInfo.h"
-//#include "GitDiff.h"
-#include "IconMenu.h"
-//#include "RevisionRangeDlg.h"
-//#include "BrowseFolder.h"
-//#include "BlameDlg.h"
-//#include "Blame.h"
-//#include "GitHelpers.h"
-#include "GitStatus.h"
-//#include "LogDlgHelper.h"
-//#include "CachedLogInfo.h"
-//#include "RepositoryInfo.h"
-//#include "EditPropertiesDlg.h"
-#include "FileDiffDlg.h"
-
-
-
-
-IMPLEMENT_DYNAMIC(CGitLogList, CHintListCtrl)
-
-CGitLogList::CGitLogList():CHintListCtrl()
-       ,m_regMaxBugIDColWidth(_T("Software\\TortoiseGit\\MaxBugIDColWidth"), 200)
-       ,m_nSearchIndex(0)
-       ,m_bNoDispUpdates(FALSE)
-       , m_bThreadRunning(FALSE)
-       , m_bStrictStopped(false)
-       , m_pStoreSelection(NULL)
-{
-       // use the default GUI font, create a copy of it and
-       // change the copy to BOLD (leave the rest of the font
-       // the same)
-       HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
-       LOGFONT lf = {0};
-       GetObject(hFont, sizeof(LOGFONT), &lf);
-       lf.lfWeight = FW_BOLD;
-       m_boldFont = CreateFontIndirect(&lf);
-
-       m_wcRev.m_CommitHash=GIT_REV_ZERO;
-       m_wcRev.m_Subject=_T("Working Copy");
-
-       m_hModifiedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONMODIFIED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-       m_hReplacedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONREPLACED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-       m_hAddedIcon    =  (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONADDED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-       m_hDeletedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONDELETED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-
-       g_Git.GetMapHashToFriendName(m_HashMap);
-}
-
-CGitLogList::~CGitLogList()
-{
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);
-
-       DestroyIcon(m_hModifiedIcon);
-       DestroyIcon(m_hReplacedIcon);
-       DestroyIcon(m_hAddedIcon);
-       DestroyIcon(m_hDeletedIcon);
-       m_logEntries.ClearAll();
-
-       if (m_boldFont)
-               DeleteObject(m_boldFont);
-
-       if ( m_pStoreSelection )
-       {
-               delete m_pStoreSelection;
-               m_pStoreSelection = NULL;
-       }
-}
-
-
-BEGIN_MESSAGE_MAP(CGitLogList, CHintListCtrl)
-       ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawLoglist)
-       ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfoLoglist)
-       ON_WM_CONTEXTMENU()
-       ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclkLoglist)
-       ON_NOTIFY_REFLECT(LVN_ODFINDITEM,OnLvnOdfinditemLoglist)
-       ON_WM_CREATE()
-END_MESSAGE_MAP()
-
-int CGitLogList:: OnCreate(LPCREATESTRUCT lpCreateStruct)
-{
-       PreSubclassWindow();
-       return CHintListCtrl::OnCreate(lpCreateStruct);
-}
-
-void CGitLogList::PreSubclassWindow()
-{
-       SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);
-       // load the icons for the action columns
-       m_Theme.SetWindowTheme(GetSafeHwnd(), L"Explorer", NULL);
-       CHintListCtrl::PreSubclassWindow();
-}
-
-void CGitLogList::InsertGitColumn()
-{
-       CString temp;
-
-       int c = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;
-       
-       while (c>=0)
-               DeleteColumn(c--);
-       temp.LoadString(IDS_LOG_GRAPH);
-
-       InsertColumn(this->LOGLIST_GRAPH, temp);
-       
-#if 0  
-       // make the revision column right aligned
-       LVCOLUMN Column;
-       Column.mask = LVCF_FMT;
-       Column.fmt = LVCFMT_RIGHT;
-       SetColumn(0, &Column); 
-#endif 
-//     CString log;
-//     g_Git.GetLog(log);
-
-       temp.LoadString(IDS_LOG_ACTIONS);
-       InsertColumn(this->LOGLIST_ACTION, temp);
-       
-       temp.LoadString(IDS_LOG_MESSAGE);
-       InsertColumn(this->LOGLIST_MESSAGE, temp);
-       
-       temp.LoadString(IDS_LOG_AUTHOR);
-       InsertColumn(this->LOGLIST_AUTHOR, temp);
-       
-       temp.LoadString(IDS_LOG_DATE);
-       InsertColumn(this->LOGLIST_DATE, temp);
-       
-
-       if (m_bShowBugtraqColumn)
-       {
-//             temp = m_ProjectProperties.sLabel;
-               if (temp.IsEmpty())
-                       temp.LoadString(IDS_LOG_BUGIDS);
-               InsertColumn(this->LOGLIST_BUG, temp);
-
-       }
-       
-       SetRedraw(false);
-       ResizeAllListCtrlCols();
-       SetRedraw(true);
-
-}
-
-void CGitLogList::ResizeAllListCtrlCols()
-{
-
-       const int nMinimumWidth = ICONITEMBORDER+16*4;
-       int maxcol = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;
-       int nItemCount = GetItemCount();
-       TCHAR textbuf[MAX_PATH];
-       CHeaderCtrl * pHdrCtrl = (CHeaderCtrl*)(GetDlgItem(0));
-       if (pHdrCtrl)
-       {
-               for (int col = 0; col <= maxcol; col++)
-               {
-                       HDITEM hdi = {0};
-                       hdi.mask = HDI_TEXT;
-                       hdi.pszText = textbuf;
-                       hdi.cchTextMax = sizeof(textbuf);
-                       pHdrCtrl->GetItem(col, &hdi);
-                       int cx = GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin
-                       for (int index = 0; index<nItemCount; ++index)
-                       {
-                               // get the width of the string and add 14 pixels for the column separator and margins
-                               int linewidth = GetStringWidth(GetItemText(index, col)) + 14;
-                               if (index < m_arShownList.GetCount())
-                               {
-                                       GitRev * pCurLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index));
-                                       if ((pCurLogEntry)&&(pCurLogEntry->m_CommitHash == m_wcRev.m_CommitHash))
-                                       {
-                                               // set the bold font and ask for the string width again
-                                               SendMessage(WM_SETFONT, (WPARAM)m_boldFont, NULL);
-                                               linewidth = GetStringWidth(GetItemText(index, col)) + 14;
-                                               // restore the system font
-                                               SendMessage(WM_SETFONT, NULL, NULL);
-                                       }
-                               }
-                               if (index == 0)
-                               {
-                                       // add the image size
-                                       CImageList * pImgList = GetImageList(LVSIL_SMALL);
-                                       if ((pImgList)&&(pImgList->GetImageCount()))
-                                       {
-                                               IMAGEINFO imginfo;
-                                               pImgList->GetImageInfo(0, &imginfo);
-                                               linewidth += (imginfo.rcImage.right - imginfo.rcImage.left);
-                                               linewidth += 3; // 3 pixels between icon and text
-                                       }
-                               }
-                               if (cx < linewidth)
-                                       cx = linewidth;
-                       }
-                       // Adjust columns "Actions" containing icons
-                       if (col == this->LOGLIST_ACTION)
-                       {
-                               if (cx < nMinimumWidth)
-                               {
-                                       cx = nMinimumWidth;
-                               }
-                       }
-                       
-                       if (col == this->LOGLIST_MESSAGE)
-                       {
-                               if (cx > LOGLIST_MESSAGE_MAX)
-                               {
-                                       cx = LOGLIST_MESSAGE_MAX;
-                               }
-                               if (cx < LOGLIST_MESSAGE_MIN)
-                               {
-                                       cx = LOGLIST_MESSAGE_MIN;
-                               }
-
-                       }
-                       // keep the bug id column small
-                       if ((col == 4)&&(m_bShowBugtraqColumn))
-                       {
-                               if (cx > (int)(DWORD)m_regMaxBugIDColWidth)
-                               {
-                                       cx = (int)(DWORD)m_regMaxBugIDColWidth;
-                               }
-                       }
-
-                       SetColumnWidth(col, cx);
-               }
-       }
-
-}
-
-void Refresh()
-{
-       
-}
-
-BOOL CGitLogList::GetShortName(CString ref, CString &shortname,CString prefix)
-{
-       if(ref.Left(prefix.GetLength()) ==  prefix)
-       {
-               shortname = ref.Right(ref.GetLength()-prefix.GetLength());
-               return TRUE;
-       }
-       return FALSE;
-}
-void CGitLogList::FillBackGround(HDC hdc, int Index,CRect &rect)
-{      
-//     HBRUSH brush;
-       LVITEM   rItem;
-       SecureZeroMemory(&rItem, sizeof(LVITEM));
-       rItem.mask  = LVIF_STATE;
-       rItem.iItem = Index;
-       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
-       GetItem(&rItem);
-
-       if (m_Theme.IsAppThemed() && m_bVista)
-       {
-               m_Theme.Open(m_hWnd, L"Explorer");
-               int state = LISS_NORMAL;
-               if (rItem.state & LVIS_SELECTED)
-               {
-                       if (::GetFocus() == m_hWnd)
-                               state |= LISS_SELECTED;
-                       else
-                               state |= LISS_SELECTEDNOTFOCUS;
-               }
-               else
-               {
-#if 0
-                       if (pLogEntry->bCopiedSelf)
-                       {
-                               // unfortunately, the pLVCD->nmcd.uItemState does not contain valid
-                               // information at this drawing stage. But we can check the whether the
-                               // previous stage changed the background color of the item
-                               if (pLVCD->clrTextBk == GetSysColor(COLOR_MENU))
-                               {
-                                       HBRUSH brush;
-                                       brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));
-                                       if (brush)
-                                       {
-                                               ::FillRect(pLVCD->nmcd.hdc, &rect, brush);
-                                               ::DeleteObject(brush);
-                                       }
-                               }
-                       }
-#endif
-               }
-
-               if (m_Theme.IsBackgroundPartiallyTransparent(LVP_LISTDETAIL, state))
-                       m_Theme.DrawParentBackground(m_hWnd, hdc, &rect);
-
-                       m_Theme.DrawBackground(hdc, LVP_LISTDETAIL, state, &rect, NULL);
-       }
-       else
-       {
-               HBRUSH brush;
-               if (rItem.state & LVIS_SELECTED)
-               {
-                       if (::GetFocus() == m_hWnd)
-                               brush = ::CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
-                       else
-                               brush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
-               }
-               else
-               {
-                       //if (pLogEntry->bCopiedSelf)
-                       //      brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));
-                       //else
-                               brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
-               }
-               if (brush == NULL)
-                       return;
-
-               ::FillRect(hdc, &rect, brush);
-               ::DeleteObject(brush);
-               
-       }
-}
-
-void CGitLogList::DrawTagBranch(HDC hdc,CRect &rect,INT_PTR index)
-{
-       GitRev* data = (GitRev*)m_arShownList.GetAt(index);
-       CRect rt=rect;
-       LVITEM   rItem;
-       SecureZeroMemory(&rItem, sizeof(LVITEM));
-       rItem.mask  = LVIF_STATE;
-       rItem.iItem = index;
-       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
-       GetItem(&rItem);
-
-       for(int i=0;i<m_HashMap[data->m_CommitHash].size();i++)
-       {
-               CString str;
-               str=m_HashMap[data->m_CommitHash][i];
-               
-               CString shortname;
-               HBRUSH brush=0;
-               shortname=_T("");
-               if(GetShortName(str,shortname,_T("refs/heads/")))
-               {
-                       brush = ::CreateSolidBrush(RGB(0xff, 0, 0));
-               }else if(GetShortName(str,shortname,_T("refs/remotes/")))
-               {
-                       brush = ::CreateSolidBrush(RGB(0xff, 0xff, 0));
-               }
-               else if(GetShortName(str,shortname,_T("refs/tags/")))
-               {
-                       brush = ::CreateSolidBrush(RGB(0, 0, 0xff));
-               }
-
-               if(!shortname.IsEmpty())
-               {
-                       SIZE size;
-                       memset(&size,0,sizeof(SIZE));
-                       GetTextExtentPoint32(hdc, shortname,shortname.GetLength(),&size);
-               
-                       rt.SetRect(rt.left,rt.top,rt.left+size.cx,rt.bottom);
-                       rt.right+=4;
-                       ::FillRect(hdc, &rt, brush);
-                       if (rItem.state & LVIS_SELECTED)
-                       {
-                               COLORREF   clrOld   = ::SetTextColor(hdc,::GetSysColor(COLOR_HIGHLIGHTTEXT));   
-                               ::DrawText(hdc,shortname,shortname.GetLength(),&rt,DT_CENTER);
-                               ::SetTextColor(hdc,clrOld);   
-                       }else
-                       {
-                               ::DrawText(hdc,shortname,shortname.GetLength(),&rt,DT_CENTER);
-                       }
-
-                       
-                       ::MoveToEx(hdc,rt.left,rt.top,NULL);
-                       ::LineTo(hdc,rt.right,rt.top);
-                       ::LineTo(hdc,rt.right,rt.bottom);
-                       ::LineTo(hdc,rt.left,rt.bottom);
-                       ::LineTo(hdc,rt.left,rt.top);
-                               
-                       rt.left=rt.right+3;
-               }
-               if(brush)
-                       ::DeleteObject(brush);
-       }               
-       rt.right=rect.right;
-
-       if (rItem.state & LVIS_SELECTED)
-       {
-               COLORREF   clrOld   = ::SetTextColor(hdc,::GetSysColor(COLOR_HIGHLIGHTTEXT));   
-               ::DrawText(hdc,data->m_Subject,data->m_Subject.GetLength(),&rt,DT_LEFT);
-               ::SetTextColor(hdc,clrOld);   
-       }else
-       {
-               ::DrawText(hdc,data->m_Subject,data->m_Subject.GetLength(),&rt,DT_LEFT);
-       }
-       
-}
-
-void CGitLogList::paintGraphLane(HDC hdc, int laneHeight,int type, int x1, int x2,
-                                      const COLORREF& col,int top
-                                                                         )  
-{
-       int h = laneHeight / 2;
-       int m = (x1 + x2) / 2;
-       int r = (x2 - x1) / 3;
-       int d =  2 * r;
-
-       #define P_CENTER m , h+top
-       #define P_0      x2, h+top
-       #define P_90     m , 0+top
-       #define P_180    x1, h+top
-       #define P_270    m , 2 * h+top
-       #define R_CENTER m - r, h - r+top, m - r+d, h - r+top+d
-
-       //static QPen myPen(Qt::black, 2); // fast path here
-       CPen pen;
-       pen.CreatePen(PS_SOLID,2,col);
-       //myPen.setColor(col);
-       HPEN oldpen=(HPEN)::SelectObject(hdc,(HPEN)pen);
-
-       //p->setPen(myPen);
-
-       // vertical line
-       switch (type) {
-       case Lanes::ACTIVE:
-       case Lanes::NOT_ACTIVE:
-       case Lanes::MERGE_FORK:
-       case Lanes::MERGE_FORK_R:
-       case Lanes::MERGE_FORK_L:
-       case Lanes::JOIN:
-       case Lanes::JOIN_R:
-       case Lanes::JOIN_L:
-               DrawLine(hdc,P_90,P_270);
-               //p->drawLine(P_90, P_270);
-               break;
-       case Lanes::HEAD:
-       case Lanes::HEAD_R:
-       case Lanes::HEAD_L:
-       case Lanes::BRANCH:
-               DrawLine(hdc,P_CENTER,P_270);
-               //p->drawLine(P_CENTER, P_270);
-               break;
-       case Lanes::TAIL:
-       case Lanes::TAIL_R:
-       case Lanes::TAIL_L:
-       case Lanes::INITIAL:
-       case Lanes::BOUNDARY:
-       case Lanes::BOUNDARY_C:
-       case Lanes::BOUNDARY_R:
-       case Lanes::BOUNDARY_L:
-               DrawLine(hdc,P_90, P_CENTER);
-               //p->drawLine(P_90, P_CENTER);
-               break;
-       default:
-               break;
-       }
-
-       // horizontal line
-       switch (type) {
-       case Lanes::MERGE_FORK:
-       case Lanes::JOIN:
-       case Lanes::HEAD:
-       case Lanes::TAIL:
-       case Lanes::CROSS:
-       case Lanes::CROSS_EMPTY:
-       case Lanes::BOUNDARY_C:
-               DrawLine(hdc,P_180,P_0);
-               //p->drawLine(P_180, P_0);
-               break;
-       case Lanes::MERGE_FORK_R:
-       case Lanes::JOIN_R:
-       case Lanes::HEAD_R:
-       case Lanes::TAIL_R:
-       case Lanes::BOUNDARY_R:
-               DrawLine(hdc,P_180,P_CENTER);
-               //p->drawLine(P_180, P_CENTER);
-               break;
-       case Lanes::MERGE_FORK_L:
-       case Lanes::JOIN_L:
-       case Lanes::HEAD_L:
-       case Lanes::TAIL_L:
-       case Lanes::BOUNDARY_L:
-               DrawLine(hdc,P_CENTER,P_0);
-               //p->drawLine(P_CENTER, P_0);
-               break;
-       default:
-               break;
-       }
-
-       CBrush brush;
-       brush.CreateSolidBrush(col);
-       HBRUSH oldbrush=(HBRUSH)::SelectObject(hdc,(HBRUSH)brush);
-       // center symbol, e.g. rect or ellipse
-       switch (type) {
-       case Lanes::ACTIVE:
-       case Lanes::INITIAL:
-       case Lanes::BRANCH:
-
-               //p->setPen(Qt::NoPen);
-               //p->setBrush(col);
-               ::Ellipse(hdc, R_CENTER);
-               //p->drawEllipse(R_CENTER);
-               break;
-       case Lanes::MERGE_FORK:
-       case Lanes::MERGE_FORK_R:
-       case Lanes::MERGE_FORK_L:
-               //p->setPen(Qt::NoPen);
-               //p->setBrush(col);
-               //p->drawRect(R_CENTER);
-               Rectangle(hdc,R_CENTER);
-               break;
-       case Lanes::UNAPPLIED:
-               // Red minus sign
-               //p->setPen(Qt::NoPen);
-               //p->setBrush(Qt::red);
-               //p->drawRect(m - r, h - 1, d, 2);
-               ::Rectangle(hdc,m-r,h-1,d,2);
-               break;
-       case Lanes::APPLIED:
-               // Green plus sign
-               //p->setPen(Qt::NoPen);
-               //p->setBrush(DARK_GREEN);
-               //p->drawRect(m - r, h - 1, d, 2);
-               //p->drawRect(m - 1, h - r, 2, d);
-               ::Rectangle(hdc,m-r,h-1,d,2);
-               ::Rectangle(hdc,m-1,h-r,2,d);
-               break;
-       case Lanes::BOUNDARY:
-               //p->setBrush(back);
-               //p->drawEllipse(R_CENTER);
-               ::Ellipse(hdc, R_CENTER);
-               break;
-       case Lanes::BOUNDARY_C:
-       case Lanes::BOUNDARY_R:
-       case Lanes::BOUNDARY_L:
-               //p->setBrush(back);
-               //p->drawRect(R_CENTER);
-               ::Rectangle(hdc,R_CENTER);
-               break;
-       default:
-               break;
-       }
-
-       ::SelectObject(hdc,oldpen);
-       ::SelectObject(hdc,oldbrush);
-       #undef P_CENTER
-       #undef P_0
-       #undef P_90
-       #undef P_180
-       #undef P_270
-       #undef R_CENTER
-}
-
-void CGitLogList::DrawGraph(HDC hdc,CRect &rect,INT_PTR index)
-{
-       //todo unfinished
-       return;
-       GitRev* data = (GitRev*)m_arShownList.GetAt(index);
-       CRect rt=rect;
-       LVITEM   rItem;
-       SecureZeroMemory(&rItem, sizeof(LVITEM));
-       rItem.mask  = LVIF_STATE;
-       rItem.iItem = index;
-       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
-       GetItem(&rItem);
-
-       static const COLORREF colors[Lanes::COLORS_NUM] = { RGB(0,0,0), RGB(0xFF,0,0), RGB(0,0x1F,0),
-                                                  RGB(0,0,0xFF), RGB(128,128,128), RGB(128,128,0),
-                                                  RGB(0,128,128), RGB(128,0,128) };
-
-
-//     p->translate(QPoint(opt.rect.left(), opt.rect.top()));
-
-
-
-       if (data->m_Lanes.size() == 0)
-               m_logEntries.setLane(data->m_CommitHash);
-
-       std::vector<int>& lanes=data->m_Lanes;
-       UINT laneNum = lanes.size();
-       UINT mergeLane = 0;
-       for (UINT i = 0; i < laneNum; i++)
-               if (Lanes::isMerge(lanes[i])) {
-                       mergeLane = i;
-                       break;
-               }
-
-       int x1 = 0, x2 = 0;
-       int maxWidth = rect.Width();
-       int lw = 3 * rect.Height() / 4; //laneWidth() 
-       for (UINT i = 0; i < laneNum && x2 < maxWidth; i++) {
-
-               x1 = x2;
-               x2 += lw;
-
-               int ln = lanes[i];
-               if (ln == Lanes::EMPTY)
-                       continue;
-
-               UINT col = (  Lanes:: isHead(ln) ||Lanes:: isTail(ln) || Lanes::isJoin(ln)
-                           || ln ==Lanes:: CROSS_EMPTY) ? mergeLane : i;
-
-               if (ln == Lanes::CROSS) {
-                       paintGraphLane(hdc, rect.Height(),Lanes::NOT_ACTIVE, x1, x2, colors[col % Lanes::COLORS_NUM],rect.top);
-                       paintGraphLane(hdc, rect.Height(),Lanes::CROSS, x1, x2, colors[mergeLane % Lanes::COLORS_NUM],rect.top);
-               } else
-                       paintGraphLane(hdc, rect.Height(),ln, x1, x2, colors[col % Lanes::COLORS_NUM],rect.top);
-       }
-
-       TRACE(_T("index %d %d\r\n"),index,data->m_Lanes.size());
-}
-
-void CGitLogList::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
-{
-
-       NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
-       // Take the default processing unless we set this to something else below.
-       *pResult = CDRF_DODEFAULT;
-
-       if (m_bNoDispUpdates)
-               return;
-
-
-
-       switch (pLVCD->nmcd.dwDrawStage)
-       {
-       case CDDS_PREPAINT:
-               {
-                       *pResult = CDRF_NOTIFYITEMDRAW;
-                       return;
-               }
-               break;
-       case CDDS_ITEMPREPAINT:
-               {
-                       // This is the prepaint stage for an item. Here's where we set the
-                       // item's text color. 
-                       
-                       // Tell Windows to send draw notifications for each subitem.
-                       *pResult = CDRF_NOTIFYSUBITEMDRAW;
-
-                       COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);
-
-                       if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)
-                       {
-                               GitRev* data = (GitRev*)m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec);
-                               if (data)
-                               {
-#if 0
-                                       if (data->bCopiedSelf)
-                                       {
-                                               // only change the background color if the item is not 'hot' (on vista with m_Themes enabled)
-                                               if (!m_Theme.IsAppm_Themed() || !m_bVista || ((pLVCD->nmcd.uItemState & CDIS_HOT)==0))
-                                                       pLVCD->clrTextBk = GetSysColor(COLOR_MENU);
-                                       }
-
-                                       if (data->bCopies)
-                                               crText = m_Colors.GetColor(CColors::Modified);
-#endif
-//                                     if ((data->childStackDepth)||(m_mergedRevs.find(data->Rev) != m_mergedRevs.end()))
-//                                             crText = GetSysColor(COLOR_GRAYTEXT);
-//                                     if (data->Rev == m_wcRev)
-//                                     {
-//                                             SelectObject(pLVCD->nmcd.hdc, m_boldFont);
-                                               // We changed the font, so we're returning CDRF_NEWFONT. This
-                                               // tells the control to recalculate the extent of the text.
-//                                             *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;
-//                                     }
-                               }
-                       }
-                       if (m_arShownList.GetCount() == (INT_PTR)pLVCD->nmcd.dwItemSpec)
-                       {
-                               if (m_bStrictStopped)
-                                       crText = GetSysColor(COLOR_GRAYTEXT);
-                       }
-                       // Store the color back in the NMLVCUSTOMDRAW struct.
-                       pLVCD->clrText = crText;
-                       return;
-               }
-               break;
-       case CDDS_ITEMPREPAINT|CDDS_ITEM|CDDS_SUBITEM:
-               {
-                       if ((m_bStrictStopped)&&(m_arShownList.GetCount() == (INT_PTR)pLVCD->nmcd.dwItemSpec))
-                       {
-                               pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED|CDIS_FOCUS);
-                       }
-
-                       if (pLVCD->iSubItem == LOGLIST_GRAPH)
-                       {
-                               if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)
-                               {
-                                       CRect rect;
-                                       GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);
-                                       
-                                       FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);
-                                       DrawGraph(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);
-
-                                       *pResult = CDRF_SKIPDEFAULT;
-                                       return;
-                               
-                               }
-                       }
-
-                       if (pLVCD->iSubItem == LOGLIST_MESSAGE)
-                       {
-                               if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)
-                               {
-                                       GitRev* data = (GitRev*)m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec);
-                                       if(!data->m_IsFull)
-                                       {
-                                               if(data->SafeFetchFullInfo(&g_Git))
-                                                       this->Invalidate();
-                                               TRACE(_T("Update ... %d\r\n"),pLVCD->nmcd.dwItemSpec);
-                                       }
-
-                                       if(m_HashMap[data->m_CommitHash].size()!=0)
-                                       {
-                                               CRect rect;
-
-                                               GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);
-                                       
-                                               FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);
-                                               DrawTagBranch(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);
-
-                                               *pResult = CDRF_SKIPDEFAULT;
-                                               return;
-
-                                       }
-                               }
-                       }
-                       
-                       if (pLVCD->iSubItem == 1)
-                       {
-                               *pResult = CDRF_DODEFAULT;
-
-                               if (m_arShownList.GetCount() <= (INT_PTR)pLVCD->nmcd.dwItemSpec)
-                                       return;
-
-                               int             nIcons = 0;
-                               int             iconwidth = ::GetSystemMetrics(SM_CXSMICON);
-                               int             iconheight = ::GetSystemMetrics(SM_CYSMICON);
-
-                               GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec));
-                               CRect rect;
-                               GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);
-                               // Get the selected state of the
-                               // item being drawn.                                                    
-
-                               // Fill the background
-                               FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);
-                               
-                               // Draw the icon(s) into the compatible DC
-                               if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_MODIFIED)
-                                       ::DrawIconEx(pLVCD->nmcd.hdc, rect.left + ICONITEMBORDER, rect.top, m_hModifiedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);
-                               nIcons++;
-
-                               if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_ADDED)
-                                       ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hAddedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);
-                               nIcons++;
-
-                               if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_DELETED)
-                                       ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hDeletedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);
-                               nIcons++;
-
-                               if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_REPLACED)
-                                       ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hReplacedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);
-                               nIcons++;
-                               *pResult = CDRF_SKIPDEFAULT;
-                               return;
-                       }
-               }
-               break;
-       }
-       *pResult = CDRF_DODEFAULT;
-
-}
-
-// CGitLogList message handlers
-
-void CGitLogList::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)
-{
-       NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
-
-       // Create a pointer to the item
-       LV_ITEM* pItem = &(pDispInfo)->item;
-
-       // Do the list need text information?
-       if (!(pItem->mask & LVIF_TEXT))
-               return;
-
-       // By default, clear text buffer.
-       lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);
-
-       bool bOutOfRange = pItem->iItem >= ShownCountWithStopped();
-       
-       *pResult = 0;
-       if (m_bNoDispUpdates || bOutOfRange)
-               return;
-
-       // Which item number?
-       int itemid = pItem->iItem;
-       GitRev * pLogEntry = NULL;
-       if (itemid < m_arShownList.GetCount())
-               pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(pItem->iItem));
-
-           
-       // Which column?
-       switch (pItem->iSubItem)
-       {
-       case this->LOGLIST_GRAPH:       //Graphic
-               if (pLogEntry)
-               {
-               }
-               break;
-       case this->LOGLIST_ACTION: //action -- no text in the column
-               break;
-       case this->LOGLIST_MESSAGE: //Message
-               if (pLogEntry)
-                       lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_Subject, pItem->cchTextMax);
-               break;
-       case this->LOGLIST_AUTHOR: //Author
-               if (pLogEntry)
-                       lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_AuthorName, pItem->cchTextMax);
-               break;
-       case this->LOGLIST_DATE: //Date
-               if (pLogEntry)
-                       lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_AuthorDate.Format(_T("%Y-%m-%d %H:%M")), pItem->cchTextMax);
-               break;
-               
-       case 5:
-
-               break;
-       default:
-               ASSERT(false);
-       }
-}
-
-void CGitLogList::OnContextMenu(CWnd* pWnd, CPoint point)
-{
-
-       int selIndex = GetSelectionMark();
-       if (selIndex < 0)
-               return; // nothing selected, nothing to do with a context menu
-
-       // if the user selected the info text telling about not all revisions shown due to
-       // the "stop on copy/rename" option, we also don't show the context menu
-       if ((m_bStrictStopped)&&(selIndex == m_arShownList.GetCount()))
-               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;
-               GetItemRect(selIndex, &rect, LVIR_LABEL);
-               ClientToScreen(&rect);
-               point = rect.CenterPoint();
-       }
-       m_nSearchIndex = selIndex;
-       m_bCancelled = FALSE;
-
-       // calculate some information the context menu commands can use
-//     CString pathURL = GetURLFromPath(m_path);
-
-       POSITION pos = GetFirstSelectedItemPosition();
-       int indexNext = GetNextSelectedItem(pos);
-       if (indexNext < 0)
-               return;
-
-       GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));
-#if 0
-       GitRev revSelected = pSelLogEntry->Rev;
-       GitRev revPrevious = git_revnum_t(revSelected)-1;
-       if ((pSelLogEntry->pArChangedPaths)&&(pSelLogEntry->pArChangedPaths->GetCount() <= 2))
-       {
-               for (int i=0; i<pSelLogEntry->pArChangedPaths->GetCount(); ++i)
-               {
-                       LogChangedPath * changedpath = (LogChangedPath *)pSelLogEntry->pArChangedPaths->GetAt(i);
-                       if (changedpath->lCopyFromRev)
-                               revPrevious = changedpath->lCopyFromRev;
-               }
-       }
-       GitRev revSelected2;
-       if (pos)
-       {
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));
-               revSelected2 = pLogEntry->Rev;
-       }
-       bool bAllFromTheSameAuthor = true;
-       CString firstAuthor;
-       CLogDataVector selEntries;
-       GitRev revLowest, revHighest;
-       GitRevRangeArray revisionRanges;
-       {
-               POSITION pos = GetFirstSelectedItemPosition();
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));
-               revisionRanges.AddRevision(pLogEntry->Rev);
-               selEntries.push_back(pLogEntry);
-               firstAuthor = pLogEntry->sAuthor;
-               revLowest = pLogEntry->Rev;
-               revHighest = pLogEntry->Rev;
-               while (pos)
-               {
-                       pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(GetNextSelectedItem(pos)));
-                       revisionRanges.AddRevision(pLogEntry->Rev);
-                       selEntries.push_back(pLogEntry);
-                       if (firstAuthor.Compare(pLogEntry->sAuthor))
-                               bAllFromTheSameAuthor = false;
-                       revLowest = (git_revnum_t(pLogEntry->Rev) > git_revnum_t(revLowest) ? revLowest : pLogEntry->Rev);
-                       revHighest = (git_revnum_t(pLogEntry->Rev) < git_revnum_t(revHighest) ? revHighest : pLogEntry->Rev);
-               }
-       }
-
-#endif
-
-       int FirstSelect=-1, LastSelect=-1;
-       pos = GetFirstSelectedItemPosition();
-       FirstSelect = GetNextSelectedItem(pos);
-       while(pos)
-       {
-               LastSelect = GetNextSelectedItem(pos);
-       }
-       //entry is selected, now show the popup menu
-       CIconMenu popup;
-       if (popup.CreatePopupMenu())
-       {
-               if (GetSelectedCount() == 1)
-               {
-#if 0
-                       if (!m_path.IsDirectory())
-                       {
-                               if (m_hasWC)
-                               {
-                                       popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);
-                                       popup.AppendMenuIcon(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);
-                               }
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);
-                               popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);
-                               popup.AppendMenu(MF_SEPARATOR, NULL);
-                               popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);
-                               popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);
-                               popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);
-                               popup.AppendMenuIcon(ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);
-                               popup.AppendMenu(MF_SEPARATOR, NULL);
-                       }
-                       else
-#endif 
-                       {
-                               if (m_hasWC)
-                               {
-                                       popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);
-                                       // TODO:
-                                       // TortoiseMerge could be improved to take a /blame switch
-                                       // and then not 'cat' the files from a unified diff but
-                                       // blame then.
-                                       // But until that's implemented, the context menu entry for
-                                       // this feature is commented out.
-                                       //popup.AppendMenu(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);
-                               }
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);
-                               popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);
-                               //popup.AppendMenuIcon(ID_BLAMEWITHPREVIOUS, IDS_LOG_POPUP_BLAMEWITHPREVIOUS, IDI_BLAME);
-                               popup.AppendMenu(MF_SEPARATOR, NULL);
-                       }
-
-//                     if (!m_ProjectProperties.sWebViewerRev.IsEmpty())
-//                     {
-//                             popup.AppendMenuIcon(ID_VIEWREV, IDS_LOG_POPUP_VIEWREV);
-//                     }
-//                     if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty())
-//                     {
-//                             popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);
-//                     }
-//                     if ((!m_ProjectProperties.sWebViewerPathRev.IsEmpty())||
-//                             (!m_ProjectProperties.sWebViewerRev.IsEmpty()))
-//                     {
-//                             popup.AppendMenu(MF_SEPARATOR, NULL);
-//                     }
-
-                       //if (m_hasWC)
-                       //      popup.AppendMenuIcon(ID_REVERTTOREV, IDS_LOG_POPUP_REVERTTOREV, IDI_REVERT);
-                       //if (m_hasWC)
-                       //      popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);
-                       //if (m_hasWC)
-                       //      popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE);
-                       
-                       popup.AppendMenuIcon(ID_SWITCHTOREV, _T("Switch/Checkout to this") , IDI_SWITCH);
-                       popup.AppendMenuIcon(ID_CREATE_BRANCH, _T("Create Branch at this version") , IDI_COPY);
-                       popup.AppendMenuIcon(ID_CREATE_TAG, _T("Create Tag at this version"), IDI_COPY);
-                       popup.AppendMenuIcon(ID_CHERRY_PICK, _T("Cherry Pick this version"), IDI_EXPORT);
-                       popup.AppendMenuIcon(ID_EXPORT, _T("Export this version"), IDI_EXPORT);
-                       
-
-                       popup.AppendMenu(MF_SEPARATOR, NULL);
-               }
-               else if (GetSelectedCount() >= 2)
-               {
-                       bool bAddSeparator = false;
-                       if (IsSelectionContinuous() || (GetSelectedCount() == 2))
-                       {
-                               popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);
-                       }
-                       if (GetSelectedCount() == 2)
-                       {
-                               //popup.AppendMenuIcon(ID_BLAMETWO, IDS_LOG_POPUP_BLAMEREVS, IDI_BLAME);
-                               popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);
-                               bAddSeparator = true;
-                       }
-                       if (m_hasWC)
-                       {
-                               //popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREVS, IDI_REVERT);
-//                             if (m_hasWC)
-//                                     popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREVS, IDI_MERGE);
-                               bAddSeparator = true;
-                       }
-                       if (bAddSeparator)
-                               popup.AppendMenu(MF_SEPARATOR, NULL);
-               }
-#if 0
-//             if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor))
-//             {
-//                     popup.AppendMenuIcon(ID_EDITAUTHOR, IDS_LOG_POPUP_EDITAUTHOR);
-//             }
-//             if (GetSelectedCount() == 1)
-//             {
-//                     popup.AppendMenuIcon(ID_EDITLOG, IDS_LOG_POPUP_EDITLOG);
-//                     popup.AppendMenuIcon(ID_REVPROPS, IDS_REPOBROWSE_SHOWREVPROP, IDI_PROPERTIES); // "Show Revision Properties"
-//                     popup.AppendMenu(MF_SEPARATOR, NULL);
-//             }
-#endif
-
-               
-               if (GetSelectedCount() == 1)
-               {
-                       popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash"));
-               }
-               if (GetSelectedCount() != 0)
-               {
-                       popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);
-               }
-               popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);
-
-               int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);
-//             DialogEnableWindow(IDOK, FALSE);
-//             SetPromptApp(&theApp);
-               theApp.DoWaitCursor(1);
-               bool bOpenWith = false;
-
-               switch (cmd)
-               {
-                       case ID_GNUDIFF1:
-                       {
-                               CString tempfile=GetTempFile();
-                               CString cmd;
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
-                               cmd.Format(_T("git.exe diff-tree -r -p --stat %s"),r1->m_CommitHash);
-                               g_Git.RunLogFile(cmd,tempfile);
-                               CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r1->m_Subject);
-                       }
-                       break;
-
-                       case ID_GNUDIFF2:
-                       {
-                               CString tempfile=GetTempFile();
-                               CString cmd;
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
-                               GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));
-                               cmd.Format(_T("git.exe diff-tree -r -p --stat %s %s"),r1->m_CommitHash,r2->m_CommitHash);
-                               g_Git.RunLogFile(cmd,tempfile);
-                               CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r2->m_CommitHash.Left(6));
-
-                       }
-                       break;
-
-               case ID_COMPARETWO:
-                       {
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
-                               GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));
-                               CFileDiffDlg dlg;
-                               dlg.SetDiff(NULL,*r1,*r2);
-                               dlg.DoModal();
-                               
-                       }
-                       break;
-               
-
-               case ID_COMPARE:
-                       {
-                               GitRev * r1 = &m_wcRev;
-                               GitRev * r2 = pSelLogEntry;
-                               CFileDiffDlg dlg;
-                               dlg.SetDiff(NULL,*r1,*r2);
-                               dlg.DoModal();
-
-                               //user clicked on the menu item "compare with working copy"
-                               //if (PromptShown())
-                               //{
-                               //      GitDiff diff(this, m_hWnd, true);
-                               //      diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-                               //      diff.SetHEADPeg(m_LogRevision);
-                               //      diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);
-                               //}
-                               //else
-                               //      CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-                       }
-                       break;
-
-               case ID_COMPAREWITHPREVIOUS:
-                       {
-
-                               CFileDiffDlg dlg;
-                               
-                               if(pSelLogEntry->m_ParentHash.size()>0)
-                               //if(m_logEntries.m_HashMap[pSelLogEntry->m_ParentHash[0]]>=0)
-                               {
-                                       dlg.SetDiff(NULL,pSelLogEntry->m_CommitHash,pSelLogEntry->m_ParentHash[0]);
-                                       dlg.DoModal();
-                               }else
-                               {
-                                       CMessageBox::Show(NULL,_T("No previous version"),_T("TortoiseGit"),MB_OK);      
-                               }
-                               //if (PromptShown())
-                               //{
-                               //      GitDiff diff(this, m_hWnd, true);
-                               //      diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-                               //      diff.SetHEADPeg(m_LogRevision);
-                               //      diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected);
-                               //}
-                               //else
-                               //      CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-                       }
-                       break;
-               case ID_COPYCLIPBOARD:
-                       {
-                               CopySelectionToClipBoard();
-                       }
-                       break;
-               case ID_COPYHASH:
-                       {
-                               CopySelectionToClipBoard(TRUE);
-                       }
-                       break;
-               case ID_EXPORT:
-                       CAppUtils::Export(&pSelLogEntry->m_CommitHash);
-                       break;
-               case ID_CREATE_BRANCH:
-                       CAppUtils::CreateBranchTag(FALSE,&pSelLogEntry->m_CommitHash);
-                       m_HashMap.clear();
-                       g_Git.GetMapHashToFriendName(m_HashMap);
-                       Invalidate();                   
-                       break;
-               case ID_CREATE_TAG:
-                       CAppUtils::CreateBranchTag(TRUE,&pSelLogEntry->m_CommitHash);
-                       m_HashMap.clear();
-                       g_Git.GetMapHashToFriendName(m_HashMap);
-                       Invalidate();
-                       break;
-               case ID_SWITCHTOREV:
-                       CAppUtils::Switch(&pSelLogEntry->m_CommitHash);
-                       break;
-
-               default:
-                       //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);
-                       break;
-#if 0
-       
-               case ID_REVERTREV:
-                       {
-                               // we need an URL to complete this command, so error out if we can't get an URL
-                               if (pathURL.IsEmpty())
-                               {
-                                       CString strMessage;
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));
-                                       break;          //exit
-                               }
-                               CString msg;
-                               msg.Format(IDS_LOG_REVERT_CONFIRM, m_path.GetWinPath());
-                               if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)
-                               {
-                                       CGitProgressDlg dlg;
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);
-                                       dlg.SetPathList(CTGitPathList(m_path));
-                                       dlg.SetUrl(pathURL);
-                                       dlg.SetSecondUrl(pathURL);
-                                       revisionRanges.AdjustForMerge(true);
-                                       dlg.SetRevisionRanges(revisionRanges);
-                                       dlg.SetPegRevision(m_LogRevision);
-                                       dlg.DoModal();
-                               }
-                       }
-                       break;
-               case ID_MERGEREV:
-                       {
-                               // we need an URL to complete this command, so error out if we can't get an URL
-                               if (pathURL.IsEmpty())
-                               {
-                                       CString strMessage;
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));
-                                       break;          //exit
-                               }
-
-                               CString path = m_path.GetWinPathString();
-                               bool bGotSavePath = false;
-                               if ((GetSelectedCount() == 1)&&(!m_path.IsDirectory()))
-                               {
-                                       bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());
-                               }
-                               else
-                               {
-                                       CBrowseFolder folderBrowser;
-                                       folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));
-                                       bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);
-                               }
-                               if (bGotSavePath)
-                               {
-                                       CGitProgressDlg dlg;
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);
-                                       dlg.SetPathList(CTGitPathList(CTGitPath(path)));
-                                       dlg.SetUrl(pathURL);
-                                       dlg.SetSecondUrl(pathURL);
-                                       revisionRanges.AdjustForMerge(false);
-                                       dlg.SetRevisionRanges(revisionRanges);
-                                       dlg.SetPegRevision(m_LogRevision);
-                                       dlg.DoModal();
-                               }
-                       }
-                       break;
-               case ID_REVERTTOREV:
-                       {
-                               // we need an URL to complete this command, so error out if we can't get an URL
-                               if (pathURL.IsEmpty())
-                               {
-                                       CString strMessage;
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));
-                                       break;          //exit
-                               }
-
-                               CString msg;
-                               msg.Format(IDS_LOG_REVERTTOREV_CONFIRM, m_path.GetWinPath());
-                               if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)
-                               {
-                                       CGitProgressDlg dlg;
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);
-                                       dlg.SetPathList(CTGitPathList(m_path));
-                                       dlg.SetUrl(pathURL);
-                                       dlg.SetSecondUrl(pathURL);
-                                       GitRevRangeArray revarray;
-                                       revarray.AddRevRange(GitRev::REV_HEAD, revSelected);
-                                       dlg.SetRevisionRanges(revarray);
-                                       dlg.SetPegRevision(m_LogRevision);
-                                       dlg.DoModal();
-                               }
-                       }
-                       break;
-       
-
-       
-               case ID_BLAMECOMPARE:
-                       {
-                               //user clicked on the menu item "compare with working copy"
-                               //now first get the revision which is selected
-                               if (PromptShown())
-                               {
-                                       GitDiff diff(this, this->m_hWnd, true);
-                                       diff.SetHEADPeg(m_LogRevision);
-                                       diff.ShowCompare(m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), false, true);
-                               }
-                               else
-                                       CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);
-                       }
-                       break;
-               case ID_BLAMETWO:
-                       {
-                               //user clicked on the menu item "compare and blame revisions"
-                               if (PromptShown())
-                               {
-                                       GitDiff diff(this, this->m_hWnd, true);
-                                       diff.SetHEADPeg(m_LogRevision);
-                                       diff.ShowCompare(CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), false, true);
-                               }
-                               else
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);
-                       }
-                       break;
-               case ID_BLAMEWITHPREVIOUS:
-                       {
-                               //user clicked on the menu item "Compare and Blame with previous revision"
-                               if (PromptShown())
-                               {
-                                       GitDiff diff(this, this->m_hWnd, true);
-                                       diff.SetHEADPeg(m_LogRevision);
-                                       diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), false, true);
-                               }
-                               else
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);
-                       }
-                       break;
-               
-               case ID_OPENWITH:
-                       bOpenWith = true;
-               case ID_OPEN:
-                       {
-                               CProgressDlg progDlg;
-                               progDlg.SetTitle(IDS_APPNAME);
-                               progDlg.SetAnimation(IDR_DOWNLOAD);
-                               CString sInfoLine;
-                               sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());
-                               progDlg.SetLine(1, sInfoLine, true);
-                               SetAndClearProgressInfo(&progDlg);
-                               progDlg.ShowModeless(m_hWnd);
-                               CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path, revSelected);
-                               bool bSuccess = true;
-                               if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))
-                               {
-                                       bSuccess = false;
-                                       // try again, but with the selected revision as the peg revision
-                                       if (!Cat(m_path, revSelected, revSelected, tempfile))
-                                       {
-                                               progDlg.Stop();
-                                               SetAndClearProgressInfo((HWND)NULL);
-                                               CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
-                                               EnableOKButton();
-                                               break;
-                                       }
-                                       bSuccess = true;
-                               }
-                               if (bSuccess)
-                               {
-                                       progDlg.Stop();
-                                       SetAndClearProgressInfo((HWND)NULL);
-                                       SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
-                                       int ret = 0;
-                                       if (!bOpenWith)
-                                               ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);
-                                       if ((ret <= HINSTANCE_ERROR)||bOpenWith)
-                                       {
-                                               CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");
-                                               cmd += tempfile.GetWinPathString() + _T(" ");
-                                               CAppUtils::LaunchApplication(cmd, NULL, false);
-                                       }
-                               }
-                       }
-                       break;
-               case ID_BLAME:
-                       {
-                               CBlameDlg dlg;
-                               dlg.EndRev = revSelected;
-                               if (dlg.DoModal() == IDOK)
-                               {
-                                       CBlame blame;
-                                       CString tempfile;
-                                       CString logfile;
-                                       tempfile = blame.BlameToTempFile(m_path, dlg.StartRev, dlg.EndRev, dlg.EndRev, logfile, _T(""), dlg.m_bIncludeMerge, TRUE, TRUE);
-                                       if (!tempfile.IsEmpty())
-                                       {
-                                               if (dlg.m_bTextView)
-                                               {
-                                                       //open the default text editor for the result file
-                                                       CAppUtils::StartTextViewer(tempfile);
-                                               }
-                                               else
-                                               {
-                                                       CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");
-                                                       if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))
-                                                       {
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       else
-                                       {
-                                               CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
-                                       }
-                               }
-                       }
-                       break;
-               case ID_UPDATE:
-                       {
-                               CString sCmd;
-                               CString url = _T("tgit:")+pathURL;
-                               sCmd.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
-                                       (LPCTSTR)m_path.GetWinPath(), (LONG)revSelected);
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);
-                       }
-                       break;
-               case ID_FINDENTRY:
-                       {
-                               m_nSearchIndex = GetSelectionMark();
-                               if (m_nSearchIndex < 0)
-                                       m_nSearchIndex = 0;
-                               if (m_pFindDialog)
-                               {
-                                       break;
-                               }
-                               else
-                               {
-                                       m_pFindDialog = new CFindReplaceDialog();
-                                       m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this);                                                                        
-                               }
-                       }
-                       break;
-               case ID_REPOBROWSE:
-                       {
-                               CString sCmd;
-                               sCmd.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
-                                       (LPCTSTR)pathURL, (LPCTSTR)revSelected.ToString());
-
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);
-                       }
-                       break;
-               case ID_EDITLOG:
-                       {
-                               EditLogMessage(selIndex);
-                       }
-                       break;
-               case ID_EDITAUTHOR:
-                       {
-                               EditAuthor(selEntries);
-                       }
-                       break;
-               case ID_REVPROPS:
-                       {
-                               CEditPropertiesDlg dlg;
-                               dlg.SetProjectProperties(&m_ProjectProperties);
-                               CTGitPathList escapedlist;
-                               dlg.SetPathList(CTGitPathList(CTGitPath(pathURL)));
-                               dlg.SetRevision(revSelected);
-                               dlg.RevProps(true);
-                               dlg.DoModal();
-                       }
-                       break;
-               
-               case ID_EXPORT:
-                       {
-                               CString sCmd;
-                               sCmd.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
-                                       (LPCTSTR)pathURL, (LONG)revSelected);
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);
-                       }
-                       break;
-               case ID_CHECKOUT:
-                       {
-                               CString sCmd;
-                               CString url = _T("tgit:")+pathURL;
-                               sCmd.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),
-                                       (LPCTSTR)url, (LONG)revSelected);
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);
-                       }
-                       break;
-               case ID_VIEWREV:
-                       {
-                               CString url = m_ProjectProperties.sWebViewerRev;
-                               url = GetAbsoluteUrlFromRelativeUrl(url);
-                               url.Replace(_T("%REVISION%"), revSelected.ToString());
-                               if (!url.IsEmpty())
-                                       ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        
-                       }
-                       break;
-               case ID_VIEWPATHREV:
-                       {
-                               CString relurl = pathURL;
-                               CString sRoot = GetRepositoryRoot(CTGitPath(relurl));
-                               relurl = relurl.Mid(sRoot.GetLength());
-                               CString url = m_ProjectProperties.sWebViewerPathRev;
-                               url = GetAbsoluteUrlFromRelativeUrl(url);
-                               url.Replace(_T("%REVISION%"), revSelected.ToString());
-                               url.Replace(_T("%PATH%"), relurl);
-                               if (!url.IsEmpty())
-                                       ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        
-                       }
-                       break;
-#endif
-               
-               } // switch (cmd)
-               theApp.DoWaitCursor(-1);
-//             EnableOKButton();
-       } // if (popup.CreatePopupMenu())
-
-}
-
-bool CGitLogList::IsSelectionContinuous()
-{
-       if ( GetSelectedCount()==1 )
-       {
-               // if only one revision is selected, the selection is of course
-               // continuous
-               return true;
-       }
-
-       POSITION pos = GetFirstSelectedItemPosition();
-       bool bContinuous = (m_arShownList.GetCount() == (INT_PTR)m_logEntries.size());
-       if (bContinuous)
-       {
-               int itemindex = GetNextSelectedItem(pos);
-               while (pos)
-               {
-                       int nextindex = GetNextSelectedItem(pos);
-                       if (nextindex - itemindex > 1)
-                       {
-                               bContinuous = false;
-                               break;
-                       }
-                       itemindex = nextindex;
-               }
-       }
-       return bContinuous;
-}
-
-void CGitLogList::CopySelectionToClipBoard(bool HashOnly)
-{
-
-       CString sClipdata;
-       POSITION pos = GetFirstSelectedItemPosition();
-       if (pos != NULL)
-       {
-               CString sRev;
-               sRev.LoadString(IDS_LOG_REVISION);
-               CString sAuthor;
-               sAuthor.LoadString(IDS_LOG_AUTHOR);
-               CString sDate;
-               sDate.LoadString(IDS_LOG_DATE);
-               CString sMessage;
-               sMessage.LoadString(IDS_LOG_MESSAGE);
-               while (pos)
-               {
-                       CString sLogCopyText;
-                       CString sPaths;
-                       GitRev * pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(GetNextSelectedItem(pos)));
-
-                       if(!HashOnly)
-                       {
-                               //pLogEntry->m_Files
-                               //LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;
-                       
-                               for (int cpPathIndex = 0; cpPathIndex<pLogEntry->m_Files.GetCount(); ++cpPathIndex)
-                               {
-                                       sPaths += ((CTGitPath&)pLogEntry->m_Files[cpPathIndex]).GetActionName() + _T(" : ") + pLogEntry->m_Files[cpPathIndex].GetGitPathString();
-                                       sPaths += _T("\r\n");
-                               }
-                               sPaths.Trim();
-                               sLogCopyText.Format(_T("%s: %s\r\n%s: %s\r\n%s: %s\r\n%s:\r\n%s\r\n----\r\n%s\r\n\r\n"),
-                                       (LPCTSTR)sRev, pLogEntry->m_CommitHash,
-                                       (LPCTSTR)sAuthor, (LPCTSTR)pLogEntry->m_AuthorName,
-                                       (LPCTSTR)sDate, (LPCTSTR)pLogEntry->m_AuthorDate.Format(_T("%Y-%m-%d %H:%M")),
-                                       (LPCTSTR)sMessage, pLogEntry->m_Subject+_T("\r\n")+pLogEntry->m_Body,
-                                       (LPCTSTR)sPaths);
-                               sClipdata +=  sLogCopyText;
-                       }else
-                       {
-                               sClipdata += pLogEntry->m_CommitHash;
-                               break;
-                       }
-
-               }
-               CStringUtils::WriteAsciiStringToClipboard(sClipdata, GetSafeHwnd());
-       }
-
-}
-
-void CGitLogList::DiffSelectedRevWithPrevious()
-{
-#if 0
-       if (m_bThreadRunning)
-               return;
-       UpdateLogInfoLabel();
-       int selIndex = m_LogList.GetSelectionMark();
-       if (selIndex < 0)
-               return;
-       int selCount = m_LogList.GetSelectedCount();
-       if (selCount != 1)
-               return;
-
-       // Find selected entry in the log list
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();
-       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));
-       long rev1 = pLogEntry->Rev;
-       long rev2 = rev1-1;
-       CTGitPath path = m_path;
-
-       // See how many files under the relative root were changed in selected revision
-       int nChanged = 0;
-       LogChangedPath * changed = NULL;
-       for (INT_PTR c = 0; c < pLogEntry->pArChangedPaths->GetCount(); ++c)
-       {
-               LogChangedPath * cpath = pLogEntry->pArChangedPaths->GetAt(c);
-               if (cpath  &&  cpath -> sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0)
-               {
-                       ++nChanged;
-                       changed = cpath;
-               }
-       }
-
-       if (m_path.IsDirectory() && nChanged == 1) 
-       {
-               // We're looking at the log for a directory and only one file under dir was changed in the revision
-               // Do diff on that file instead of whole directory
-               path.AppendPathString(changed->sPath.Mid(m_sRelativeRoot.GetLength()));
-       } 
-
-       m_bCancelled = FALSE;
-       DialogEnableWindow(IDOK, FALSE);
-       SetPromptApp(&theApp);
-       theApp.DoWaitCursor(1);
-
-       if (PromptShown())
-       {
-               GitDiff diff(this, m_hWnd, true);
-               diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-               diff.SetHEADPeg(m_LogRevision);
-               diff.ShowCompare(path, rev2, path, rev1);
-       }
-       else
-       {
-               CAppUtils::StartShowCompare(m_hWnd, path, rev2, path, rev1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
-       }
-
-       theApp.DoWaitCursor(-1);
-       EnableOKButton();
-#endif
-}
-
-void CGitLogList::OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult)
-{
-       LPNMLVFINDITEM pFindInfo = reinterpret_cast<LPNMLVFINDITEM>(pNMHDR);
-       *pResult = -1;
-       
-       if (pFindInfo->lvfi.flags & LVFI_PARAM)
-               return; 
-       if ((pFindInfo->iStart < 0)||(pFindInfo->iStart >= m_arShownList.GetCount()))
-               return;
-       if (pFindInfo->lvfi.psz == 0)
-               return;
-#if 0
-       CString sCmp = pFindInfo->lvfi.psz;
-       CString sRev;   
-       for (int i=pFindInfo->iStart; i<m_arShownList.GetCount(); ++i)
-       {
-               GitRev * pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(i));
-               sRev.Format(_T("%ld"), pLogEntry->Rev);
-               if (pFindInfo->lvfi.flags & LVFI_PARTIAL)
-               {
-                       if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)
-                       {
-                               *pResult = i;
-                               return;
-                       }
-               }
-               else
-               {
-                       if (sCmp.Compare(sRev)==0)
-                       {
-                               *pResult = i;
-                               return;
-                       }
-               }
-       }
-       if (pFindInfo->lvfi.flags & LVFI_WRAP)
-       {
-               for (int i=0; i<pFindInfo->iStart; ++i)
-               {
-                       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(i));
-                       sRev.Format(_T("%ld"), pLogEntry->Rev);
-                       if (pFindInfo->lvfi.flags & LVFI_PARTIAL)
-                       {
-                               if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)
-                               {
-                                       *pResult = i;
-                                       return;
-                               }
-                       }
-                       else
-                       {
-                               if (sCmp.Compare(sRev)==0)
-                               {
-                                       *pResult = i;
-                                       return;
-                               }
-                       }
-               }
-       }
-#endif
-       *pResult = -1;
-}
-
-int CGitLogList::FillGitShortLog()
-{
-       ClearText();
-
-       this->m_logEntries.ClearAll();
-       this->m_logEntries.ParserShortLog();
-
-       //this->m_logEntries.ParserFromLog();
-       SetItemCountEx(this->m_logEntries.size());
-
-       this->m_arShownList.RemoveAll();
-
-       for(int i=0;i<m_logEntries.size();i++)
-               this->m_arShownList.Add(&m_logEntries[i]);
-
-       return 0;
-}
-
-BOOL CGitLogList::PreTranslateMessage(MSG* pMsg)
-{
-       // Skip Ctrl-C when copying text out of the log message or search filter
-       BOOL bSkipAccelerator = ( pMsg->message == WM_KEYDOWN && pMsg->wParam=='C' && (GetFocus()==GetDlgItem(IDC_MSGVIEW) || GetFocus()==GetDlgItem(IDC_SEARCHEDIT) ) && GetKeyState(VK_CONTROL)&0x8000 );
-       if (pMsg->message == WM_KEYDOWN && pMsg->wParam=='\r')
-       {
-               //if (GetFocus()==GetDlgItem(IDC_LOGLIST))
-               {
-                       if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))
-                       {
-                               DiffSelectedRevWithPrevious();
-                               return TRUE;
-                       }
-               }
-#if 0
-               if (GetFocus()==GetDlgItem(IDC_LOGMSG))
-               {
-                       DiffSelectedFile();
-                       return TRUE;
-               }
-#endif
-       }
-
-#if 0
-       if (m_hAccel && !bSkipAccelerator)
-       {
-               int ret = TranslateAccelerator(m_hWnd, m_hAccel, pMsg);
-               if (ret)
-                       return TRUE;
-       }
-       
-#endif
-       //m_tooltips.RelayEvent(pMsg);
-       return __super::PreTranslateMessage(pMsg);
-}
-
-void CGitLogList::OnNMDblclkLoglist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
-{
-       // a double click on an entry in the revision list has happened
-       *pResult = 0;
-
-  if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))
-         DiffSelectedRevWithPrevious();
-}
-
-int CGitLogList::FetchLogAsync(CALLBACK_PROCESS *proc,void * data)
-{
-       m_ProcCallBack=proc;
-       m_ProcData=data;
-
-       InterlockedExchange(&m_bThreadRunning, TRUE);
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);
-       if (AfxBeginThread(LogThreadEntry, this)==NULL)
-       {
-               InterlockedExchange(&m_bThreadRunning, FALSE);
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);
-               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
-               return -1;
-       }
-       return 0;
-}
-
-//this is the thread function which calls the subversion function
-UINT CGitLogList::LogThreadEntry(LPVOID pVoid)
-{
-       return ((CGitLogList*)pVoid)->LogThread();
-}
-
-
-UINT CGitLogList::LogThread()
-{
-
-       if(m_ProcCallBack)
-               m_ProcCallBack(m_ProcData,GITLOG_START);
-
-       InterlockedExchange(&m_bThreadRunning, TRUE);
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);
-
-    //does the user force the cache to refresh (shift or control key down)?
-    bool refresh =    (GetKeyState (VK_CONTROL) < 0) 
-                   || (GetKeyState (VK_SHIFT) < 0);
-
-       //disable the "Get All" button while we're receiving
-       //log messages.
-
-       CString temp;
-       temp.LoadString(IDS_PROGRESSWAIT);
-       ShowText(temp, true);
-
-       FillGitShortLog();
-       
-       
-
-       RedrawItems(0, m_arShownList.GetCount());
-       SetRedraw(false);
-       ResizeAllListCtrlCols();
-       SetRedraw(true);
-
-       if ( m_pStoreSelection )
-       {
-               // Deleting the instance will restore the
-               // selection of the CLogDlg.
-               delete m_pStoreSelection;
-               m_pStoreSelection = NULL;
-       }
-       else
-       {
-               // If no selection has been set then this must be the first time
-               // the revisions are shown. Let's preselect the topmost revision.
-               if ( GetItemCount()>0 )
-               {
-                       SetSelectionMark(0);
-                       SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
-               }
-       }
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);
-
-       int index=0;
-       int updated=0;
-       int percent=0;
-       while(1)
-       {
-               for(int i=0;i<m_logEntries.size();i++)
-               {
-                       if(!m_logEntries.FetchFullInfo(i))
-                       {
-                               updated++;
-                       }
-                       
-                       percent=updated*98/m_logEntries.size() + GITLOG_START+1;
-                       if(percent == GITLOG_END)
-                               percent == GITLOG_END -1;
-                       
-                       if(m_ProcCallBack)
-                               m_ProcCallBack(m_ProcData,percent);
-               }
-               if(updated==m_logEntries.size())
-                       break;
-       }
-
-       //RefreshCursor();
-       // make sure the filter is applied (if any) now, after we refreshed/fetched
-       // the log messages
-
-       
-
-       if(m_ProcCallBack)
-               m_ProcCallBack(m_ProcData,GITLOG_END);
-
-       InterlockedExchange(&m_bThreadRunning, FALSE);
-
-       return 0;
-}
-
-void CGitLogList::Refresh()
-{
-       if(!m_bThreadRunning)
-       {
-               this->SetItemCountEx(0);
-               m_logEntries.clear();
-               InterlockedExchange(&m_bThreadRunning, TRUE);
-               InterlockedExchange(&m_bNoDispUpdates, TRUE);
-               if (AfxBeginThread(LogThreadEntry, this)==NULL)
-               {
-                       InterlockedExchange(&m_bThreadRunning, FALSE);
-                       InterlockedExchange(&m_bNoDispUpdates, FALSE);
-                       CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
-               }
-       }
-}
+// GitLogList.cpp : implementation file\r
+//\r
+/*\r
+       Description: qgit revision list view\r
+\r
+       Author: Marco Costalba (C) 2005-2007\r
+\r
+       Copyright: See COPYING file that comes with this distribution\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
+       ,m_bNoDispUpdates(FALSE)\r
+       , m_bThreadRunning(FALSE)\r
+       , m_bStrictStopped(false)\r
+       , m_pStoreSelection(NULL)\r
+       , m_nSelectedFilter(LOGFILTER_ALL)\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
+       m_wcRev.m_CommitHash=GIT_REV_ZERO;\r
+       m_wcRev.m_Subject=_T("Working Copy");\r
+\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
+       m_bFilterWithRegex = !!CRegDWORD(_T("Software\\TortoiseGit\\UseRegexFilter"), TRUE);\r
+\r
+       g_Git.GetMapHashToFriendName(m_HashMap);\r
+}\r
+\r
+CGitLogList::~CGitLogList()\r
+{\r
+       InterlockedExchange(&m_bNoDispUpdates, TRUE);\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
+       if ( m_pStoreSelection )\r
+       {\r
+               delete m_pStoreSelection;\r
+               m_pStoreSelection = NULL;\r
+       }\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CGitLogList, CHintListCtrl)\r
+       ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawLoglist)\r
+       ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfoLoglist)\r
+       ON_WM_CONTEXTMENU()\r
+       ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclkLoglist)\r
+       ON_NOTIFY_REFLECT(LVN_ODFINDITEM,OnLvnOdfinditemLoglist)\r
+       ON_WM_CREATE()\r
+END_MESSAGE_MAP()\r
+\r
+int CGitLogList:: OnCreate(LPCREATESTRUCT lpCreateStruct)\r
+{\r
+       PreSubclassWindow();\r
+       return CHintListCtrl::OnCreate(lpCreateStruct);\r
+}\r
+\r
+void CGitLogList::PreSubclassWindow()\r
+{\r
+       SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);\r
+       // load the icons for the action columns\r
+       m_Theme.SetWindowTheme(GetSafeHwnd(), L"Explorer", NULL);\r
+       CHintListCtrl::PreSubclassWindow();\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
+                               if (cx < LOGLIST_MESSAGE_MIN)\r
+                               {\r
+                                       cx = LOGLIST_MESSAGE_MIN;\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
+void Refresh()\r
+{\r
+       \r
+}\r
+\r
+BOOL CGitLogList::GetShortName(CString ref, CString &shortname,CString prefix)\r
+{\r
+       if(ref.Left(prefix.GetLength()) ==  prefix)\r
+       {\r
+               shortname = ref.Right(ref.GetLength()-prefix.GetLength());\r
+               return TRUE;\r
+       }\r
+       return FALSE;\r
+}\r
+void CGitLogList::FillBackGround(HDC hdc, int Index,CRect &rect)\r
+{      \r
+//     HBRUSH brush;\r
+       LVITEM   rItem;\r
+       SecureZeroMemory(&rItem, sizeof(LVITEM));\r
+       rItem.mask  = LVIF_STATE;\r
+       rItem.iItem = Index;\r
+       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
+       GetItem(&rItem);\r
+\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, hdc, &rect);\r
+\r
+                       m_Theme.DrawBackground(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(hdc, &rect, brush);\r
+               ::DeleteObject(brush);\r
+               \r
+       }\r
+}\r
+\r
+void CGitLogList::DrawTagBranch(HDC hdc,CRect &rect,INT_PTR index)\r
+{\r
+       GitRev* data = (GitRev*)m_arShownList.GetAt(index);\r
+       CRect rt=rect;\r
+       LVITEM   rItem;\r
+       SecureZeroMemory(&rItem, sizeof(LVITEM));\r
+       rItem.mask  = LVIF_STATE;\r
+       rItem.iItem = index;\r
+       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
+       GetItem(&rItem);\r
+\r
+       for(int i=0;i<m_HashMap[data->m_CommitHash].size();i++)\r
+       {\r
+               CString str;\r
+               str=m_HashMap[data->m_CommitHash][i];\r
+               \r
+               CString shortname;\r
+               HBRUSH brush=0;\r
+               shortname=_T("");\r
+               if(GetShortName(str,shortname,_T("refs/heads/")))\r
+               {\r
+                       brush = ::CreateSolidBrush(RGB(0xff, 0, 0));\r
+               }else if(GetShortName(str,shortname,_T("refs/remotes/")))\r
+               {\r
+                       brush = ::CreateSolidBrush(RGB(0xff, 0xff, 0));\r
+               }\r
+               else if(GetShortName(str,shortname,_T("refs/tags/")))\r
+               {\r
+                       brush = ::CreateSolidBrush(RGB(0, 0, 0xff));\r
+               }\r
+\r
+               if(!shortname.IsEmpty())\r
+               {\r
+                       SIZE size;\r
+                       memset(&size,0,sizeof(SIZE));\r
+                       GetTextExtentPoint32(hdc, shortname,shortname.GetLength(),&size);\r
+               \r
+                       rt.SetRect(rt.left,rt.top,rt.left+size.cx,rt.bottom);\r
+                       rt.right+=4;\r
+                       ::FillRect(hdc, &rt, brush);\r
+                       if (rItem.state & LVIS_SELECTED)\r
+                       {\r
+                               COLORREF   clrOld   = ::SetTextColor(hdc,::GetSysColor(COLOR_HIGHLIGHTTEXT));   \r
+                               ::DrawText(hdc,shortname,shortname.GetLength(),&rt,DT_CENTER);\r
+                               ::SetTextColor(hdc,clrOld);   \r
+                       }else\r
+                       {\r
+                               ::DrawText(hdc,shortname,shortname.GetLength(),&rt,DT_CENTER);\r
+                       }\r
+\r
+                       \r
+                       ::MoveToEx(hdc,rt.left,rt.top,NULL);\r
+                       ::LineTo(hdc,rt.right,rt.top);\r
+                       ::LineTo(hdc,rt.right,rt.bottom);\r
+                       ::LineTo(hdc,rt.left,rt.bottom);\r
+                       ::LineTo(hdc,rt.left,rt.top);\r
+                               \r
+                       rt.left=rt.right+3;\r
+               }\r
+               if(brush)\r
+                       ::DeleteObject(brush);\r
+       }               \r
+       rt.right=rect.right;\r
+\r
+       if (rItem.state & LVIS_SELECTED)\r
+       {\r
+               COLORREF   clrOld   = ::SetTextColor(hdc,::GetSysColor(COLOR_HIGHLIGHTTEXT));   \r
+               ::DrawText(hdc,data->m_Subject,data->m_Subject.GetLength(),&rt,DT_LEFT);\r
+               ::SetTextColor(hdc,clrOld);   \r
+       }else\r
+       {\r
+               ::DrawText(hdc,data->m_Subject,data->m_Subject.GetLength(),&rt,DT_LEFT);\r
+       }\r
+       \r
+}\r
+\r
+void CGitLogList::paintGraphLane(HDC hdc, int laneHeight,int type, int x1, int x2,\r
+                                      const COLORREF& col,int top\r
+                                                                         )  \r
+{\r
+       int h = laneHeight / 2;\r
+       int m = (x1 + x2) / 2;\r
+       int r = (x2 - x1) / 3;\r
+       int d =  2 * r;\r
+\r
+       #define P_CENTER m , h+top\r
+       #define P_0      x2, h+top\r
+       #define P_90     m , 0+top\r
+       #define P_180    x1, h+top\r
+       #define P_270    m , 2 * h+top\r
+       #define R_CENTER m - r, h - r+top, m - r+d, h - r+top+d\r
+\r
+       //static QPen myPen(Qt::black, 2); // fast path here\r
+       CPen pen;\r
+       pen.CreatePen(PS_SOLID,2,col);\r
+       //myPen.setColor(col);\r
+       HPEN oldpen=(HPEN)::SelectObject(hdc,(HPEN)pen);\r
+\r
+       //p->setPen(myPen);\r
+\r
+       // vertical line\r
+       switch (type) {\r
+       case Lanes::ACTIVE:\r
+       case Lanes::NOT_ACTIVE:\r
+       case Lanes::MERGE_FORK:\r
+       case Lanes::MERGE_FORK_R:\r
+       case Lanes::MERGE_FORK_L:\r
+       case Lanes::JOIN:\r
+       case Lanes::JOIN_R:\r
+       case Lanes::JOIN_L:\r
+               DrawLine(hdc,P_90,P_270);\r
+               //p->drawLine(P_90, P_270);\r
+               break;\r
+       case Lanes::HEAD:\r
+       case Lanes::HEAD_R:\r
+       case Lanes::HEAD_L:\r
+       case Lanes::BRANCH:\r
+               DrawLine(hdc,P_CENTER,P_270);\r
+               //p->drawLine(P_CENTER, P_270);\r
+               break;\r
+       case Lanes::TAIL:\r
+       case Lanes::TAIL_R:\r
+       case Lanes::TAIL_L:\r
+       case Lanes::INITIAL:\r
+       case Lanes::BOUNDARY:\r
+       case Lanes::BOUNDARY_C:\r
+       case Lanes::BOUNDARY_R:\r
+       case Lanes::BOUNDARY_L:\r
+               DrawLine(hdc,P_90, P_CENTER);\r
+               //p->drawLine(P_90, P_CENTER);\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+\r
+       // horizontal line\r
+       switch (type) {\r
+       case Lanes::MERGE_FORK:\r
+       case Lanes::JOIN:\r
+       case Lanes::HEAD:\r
+       case Lanes::TAIL:\r
+       case Lanes::CROSS:\r
+       case Lanes::CROSS_EMPTY:\r
+       case Lanes::BOUNDARY_C:\r
+               DrawLine(hdc,P_180,P_0);\r
+               //p->drawLine(P_180, P_0);\r
+               break;\r
+       case Lanes::MERGE_FORK_R:\r
+       case Lanes::JOIN_R:\r
+       case Lanes::HEAD_R:\r
+       case Lanes::TAIL_R:\r
+       case Lanes::BOUNDARY_R:\r
+               DrawLine(hdc,P_180,P_CENTER);\r
+               //p->drawLine(P_180, P_CENTER);\r
+               break;\r
+       case Lanes::MERGE_FORK_L:\r
+       case Lanes::JOIN_L:\r
+       case Lanes::HEAD_L:\r
+       case Lanes::TAIL_L:\r
+       case Lanes::BOUNDARY_L:\r
+               DrawLine(hdc,P_CENTER,P_0);\r
+               //p->drawLine(P_CENTER, P_0);\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+\r
+       CBrush brush;\r
+       brush.CreateSolidBrush(col);\r
+       HBRUSH oldbrush=(HBRUSH)::SelectObject(hdc,(HBRUSH)brush);\r
+       // center symbol, e.g. rect or ellipse\r
+       switch (type) {\r
+       case Lanes::ACTIVE:\r
+       case Lanes::INITIAL:\r
+       case Lanes::BRANCH:\r
+\r
+               //p->setPen(Qt::NoPen);\r
+               //p->setBrush(col);\r
+               ::Ellipse(hdc, R_CENTER);\r
+               //p->drawEllipse(R_CENTER);\r
+               break;\r
+       case Lanes::MERGE_FORK:\r
+       case Lanes::MERGE_FORK_R:\r
+       case Lanes::MERGE_FORK_L:\r
+               //p->setPen(Qt::NoPen);\r
+               //p->setBrush(col);\r
+               //p->drawRect(R_CENTER);\r
+               Rectangle(hdc,R_CENTER);\r
+               break;\r
+       case Lanes::UNAPPLIED:\r
+               // Red minus sign\r
+               //p->setPen(Qt::NoPen);\r
+               //p->setBrush(Qt::red);\r
+               //p->drawRect(m - r, h - 1, d, 2);\r
+               ::Rectangle(hdc,m-r,h-1,d,2);\r
+               break;\r
+       case Lanes::APPLIED:\r
+               // Green plus sign\r
+               //p->setPen(Qt::NoPen);\r
+               //p->setBrush(DARK_GREEN);\r
+               //p->drawRect(m - r, h - 1, d, 2);\r
+               //p->drawRect(m - 1, h - r, 2, d);\r
+               ::Rectangle(hdc,m-r,h-1,d,2);\r
+               ::Rectangle(hdc,m-1,h-r,2,d);\r
+               break;\r
+       case Lanes::BOUNDARY:\r
+               //p->setBrush(back);\r
+               //p->drawEllipse(R_CENTER);\r
+               ::Ellipse(hdc, R_CENTER);\r
+               break;\r
+       case Lanes::BOUNDARY_C:\r
+       case Lanes::BOUNDARY_R:\r
+       case Lanes::BOUNDARY_L:\r
+               //p->setBrush(back);\r
+               //p->drawRect(R_CENTER);\r
+               ::Rectangle(hdc,R_CENTER);\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+\r
+       ::SelectObject(hdc,oldpen);\r
+       ::SelectObject(hdc,oldbrush);\r
+       #undef P_CENTER\r
+       #undef P_0\r
+       #undef P_90\r
+       #undef P_180\r
+       #undef P_270\r
+       #undef R_CENTER\r
+}\r
+\r
+void CGitLogList::DrawGraph(HDC hdc,CRect &rect,INT_PTR index)\r
+{\r
+       //todo unfinished\r
+       return;\r
+       GitRev* data = (GitRev*)m_arShownList.GetAt(index);\r
+       CRect rt=rect;\r
+       LVITEM   rItem;\r
+       SecureZeroMemory(&rItem, sizeof(LVITEM));\r
+       rItem.mask  = LVIF_STATE;\r
+       rItem.iItem = index;\r
+       rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
+       GetItem(&rItem);\r
+\r
+       static const COLORREF colors[Lanes::COLORS_NUM] = { RGB(0,0,0), RGB(0xFF,0,0), RGB(0,0x1F,0),\r
+                                                  RGB(0,0,0xFF), RGB(128,128,128), RGB(128,128,0),\r
+                                                  RGB(0,128,128), RGB(128,0,128) };\r
+\r
+\r
+//     p->translate(QPoint(opt.rect.left(), opt.rect.top()));\r
+\r
+\r
+\r
+       if (data->m_Lanes.size() == 0)\r
+               m_logEntries.setLane(data->m_CommitHash);\r
+\r
+       std::vector<int>& lanes=data->m_Lanes;\r
+       UINT laneNum = lanes.size();\r
+       UINT mergeLane = 0;\r
+       for (UINT i = 0; i < laneNum; i++)\r
+               if (Lanes::isMerge(lanes[i])) {\r
+                       mergeLane = i;\r
+                       break;\r
+               }\r
+\r
+       int x1 = 0, x2 = 0;\r
+       int maxWidth = rect.Width();\r
+       int lw = 3 * rect.Height() / 4; //laneWidth() \r
+       for (UINT i = 0; i < laneNum && x2 < maxWidth; i++) {\r
+\r
+               x1 = x2;\r
+               x2 += lw;\r
+\r
+               int ln = lanes[i];\r
+               if (ln == Lanes::EMPTY)\r
+                       continue;\r
+\r
+               UINT col = (  Lanes:: isHead(ln) ||Lanes:: isTail(ln) || Lanes::isJoin(ln)\r
+                           || ln ==Lanes:: CROSS_EMPTY) ? mergeLane : i;\r
+\r
+               if (ln == Lanes::CROSS) {\r
+                       paintGraphLane(hdc, rect.Height(),Lanes::NOT_ACTIVE, x1, x2, colors[col % Lanes::COLORS_NUM],rect.top);\r
+                       paintGraphLane(hdc, rect.Height(),Lanes::CROSS, x1, x2, colors[mergeLane % Lanes::COLORS_NUM],rect.top);\r
+               } else\r
+                       paintGraphLane(hdc, rect.Height(),ln, x1, x2, colors[col % Lanes::COLORS_NUM],rect.top);\r
+       }\r
+\r
+       TRACE(_T("index %d %d\r\n"),index,data->m_Lanes.size());\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
+\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
+\r
+                       if (pLVCD->iSubItem == LOGLIST_GRAPH)\r
+                       {\r
+                               if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+                               {\r
+                                       CRect rect;\r
+                                       GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+                                       \r
+                                       FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);\r
+                                       DrawGraph(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);\r
+\r
+                                       *pResult = CDRF_SKIPDEFAULT;\r
+                                       return;\r
+                               \r
+                               }\r
+                       }\r
+\r
+                       if (pLVCD->iSubItem == LOGLIST_MESSAGE)\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->m_IsFull)\r
+                                       {\r
+                                               if(data->SafeFetchFullInfo(&g_Git))\r
+                                                       this->Invalidate();\r
+                                               TRACE(_T("Update ... %d\r\n"),pLVCD->nmcd.dwItemSpec);\r
+                                       }\r
+\r
+                                       if(m_HashMap[data->m_CommitHash].size()!=0)\r
+                                       {\r
+                                               CRect rect;\r
+\r
+                                               GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+                                       \r
+                                               FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);\r
+                                               DrawTagBranch(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);\r
+\r
+                                               *pResult = CDRF_SKIPDEFAULT;\r
+                                               return;\r
+\r
+                                       }\r
+                               }\r
+                       }\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
+                               CRect rect;\r
+                               GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+                               // Get the selected state of the\r
+                               // item being drawn.                                                    \r
+\r
+                               // Fill the background\r
+                               FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);\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 || 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
+           \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
+                       //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
+                       \r
+                       popup.AppendMenuIcon(ID_SWITCHTOREV, _T("Switch/Checkout to this") , IDI_SWITCH);\r
+                       popup.AppendMenuIcon(ID_CREATE_BRANCH, _T("Create Branch at this version") , IDI_COPY);\r
+                       popup.AppendMenuIcon(ID_CREATE_TAG, _T("Create Tag at this version"), IDI_COPY);\r
+                       popup.AppendMenuIcon(ID_CHERRY_PICK, _T("Cherry Pick this version"), IDI_EXPORT);\r
+                       popup.AppendMenuIcon(ID_EXPORT, _T("Export this version"), IDI_EXPORT);\r
+                       \r
+\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
+\r
+               \r
+               if (GetSelectedCount() == 1)\r
+               {\r
+                       popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash"));\r
+               }\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.exe 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.exe 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
+\r
+               case ID_COMPARE:\r
+                       {\r
+                               GitRev * r1 = &m_wcRev;\r
+                               GitRev * r2 = pSelLogEntry;\r
+                               CFileDiffDlg dlg;\r
+                               dlg.SetDiff(NULL,*r1,*r2);\r
+                               dlg.DoModal();\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
+\r
+               case ID_COMPAREWITHPREVIOUS:\r
+                       {\r
+\r
+                               CFileDiffDlg dlg;\r
+                               \r
+                               if(pSelLogEntry->m_ParentHash.size()>0)\r
+                               //if(m_logEntries.m_HashMap[pSelLogEntry->m_ParentHash[0]]>=0)\r
+                               {\r
+                                       dlg.SetDiff(NULL,pSelLogEntry->m_CommitHash,pSelLogEntry->m_ParentHash[0]);\r
+                                       dlg.DoModal();\r
+                               }else\r
+                               {\r
+                                       CMessageBox::Show(NULL,_T("No previous version"),_T("TortoiseGit"),MB_OK);      \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_COPYCLIPBOARD:\r
+                       {\r
+                               CopySelectionToClipBoard();\r
+                       }\r
+                       break;\r
+               case ID_COPYHASH:\r
+                       {\r
+                               CopySelectionToClipBoard(TRUE);\r
+                       }\r
+                       break;\r
+               case ID_EXPORT:\r
+                       CAppUtils::Export(&pSelLogEntry->m_CommitHash);\r
+                       break;\r
+               case ID_CREATE_BRANCH:\r
+                       CAppUtils::CreateBranchTag(FALSE,&pSelLogEntry->m_CommitHash);\r
+                       m_HashMap.clear();\r
+                       g_Git.GetMapHashToFriendName(m_HashMap);\r
+                       Invalidate();                   \r
+                       break;\r
+               case ID_CREATE_TAG:\r
+                       CAppUtils::CreateBranchTag(TRUE,&pSelLogEntry->m_CommitHash);\r
+                       m_HashMap.clear();\r
+                       g_Git.GetMapHashToFriendName(m_HashMap);\r
+                       Invalidate();\r
+                       break;\r
+               case ID_SWITCHTOREV:\r
+                       CAppUtils::Switch(&pSelLogEntry->m_CommitHash);\r
+                       break;\r
+\r
+               default:\r
+                       //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);\r
+                       break;\r
+#if 0\r
+       \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
+       \r
+\r
+       \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
+               \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
+               \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
+               \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(bool HashOnly)\r
+{\r
+\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
+                       GitRev * pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(GetNextSelectedItem(pos)));\r
+\r
+                       if(!HashOnly)\r
+                       {\r
+                               //pLogEntry->m_Files\r
+                               //LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;\r
+                       \r
+                               for (int cpPathIndex = 0; cpPathIndex<pLogEntry->m_Files.GetCount(); ++cpPathIndex)\r
+                               {\r
+                                       sPaths += ((CTGitPath&)pLogEntry->m_Files[cpPathIndex]).GetActionName() + _T(" : ") + pLogEntry->m_Files[cpPathIndex].GetGitPathString();\r
+                                       sPaths += _T("\r\n");\r
+                               }\r
+                               sPaths.Trim();\r
+                               sLogCopyText.Format(_T("%s: %s\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->m_CommitHash,\r
+                                       (LPCTSTR)sAuthor, (LPCTSTR)pLogEntry->m_AuthorName,\r
+                                       (LPCTSTR)sDate, (LPCTSTR)pLogEntry->m_AuthorDate.Format(_T("%Y-%m-%d %H:%M")),\r
+                                       (LPCTSTR)sMessage, pLogEntry->m_Subject+_T("\r\n")+pLogEntry->m_Body,\r
+                                       (LPCTSTR)sPaths);\r
+                               sClipdata +=  sLogCopyText;\r
+                       }else\r
+                       {\r
+                               sClipdata += pLogEntry->m_CommitHash;\r
+                               break;\r
+                       }\r
+\r
+               }\r
+               CStringUtils::WriteAsciiStringToClipboard(sClipdata, GetSafeHwnd());\r
+       }\r
+\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::FillGitShortLog()\r
+{\r
+       ClearText();\r
+\r
+       this->m_logEntries.ClearAll();\r
+       this->m_logEntries.ParserShortLog();\r
+\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
+}\r
+\r
+int CGitLogList::FetchLogAsync(CALLBACK_PROCESS *proc,void * data)\r
+{\r
+       m_ProcCallBack=proc;\r
+       m_ProcData=data;\r
+\r
+       InterlockedExchange(&m_bThreadRunning, TRUE);\r
+       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+       if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
+       {\r
+               InterlockedExchange(&m_bThreadRunning, FALSE);\r
+               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
+               return -1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+//this is the thread function which calls the subversion function\r
+UINT CGitLogList::LogThreadEntry(LPVOID pVoid)\r
+{\r
+       return ((CGitLogList*)pVoid)->LogThread();\r
+}\r
+\r
+\r
+UINT CGitLogList::LogThread()\r
+{\r
+\r
+       if(m_ProcCallBack)\r
+               m_ProcCallBack(m_ProcData,GITLOG_START);\r
+\r
+       InterlockedExchange(&m_bThreadRunning, TRUE);\r
+       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+\r
+    //does the user force the cache to refresh (shift or control key down)?\r
+    bool refresh =    (GetKeyState (VK_CONTROL) < 0) \r
+                   || (GetKeyState (VK_SHIFT) < 0);\r
+\r
+       //disable the "Get All" button while we're receiving\r
+       //log messages.\r
+\r
+       CString temp;\r
+       temp.LoadString(IDS_PROGRESSWAIT);\r
+       ShowText(temp, true);\r
+\r
+       FillGitShortLog();\r
+       \r
+       \r
+\r
+       RedrawItems(0, m_arShownList.GetCount());\r
+       SetRedraw(false);\r
+       ResizeAllListCtrlCols();\r
+       SetRedraw(true);\r
+\r
+       if ( m_pStoreSelection )\r
+       {\r
+               // Deleting the instance will restore the\r
+               // selection of the CLogDlg.\r
+               delete m_pStoreSelection;\r
+               m_pStoreSelection = NULL;\r
+       }\r
+       else\r
+       {\r
+               // If no selection has been set then this must be the first time\r
+               // the revisions are shown. Let's preselect the topmost revision.\r
+               if ( GetItemCount()>0 )\r
+               {\r
+                       SetSelectionMark(0);\r
+                       SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\r
+               }\r
+       }\r
+       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+\r
+       int index=0;\r
+       int updated=0;\r
+       int percent=0;\r
+       while(1)\r
+       {\r
+               for(int i=0;i<m_logEntries.size();i++)\r
+               {\r
+                       if(!m_logEntries.FetchFullInfo(i))\r
+                       {\r
+                               updated++;\r
+                       }\r
+                       \r
+                       percent=updated*98/m_logEntries.size() + GITLOG_START+1;\r
+                       if(percent == GITLOG_END)\r
+                               percent == GITLOG_END -1;\r
+                       \r
+                       if(m_ProcCallBack)\r
+                               m_ProcCallBack(m_ProcData,percent);\r
+               }\r
+               if(updated==m_logEntries.size())\r
+                       break;\r
+       }\r
+\r
+       //RefreshCursor();\r
+       // make sure the filter is applied (if any) now, after we refreshed/fetched\r
+       // the log messages\r
+\r
+       \r
+\r
+       if(m_ProcCallBack)\r
+               m_ProcCallBack(m_ProcData,GITLOG_END);\r
+\r
+       InterlockedExchange(&m_bThreadRunning, FALSE);\r
+\r
+       return 0;\r
+}\r
+\r
+void CGitLogList::Refresh()\r
+{\r
+       if(!m_bThreadRunning)\r
+       {\r
+               this->SetItemCountEx(0);\r
+               m_logEntries.clear();\r
+               InterlockedExchange(&m_bThreadRunning, TRUE);\r
+               InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+               if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
+               {\r
+                       InterlockedExchange(&m_bThreadRunning, FALSE);\r
+                       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+                       CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
+               }\r
+       }\r
+}\r
+bool CGitLogList::ValidateRegexp(LPCTSTR regexp_str, tr1::wregex& pat, bool bMatchCase /* = false */)\r
+{\r
+       try\r
+       {\r
+               tr1::regex_constants::syntax_option_type type = tr1::regex_constants::ECMAScript;\r
+               if (!bMatchCase)\r
+                       type |= tr1::regex_constants::icase;\r
+               pat = tr1::wregex(regexp_str, type);\r
+               return true;\r
+       }\r
+       catch (exception) {}\r
+       return false;\r
+}\r
+\r
+void CGitLogList::RecalculateShownList(CPtrArray * pShownlist)\r
+{\r
+\r
+       pShownlist->RemoveAll();\r
+       tr1::wregex pat;//(_T("Remove"), tr1::regex_constants::icase);\r
+       bool bRegex = false;\r
+       if (m_bFilterWithRegex)\r
+               bRegex = ValidateRegexp(m_sFilterText, pat, false);\r
+\r
+       tr1::regex_constants::match_flag_type flags = tr1::regex_constants::match_any;\r
+       CString sRev;\r
+       for (DWORD i=0; i<m_logEntries.size(); ++i)\r
+       {\r
+               if ((bRegex)&&(m_bFilterWithRegex))\r
+               {\r
+#if 0\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_BUGID))\r
+                       {\r
+                               ATLTRACE(_T("bugID = \"%s\"\n"), (LPCTSTR)m_logEntries[i]->sBugIDs);\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries[i]->sBugIDs), pat, flags)&&IsEntryInDateRange(i))\r
+                               {\r
+                                       pShownlist->Add(m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+#endif\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
+                       {\r
+                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries[i].m_Subject);\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_Subject), pat, flags)&&IsEntryInDateRange(i))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+\r
+                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries[i].m_Body);\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_Body), pat, flags)&&IsEntryInDateRange(i))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+#if 0\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_PATHS))\r
+                       {\r
+                               LogChangedPathArray * cpatharray = m_logEntries[i]->pArChangedPaths;\r
+\r
+                               bool bGoing = true;\r
+                               for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount() && bGoing; ++cpPathIndex)\r
+                               {\r
+                                       LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
+                                       if (regex_search(wstring((LPCTSTR)cpath->sCopyFromPath), pat, flags)&&IsEntryInDateRange(i))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                                       if (regex_search(wstring((LPCTSTR)cpath->sPath), pat, flags)&&IsEntryInDateRange(i))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                                       if (regex_search(wstring((LPCTSTR)cpath->GetAction()), pat, flags)&&IsEntryInDateRange(i))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                               if (!bGoing)\r
+                                       continue;\r
+                       }\r
+#endif\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
+                       {\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_AuthorName), pat, flags)&&IsEntryInDateRange(i))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
+                       {\r
+                               sRev.Format(_T("%ld"), m_logEntries[i].m_CommitHash);\r
+                               if (regex_search(wstring((LPCTSTR)sRev), pat, flags)&&IsEntryInDateRange(i))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+               } // if (bRegex)\r
+               else\r
+               {\r
+                       CString find = m_sFilterText;\r
+                       find.MakeLower();\r
+#if 0\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_BUGID))\r
+                       {\r
+                               CString sBugIDs = m_logEntries[i]->sBugIDs;\r
+\r
+                               sBugIDs = sBugIDs.MakeLower();\r
+                               if ((sBugIDs.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
+                               {\r
+                                       pShownlist->Add(m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+#endif\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
+                       {\r
+                               CString msg = m_logEntries[i].m_Subject;\r
+\r
+                               msg = msg.MakeLower();\r
+                               if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                               msg = m_logEntries[i].m_Body;\r
+\r
+                               msg = msg.MakeLower();\r
+                               if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+#if 0\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_PATHS))\r
+                       {\r
+                               LogChangedPathArray * cpatharray = m_logEntries[i]->pArChangedPaths;\r
+\r
+                               bool bGoing = true;\r
+                               for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount() && bGoing; ++cpPathIndex)\r
+                               {\r
+                                       LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
+                                       CString path = cpath->sCopyFromPath;\r
+                                       path.MakeLower();\r
+                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                                       path = cpath->sPath;\r
+                                       path.MakeLower();\r
+                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                                       path = cpath->GetAction();\r
+                                       path.MakeLower();\r
+                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
+                                       {\r
+                                               pShownlist->Add(m_logEntries[i]);\r
+                                               bGoing = false;\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                       }\r
+#endif\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
+                       {\r
+                               CString msg = m_logEntries[i].m_AuthorName;\r
+                               msg = msg.MakeLower();\r
+                               if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
+                       {\r
+                               sRev.Format(_T("%ld"), m_logEntries[i].m_CommitHash);\r
+                               if ((sRev.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
+                               {\r
+                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       continue;\r
+                               }\r
+                       }\r
+               } // else (from if (bRegex))    \r
+       } // for (DWORD i=0; i<m_logEntries.size(); ++i) \r
+\r
+}\r
+\r
+BOOL CGitLogList::IsEntryInDateRange(int i)\r
+{\r
+#if 0\r
+       __time64_t time = m_logEntries[i]->tmDate;\r
+       if ((time >= m_tFrom)&&(time <= m_tTo))\r
+               return TRUE;\r
+\r
+       return FALSE;\r
+\r
+#endif;\r
+       return TRUE;\r
+}
\ No newline at end of file
index d5cd33d..6b92589 100644 (file)
@@ -46,6 +46,14 @@ enum LISTITEMSTATES_MINE {
 #define GITLOG_START_ALL 1\r
 #define GITLOG_END   100\r
 \r
+#define LOGFILTER_ALL      1\r
+#define LOGFILTER_MESSAGES 2\r
+#define LOGFILTER_PATHS    3\r
+#define LOGFILTER_AUTHORS  4\r
+#define LOGFILTER_REVS    5\r
+#define LOGFILTER_REGEX           6\r
+#define LOGFILTER_BUGID    7\r
+\r
 typedef void CALLBACK_PROCESS(void * data, int progress);\r
 \r
 class CGitLogList : public CHintListCtrl\r
@@ -127,6 +135,9 @@ public:
        int FetchLogAsync(CALLBACK_PROCESS *proc=NULL, void * data=NULL);\r
        CPtrArray                       m_arShownList;\r
        void Refresh();\r
+       void RecalculateShownList(CPtrArray * pShownlist);\r
+\r
+       int                                     m_nSelectedFilter;\r
 \r
 protected:\r
        DECLARE_MESSAGE_MAP()\r
@@ -149,7 +160,11 @@ protected:
                                       const COLORREF& col,int top) ; \r
        void DrawLine(HDC hdc, int x1, int y1, int x2, int y2){::MoveToEx(hdc,x1,y1,NULL);::LineTo(hdc,x2,y2);}\r
 \r
+       bool ValidateRegexp(LPCTSTR regexp_str, tr1::wregex& pat, bool bMatchCase = false );\r
+       BOOL IsEntryInDateRange(int i);\r
 \r
+       bool                            m_bFilterWithRegex;\r
+       CString                         m_sFilterText;\r
        \r
        CXPTheme                        m_Theme;\r
        BOOL                            m_bVista;\r
index fc5c6b7..758d7b6 100644 (file)
@@ -25,7 +25,7 @@
 #include "ProgressDlg.h"\r
 //#include "RepositoryBrowser.h"\r
 //#include "CopyDlg.h"\r
-//#include "StatGraphDlg.h"\r
+#include "StatGraphDlg.h"\r
 #include "Logdlg.h"\r
 #include "MessageBox.h"\r
 #include "Registry.h"\r
@@ -61,7 +61,6 @@ CLogDlg::CLogDlg(CWnd* pParent /*=NULL*/)
        , m_logcounter(0)\r
        , m_nSearchIndex(0)\r
        , m_wParam(0)\r
-       , m_nSelectedFilter(LOGFILTER_ALL)\r
        , m_currentChangedArray(NULL)\r
        , m_nSortColumn(0)\r
        , m_bShowedAll(false)\r
@@ -390,6 +389,7 @@ void CLogDlg::LogRunStatus(int cur)
                DialogEnableWindow(IDC_INCLUDEMERGE, FALSE);\r
                DialogEnableWindow(IDC_STATBUTTON, FALSE);\r
                DialogEnableWindow(IDC_REFRESH, FALSE);\r
+               DialogEnableWindow(IDC_HIDEPATHS,FALSE);\r
        }\r
 \r
        if( cur == GITLOG_END)\r
@@ -398,8 +398,8 @@ void CLogDlg::LogRunStatus(int cur)
                if (!m_bShowedAll)\r
                        DialogEnableWindow(IDC_NEXTHUNDRED, TRUE);\r
 \r
-               DialogEnableWindow(IDC_CHECK_STOPONCOPY, TRUE);\r
-               DialogEnableWindow(IDC_INCLUDEMERGE, TRUE);\r
+               //DialogEnableWindow(IDC_CHECK_STOPONCOPY, TRUE);\r
+               //DialogEnableWindow(IDC_INCLUDEMERGE, TRUE);\r
                DialogEnableWindow(IDC_STATBUTTON, TRUE);\r
                DialogEnableWindow(IDC_REFRESH, TRUE);\r
 \r
@@ -1872,30 +1872,30 @@ void CLogDlg::OnEnLinkMsgview(NMHDR *pNMHDR, LRESULT *pResult)
 \r
 void CLogDlg::OnBnClickedStatbutton()\r
 {\r
-#if 0\r
-       if (m_bThreadRunning)\r
+\r
+       if (this->IsThreadRunning())\r
                return;\r
-       if (m_arShownList.IsEmpty())\r
+       if (m_LogList.m_arShownList.IsEmpty())\r
                return;         // nothing is shown, so no statistics.\r
        // the statistics dialog expects the log entries to be sorted by date\r
        SortByColumn(3, false);\r
        CPtrArray shownlist;\r
-       RecalculateShownList(&shownlist);\r
+       m_LogList.RecalculateShownList(&shownlist);\r
        // create arrays which are aware of the current filter\r
        CStringArray m_arAuthorsFiltered;\r
        CDWordArray m_arDatesFiltered;\r
        CDWordArray m_arFileChangesFiltered;\r
        for (INT_PTR i=0; i<shownlist.GetCount(); ++i)\r
        {\r
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(shownlist.GetAt(i));\r
-               CString strAuthor = pLogEntry->sAuthor;\r
+               GitRev* pLogEntry = reinterpret_cast<GitRev*>(shownlist.GetAt(i));\r
+               CString strAuthor = pLogEntry->m_AuthorName;\r
                if ( strAuthor.IsEmpty() )\r
                {\r
                        strAuthor.LoadString(IDS_STATGRAPH_EMPTYAUTHOR);\r
                }\r
                m_arAuthorsFiltered.Add(strAuthor);\r
-               m_arDatesFiltered.Add(static_cast<DWORD>(pLogEntry->tmDate));\r
-               m_arFileChangesFiltered.Add(pLogEntry->dwFileChanges);\r
+               m_arDatesFiltered.Add(pLogEntry->m_AuthorDate.GetTime());\r
+               m_arFileChangesFiltered.Add(pLogEntry->m_Files.GetCount());\r
        }\r
        CStatGraphDlg dlg;\r
        dlg.m_parAuthors = &m_arAuthorsFiltered;\r
@@ -1906,7 +1906,7 @@ void CLogDlg::OnBnClickedStatbutton()
        // restore the previous sorting\r
        SortByColumn(m_nSortColumn, m_bAscending);\r
        OnTimer(LOGFILTER_TIMER);\r
-#endif\r
+\r
 }\r
 \r
 #if 0\r
@@ -2268,7 +2268,7 @@ LRESULT CLogDlg::OnClickedInfoIcon(WPARAM /*wParam*/, LPARAM lParam)
        CPoint point;\r
        CString temp;\r
        point = CPoint(rect->left, rect->bottom);\r
-#define LOGMENUFLAGS(x) (MF_STRING | MF_ENABLED | (m_nSelectedFilter == x ? MF_CHECKED : MF_UNCHECKED))\r
+#define LOGMENUFLAGS(x) (MF_STRING | MF_ENABLED | (m_LogList.m_nSelectedFilter == x ? MF_CHECKED : MF_UNCHECKED))\r
        CMenu popup;\r
        if (popup.CreatePopupMenu())\r
        {\r
@@ -2307,7 +2307,7 @@ LRESULT CLogDlg::OnClickedInfoIcon(WPARAM /*wParam*/, LPARAM lParam)
                        }\r
                        else\r
                        {\r
-                               m_nSelectedFilter = selection;\r
+                               m_LogList.m_nSelectedFilter = selection;\r
                                SetFilterCueText();\r
                        }\r
                        SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
@@ -2361,7 +2361,7 @@ LRESULT CLogDlg::OnClickedCancelFilter(WPARAM /*wParam*/, LPARAM /*lParam*/)
 void CLogDlg::SetFilterCueText()\r
 {\r
        CString temp;\r
-       switch (m_nSelectedFilter)\r
+       switch (m_LogList.m_nSelectedFilter)\r
        {\r
        case LOGFILTER_ALL:\r
                temp.LoadString(IDS_LOG_FILTER_ALL);\r
@@ -2584,170 +2584,6 @@ bool CLogDlg::Validate(LPCTSTR string)
        return ValidateRegexp(string, pat, false);\r
 }\r
 \r
-void CLogDlg::RecalculateShownList(CPtrArray * pShownlist)\r
-{\r
-#if 0\r
-       pShownlist->RemoveAll();\r
-       tr1::wregex pat;//(_T("Remove"), tr1::regex_constants::icase);\r
-       bool bRegex = false;\r
-       if (m_bFilterWithRegex)\r
-               bRegex = ValidateRegexp(m_sFilterText, pat, false);\r
-\r
-       tr1::regex_constants::match_flag_type flags = tr1::regex_constants::match_any;\r
-       CString sRev;\r
-       for (DWORD i=0; i<m_logEntries.size(); ++i)\r
-       {\r
-               if ((bRegex)&&(m_bFilterWithRegex))\r
-               {\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_BUGID))\r
-                       {\r
-                               ATLTRACE(_T("bugID = \"%s\"\n"), (LPCTSTR)m_logEntries[i]->sBugIDs);\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i]->sBugIDs), pat, flags)&&IsEntryInDateRange(i))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
-                       {\r
-                               ATLTRACE(_T("messge = \"%s\"\n"), (LPCTSTR)m_logEntries[i]->sMessage);\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i]->sMessage), pat, flags)&&IsEntryInDateRange(i))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_PATHS))\r
-                       {\r
-                               LogChangedPathArray * cpatharray = m_logEntries[i]->pArChangedPaths;\r
-\r
-                               bool bGoing = true;\r
-                               for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount() && bGoing; ++cpPathIndex)\r
-                               {\r
-                                       LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
-                                       if (regex_search(wstring((LPCTSTR)cpath->sCopyFromPath), pat, flags)&&IsEntryInDateRange(i))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                                       if (regex_search(wstring((LPCTSTR)cpath->sPath), pat, flags)&&IsEntryInDateRange(i))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                                       if (regex_search(wstring((LPCTSTR)cpath->GetAction()), pat, flags)&&IsEntryInDateRange(i))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                               }\r
-                               if (!bGoing)\r
-                                       continue;\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
-                       {\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i]->sAuthor), pat, flags)&&IsEntryInDateRange(i))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
-                       {\r
-                               sRev.Format(_T("%ld"), m_logEntries[i]->Rev);\r
-                               if (regex_search(wstring((LPCTSTR)sRev), pat, flags)&&IsEntryInDateRange(i))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-               } // if (bRegex)\r
-               else\r
-               {\r
-                       CString find = m_sFilterText;\r
-                       find.MakeLower();\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_BUGID))\r
-                       {\r
-                               CString sBugIDs = m_logEntries[i]->sBugIDs;\r
-\r
-                               sBugIDs = sBugIDs.MakeLower();\r
-                               if ((sBugIDs.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
-                       {\r
-                               CString msg = m_logEntries[i]->sMessage;\r
-\r
-                               msg = msg.MakeLower();\r
-                               if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_PATHS))\r
-                       {\r
-                               LogChangedPathArray * cpatharray = m_logEntries[i]->pArChangedPaths;\r
-\r
-                               bool bGoing = true;\r
-                               for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount() && bGoing; ++cpPathIndex)\r
-                               {\r
-                                       LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
-                                       CString path = cpath->sCopyFromPath;\r
-                                       path.MakeLower();\r
-                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                                       path = cpath->sPath;\r
-                                       path.MakeLower();\r
-                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                                       path = cpath->GetAction();\r
-                                       path.MakeLower();\r
-                                       if ((path.Find(find)>=0)&&(IsEntryInDateRange(i)))\r
-                                       {\r
-                                               pShownlist->Add(m_logEntries[i]);\r
-                                               bGoing = false;\r
-                                               continue;\r
-                                       }\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
-                       {\r
-                               CString msg = m_logEntries[i]->sAuthor;\r
-                               msg = msg.MakeLower();\r
-                               if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
-                       {\r
-                               sRev.Format(_T("%ld"), m_logEntries[i]->Rev);\r
-                               if ((sRev.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
-                               {\r
-                                       pShownlist->Add(m_logEntries[i]);\r
-                                       continue;\r
-                               }\r
-                       }\r
-               } // else (from if (bRegex))    \r
-       } // for (DWORD i=0; i<m_logEntries.size(); ++i) \r
-#endif\r
-}\r
 \r
 void CLogDlg::OnTimer(UINT_PTR nIDEvent)\r
 {\r
@@ -2844,16 +2680,7 @@ void CLogDlg::OnDtnDatetimechangeDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult)
        *pResult = 0;\r
 }\r
 \r
-BOOL CLogDlg::IsEntryInDateRange(int i)\r
-{\r
-#if 0\r
-       __time64_t time = m_logEntries[i]->tmDate;\r
-       if ((time >= m_tFrom)&&(time <= m_tTo))\r
-               return TRUE;\r
-#endif\r
-       return FALSE;\r
 \r
-}\r
 \r
 CTGitPathList CLogDlg::GetChangedPathsFromSelectedRevisions(bool bRelativePaths /* = false */, bool bUseFilter /* = true */)\r
 {\r
index f63c2cb..b6ce6b9 100644 (file)
@@ -35,6 +35,7 @@
 #include <regex>\r
 #include "GitLogList.h"\r
 #include "GitStatusListCtrl.h"\r
+\r
 using namespace std;\r
 \r
 \r
@@ -43,14 +44,6 @@ using namespace std;
 #define MERGE_REVSELECTSTARTEND  3             ///< both\r
 #define MERGE_REVSELECTMINUSONE  4             ///< first with N-1\r
 \r
-#define LOGFILTER_ALL      1\r
-#define LOGFILTER_MESSAGES 2\r
-#define LOGFILTER_PATHS    3\r
-#define LOGFILTER_AUTHORS  4\r
-#define LOGFILTER_REVS    5\r
-#define LOGFILTER_REGEX           6\r
-#define LOGFILTER_BUGID    7\r
-\r
 \r
 #define LOGFILTER_TIMER                101\r
 \r
@@ -173,12 +166,12 @@ private:
        void AdjustMinSize();\r
        void SetSplitterRange();\r
        void SetFilterCueText();\r
-       BOOL IsEntryInDateRange(int i);\r
+       \r
        void CopySelectionToClipBoard();\r
        void CopyChangedSelectionToClipBoard();\r
        CTGitPathList GetChangedPathsFromSelectedRevisions(bool bRelativePaths = false, bool bUseFilter = true);\r
     void SortShownListArray();\r
-       void RecalculateShownList(CPtrArray * pShownlist);\r
+       \r
     void SetSortArrow(CListCtrl * control, int nColumn, bool bAscending);\r
        void SortByColumn(int nSortColumn, bool bAscending);\r
        \r
@@ -220,10 +213,7 @@ private:
        CString                         m_sURL;\r
        CString                         m_sUUID;    ///< empty if the log cache is not used\r
        CGitLogList                     m_LogList;\r
-       //CListCtrl                     m_ChangedFileListCtrl;\r
-       \r
        CGitStatusListCtrl  m_ChangedFileListCtrl;\r
-\r
        CFilterEdit                     m_cFilter;\r
        CProgressCtrl           m_LogProgress;\r
        CMenuButton                     m_btnShow;\r
@@ -263,7 +253,7 @@ private:
        CRect                           m_LogListOrigRect;\r
        CRect                           m_ChgOrigRect;\r
        CString                         m_sFilterText;\r
-       int                                     m_nSelectedFilter;\r
+       \r
        //volatile LONG         m_bNoDispUpdates;\r
        CDateTimeCtrl           m_DateFrom;\r
        CDateTimeCtrl           m_DateTo;\r
index e8b04f3..d4d15cb 100644 (file)
@@ -42,29 +42,7 @@ protected:
        std::set<LONG> m_SetSelectedRevisions;\r
 };\r
 \r
-/**\r
- * \ingroup TortoiseProc\r
- * Contains the data of one log entry, used in the log dialog\r
- */\r
-#if 0\r
-typedef struct LogEntryData\r
-{   \r
-       git_revnum_t Rev;\r
-       __time64_t tmDate;\r
-       CString sDate;\r
-       CString sAuthor;\r
-       CString sMessage;\r
-       CString sShortMessage;\r
-       CString sBugIDs;\r
-       DWORD dwFileChanges;\r
-       LogChangedPathArray* pArChangedPaths;\r
-       BOOL bCopies;\r
-       BOOL bCopiedSelf;\r
-       DWORD actions;\r
-       BOOL haschildren;\r
-       DWORD childStackDepth;\r
-} LOGENTRYDATA, *PLOGENTRYDATA;\r
-#endif\r
+\r
 /**\r
  * \ingroup TortoiseProc\r
  * Helper class for the log dialog, handles all the log entries, including\r
index 28ab241..805c5c0 100644 (file)
@@ -21,7 +21,7 @@
 #include "StandAloneDlg.h"\r
 #include "MyGraph.h"\r
 #include "XPImageButton.h"\r
-#include "TSVNPath.h"\r
+#include "TGitPath.h"\r
 #include "UnicodeUtils.h"\r
 \r
 #include <map>\r
@@ -69,7 +69,7 @@ public:
        CDWordArray     *       m_parDates;\r
        CDWordArray     *       m_parFileChanges;\r
        CStringArray *  m_parAuthors;\r
-       CTSVNPath               m_path;\r
+       CTGitPath               m_path;\r
 \r
 protected:\r
 \r
index d346634..59d0b88 100644 (file)
                                RelativePath=".\ProgressDlg.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath=".\StatGraphDlg.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\StatGraphDlg.h"\r
+                               >\r
+                       </File>\r
                </Filter>\r
                <Filter\r
                        Name="Git"\r