OSDN Git Service

Fix Issue 85: Installer: warns of downgrade when running 0.6.2.0 on top of 0.6.1.0
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / GitLogListBase.cpp
index 2bcb049..e9a914e 100644 (file)
@@ -57,6 +57,7 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        , 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
@@ -118,6 +119,15 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        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
@@ -254,7 +264,7 @@ void CGitLogListBase::ResizeAllListCtrlCols()
                {\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
@@ -307,7 +317,9 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect)
        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
@@ -321,34 +333,27 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect)
                }\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
@@ -623,6 +628,9 @@ void CGitLogListBase::DrawGraph(HDC hdc,CRect &rect,INT_PTR index)
        //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
@@ -1031,6 +1039,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
        }\r
        //entry is selected, now show the popup menu\r
        CIconMenu popup;\r
+       CIconMenu submenu;\r
        if (popup.CreatePopupMenu())\r
        {\r
 \r
@@ -1125,6 +1134,13 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        popup.AppendMenu(MF_SEPARATOR, NULL);\r
 \r
                }\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
@@ -1176,6 +1192,11 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        }\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
@@ -1209,6 +1230,38 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                if(m_ContextMenuMask&GetContextMenuBit(ID_FINDENTRY))\r
                        popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
 \r
+\r
+               if (GetSelectedCount() == 1)\r
+               {\r
+                       if(m_ContextMenuMask &GetContextMenuBit(ID_DELETE))\r
+                       {\r
+                               if( this->m_HashMap.find(pSelLogEntry->m_CommitHash) != m_HashMap.end() )\r
+                               {\r
+                                       CString str;\r
+                                       str.LoadString(IDS_DELETE_BRANCHTAG);\r
+                                       if( m_HashMap[pSelLogEntry->m_CommitHash].size() == 1 )\r
+                                       {\r
+                                               str+=_T(" ");\r
+                                               str+=m_HashMap[pSelLogEntry->m_CommitHash].at(0);\r
+                                               popup.AppendMenuIcon(ID_DELETE,str+_T("..."),IDI_DELETE);\r
+                                       }\r
+                                       else if( m_HashMap[pSelLogEntry->m_CommitHash].size() > 1 )\r
+                                       {\r
+                                               \r
+                                               submenu.CreatePopupMenu();\r
+                                               for(int i=0;i<m_HashMap[pSelLogEntry->m_CommitHash].size();i++)\r
+                                               {\r
+                                                       submenu.AppendMenuIcon(ID_DELETE+(i<<16),m_HashMap[pSelLogEntry->m_CommitHash][i]+_T("..."));\r
+                                               }\r
+\r
+                                               popup.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING,(UINT) submenu.m_hMenu,str); \r
+\r
+                                       }\r
+                                       \r
+                               }\r
+                       }\r
+               }\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
@@ -1488,9 +1541,8 @@ int CGitLogListBase::FillGitShortLog()
 //     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
@@ -1501,6 +1553,7 @@ int CGitLogListBase::FillGitShortLog()
 \r
        for(unsigned int i=0;i<m_logEntries.size();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
@@ -1610,8 +1663,8 @@ public:
                m_ByteCollector.append(data,size);\r
 \r
                //Find loginfo endmarker\r
-               static const BYTE dataToFind[]={0,0};\r
-               int found=m_ByteCollector.findData(dataToFind,2);\r
+               static const BYTE dataToFind[]={0,0,'#','<'};\r
+               int found=m_ByteCollector.findData(dataToFind,4);\r
                if(found<0)\r
                        return m_ploglist->m_bExitThread;//Not found\r
                found+=2;//Position after loginfo end-marker\r
@@ -1649,9 +1702,21 @@ public:
                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
@@ -1667,6 +1732,9 @@ public:
                                                               //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
@@ -1676,7 +1744,7 @@ public:
 \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
@@ -1689,26 +1757,36 @@ public:
 \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_STAT|\r
                CGit::LOG_INFO_FILESTATE|\r
                CGit::LOG_INFO_DETECT_COPYRENAME|\r
+               CGit::LOG_INFO_SHOW_MERGEDFILE |\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
@@ -1731,18 +1809,8 @@ void CGitLogListBase::FetchFullLogInfoOrig()
                                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
@@ -1771,6 +1839,50 @@ UINT CGitLogListBase::LogThread()
                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
@@ -1795,11 +1907,11 @@ UINT CGitLogListBase::LogThread()
                }\r
        }\r
 #endif\r
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+\r
 \r
 \r
        //FetchFullLogInfo();\r
-       FetchFullLogInfoOrig();\r
+       //FetchFullLogInfoOrig();\r
        //RefreshCursor();\r
        // make sure the filter is applied (if any) now, after we refreshed/fetched\r
        // the log messages\r
@@ -2113,13 +2225,9 @@ void CGitLogListBase::RemoveFilter()
 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
@@ -2166,7 +2274,7 @@ void CGitLogListBase::SaveColumnWidths()
                {\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