, m_bStrictStopped(false)\r
, m_pStoreSelection(NULL)\r
, m_nSelectedFilter(LOGFILTER_ALL)\r
+ , m_bVista(false)\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
\r
g_Git.GetMapHashToFriendName(m_HashMap);\r
m_CurrentBranch=g_Git.GetCurrentBranch();\r
+ this->m_HeadHash=g_Git.GetHash(CString(_T("HEAD"))).Left(40);\r
\r
m_From=CTime(1970,1,2,0,0,0);\r
m_To=CTime::GetCurrentTime();\r
m_LoadingThread = NULL;\r
\r
m_bExitThread=FALSE;\r
+ m_IsOldFirst = FALSE;\r
+ m_IsRebaseReplaceGraph = FALSE;\r
+\r
\r
for(int i=0;i<Lanes::COLORS_NUM;i++)\r
{\r
// get relative time display setting from registry\r
DWORD regRelativeTimes = CRegDWORD(_T("Software\\TortoiseGit\\RelativeTimes"), FALSE);\r
m_bRelativeTimes = (regRelativeTimes != 0);\r
+ m_ContextMenuMask = 0xFFFFFFFFFFFFFFFF;\r
+\r
+ m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_PICK);\r
+ m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_SQUASH);\r
+ m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_EDIT);\r
+ m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_SKIP);\r
+\r
+ OSVERSIONINFOEX inf;\r
+ SecureZeroMemory(&inf, sizeof(OSVERSIONINFOEX));\r
+ inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\r
+ GetVersionEx((OSVERSIONINFO *)&inf);\r
+ WORD fullver = MAKEWORD(inf.dwMinorVersion, inf.dwMajorVersion);\r
+ m_bVista = (fullver >= 0x0600);\r
+\r
+ m_ColumnRegKey=_T("log");\r
}\r
\r
CGitLogListBase::~CGitLogListBase()\r
DeleteColumn(c--);\r
temp.LoadString(IDS_LOG_GRAPH);\r
\r
+ if(m_IsRebaseReplaceGraph)\r
+ {\r
+ temp=_T("Rebase");\r
+ }\r
+ else\r
+ {\r
+ temp.LoadString(IDS_LOG_GRAPH);\r
+ }\r
InsertColumn(this->LOGLIST_GRAPH, temp);\r
\r
#if 0 \r
{\r
// get width for this col last time from registry\r
CString regentry;\r
- regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col);\r
+ regentry.Format( _T("Software\\TortoiseGit\\%s\\ColWidth%d"),m_ColumnRegKey, col);\r
CRegDWORD regwidth(regentry, 0);\r
int cx = regwidth;\r
if ( cx == 0 )\r
rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
GetItem(&rItem);\r
\r
+ GitRev* pLogEntry = (GitRev*)m_arShownList.GetAt(Index);\r
+ HBRUSH brush;\r
+\r
+ \r
if (m_Theme.IsAppThemed() && m_bVista)\r
{\r
m_Theme.Open(m_hWnd, L"Explorer");\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
+ if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+ brush = ::CreateSolidBrush(RGB(156,156,156));\r
+ else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+ brush = ::CreateSolidBrush(RGB(200,200,128));\r
+\r
+ if (brush == NULL)\r
+ return;\r
+\r
+ ::FillRect(hdc, &rect, brush);\r
+ ::DeleteObject(brush);\r
+\r
}\r
\r
if (m_Theme.IsBackgroundPartiallyTransparent(LVP_LISTDETAIL, state))\r
m_Theme.DrawParentBackground(m_hWnd, hdc, &rect);\r
-\r
+ else\r
m_Theme.DrawBackground(hdc, LVP_LISTDETAIL, state, &rect, NULL);\r
}\r
else\r
{\r
- HBRUSH brush;\r
+ \r
if (rItem.state & LVIS_SELECTED)\r
{\r
if (::GetFocus() == m_hWnd)\r
//if (pLogEntry->bCopiedSelf)\r
// brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));\r
//else\r
+ if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+ brush = ::CreateSolidBrush(RGB(156,156,156));\r
+ else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+ brush = ::CreateSolidBrush(RGB(200,200,128));\r
+ else \r
brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));\r
}\r
if (brush == NULL)\r
{\r
brush = ::CreateSolidBrush(m_Colors.GetColor(CColors::Tag));\r
}\r
+ else if(GetShortName(str,shortname,_T("refs/stash")))\r
+ {\r
+ brush = ::CreateSolidBrush(m_Colors.GetColor(CColors::Stash));\r
+ shortname=_T("stash");\r
+ }\r
+ \r
\r
if(!shortname.IsEmpty())\r
{\r
//todo unfinished\r
// return;\r
GitRev* data = (GitRev*)m_arShownList.GetAt(index);\r
+ if(data->m_CommitHash.IsEmpty())\r
+ return;\r
+\r
CRect rt=rect;\r
LVITEM rItem;\r
SecureZeroMemory(&rItem, sizeof(LVITEM));\r
if (data->bCopies)\r
crText = m_Colors.GetColor(CColors::Modified);\r
#endif\r
+ if (data->m_Action& (CTGitPath::LOGACTIONS_REBASE_DONE| CTGitPath::LOGACTIONS_REBASE_SKIP) ) \r
+ crText = RGB(128,128,128);\r
+\r
+ if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+ pLVCD->clrTextBk = RGB(156,156,156);\r
+ else if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+ pLVCD->clrTextBk = RGB(200,200,128);\r
+ else \r
+ pLVCD->clrTextBk = ::GetSysColor(COLOR_WINDOW);\r
+\r
+ if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_CURRENT)\r
+ {\r
+ SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
+ *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
+ }\r
+\r
+ if(data->m_CommitHash == m_HeadHash)\r
+ {\r
+ SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
+ *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
+ }\r
+\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
if (pLVCD->iSubItem == LOGLIST_GRAPH)\r
{\r
- if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+ if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec && (!this->m_IsRebaseReplaceGraph) )\r
{\r
CRect rect;\r
GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\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
+ if (pLogEntry->m_Action & (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY) )\r
::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hAddedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
nIcons++;\r
\r
pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(pItem->iItem));\r
\r
CString temp;\r
- temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem);\r
+ if(m_IsOldFirst)\r
+ {\r
+ temp.Format(_T("%d"),pItem->iItem+1);\r
+\r
+ }else\r
+ {\r
+ temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem);\r
+ }\r
\r
// Which column?\r
switch (pItem->iSubItem)\r
case this->LOGLIST_GRAPH: //Graphic\r
if (pLogEntry)\r
{\r
+ if(this->m_IsRebaseReplaceGraph)\r
+ {\r
+ CTGitPath path;\r
+ path.m_Action=pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_MODE_MASK;\r
+\r
+ lstrcpyn(pItem->pszText,path.GetActionName(), pItem->cchTextMax);\r
+ }\r
}\r
break;\r
case this->LOGLIST_ACTION: //action -- no text in the column\r
CIconMenu popup;\r
if (popup.CreatePopupMenu())\r
{\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_PICK))\r
+ popup.AppendMenuIcon(ID_REBASE_PICK, IDS_REBASE_SKIP, IDI_PICK);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SQUASH))\r
+ popup.AppendMenuIcon(ID_REBASE_SQUASH,IDS_REBASE_SQUASH, IDI_SQUASH);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_EDIT))\r
+ popup.AppendMenuIcon(ID_REBASE_EDIT, IDS_REBASE_EDIT, IDI_EDIT);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SKIP))\r
+ popup.AppendMenuIcon(ID_REBASE_SKIP, IDS_REBASE_SKIP, IDI_SKIP);\r
+ \r
+ if(m_ContextMenuMask&(GetContextMenuBit(ID_REBASE_SKIP)|GetContextMenuBit(ID_REBASE_EDIT)|\r
+ GetContextMenuBit(ID_REBASE_SQUASH)|GetContextMenuBit(ID_REBASE_PICK)))\r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\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
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARE))\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
// 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
+ if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF1))\r
+ popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COMPAREWITHPREVIOUS))\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
//if (m_hasWC)\r
// popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE);\r
\r
- CString str;\r
- str.Format(_T("Reset %s to this"),g_Git.GetCurrentBranch());\r
- popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\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
+ CString str,format;\r
+ format.LoadString(IDS_RESET_TO_THIS_FORMAT);\r
+ str.Format(format,g_Git.GetCurrentBranch());\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_RESET))\r
+ popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_SWITCHTOREV))\r
+ popup.AppendMenuIcon(ID_SWITCHTOREV, IDS_SWITCH_TO_THIS , IDI_SWITCH);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_BRANCH))\r
+ popup.AppendMenuIcon(ID_CREATE_BRANCH, IDS_CREATE_BRANCH_AT_THIS , IDI_COPY);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_TAG))\r
+ popup.AppendMenuIcon(ID_CREATE_TAG,IDS_CREATE_TAG_AT_THIS , IDI_COPY);\r
+ \r
+ format.LoadString(IDS_REBASE_THIS_FORMAT);\r
+ str.Format(format,g_Git.GetCurrentBranch());\r
+\r
+ if(pSelLogEntry->m_CommitHash != m_HeadHash)\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_TO_VERSION))\r
+ popup.AppendMenuIcon(ID_REBASE_TO_VERSION, str , IDI_REBASE); \r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_EXPORT))\r
+ popup.AppendMenuIcon(ID_EXPORT,IDS_EXPORT_TO_THIS, IDI_EXPORT); \r
\r
\r
popup.AppendMenu(MF_SEPARATOR, NULL);\r
+\r
}\r
- else if (GetSelectedCount() >= 2)\r
+\r
+ if(!pSelLogEntry->m_Ref.IsEmpty() && GetSelectedCount() == 1)\r
+ {\r
+ popup.AppendMenuIcon(ID_REFLOG_DEL, IDS_REFLOG_DEL, IDI_DELETE); \r
+ popup.AppendMenuIcon(ID_STASH_APPLY,IDS_MENUSTASHAPPLY, IDI_RELOCATE); \r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ }\r
+ \r
+ 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
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARETWO))\r
+ popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);\r
}\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
+ if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF2))\r
+ popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);\r
bAddSeparator = true;\r
}\r
+\r
if (m_hasWC)\r
{\r
//popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREVS, IDI_REVERT);\r
if (bAddSeparator)\r
popup.AppendMenu(MF_SEPARATOR, NULL);\r
}\r
+\r
+ if ( GetSelectedCount() >0 )\r
+ {\r
+ if ( IsSelectionContinuous() && GetSelectedCount() >= 2 )\r
+ {\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COMBINE_COMMIT))\r
+ {\r
+ CString head;\r
+ int headindex;\r
+ headindex = this->GetHeadIndex();\r
+ if(headindex>=0)\r
+ {\r
+ head.Format(_T("HEAD~%d"),LastSelect-headindex);\r
+ CString hash=g_Git.GetHash(head);\r
+ hash=hash.Left(40);\r
+ GitRev* pLastEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
+ if(pLastEntry->m_CommitHash == hash)\r
+ popup.AppendMenuIcon(ID_COMBINE_COMMIT,IDS_COMBINE_TO_ONE,IDI_COMBINE);\r
+ }\r
+ }\r
+ }\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_CHERRY_PICK))\r
+ popup.AppendMenuIcon(ID_CHERRY_PICK, IDS_CHERRY_PICK_VERSION, IDI_EXPORT);\r
+\r
+ if(GetSelectedCount()<=2)\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_PATCH))\r
+ popup.AppendMenuIcon(ID_CREATE_PATCH, IDS_CREATE_PATCH, IDI_PATCH);\r
+ \r
+ popup.AppendMenu(MF_SEPARATOR, NULL);\r
+ \r
+ }\r
+\r
+ \r
#if 0\r
// if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor))\r
// {\r
\r
if (GetSelectedCount() == 1)\r
{\r
- popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash"));\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COPYHASH))\r
+ popup.AppendMenuIcon(ID_COPYHASH, IDS_COPY_COMMIT_HASH);\r
}\r
if (GetSelectedCount() != 0)\r
{\r
- popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_COPYCLIPBOARD))\r
+ popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
}\r
- popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
+\r
+ if(m_ContextMenuMask&GetContextMenuBit(ID_FINDENTRY))\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
\r
void CGitLogListBase::DiffSelectedRevWithPrevious()\r
{\r
-#if 0\r
if (m_bThreadRunning)\r
return;\r
+\r
+ int FirstSelect=-1, LastSelect=-1;\r
+ POSITION pos = GetFirstSelectedItemPosition();\r
+ FirstSelect = GetNextSelectedItem(pos);\r
+ while(pos)\r
+ {\r
+ LastSelect = GetNextSelectedItem(pos);\r
+ }\r
+\r
+ ContextMenuAction(ID_COMPAREWITHPREVIOUS,FirstSelect,LastSelect);\r
+\r
+#if 0\r
UpdateLogInfoLabel();\r
int selIndex = m_LogList.GetSelectionMark();\r
if (selIndex < 0)\r
*pResult = -1;\r
}\r
\r
-int CGitLogListBase::FillGitLog(CTGitPath *path,int info)\r
+int CGitLogListBase::FillGitLog(CTGitPath *path,int info,CString *from,CString *to)\r
{\r
ClearText();\r
\r
this->m_logEntries.ClearAll();\r
- this->m_logEntries.ParserFromLog(path,-1,info);\r
+ this->m_logEntries.ParserFromLog(path,-1,info,from,to);\r
\r
//this->m_logEntries.ParserFromLog();\r
SetItemCountEx(this->m_logEntries.size());\r
\r
for(unsigned int i=0;i<m_logEntries.size();i++)\r
{\r
- m_logEntries[i].m_IsFull=TRUE;\r
- this->m_arShownList.Add(&m_logEntries[i]);\r
+ if(m_IsOldFirst)\r
+ {\r
+ m_logEntries[m_logEntries.size()-i-1].m_IsFull=TRUE;\r
+ this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]);\r
+ \r
+ }else\r
+ {\r
+ m_logEntries[i].m_IsFull=TRUE;\r
+ this->m_arShownList.Add(&m_logEntries[i]);\r
+ }\r
}\r
\r
if(path)\r
// if(this->m_bAllBranch)\r
mask |= m_ShowMask;\r
\r
- this->m_logEntries.ParserShortLog(path,hash,-1,mask);\r
+ this->m_logEntries.FetchShortLog(path,m_StartRef,-1,mask);\r
\r
-\r
//this->m_logEntries.ParserFromLog();\r
if(IsInWorkingThread())\r
PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL);\r
this->m_arShownList.RemoveAll();\r
\r
for(unsigned int i=0;i<m_logEntries.size();i++)\r
- this->m_arShownList.Add(&m_logEntries[i]);\r
+ {\r
+ m_logEntries[i].m_Subject=_T("parser...");\r
+ if(this->m_IsOldFirst)\r
+ {\r
+ this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-1-i]);\r
\r
+ }else\r
+ {\r
+ this->m_arShownList.Add(&m_logEntries[i]);\r
+ }\r
+ }\r
return 0;\r
}\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
+ if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
+ DiffSelectedRevWithPrevious();\r
}\r
\r
int CGitLogListBase::FetchLogAsync(void * data)\r
GitRev* revInVector=&m_ploglist->m_logEntries[rev];\r
\r
\r
+ if(revInVector->m_IsFull)\r
+ return;\r
+\r
+ if(!m_ploglist->m_LogCache.GetCacheData(m_ploglist->m_logEntries[rev]))\r
+ {\r
+ ++m_CollectedCount;\r
+ InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsUpdateing,FALSE);\r
+ InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsFull,TRUE);\r
+ ::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0);\r
+ return;\r
+ }\r
+\r
// fullRev.m_IsUpdateing=TRUE;\r
// fullRev.m_IsFull=TRUE;\r
-\r
+ \r
\r
if(InterlockedExchange(&revInVector->m_IsUpdateing,TRUE))\r
return;//Cannot update this row now. Ignore.\r
//So we need keep old bound mark.\r
revInVector->m_ParentHash=oldlist;\r
\r
+ //update cache\r
+ m_ploglist->m_LogCache.AddCacheEntry(*revInVector);\r
+\r
//Reset updating\r
InterlockedExchange(&revInVector->m_IsFull,TRUE);\r
InterlockedExchange(&revInVector->m_IsUpdateing,FALSE);\r
\r
::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0);\r
\r
- DWORD percent=m_CollectedCount*98/m_ploglist->m_logEntries.size() + GITLOG_START+1;\r
+ DWORD percent=m_CollectedCount*68/m_ploglist->m_logEntries.size() + GITLOG_START+1+30;\r
if(percent == GITLOG_END)\r
percent = GITLOG_END -1;\r
\r
\r
};\r
\r
-void CGitLogListBase::FetchFullLogInfo()\r
+void CGitLogListBase::FetchFullLogInfo(CString &from, CString &to)\r
{\r
CGitCall_FetchFullLogInfo fetcher(this);\r
int mask=\r
CGit::LOG_INFO_FILESTATE|\r
CGit::LOG_INFO_DETECT_COPYRENAME|\r
m_ShowMask;\r
- g_Git.GetLog(&fetcher,CString(),NULL,-1,mask);\r
+\r
+ CTGitPath *path;\r
+ if(this->m_Path.IsEmpty())\r
+ path=NULL;\r
+ else\r
+ path=&this->m_Path;\r
+\r
+ g_Git.GetLog(&fetcher,CString(),path,-1,mask,&from,&to);\r
}\r
\r
-void CGitLogListBase::FetchFullLogInfoOrig()\r
+void CGitLogListBase::FetchLastLogInfo()\r
{\r
unsigned int updated=0;\r
int percent=0;\r
CRect rect;\r
- while(1)\r
{\r
for(unsigned int i=0;i<m_logEntries.size();i++)\r
{\r
+ if(m_logEntries[i].m_IsFull)\r
+ continue;\r
+\r
if(m_LogCache.GetCacheData(m_logEntries[i]))\r
{\r
if(!m_logEntries.FetchFullInfo(i))\r
InterlockedExchange(&m_bThreadRunning, FALSE);\r
InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
return;\r
- }\r
-\r
- percent=updated*98/m_logEntries.size() + GITLOG_START+1;\r
- if(percent == GITLOG_END)\r
- percent = GITLOG_END -1;\r
- \r
- ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent,0);\r
-\r
- \r
+ } \r
}\r
- if(updated==m_logEntries.size())\r
- break;\r
}\r
}\r
\r
InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
return 0;\r
}\r
+ InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+ ::PostMessage(GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_START_ALL, 0);\r
+\r
+ int start=0; CString firstcommit,lastcommit;\r
+ int update=0;\r
+ for(int i=0;i<m_logEntries.size();i++)\r
+ {\r
+ start=this->m_logEntries[i].ParserFromLog(m_logEntries.m_RawlogData,start);\r
+ m_logEntries.m_HashMap[m_logEntries[i].m_CommitHash]=i;\r
+\r
+ if(m_LogCache.GetCacheData(m_logEntries[i]))\r
+ {\r
+ if(firstcommit.IsEmpty())\r
+ firstcommit=m_logEntries[i].m_CommitHash;\r
+ lastcommit=m_logEntries[i].m_CommitHash;\r
+\r
+ }else\r
+ {\r
+ InterlockedExchange(&m_logEntries[i].m_IsUpdateing,FALSE);\r
+ InterlockedExchange(&m_logEntries[i].m_IsFull,TRUE);\r
+ update++;\r
+ }\r
+ if(start<0)\r
+ break;\r
+ if(start>=m_logEntries.m_RawlogData.size())\r
+ break;\r
+\r
+ int percent=i*30/m_logEntries.size() + GITLOG_START+1;\r
+\r
+ ::PostMessage(GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent, 0);\r
+ ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM) i, 0);\r
+\r
+ if(this->m_bExitThread)\r
+ { \r
+ InterlockedExchange(&m_bThreadRunning, FALSE);\r
+ InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+ return 0;\r
+ }\r
+ }\r
+ if(!lastcommit.IsEmpty())\r
+ FetchFullLogInfo(lastcommit,firstcommit);\r
+ \r
+ this->FetchLastLogInfo();\r
+ \r
#if 0\r
RedrawItems(0, m_arShownList.GetCount());\r
// SetRedraw(false);\r
}\r
}\r
#endif\r
- InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
\r
\r
- FetchFullLogInfo();\r
+\r
+ //FetchFullLogInfo();\r
//FetchFullLogInfoOrig();\r
//RefreshCursor();\r
// make sure the filter is applied (if any) now, after we refreshed/fetched\r
void CGitLogListBase::Refresh()\r
{ \r
m_bExitThread=TRUE;\r
- DWORD ret =::WaitForSingleObject(m_LoadingThread->m_hThread,20000);\r
- if(ret == WAIT_TIMEOUT)\r
- TerminateThread();\r
+ if(m_LoadingThread!=NULL)\r
+ {\r
+ DWORD ret =::WaitForSingleObject(m_LoadingThread->m_hThread,20000);\r
+ if(ret == WAIT_TIMEOUT)\r
+ TerminateThread();\r
+ }\r
\r
this->Clear();\r
\r
\r
for (DWORD i=0; i<m_logEntries.size(); ++i)\r
{\r
- m_arShownList.Add(&m_logEntries[i]);\r
+ if(this->m_IsOldFirst)\r
+ {\r
+ m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]);\r
+ }else\r
+ {\r
+ m_arShownList.Add(&m_logEntries[i]);\r
+ }\r
}\r
// InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
DeleteAllItems();\r
void CGitLogListBase::Clear()\r
{\r
m_arShownList.RemoveAll();\r
- m_logEntries.clear();\r
- m_logEntries.m_HashMap.clear();\r
DeleteAllItems();\r
- m_logEntries.m_Lns.clear();\r
\r
- m_logEntries.m_FirstFreeLane=0;\r
- m_logEntries.m_Lns.clear();\r
+ m_logEntries.ClearAll();\r
\r
}\r
\r
{\r
int width = GetColumnWidth( col );\r
CString regentry;\r
- regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col);\r
+ regentry.Format( _T("Software\\TortoiseGit\\%s\\ColWidth%d"),m_ColumnRegKey, col);\r
CRegDWORD regwidth(regentry, 0);\r
regwidth = width; // this writes it to reg\r
}\r
}\r
}\r
\r
+int CGitLogListBase::GetHeadIndex()\r
+{\r
+ if(m_HeadHash.IsEmpty())\r
+ return -1;\r
+\r
+ for(int i=0;i<m_arShownList.GetCount();i++)\r
+ {\r
+ GitRev *pRev = (GitRev*)m_arShownList[i];\r
+ if(pRev)\r
+ {\r
+ if(pRev->m_CommitHash == m_HeadHash )\r
+ return i;\r
+ }\r
+ }\r
+ return -1;\r
+}
\ No newline at end of file