OSDN Git Service

First pass at relative times in log. This version shows both local and relative time...
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / GitLogListBase.cpp
index f02f247..9c9d86d 100644 (file)
@@ -47,7 +47,6 @@
 #include "..\\TortoiseShell\\Resource.h"\r
 \r
 \r
-\r
 IMPLEMENT_DYNAMIC(CGitLogListBase, CHintListCtrl)\r
 \r
 CGitLogListBase::CGitLogListBase():CHintListCtrl()\r
@@ -87,7 +86,7 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
 \r
        m_From=CTime(1970,1,2,0,0,0);\r
        m_To=CTime::GetCurrentTime();\r
-    m_bAllBranch = FALSE;\r
+    m_ShowMask = 0;\r
        m_LoadingThread = NULL;\r
 \r
        m_bExitThread=FALSE;\r
@@ -96,6 +95,16 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        {\r
                m_LineColors[i] = m_Colors.GetColor((CColors::Colors)(CColors::BranchLine1+i));\r
        }\r
+       // get short/long datetime setting from registry\r
+       DWORD RegUseShortDateFormat = CRegDWORD(_T("Software\\TortoiseGit\\LogDateFormat"), TRUE);\r
+       if ( RegUseShortDateFormat )\r
+       {\r
+               m_DateFormat = DATE_SHORTDATE;\r
+       }\r
+       else\r
+       {\r
+               m_DateFormat = DATE_LONGDATE;\r
+       }\r
 }\r
 \r
 CGitLogListBase::~CGitLogListBase()\r
@@ -116,6 +125,13 @@ CGitLogListBase::~CGitLogListBase()
                delete m_pStoreSelection;\r
                m_pStoreSelection = NULL;\r
        }\r
+\r
+       if(this->m_bThreadRunning)\r
+       {\r
+               m_bExitThread=true;\r
+               WaitForSingleObject(m_LoadingThread->m_hThread,1000);\r
+               TerminateThread();\r
+       }\r
 }\r
 \r
 \r
@@ -127,6 +143,7 @@ BEGIN_MESSAGE_MAP(CGitLogListBase, CHintListCtrl)
        ON_NOTIFY_REFLECT(LVN_ODFINDITEM,OnLvnOdfinditemLoglist)\r
        ON_WM_CREATE()\r
        ON_WM_DESTROY()\r
+       ON_MESSAGE(MSG_LOADED,OnLoad)\r
 END_MESSAGE_MAP()\r
 \r
 int CGitLogListBase:: OnCreate(LPCREATESTRUCT lpCreateStruct)\r
@@ -200,83 +217,31 @@ void CGitLogListBase::InsertGitColumn()
 \r
 }\r
 \r
+/**\r
+ * Resizes all columns in a list control to values in registry.\r
+ */\r
 void CGitLogListBase::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
+       // column max and min widths to allow\r
+       static const int nMinimumWidth = 10;\r
+       static const int nMaximumWidth = 1000;\r
+       CHeaderCtrl* pHdrCtrl = (CHeaderCtrl*)(GetDlgItem(0));\r
        if (pHdrCtrl)\r
        {\r
-               for (int col = 0; col <= maxcol; col++)\r
+               int numcols = pHdrCtrl->GetItemCount();\r
+               for (int col = 0; col < numcols; 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
+                       // get width for this col last time from registry\r
+                       CString regentry;\r
+                       regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col);\r
+                       CRegDWORD regwidth(regentry, 0);\r
+                       int cx = regwidth;\r
+                       if (cx < nMinimumWidth)\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
+                               cx = nMinimumWidth;\r
+                       } else if (cx > nMaximumWidth)\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
+                               cx = nMaximumWidth;\r
                        }\r
 \r
                        SetColumnWidth(col, cx);\r
@@ -884,7 +849,9 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                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
+                       lstrcpyn(pItem->pszText,\r
+                               CAppUtils::FormatDateAndTime( pLogEntry->m_AuthorDate, m_DateFormat, true, true ), \r
+                               pItem->cchTextMax);\r
                break;\r
                \r
        case 5:\r
@@ -1177,7 +1144,7 @@ void CGitLogListBase::CopySelectionToClipBoard(bool HashOnly)
                                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)sDate, (LPCTSTR)CAppUtils::FormatDateAndTime( pLogEntry->m_AuthorDate, m_DateFormat ),\r
                                        (LPCTSTR)sMessage, pLogEntry->m_Subject+_T("\r\n")+pLogEntry->m_Body,\r
                                        (LPCTSTR)sPaths);\r
                                sClipdata +=  sLogCopyText;\r
@@ -1359,14 +1326,17 @@ int CGitLogListBase::FillGitShortLog()
        CString hash;\r
        int mask;\r
        mask = CGit::LOG_INFO_ONLY_HASH | CGit::LOG_INFO_BOUNDARY;\r
-       if(this->m_bAllBranch)\r
-               mask |= CGit::LOG_INFO_ALL_BRANCH;\r
+//     if(this->m_bAllBranch)\r
+       mask |= m_ShowMask;\r
 \r
        this->m_logEntries.ParserShortLog(path,hash,-1,mask);\r
        \r
 \r
        //this->m_logEntries.ParserFromLog();\r
-       SetItemCountEx(this->m_logEntries.size());\r
+       if(IsInWorkingThread())\r
+               PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL);\r
+       else\r
+               SetItemCountEx(this->m_logEntries.size());\r
 \r
        this->m_arShownList.RemoveAll();\r
 \r
@@ -1421,9 +1391,8 @@ void CGitLogListBase::OnNMDblclkLoglist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
          DiffSelectedRevWithPrevious();\r
 }\r
 \r
-int CGitLogListBase::FetchLogAsync(CALLBACK_PROCESS *proc,void * data)\r
+int CGitLogListBase::FetchLogAsync(void * data)\r
 {\r
-       m_ProcCallBack=proc;\r
        m_ProcData=data;\r
        m_bExitThread=FALSE;\r
        InterlockedExchange(&m_bThreadRunning, TRUE);\r
@@ -1464,8 +1433,9 @@ void CGitLogListBase::GetTimeRange(CTime &oldest, CTime &latest)
 UINT CGitLogListBase::LogThread()\r
 {\r
 \r
-       if(m_ProcCallBack)\r
-               m_ProcCallBack(m_ProcData,GITLOG_START);\r
+//     if(m_ProcCallBack)\r
+//             m_ProcCallBack(m_ProcData,GITLOG_START);\r
+       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_START,0);\r
 \r
        InterlockedExchange(&m_bThreadRunning, TRUE);\r
        InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
@@ -1477,18 +1447,15 @@ UINT CGitLogListBase::LogThread()
        //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
+       if(this->m_bExitThread)\r
+               return 0;\r
+#if 0\r
        RedrawItems(0, m_arShownList.GetCount());\r
-       SetRedraw(false);\r
-       ResizeAllListCtrlCols();\r
-       SetRedraw(true);\r
+//     SetRedraw(false);\r
+//     ResizeAllListCtrlCols();\r
+//     SetRedraw(true);\r
 \r
        if ( m_pStoreSelection )\r
        {\r
@@ -1507,9 +1474,9 @@ UINT CGitLogListBase::LogThread()
                        SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\r
                }\r
        }\r
+#endif\r
        InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
 \r
-       int index=0;\r
        unsigned int updated=0;\r
        int percent=0;\r
        CRect rect;\r
@@ -1522,8 +1489,6 @@ UINT CGitLogListBase::LogThread()
                                if(!m_logEntries.FetchFullInfo(i))\r
                                {\r
                                        updated++;\r
-                                       this->GetItemRect(i,&rect,LVIR_BOUNDS);\r
-                                       this->InvalidateRect(rect);\r
                                }\r
                                m_LogCache.AddCacheEntry(m_logEntries[i]);\r
 \r
@@ -1532,20 +1497,20 @@ UINT CGitLogListBase::LogThread()
                                updated++;\r
                                InterlockedExchange(&m_logEntries[i].m_IsUpdateing,FALSE);\r
                                InterlockedExchange(&m_logEntries[i].m_IsFull,TRUE);\r
-\r
-                               this->GetItemRect(i,&rect,LVIR_BOUNDS);\r
-                               this->InvalidateRect(rect);\r
                        }\r
                        \r
+                       ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM)i,0);\r
+\r
+                       if(m_bExitThread)\r
+                               return 0;\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
+                       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent,0);\r
 \r
-                       if(m_bExitThread)\r
-                               break;\r
+                       \r
                }\r
                if(updated==m_logEntries.size())\r
                        break;\r
@@ -1555,10 +1520,7 @@ UINT CGitLogListBase::LogThread()
        // 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
+       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_END,0);\r
 \r
        InterlockedExchange(&m_bThreadRunning, FALSE);\r
 \r
@@ -1810,6 +1772,7 @@ void CGitLogListBase::StartFilter()
        //ResizeAllListCtrlCols();\r
        SetRedraw(true);\r
        Invalidate();\r
+\r
 }\r
 void CGitLogListBase::RemoveFilter()\r
 {\r
@@ -1836,9 +1799,9 @@ void CGitLogListBase::RemoveFilter()
        DeleteAllItems();\r
        SetItemCountEx(ShownCountWithStopped());\r
        RedrawItems(0, ShownCountWithStopped());\r
-       SetRedraw(false);\r
-       ResizeAllListCtrlCols();\r
-       SetRedraw(true);\r
+//     SetRedraw(false);\r
+//     ResizeAllListCtrlCols();\r
+//     SetRedraw(true);\r
 \r
        InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
 }\r
@@ -1858,11 +1821,50 @@ void CGitLogListBase::Clear()
 \r
 void CGitLogListBase::OnDestroy()\r
 {\r
+       // save the column widths to the registry\r
+       SaveColumnWidths();\r
+\r
+       if(this->m_bThreadRunning)\r
+       {\r
+               this->m_bExitThread=true;\r
+               DWORD ret =::WaitForSingleObject(m_LoadingThread->m_hThread,20000);\r
+               if(ret == WAIT_TIMEOUT)\r
+                       TerminateThread();\r
+       }\r
        while(m_LogCache.SaveCache())\r
        {\r
-               if(CMessageBox::Show(NULL,_T("Can Save Log Cache to Disk,click yes for retry, click no for give up"),_T("TortoiseGit"),\r
+               if(CMessageBox::Show(NULL,_T("Cannot Save Log Cache to Disk. To retry click yes. To give up click no."),_T("TortoiseGit"),\r
                                                        MB_YESNO) == IDNO)\r
                                                        break;\r
        }\r
        CHintListCtrl::OnDestroy();\r
-}
\ No newline at end of file
+}\r
+\r
+LRESULT CGitLogListBase::OnLoad(WPARAM wParam,LPARAM lParam)\r
+{\r
+       CRect rect;\r
+       int i=(int)wParam;\r
+       this->GetItemRect(i,&rect,LVIR_BOUNDS);\r
+       this->InvalidateRect(rect);\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * Save column widths to the registry\r
+ */\r
+void CGitLogListBase::SaveColumnWidths()\r
+{\r
+       CHeaderCtrl* pHdrCtrl = (CHeaderCtrl*)(GetDlgItem(0));\r
+       if (pHdrCtrl)\r
+       {\r
+               int numcols = pHdrCtrl->GetItemCount();\r
+               for (int col = 0; col < numcols; col++)\r
+               {\r
+                       int width = GetColumnWidth( col );\r
+                       CString regentry;\r
+                       regentry.Format( _T("Software\\TortoiseGit\\log\\ColWidth%d"), col);\r
+                       CRegDWORD regwidth(regentry, 0);\r
+                       regwidth = width;       // this writes it to reg\r
+               }\r
+       }\r
+}\r