X-Git-Url: http://git.sourceforge.jp/view?p=tortoisegit%2FTortoiseGitJp.git;a=blobdiff_plain;f=src%2FTortoiseProc%2FGitLogListBase.cpp;h=453ed3352717cc21d72d81d4dfdab31a393a4b60;hp=e36c23a51801ddf04482f043e75388eb1a05674b;hb=c8ba531d4ec5690ae42413b437bf4b355257c92a;hpb=da425587cf4787e8961ba9740075fe06309de5d4 diff --git a/src/TortoiseProc/GitLogListBase.cpp b/src/TortoiseProc/GitLogListBase.cpp index e36c23a..453ed33 100644 --- a/src/TortoiseProc/GitLogListBase.cpp +++ b/src/TortoiseProc/GitLogListBase.cpp @@ -57,6 +57,7 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl() , m_bStrictStopped(false) , m_pStoreSelection(NULL) , m_nSelectedFilter(LOGFILTER_ALL) + , m_bVista(false) { // use the default GUI font, create a copy of it and // change the copy to BOLD (leave the rest of the font @@ -83,6 +84,7 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl() g_Git.GetMapHashToFriendName(m_HashMap); m_CurrentBranch=g_Git.GetCurrentBranch(); + this->m_HeadHash=g_Git.GetHash(CString(_T("HEAD"))).Left(40); m_From=CTime(1970,1,2,0,0,0); m_To=CTime::GetCurrentTime(); @@ -90,6 +92,9 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl() m_LoadingThread = NULL; m_bExitThread=FALSE; + m_IsOldFirst = FALSE; + m_IsRebaseReplaceGraph = FALSE; + for(int i=0;i= 0x0600); + + m_ColumnRegKey=_T("log"); } CGitLogListBase::~CGitLogListBase() @@ -173,6 +193,14 @@ void CGitLogListBase::InsertGitColumn() DeleteColumn(c--); temp.LoadString(IDS_LOG_GRAPH); + if(m_IsRebaseReplaceGraph) + { + temp=_T("Rebase"); + } + else + { + temp.LoadString(IDS_LOG_GRAPH); + } InsertColumn(this->LOGLIST_GRAPH, temp); #if 0 @@ -236,7 +264,7 @@ void CGitLogListBase::ResizeAllListCtrlCols() { // get width for this col last time from registry CString regentry; - regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col); + regentry.Format( _T("Software\\TortoiseGit\\%s\\ColWidth%d"),m_ColumnRegKey, col); CRegDWORD regwidth(regentry, 0); int cx = regwidth; if ( cx == 0 ) @@ -288,6 +316,10 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect) rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; GetItem(&rItem); + GitRev* pLogEntry = (GitRev*)m_arShownList.GetAt(Index); + HBRUSH brush; + + if (m_Theme.IsAppThemed() && m_bVista) { m_Theme.Open(m_hWnd, L"Explorer"); @@ -301,34 +333,27 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect) } 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(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH) + brush = ::CreateSolidBrush(RGB(156,156,156)); + else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT) + brush = ::CreateSolidBrush(RGB(200,200,128)); + + if (brush == NULL) + return; + + ::FillRect(hdc, &rect, brush); + ::DeleteObject(brush); + } if (m_Theme.IsBackgroundPartiallyTransparent(LVP_LISTDETAIL, state)) m_Theme.DrawParentBackground(m_hWnd, hdc, &rect); - + else m_Theme.DrawBackground(hdc, LVP_LISTDETAIL, state, &rect, NULL); } else { - HBRUSH brush; + if (rItem.state & LVIS_SELECTED) { if (::GetFocus() == m_hWnd) @@ -341,6 +366,11 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect) //if (pLogEntry->bCopiedSelf) // brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU)); //else + if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH) + brush = ::CreateSolidBrush(RGB(156,156,156)); + else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT) + brush = ::CreateSolidBrush(RGB(200,200,128)); + else brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW)); } if (brush == NULL) @@ -386,6 +416,12 @@ void CGitLogListBase::DrawTagBranch(HDC hdc,CRect &rect,INT_PTR index) { brush = ::CreateSolidBrush(m_Colors.GetColor(CColors::Tag)); } + else if(GetShortName(str,shortname,_T("refs/stash"))) + { + brush = ::CreateSolidBrush(m_Colors.GetColor(CColors::Stash)); + shortname=_T("stash"); + } + if(!shortname.IsEmpty()) { @@ -592,6 +628,9 @@ void CGitLogListBase::DrawGraph(HDC hdc,CRect &rect,INT_PTR index) //todo unfinished // return; GitRev* data = (GitRev*)m_arShownList.GetAt(index); + if(data->m_CommitHash.IsEmpty()) + return; + CRect rt=rect; LVITEM rItem; SecureZeroMemory(&rItem, sizeof(LVITEM)); @@ -688,6 +727,28 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult) if (data->bCopies) crText = m_Colors.GetColor(CColors::Modified); #endif + if (data->m_Action& (CTGitPath::LOGACTIONS_REBASE_DONE| CTGitPath::LOGACTIONS_REBASE_SKIP) ) + crText = RGB(128,128,128); + + if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH) + pLVCD->clrTextBk = RGB(156,156,156); + else if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT) + pLVCD->clrTextBk = RGB(200,200,128); + else + pLVCD->clrTextBk = ::GetSysColor(COLOR_WINDOW); + + if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_CURRENT) + { + SelectObject(pLVCD->nmcd.hdc, m_boldFont); + *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT; + } + + if(data->m_CommitHash == m_HeadHash) + { + SelectObject(pLVCD->nmcd.hdc, m_boldFont); + *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT; + } + // if ((data->childStackDepth)||(m_mergedRevs.find(data->Rev) != m_mergedRevs.end())) // crText = GetSysColor(COLOR_GRAYTEXT); // if (data->Rev == m_wcRev) @@ -718,7 +779,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult) if (pLVCD->iSubItem == LOGLIST_GRAPH) { - if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec) + if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec && (!this->m_IsRebaseReplaceGraph) ) { CRect rect; GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect); @@ -790,7 +851,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult) ::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) + if (pLogEntry->m_Action & (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY) ) ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hAddedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL); nIcons++; @@ -840,7 +901,14 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult) pLogEntry = reinterpret_cast(m_arShownList.GetAt(pItem->iItem)); CString temp; - temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem); + if(m_IsOldFirst) + { + temp.Format(_T("%d"),pItem->iItem+1); + + }else + { + temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem); + } // Which column? switch (pItem->iSubItem) @@ -848,6 +916,13 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult) case this->LOGLIST_GRAPH: //Graphic if (pLogEntry) { + if(this->m_IsRebaseReplaceGraph) + { + CTGitPath path; + path.m_Action=pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_MODE_MASK; + + lstrcpyn(pItem->pszText,path.GetActionName(), pItem->cchTextMax); + } } break; case this->LOGLIST_ACTION: //action -- no text in the column @@ -966,31 +1041,30 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) CIconMenu popup; if (popup.CreatePopupMenu()) { + + if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_PICK)) + popup.AppendMenuIcon(ID_REBASE_PICK, IDS_REBASE_SKIP, IDI_PICK); + + if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SQUASH)) + popup.AppendMenuIcon(ID_REBASE_SQUASH,IDS_REBASE_SQUASH, IDI_SQUASH); + + if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_EDIT)) + popup.AppendMenuIcon(ID_REBASE_EDIT, IDS_REBASE_EDIT, IDI_EDIT); + + if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SKIP)) + popup.AppendMenuIcon(ID_REBASE_SKIP, IDS_REBASE_SKIP, IDI_SKIP); + + if(m_ContextMenuMask&(GetContextMenuBit(ID_REBASE_SKIP)|GetContextMenuBit(ID_REBASE_EDIT)| + GetContextMenuBit(ID_REBASE_SQUASH)|GetContextMenuBit(ID_REBASE_PICK))) + popup.AppendMenu(MF_SEPARATOR, NULL); + 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); + if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARE)) + 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 @@ -999,8 +1073,11 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) // 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); + if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF1)) + popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF); + + if(m_ContextMenuMask&GetContextMenuBit(ID_COMPAREWITHPREVIOUS)) + 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); } @@ -1026,31 +1103,61 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) //if (m_hasWC) // popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE); - CString str; - str.Format(_T("Reset %s to this"),g_Git.GetCurrentBranch()); - popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT); - 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); + CString str,format; + format.LoadString(IDS_RESET_TO_THIS_FORMAT); + str.Format(format,g_Git.GetCurrentBranch()); + + if(m_ContextMenuMask&GetContextMenuBit(ID_RESET)) + popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT); + + if(m_ContextMenuMask&GetContextMenuBit(ID_SWITCHTOREV)) + popup.AppendMenuIcon(ID_SWITCHTOREV, IDS_SWITCH_TO_THIS , IDI_SWITCH); + + if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_BRANCH)) + popup.AppendMenuIcon(ID_CREATE_BRANCH, IDS_CREATE_BRANCH_AT_THIS , IDI_COPY); + + if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_TAG)) + popup.AppendMenuIcon(ID_CREATE_TAG,IDS_CREATE_TAG_AT_THIS , IDI_COPY); + + format.LoadString(IDS_REBASE_THIS_FORMAT); + str.Format(format,g_Git.GetCurrentBranch()); + + if(pSelLogEntry->m_CommitHash != m_HeadHash) + if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_TO_VERSION)) + popup.AppendMenuIcon(ID_REBASE_TO_VERSION, str , IDI_REBASE); + + if(m_ContextMenuMask&GetContextMenuBit(ID_EXPORT)) + popup.AppendMenuIcon(ID_EXPORT,IDS_EXPORT_TO_THIS, IDI_EXPORT); popup.AppendMenu(MF_SEPARATOR, NULL); + + } + + if(!pSelLogEntry->m_Ref.IsEmpty() && GetSelectedCount() == 1) + { + popup.AppendMenuIcon(ID_REFLOG_DEL, IDS_REFLOG_DEL, IDI_DELETE); + popup.AppendMenuIcon(ID_STASH_APPLY,IDS_MENUSTASHAPPLY, IDI_RELOCATE); + popup.AppendMenu(MF_SEPARATOR, NULL); } - else if (GetSelectedCount() >= 2) + + if (GetSelectedCount() >= 2) { bool bAddSeparator = false; if (IsSelectionContinuous() || (GetSelectedCount() == 2)) { - popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); + if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARETWO)) + 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); + if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF2)) + 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); @@ -1061,6 +1168,34 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) if (bAddSeparator) popup.AppendMenu(MF_SEPARATOR, NULL); } + + if ( GetSelectedCount() >0 ) + { + if ( IsSelectionContinuous() && GetSelectedCount() >= 2 ) + { + if(m_ContextMenuMask&GetContextMenuBit(ID_COMBINE_COMMIT)) + { + CString head; + int headindex; + headindex = this->GetHeadIndex(); + if(headindex>=0) + { + head.Format(_T("HEAD~%d"),LastSelect-headindex); + CString hash=g_Git.GetHash(head); + hash=hash.Left(40); + GitRev* pLastEntry = reinterpret_cast(m_arShownList.GetAt(LastSelect)); + if(pLastEntry->m_CommitHash == hash) + popup.AppendMenuIcon(ID_COMBINE_COMMIT,IDS_COMBINE_TO_ONE,IDI_COMBINE); + } + } + } + if(m_ContextMenuMask&GetContextMenuBit(ID_CHERRY_PICK)) + popup.AppendMenuIcon(ID_CHERRY_PICK, IDS_CHERRY_PICK_VERSION, IDI_EXPORT); + popup.AppendMenu(MF_SEPARATOR, NULL); + + } + + #if 0 // if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor)) // { @@ -1077,13 +1212,17 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) if (GetSelectedCount() == 1) { - popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash")); + if(m_ContextMenuMask&GetContextMenuBit(ID_COPYHASH)) + popup.AppendMenuIcon(ID_COPYHASH, IDS_COPY_COMMIT_HASH); } if (GetSelectedCount() != 0) { - popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD); + if(m_ContextMenuMask&GetContextMenuBit(ID_COPYCLIPBOARD)) + popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD); } - popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND); + + if(m_ContextMenuMask&GetContextMenuBit(ID_FINDENTRY)) + 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); @@ -1178,9 +1317,20 @@ void CGitLogListBase::CopySelectionToClipBoard(bool HashOnly) void CGitLogListBase::DiffSelectedRevWithPrevious() { -#if 0 if (m_bThreadRunning) return; + + int FirstSelect=-1, LastSelect=-1; + POSITION pos = GetFirstSelectedItemPosition(); + FirstSelect = GetNextSelectedItem(pos); + while(pos) + { + LastSelect = GetNextSelectedItem(pos); + } + + ContextMenuAction(ID_COMPAREWITHPREVIOUS,FirstSelect,LastSelect); + +#if 0 UpdateLogInfoLabel(); int selIndex = m_LogList.GetSelectionMark(); if (selIndex < 0) @@ -1301,12 +1451,12 @@ void CGitLogListBase::OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult) *pResult = -1; } -int CGitLogListBase::FillGitLog(CTGitPath *path,int info) +int CGitLogListBase::FillGitLog(CTGitPath *path,int info,CString *from,CString *to) { ClearText(); this->m_logEntries.ClearAll(); - this->m_logEntries.ParserFromLog(path,-1,info); + this->m_logEntries.ParserFromLog(path,-1,info,from,to); //this->m_logEntries.ParserFromLog(); SetItemCountEx(this->m_logEntries.size()); @@ -1315,8 +1465,16 @@ int CGitLogListBase::FillGitLog(CTGitPath *path,int info) for(unsigned int i=0;im_arShownList.Add(&m_logEntries[i]); + if(m_IsOldFirst) + { + m_logEntries[m_logEntries.size()-i-1].m_IsFull=TRUE; + this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]); + + }else + { + m_logEntries[i].m_IsFull=TRUE; + this->m_arShownList.Add(&m_logEntries[i]); + } } if(path) @@ -1345,9 +1503,8 @@ int CGitLogListBase::FillGitShortLog() // if(this->m_bAllBranch) mask |= m_ShowMask; - this->m_logEntries.ParserShortLog(path,hash,-1,mask); + this->m_logEntries.FetchShortLog(path,hash,-1,mask); - //this->m_logEntries.ParserFromLog(); if(IsInWorkingThread()) PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL); @@ -1357,8 +1514,17 @@ int CGitLogListBase::FillGitShortLog() this->m_arShownList.RemoveAll(); for(unsigned int i=0;im_arShownList.Add(&m_logEntries[i]); + { + m_logEntries[i].m_Subject=_T("parser..."); + if(this->m_IsOldFirst) + { + this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-1-i]); + }else + { + this->m_arShownList.Add(&m_logEntries[i]); + } + } return 0; } @@ -1403,8 +1569,8 @@ void CGitLogListBase::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(); + if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE)) + DiffSelectedRevWithPrevious(); } int CGitLogListBase::FetchLogAsync(void * data) @@ -1498,9 +1664,21 @@ public: GitRev* revInVector=&m_ploglist->m_logEntries[rev]; + if(revInVector->m_IsFull) + return; + + if(!m_ploglist->m_LogCache.GetCacheData(m_ploglist->m_logEntries[rev])) + { + ++m_CollectedCount; + InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsUpdateing,FALSE); + InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsFull,TRUE); + ::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0); + return; + } + // fullRev.m_IsUpdateing=TRUE; // fullRev.m_IsFull=TRUE; - + if(InterlockedExchange(&revInVector->m_IsUpdateing,TRUE)) return;//Cannot update this row now. Ignore. @@ -1516,6 +1694,9 @@ public: //So we need keep old bound mark. revInVector->m_ParentHash=oldlist; + //update cache + m_ploglist->m_LogCache.AddCacheEntry(*revInVector); + //Reset updating InterlockedExchange(&revInVector->m_IsFull,TRUE); InterlockedExchange(&revInVector->m_IsUpdateing,FALSE); @@ -1525,7 +1706,7 @@ public: ::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0); - DWORD percent=m_CollectedCount*98/m_ploglist->m_logEntries.size() + GITLOG_START+1; + DWORD percent=m_CollectedCount*68/m_ploglist->m_logEntries.size() + GITLOG_START+1+30; if(percent == GITLOG_END) percent = GITLOG_END -1; @@ -1538,7 +1719,7 @@ public: }; -void CGitLogListBase::FetchFullLogInfo() +void CGitLogListBase::FetchFullLogInfo(CString &from, CString &to) { CGitCall_FetchFullLogInfo fetcher(this); int mask= @@ -1546,18 +1727,27 @@ void CGitLogListBase::FetchFullLogInfo() CGit::LOG_INFO_FILESTATE| CGit::LOG_INFO_DETECT_COPYRENAME| m_ShowMask; - g_Git.GetLog(&fetcher,CString(),NULL,-1,mask); + + CTGitPath *path; + if(this->m_Path.IsEmpty()) + path=NULL; + else + path=&this->m_Path; + + g_Git.GetLog(&fetcher,CString(),path,-1,mask,&from,&to); } -void CGitLogListBase::FetchFullLogInfoOrig() +void CGitLogListBase::FetchLastLogInfo() { unsigned int updated=0; int percent=0; CRect rect; - while(1) { for(unsigned int i=0;iGetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent,0); - - + } } - if(updated==m_logEntries.size()) - break; } } @@ -1620,6 +1800,50 @@ UINT CGitLogListBase::LogThread() InterlockedExchange(&m_bNoDispUpdates, FALSE); return 0; } + InterlockedExchange(&m_bNoDispUpdates, FALSE); + ::PostMessage(GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_START_ALL, 0); + + int start=0; CString firstcommit,lastcommit; + int update=0; + for(int i=0;im_logEntries[i].ParserFromLog(m_logEntries.m_RawlogData,start); + m_logEntries.m_HashMap[m_logEntries[i].m_CommitHash]=i; + + if(m_LogCache.GetCacheData(m_logEntries[i])) + { + if(firstcommit.IsEmpty()) + firstcommit=m_logEntries[i].m_CommitHash; + lastcommit=m_logEntries[i].m_CommitHash; + + }else + { + InterlockedExchange(&m_logEntries[i].m_IsUpdateing,FALSE); + InterlockedExchange(&m_logEntries[i].m_IsFull,TRUE); + update++; + } + if(start<0) + break; + if(start>=m_logEntries.m_RawlogData.size()) + break; + + int percent=i*30/m_logEntries.size() + GITLOG_START+1; + + ::PostMessage(GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent, 0); + ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM) i, 0); + + if(this->m_bExitThread) + { + InterlockedExchange(&m_bThreadRunning, FALSE); + InterlockedExchange(&m_bNoDispUpdates, FALSE); + return 0; + } + } + if(!lastcommit.IsEmpty()) + FetchFullLogInfo(lastcommit,firstcommit); + + this->FetchLastLogInfo(); + #if 0 RedrawItems(0, m_arShownList.GetCount()); // SetRedraw(false); @@ -1644,11 +1868,11 @@ UINT CGitLogListBase::LogThread() } } #endif - InterlockedExchange(&m_bNoDispUpdates, FALSE); + //FetchFullLogInfo(); - FetchFullLogInfoOrig(); + //FetchFullLogInfoOrig(); //RefreshCursor(); // make sure the filter is applied (if any) now, after we refreshed/fetched // the log messages @@ -1663,9 +1887,12 @@ UINT CGitLogListBase::LogThread() void CGitLogListBase::Refresh() { m_bExitThread=TRUE; - DWORD ret =::WaitForSingleObject(m_LoadingThread->m_hThread,20000); - if(ret == WAIT_TIMEOUT) - TerminateThread(); + if(m_LoadingThread!=NULL) + { + DWORD ret =::WaitForSingleObject(m_LoadingThread->m_hThread,20000); + if(ret == WAIT_TIMEOUT) + TerminateThread(); + } this->Clear(); @@ -1937,7 +2164,13 @@ void CGitLogListBase::RemoveFilter() for (DWORD i=0; im_IsOldFirst) + { + m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]); + }else + { + m_arShownList.Add(&m_logEntries[i]); + } } // InterlockedExchange(&m_bNoDispUpdates, FALSE); DeleteAllItems(); @@ -1953,13 +2186,9 @@ void CGitLogListBase::RemoveFilter() void CGitLogListBase::Clear() { m_arShownList.RemoveAll(); - m_logEntries.clear(); - m_logEntries.m_HashMap.clear(); DeleteAllItems(); - m_logEntries.m_Lns.clear(); - m_logEntries.m_FirstFreeLane=0; - m_logEntries.m_Lns.clear(); + m_logEntries.ClearAll(); } @@ -2006,10 +2235,26 @@ void CGitLogListBase::SaveColumnWidths() { int width = GetColumnWidth( col ); CString regentry; - regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col); + regentry.Format( _T("Software\\TortoiseGit\\%s\\ColWidth%d"),m_ColumnRegKey, col); CRegDWORD regwidth(regentry, 0); regwidth = width; // this writes it to reg } } } +int CGitLogListBase::GetHeadIndex() +{ + if(m_HeadHash.IsEmpty()) + return -1; + + for(int i=0;im_CommitHash == m_HeadHash ) + return i; + } + } + return -1; +} \ No newline at end of file