OSDN Git Service

Add multi-thread protection and correct log info label
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / LogDlg.cpp
index 88c1a17..41e84bf 100644 (file)
@@ -1,12 +1,9 @@
 // TortoiseGit - a Windows shell extension for easy version control\r
-\r
 // Copyright (C) 2003-2008 - TortoiseGit\r
-\r
 // This program is free software; you can redistribute it and/or\r
 // modify it under the terms of the GNU General Public License\r
 // as published by the Free Software Foundation; either version 2\r
 // of the License, or (at your option) any later version.\r
-\r
 // This program is distributed in the hope that it will be useful,\r
 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
@@ -25,7 +22,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
 //#include "RepositoryInfo.h"\r
 //#include "EditPropertiesDlg.h"\r
 #include "FileDiffDlg.h"\r
-\r
+#include "BrowseRefsDlg.h"\r
 \r
 const UINT CLogDlg::m_FindDialogMessage = RegisterWindowMessage(FINDMSGSTRING);\r
 \r
 \r
-\r
-\r
 IMPLEMENT_DYNAMIC(CLogDlg, CResizableStandAloneDialog)\r
 CLogDlg::CLogDlg(CWnd* pParent /*=NULL*/)\r
        : CResizableStandAloneDialog(CLogDlg::IDD, pParent)\r
        , 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
        , m_bSelect(false)\r
-       , m_regLastStrict(_T("Software\\TortoiseGit\\LastLogStrict"), FALSE)\r
        \r
        , m_bSelectionMustBeContinuous(false)\r
        , m_bShowBugtraqColumn(false)\r
@@ -84,10 +77,11 @@ CLogDlg::CLogDlg(CWnd* pParent /*=NULL*/)
        , m_maxChild(0)\r
        , m_bIncludeMerges(FALSE)\r
        , m_hAccel(NULL)\r
-       , m_bVista(false)\r
 {\r
        m_bFilterWithRegex = !!CRegDWORD(_T("Software\\TortoiseGit\\UseRegexFilter"), TRUE);\r
-       \r
+       m_bAllBranch=FALSE;\r
+       m_bFirstParent=FALSE;\r
+       m_bWholeProject=FALSE;\r
 }\r
 \r
 CLogDlg::~CLogDlg()\r
@@ -95,9 +89,6 @@ CLogDlg::~CLogDlg()
        \r
     m_CurrentFilteredChangedArray.RemoveAll();\r
        \r
-\r
-\r
-       \r
 }\r
 \r
 void CLogDlg::DoDataExchange(CDataExchange* pDX)\r
@@ -108,55 +99,61 @@ void CLogDlg::DoDataExchange(CDataExchange* pDX)
        DDX_Control(pDX, IDC_PROGRESS, m_LogProgress);\r
        DDX_Control(pDX, IDC_SPLITTERTOP, m_wndSplitter1);\r
        DDX_Control(pDX, IDC_SPLITTERBOTTOM, m_wndSplitter2);\r
-       DDX_Check(pDX, IDC_CHECK_STOPONCOPY, m_bStrict);\r
-       DDX_Text(pDX, IDC_SEARCHEDIT, m_sFilterText);\r
+       DDX_Text(pDX, IDC_SEARCHEDIT, m_LogList.m_sFilterText);\r
        DDX_Control(pDX, IDC_DATEFROM, m_DateFrom);\r
        DDX_Control(pDX, IDC_DATETO, m_DateTo);\r
        DDX_Control(pDX, IDC_HIDEPATHS, m_cHidePaths);\r
-       DDX_Control(pDX, IDC_GETALL, m_btnShow);\r
        DDX_Text(pDX, IDC_LOGINFO, m_sLogInfo);\r
-       DDX_Check(pDX, IDC_INCLUDEMERGE, m_bIncludeMerges);\r
+       DDX_Check(pDX, IDC_LOG_FIRSTPARENT, m_bFirstParent);\r
+       DDX_Check(pDX, IDC_LOG_ALLBRANCH,m_bAllBranch);\r
+       DDX_Check(pDX, IDC_SHOWWHOLEPROJECT,m_bWholeProject);\r
        DDX_Control(pDX, IDC_SEARCHEDIT, m_cFilter);\r
+       DDX_Control(pDX, IDC_STATIC_REF, m_staticRef);\r
 }\r
 \r
 BEGIN_MESSAGE_MAP(CLogDlg, CResizableStandAloneDialog)\r
        ON_REGISTERED_MESSAGE(m_FindDialogMessage, OnFindDialogMessage) \r
-       ON_BN_CLICKED(IDC_GETALL, OnBnClickedGetall)\r
-       ON_NOTIFY(NM_DBLCLK, IDC_LOGMSG, OnNMDblclkChangedFileList)\r
+       //ON_BN_CLICKED(IDC_GETALL, OnBnClickedGetall)\r
+       //ON_NOTIFY(NM_DBLCLK, IDC_LOGMSG, OnNMDblclkChangedFileList)\r
        ON_WM_CONTEXTMENU()\r
        ON_WM_SETCURSOR()\r
        ON_BN_CLICKED(IDHELP, OnBnClickedHelp)\r
        ON_NOTIFY(LVN_ITEMCHANGED, IDC_LOGLIST, OnLvnItemchangedLoglist)\r
        ON_NOTIFY(EN_LINK, IDC_MSGVIEW, OnEnLinkMsgview)\r
        ON_BN_CLICKED(IDC_STATBUTTON, OnBnClickedStatbutton)\r
+\r
        \r
        ON_MESSAGE(WM_FILTEREDIT_INFOCLICKED, OnClickedInfoIcon)\r
        ON_MESSAGE(WM_FILTEREDIT_CANCELCLICKED, OnClickedCancelFilter)\r
+\r
+       ON_MESSAGE(MSG_LOAD_PERCENTAGE,OnLogListLoading)\r
        \r
        ON_EN_CHANGE(IDC_SEARCHEDIT, OnEnChangeSearchedit)\r
        ON_WM_TIMER()\r
        ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DATETO, OnDtnDatetimechangeDateto)\r
        ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DATEFROM, OnDtnDatetimechangeDatefrom)\r
-       ON_BN_CLICKED(IDC_NEXTHUNDRED, OnBnClickedNexthundred)\r
-       ON_NOTIFY(NM_CUSTOMDRAW, IDC_LOGMSG, OnNMCustomdrawChangedFileList)\r
-       ON_NOTIFY(LVN_GETDISPINFO, IDC_LOGMSG, OnLvnGetdispinfoChangedFileList)\r
+       ON_BN_CLICKED(IDC_SHOWWHOLEPROJECT, OnBnClickShowWholeProject)\r
+       //ON_NOTIFY(NM_CUSTOMDRAW, IDC_LOGMSG, OnNMCustomdrawChangedFileList)\r
+       //ON_NOTIFY(LVN_GETDISPINFO, IDC_LOGMSG, OnLvnGetdispinfoChangedFileList)\r
        ON_NOTIFY(LVN_COLUMNCLICK,IDC_LOGLIST   , OnLvnColumnclick)\r
-       ON_NOTIFY(LVN_COLUMNCLICK, IDC_LOGMSG, OnLvnColumnclickChangedFileList)\r
+       //ON_NOTIFY(LVN_COLUMNCLICK, IDC_LOGMSG, OnLvnColumnclickChangedFileList)\r
        ON_BN_CLICKED(IDC_HIDEPATHS, OnBnClickedHidepaths)\r
+       ON_BN_CLICKED(IDC_LOG_ALLBRANCH,OnBnClickedAllBranch)\r
        \r
-       ON_BN_CLICKED(IDC_CHECK_STOPONCOPY, &CLogDlg::OnBnClickedCheckStoponcopy)\r
        ON_NOTIFY(DTN_DROPDOWN, IDC_DATEFROM, &CLogDlg::OnDtnDropdownDatefrom)\r
        ON_NOTIFY(DTN_DROPDOWN, IDC_DATETO, &CLogDlg::OnDtnDropdownDateto)\r
        ON_WM_SIZE()\r
-       ON_BN_CLICKED(IDC_INCLUDEMERGE, &CLogDlg::OnBnClickedIncludemerge)\r
+       ON_BN_CLICKED(IDC_LOG_FIRSTPARENT, &CLogDlg::OnBnClickedFirstParent)\r
        ON_BN_CLICKED(IDC_REFRESH, &CLogDlg::OnBnClickedRefresh)\r
+//     ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF, &CLogDlg::OnBnClickedBrowseRef)\r
+       ON_STN_CLICKED(IDC_STATIC_REF, &CLogDlg::OnBnClickedBrowseRef)\r
        ON_COMMAND(ID_LOGDLG_REFRESH,&CLogDlg::OnRefresh)\r
        ON_COMMAND(ID_LOGDLG_FIND,&CLogDlg::OnFind)\r
        ON_COMMAND(ID_LOGDLG_FOCUSFILTER,&CLogDlg::OnFocusFilter)\r
        ON_COMMAND(ID_EDIT_COPY, &CLogDlg::OnEditCopy)\r
 END_MESSAGE_MAP()\r
 \r
-void CLogDlg::SetParams(const CTGitPath& path, GitRev pegrev, GitRev startrev, GitRev endrev, int limit, BOOL bStrict /* = FALSE */, BOOL bSaveStrict /* = TRUE */)\r
+void CLogDlg::SetParams(const CTGitPath& path, GitRev pegrev, GitRev startrev, GitRev endrev, int limit /* = FALSE */)\r
 {\r
        m_path = path;\r
        m_pegrev = pegrev;\r
@@ -164,8 +161,6 @@ void CLogDlg::SetParams(const CTGitPath& path, GitRev pegrev, GitRev startrev, G
        m_LogRevision = startrev;\r
        m_endrev = endrev;\r
        m_hasWC = !path.IsUrl();\r
-       m_bStrict = bStrict;\r
-       m_bSaveStrict = bSaveStrict;\r
        m_limit = limit;\r
        if (::IsWindow(m_hWnd))\r
                UpdateData(FALSE);\r
@@ -173,29 +168,15 @@ void CLogDlg::SetParams(const CTGitPath& path, GitRev pegrev, GitRev startrev, G
 \r
 BOOL CLogDlg::OnInitDialog()\r
 {\r
+       CString temp;\r
        CResizableStandAloneDialog::OnInitDialog();\r
 \r
        m_hAccel = LoadAccelerators(AfxGetResourceHandle(),MAKEINTRESOURCE(IDR_ACC_LOGDLG));\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
        // use the state of the "stop on copy/rename" option from the last time\r
-       if (!m_bStrict)\r
-               m_bStrict = m_regLastStrict;\r
        UpdateData(FALSE);\r
-       CString temp;\r
-       if (m_limit)\r
-               temp.Format(IDS_LOG_SHOWNEXT, m_limit);\r
-       else\r
-               temp.Format(IDS_LOG_SHOWNEXT, (int)(DWORD)CRegDWORD(_T("Software\\TortoiseGit\\NumberOfLogs"), 100));\r
-\r
-       SetDlgItemText(IDC_NEXTHUNDRED, temp);\r
-\r
+       \r
        // set the font to use in the log message view, configured in the settings dialog\r
        CAppUtils::CreateFontForLogs(m_logFont);\r
        GetDlgItem(IDC_MSGVIEW)->SetFont(&m_logFont);\r
@@ -219,30 +200,13 @@ BOOL CLogDlg::OnInitDialog()
                m_bShowBugtraqColumn = true;\r
 \r
        //theme.SetWindowTheme(m_LogList.GetSafeHwnd(), L"Explorer", NULL);\r
-       theme.SetWindowTheme(m_ChangedFileListCtrl.GetSafeHwnd(), L"Explorer", NULL);\r
+       //theme.SetWindowTheme(m_ChangedFileListCtrl.GetSafeHwnd(), L"Explorer", NULL);\r
 \r
        // set up the columns\r
        m_LogList.DeleteAllItems();\r
        m_LogList.InsertGitColumn();\r
 \r
-       m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
-       m_ChangedFileListCtrl.DeleteAllItems();\r
-       int c = ((CHeaderCtrl*)(m_ChangedFileListCtrl.GetDlgItem(0)))->GetItemCount()-1;\r
-       while (c>=0)\r
-               m_ChangedFileListCtrl.DeleteColumn(c--);\r
-       temp.LoadString(IDS_PROGRS_ACTION);\r
-       m_ChangedFileListCtrl.InsertColumn(this->FILELIST_ACTION, temp);\r
-       temp.LoadString(IDS_LOG_FILE_LINE_ADD);\r
-       m_ChangedFileListCtrl.InsertColumn(this->FILELIST_ADD, temp);\r
-       temp.LoadString(IDS_LOG_FILE_LINE_DEL);\r
-       m_ChangedFileListCtrl.InsertColumn(this->FILELIST_DEL, temp);\r
-       temp.LoadString(IDS_PROGRS_PATH);\r
-       m_ChangedFileListCtrl.InsertColumn(this->FILELIST_PATH, temp);\r
-       \r
-       m_ChangedFileListCtrl.SetRedraw(false);\r
-       CAppUtils::ResizeAllListCtrlCols(&m_ChangedFileListCtrl);\r
-       m_ChangedFileListCtrl.SetRedraw(true);\r
-\r
+       m_ChangedFileListCtrl.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |SVNSLC_COLADD|SVNSLC_COLDEL , _T("LogDlg"),(SVNSLC_POPALL ^ (SVNSLC_POPCOMMIT|SVNSLC_POPREVERT)),false);\r
 \r
        GetDlgItem(IDC_LOGLIST)->UpdateData(FALSE);\r
 \r
@@ -263,8 +227,8 @@ BOOL CLogDlg::OnInitDialog()
        m_cFilter.SetValidator(this);\r
        \r
        AdjustControlSize(IDC_HIDEPATHS);\r
-       AdjustControlSize(IDC_CHECK_STOPONCOPY);\r
-       AdjustControlSize(IDC_INCLUDEMERGE);\r
+       AdjustControlSize(IDC_LOG_FIRSTPARENT);\r
+       AdjustControlSize(IDC_LOG_ALLBRANCH);\r
 \r
        GetClientRect(m_DlgOrigRect);\r
        m_LogList.GetClientRect(m_LogListOrigRect);\r
@@ -274,7 +238,11 @@ BOOL CLogDlg::OnInitDialog()
        m_DateFrom.SendMessage(DTM_SETMCSTYLE, 0, MCS_WEEKNUMBERS|MCS_NOTODAY|MCS_NOTRAILINGDATES|MCS_NOSELCHANGEONNAV);\r
        m_DateTo.SendMessage(DTM_SETMCSTYLE, 0, MCS_WEEKNUMBERS|MCS_NOTODAY|MCS_NOTRAILINGDATES|MCS_NOSELCHANGEONNAV);\r
 \r
+       m_staticRef.SetURL(CString());\r
+\r
        // resizable stuff\r
+       AddAnchor(IDC_STATIC_REF, TOP_LEFT);\r
+       //AddAnchor(IDC_BUTTON_BROWSE_REF, TOP_LEFT);\r
        AddAnchor(IDC_FROMLABEL, TOP_LEFT);\r
        AddAnchor(IDC_DATEFROM, TOP_LEFT);\r
        AddAnchor(IDC_TOLABEL, TOP_LEFT);\r
@@ -291,10 +259,10 @@ BOOL CLogDlg::OnInitDialog()
 \r
        AddAnchor(IDC_LOGINFO, BOTTOM_LEFT, BOTTOM_RIGHT);      \r
        AddAnchor(IDC_HIDEPATHS, BOTTOM_LEFT);  \r
-       AddAnchor(IDC_CHECK_STOPONCOPY, BOTTOM_LEFT);\r
-       AddAnchor(IDC_INCLUDEMERGE, BOTTOM_LEFT);\r
-       AddAnchor(IDC_GETALL, BOTTOM_LEFT);\r
-       AddAnchor(IDC_NEXTHUNDRED, BOTTOM_LEFT);\r
+       AddAnchor(IDC_LOG_ALLBRANCH,BOTTOM_LEFT);\r
+       AddAnchor(IDC_LOG_FIRSTPARENT, BOTTOM_LEFT);\r
+       //AddAnchor(IDC_GETALL, BOTTOM_LEFT);\r
+       AddAnchor(IDC_SHOWWHOLEPROJECT, BOTTOM_LEFT);\r
        AddAnchor(IDC_REFRESH, BOTTOM_LEFT);\r
        AddAnchor(IDC_STATBUTTON, BOTTOM_RIGHT);\r
        AddAnchor(IDC_PROGRESS, BOTTOM_LEFT, BOTTOM_RIGHT);\r
@@ -347,82 +315,99 @@ BOOL CLogDlg::OnInitDialog()
        if (m_bSelect)\r
        {\r
                // the dialog is used to select revisions\r
-               if (m_bSelectionMustBeContinuous)\r
-                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
-               else\r
-                       DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
+               // enable the OK button if appropriate\r
+               EnableOKButton();\r
        }\r
        else\r
        {\r
                // the dialog is used to just view log messages\r
+               // hide the OK button and set text on Cancel button to OK\r
                GetDlgItemText(IDOK, temp);\r
                SetDlgItemText(IDCANCEL, temp);\r
                GetDlgItem(IDOK)->ShowWindow(SW_HIDE);\r
        }\r
        \r
-       // set the choices for the "Show All" button\r
-       temp.LoadString(IDS_LOG_SHOWALL);\r
-       m_btnShow.AddEntry(temp);\r
-       temp.LoadString(IDS_LOG_SHOWRANGE);\r
-       m_btnShow.AddEntry(temp);\r
-       m_btnShow.SetCurrentEntry((LONG)CRegDWORD(_T("Software\\TortoiseGit\\ShowAllEntry")));\r
-\r
        m_mergedRevs.clear();\r
 \r
        // first start a thread to obtain the log messages without\r
        // blocking the dialog\r
-       m_tTo = 0;\r
-       m_tFrom = (DWORD)-1;\r
+       //m_tTo = 0;\r
+       //m_tFrom = (DWORD)-1;\r
 \r
-       m_LogList.FetchLogAsync(LogCallBack,this);\r
+       m_LogList.m_Path=m_path;\r
+       m_LogList.m_bShowWC = true;\r
+       m_LogList.FetchLogAsync(this);\r
 \r
        GetDlgItem(IDC_LOGLIST)->SetFocus();\r
+\r
+       ShowStartRef();\r
        return FALSE;\r
 }\r
 \r
-void CLogDlg::LogRunStatus(int cur)\r
+LRESULT CLogDlg::OnLogListLoading(WPARAM wParam, LPARAM /*lParam*/)\r
 {\r
+       int cur=(int)wParam;\r
+\r
        if( cur == GITLOG_START )\r
        {\r
                CString temp;\r
                temp.LoadString(IDS_PROGRESSWAIT);\r
 \r
-               // change the text of the close button to "Cancel" since now the thread\r
-               // is running, and simply closing the dialog doesn't work.\r
-               if (!GetDlgItem(IDOK)->IsWindowVisible())\r
-               {\r
-                       temp.LoadString(IDS_MSGBOX_CANCEL);\r
-                       SetDlgItemText(IDCANCEL, temp);\r
-               }\r
+               this->m_LogList.ShowText(temp, true);\r
 \r
                // We use a progress bar while getting the logs \r
-               //m_LogProgress.SetRange32(0, 100);\r
-               //m_LogProgress.SetPos(0);\r
+               m_LogProgress.SetRange32(0, 100);\r
+               m_LogProgress.SetPos(0);\r
 \r
                GetDlgItem(IDC_PROGRESS)->ShowWindow(TRUE);\r
 \r
-               DialogEnableWindow(IDC_GETALL, FALSE);\r
-               DialogEnableWindow(IDC_NEXTHUNDRED, FALSE);\r
-               DialogEnableWindow(IDC_CHECK_STOPONCOPY, FALSE);\r
-               DialogEnableWindow(IDC_INCLUDEMERGE, FALSE);\r
+               //DialogEnableWindow(IDC_GETALL, FALSE);\r
+               //DialogEnableWindow(IDC_SHOWWHOLEPROJECT, FALSE);\r
+               //DialogEnableWindow(IDC_LOG_FIRSTPARENT, FALSE);\r
                DialogEnableWindow(IDC_STATBUTTON, FALSE);\r
                DialogEnableWindow(IDC_REFRESH, FALSE);\r
-       }\r
+               DialogEnableWindow(IDC_HIDEPATHS,FALSE);\r
+               \r
 \r
-       if( cur == GITLOG_END)\r
+       }else if( cur == GITLOG_END)\r
        {\r
                \r
-               if (!m_bShowedAll)\r
-                       DialogEnableWindow(IDC_NEXTHUNDRED, TRUE);\r
+               if(this->m_LogList.HasText())\r
+               {\r
+                       this->m_LogList.ClearText();\r
+                       \r
+               }\r
+               UpdateLogInfoLabel();\r
+\r
+#if 0\r
+               //if (!m_bShowedAll)\r
+               DialogEnableWindow(IDC_SHOWWHOLEPROJECT, TRUE);\r
 \r
-               DialogEnableWindow(IDC_CHECK_STOPONCOPY, TRUE);\r
-               DialogEnableWindow(IDC_INCLUDEMERGE, TRUE);\r
+               //DialogEnableWindow(IDC_GETALL, TRUE);\r
+               DialogEnableWindow(IDC_LOG_FIRSTPARENT, TRUE);\r
                DialogEnableWindow(IDC_STATBUTTON, TRUE);\r
                DialogEnableWindow(IDC_REFRESH, TRUE);\r
+               DialogEnableWindow(IDC_HIDEPATHS,TRUE);\r
+\r
+//             PostMessage(WM_TIMER, LOGFILTER_TIMER);\r
+               GetDlgItem(IDC_PROGRESS)->ShowWindow(FALSE);\r
+               //CTime time=m_LogList.GetOldestTime();\r
+               CTime begin,end;\r
+               m_LogList.GetTimeRange(begin,end);\r
+               m_DateFrom.SetTime(&begin);\r
+               m_DateTo.SetTime(&end);\r
+#endif\r
 \r
-               PostMessage(WM_TIMER, LOGFILTER_TIMER);\r
-\r
+       }else\r
+       {\r
+               if(this->m_LogList.HasText())\r
+               {\r
+                       this->m_LogList.ClearText();\r
+                       UpdateLogInfoLabel();\r
+               }\r
+               m_LogProgress.SetPos(cur);\r
        }\r
+       return 0;\r
 }\r
 void CLogDlg::SetDlgTitle(bool bOffline)\r
 {\r
@@ -444,6 +429,8 @@ void CLogDlg::SetDlgTitle(bool bOffline)
        {\r
                if (m_path.IsUrl())\r
                        SetWindowText(m_sTitle + _T(" - ") + m_path.GetUIPathString());\r
+               else if (m_path.IsEmpty())\r
+                       SetWindowText(m_sTitle + _T(" - ") + CString(_T("Whole Project")));\r
                else if (m_path.IsDirectory())\r
                        SetWindowText(m_sTitle + _T(" - ") + m_path.GetWinPathString());\r
                else\r
@@ -468,7 +455,12 @@ void CLogDlg::EnableOKButton()
        if (m_bSelect)\r
        {\r
                // the dialog is used to select revisions\r
-               if (m_bSelectionMustBeContinuous)\r
+               if (m_bSelectionMustBeSingle)\r
+               {\r
+                       // enable OK button if only a single revision is selected\r
+                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()==1));\r
+               }\r
+               else if (m_bSelectionMustBeContinuous)\r
                        DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
                else\r
                        DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
@@ -483,17 +475,16 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        // and also populate the changed files list control\r
        // according to the selected revision(s).\r
 \r
-       CWnd * pMsgView = GetDlgItem(IDC_MSGVIEW);\r
+       CRichEditCtrl * pMsgView = (CRichEditCtrl*)GetDlgItem(IDC_MSGVIEW);\r
        // empty the log message view\r
        pMsgView->SetWindowText(_T(" "));\r
        // empty the changed files list\r
        m_ChangedFileListCtrl.SetRedraw(FALSE);\r
 //     InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
        m_currentChangedArray = NULL;\r
-       m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
+       //m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
        m_ChangedFileListCtrl.DeleteAllItems();\r
-       m_ChangedFileListCtrl.SetItemCountEx(0);\r
-\r
+       \r
        // if we're not here to really show a selected revision, just\r
        // get out of here after clearing the views, which is what is intended\r
        // if that flag is not set.\r
@@ -531,37 +522,71 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
                }\r
                GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(selIndex));\r
 \r
-               // set the log message text\r
-               pMsgView->SetWindowText(_T("*")+pLogEntry->m_Subject+_T("\n\n")+pLogEntry->m_Body);\r
-               // turn bug ID's into links if the bugtraq: properties have been set\r
-               // and we can find a match of those in the log message\r
-               m_ProjectProperties.FindBugID(pLogEntry->m_Body, pMsgView);\r
-               CAppUtils::FormatTextInRichEditControl(pMsgView);\r
-               m_currentChangedArray = &(pLogEntry->m_Files);\r
-               if (m_currentChangedArray == NULL)\r
+               if(!pLogEntry->m_IsFull)\r
                {\r
-//                     InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-                       m_ChangedFileListCtrl.SetRedraw(TRUE);\r
-                       return;\r
-               }\r
-#if 0\r
-               // fill in the changed files list control\r
-               if ((m_cHidePaths.GetState() & 0x0003)==BST_CHECKED)\r
+                       pMsgView->SetWindowText(_T("load ..."));\r
+               }else\r
                {\r
-                       m_CurrentFilteredChangedArray.RemoveAll();\r
-                       for (INT_PTR c = 0; c < m_currentChangedArray->GetCount(); ++c)\r
+                       // set the log message text\r
+                       pMsgView->SetWindowText(_T("Commit:")+pLogEntry->m_CommitHash.ToString()+_T("\r\n\r\n"));\r
+                       // turn bug ID's into links if the bugtraq: properties have been set\r
+                       // and we can find a match of those in the log message\r
+                       \r
+                       pMsgView->SetSel(-1,-1);\r
+                       CHARFORMAT2 format;\r
+                       SecureZeroMemory(&format, sizeof(CHARFORMAT2));\r
+                       format.cbSize = sizeof(CHARFORMAT2);\r
+                       format.dwMask = CFM_BOLD;\r
+                       format.dwEffects = CFE_BOLD;\r
+                       pMsgView->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);\r
+                       \r
+                       CString msg=_T("* ");\r
+                       msg+=pLogEntry->m_Subject;\r
+                       pMsgView->ReplaceSel(msg);\r
+\r
+                       pMsgView->SetSel(-1,-1);\r
+                       format.dwEffects = 0;\r
+                       pMsgView->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);\r
+                       \r
+                       msg=_T("\n\n");\r
+                       msg+=pLogEntry->m_Body;\r
+                       pMsgView->ReplaceSel(msg);\r
+\r
+                       CString text;\r
+                       pMsgView->GetWindowText(text);\r
+                       // the rich edit control doesn't count the CR char!\r
+                       // to be exact: CRLF is treated as one char.\r
+                       text.Replace(_T("\r"), _T(""));\r
+\r
+                       m_ProjectProperties.FindBugID(text, pMsgView);\r
+                       CAppUtils::FormatTextInRichEditControl(pMsgView);\r
+\r
+                       int HidePaths=m_cHidePaths.GetState() & 0x0003;\r
+                       CString matchpath=this->m_path.GetGitPathString();\r
+\r
+                       for(int i=0;i<pLogEntry->m_Files.GetCount() && (!matchpath.IsEmpty());i++)\r
                        {\r
-                               LogChangedPath * cpath = m_currentChangedArray->GetAt(c);\r
-                               if (cpath == NULL)\r
-                                       continue;\r
-                               if (m_currentChangedArray->GetAt(c)->sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0)\r
+                               if( m_bWholeProject )\r
+                                       break;\r
+\r
+                               ((CTGitPath&)pLogEntry->m_Files[i]).m_Action &= ~(CTGitPath::LOGACTIONS_HIDE|CTGitPath::LOGACTIONS_GRAY);\r
+                               \r
+                               if(pLogEntry->m_Files[i].GetGitPathString().Left(matchpath.GetLength()) != matchpath)\r
                                {\r
-                                       m_CurrentFilteredChangedArray.Add(cpath);\r
+                                       if(HidePaths==BST_CHECKED)\r
+                                               ((CTGitPath&)pLogEntry->m_Files[i]).m_Action |= CTGitPath::LOGACTIONS_HIDE;\r
+                                       if(HidePaths==BST_INDETERMINATE)\r
+                                               ((CTGitPath&)pLogEntry->m_Files[i]).m_Action |= CTGitPath::LOGACTIONS_GRAY;\r
                                }\r
                        }\r
-                       m_currentChangedArray = &m_CurrentFilteredChangedArray;\r
+                       m_ChangedFileListCtrl.UpdateWithGitPathList(pLogEntry->m_Files);\r
+                       m_ChangedFileListCtrl.m_CurrentVersion=pLogEntry->m_CommitHash;\r
+                       m_ChangedFileListCtrl.Show(SVNSLC_SHOWVERSIONED);\r
+\r
+                       m_ChangedFileListCtrl.SetRedraw(TRUE);\r
+                       return;\r
                }\r
-#endif\r
+\r
        }\r
        else\r
        {\r
@@ -574,6 +599,7 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        \r
        // redraw the views\r
 //     InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+#if 0\r
        if (m_currentChangedArray)\r
        {\r
                m_ChangedFileListCtrl.SetItemCountEx(m_currentChangedArray->GetCount());\r
@@ -589,7 +615,7 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
                m_ChangedFileListCtrl.SetItemCountEx(0);\r
                m_ChangedFileListCtrl.Invalidate();\r
        }\r
-       CAppUtils::ResizeAllListCtrlCols(&m_ChangedFileListCtrl);\r
+#endif\r
        // sort according to the settings\r
        if (m_nSortColumnPathList > 0)\r
                SetSortArrow(&m_ChangedFileListCtrl, m_nSortColumnPathList, m_bAscendingPathList);\r
@@ -599,204 +625,20 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
 \r
 }\r
 \r
-void CLogDlg::OnBnClickedGetall()\r
-{\r
-       GetAll();\r
-}\r
-\r
-void CLogDlg::GetAll(bool bForceAll /* = false */)\r
-{\r
-#if 0\r
-       // fetch all requested log messages, either the specified range or\r
-       // really *all* available log messages.\r
-       UpdateData();\r
-       INT_PTR entry = m_btnShow.GetCurrentEntry();\r
-       if (bForceAll)\r
-               entry = 0;\r
-\r
-       switch (entry)\r
-       {\r
-       case 0: // show all\r
-       \r
-               m_endrev = 0;\r
-               m_startrev = m_LogRevision;\r
-               if (m_bStrict)\r
-                       m_bShowedAll = true;\r
-\r
-               break;\r
-       case 1: // show range\r
-               {\r
-\r
-                       // ask for a revision range\r
-                       CRevisionRangeDlg dlg;\r
-                       dlg.SetStartRevision(m_startrev);\r
-                       dlg.SetEndRevision( (m_endrev>=0) ? m_endrev : 0);\r
-                       if (dlg.DoModal()!=IDOK)\r
-                       {\r
-                               return;\r
-                       }\r
-                       m_endrev = dlg.GetEndRevision();\r
-                       m_startrev = dlg.GetStartRevision();\r
-                       if (((m_endrev.IsNumber())&&(m_startrev.IsNumber()))||\r
-                               (m_endrev.IsHead()||m_startrev.IsHead()))\r
-                       {\r
-                               if (((LONG)m_startrev < (LONG)m_endrev)||\r
-                                       (m_endrev.IsHead()))\r
-                               {\r
-                                       git_revnum_t temp = m_startrev;\r
-                                       m_startrev = m_endrev;\r
-                                       m_endrev = temp;\r
-                               }\r
-                       }\r
-                       m_bShowedAll = false;\r
-               }\r
-\r
-               break;\r
-       }\r
-       m_ChangedFileListCtrl.SetItemCountEx(0);\r
-       m_ChangedFileListCtrl.Invalidate();\r
-       // We need to create CStoreSelection on the heap or else\r
-       // the variable will run out of the scope before the\r
-       // thread ends. Therefore we let the thread delete\r
-       // the instance.\r
-       m_pStoreSelection = new CStoreSelection(this);\r
-       m_LogList.SetItemCountEx(0);\r
-       m_LogList.Invalidate();\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       CWnd * pMsgView = GetDlgItem(IDC_MSGVIEW);\r
-       pMsgView->SetWindowText(_T(""));\r
-\r
-       SetSortArrow(&m_LogList, -1, true);\r
-\r
-       m_LogList.DeleteAllItems();\r
-       m_arShownList.RemoveAll();\r
-       m_logEntries.ClearAll();\r
-\r
-       m_logcounter = 0;\r
-       m_bCancelled = FALSE;\r
-       m_tTo = 0;\r
-       m_tFrom = (DWORD)-1;\r
-       m_limit = 0;\r
-\r
-       InterlockedExchange(&m_bThreadRunning, TRUE);\r
-       if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
-       {\r
-               InterlockedExchange(&m_bThreadRunning, FALSE);\r
-               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
-       }\r
-       GetDlgItem(IDC_LOGLIST)->UpdateData(FALSE);\r
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-#endif\r
-}\r
-\r
 void CLogDlg::OnBnClickedRefresh()\r
 {\r
-       m_limit = 0;\r
+       \r
        Refresh (true);\r
 }\r
 \r
-void CLogDlg::Refresh (bool autoGoOnline)\r
+void CLogDlg::Refresh (bool /*autoGoOnline*/)\r
 {\r
-#if 0\r
-       // refreshing means re-downloading the already shown log messages\r
-       UpdateData();\r
-       m_maxChild = 0;\r
-       m_childCounter = 0;\r
-\r
-       if ((m_limit == 0)||(m_bStrict)||(int(m_logEntries.size()-1) > m_limit))\r
-       {\r
-               if (m_logEntries.size() != 0)\r
-               {\r
-                       m_endrev = m_logEntries[m_logEntries.size()-1]->Rev;\r
-               }\r
-       }\r
-       m_startrev = -1;\r
-       m_bCancelled = FALSE;\r
-\r
-       // We need to create CStoreSelection on the heap or else\r
-       // the variable will run out of the scope before the\r
-       // thread ends. Therefore we let the thread delete\r
-       // the instance.\r
-       m_pStoreSelection = new CStoreSelection(this);\r
-       m_ChangedFileListCtrl.SetItemCountEx(0);\r
-       m_ChangedFileListCtrl.Invalidate();\r
-       m_LogList.SetItemCountEx(0);\r
-       m_LogList.Invalidate();\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       CWnd * pMsgView = GetDlgItem(IDC_MSGVIEW);\r
-       pMsgView->SetWindowText(_T(""));\r
-\r
-       SetSortArrow(&m_LogList, -1, true);\r
-\r
-       m_LogList.DeleteAllItems();\r
-       m_arShownList.RemoveAll();\r
-       m_logEntries.ClearAll();\r
-\r
-    // reset the cached HEAD property & go on-line\r
-\r
-    if (autoGoOnline)\r
-    {\r
-           SetDlgTitle (false);\r
-        logCachePool.GetRepositoryInfo().ResetHeadRevision (m_sUUID, m_sRepositoryRoot);\r
-    }\r
-\r
-       InterlockedExchange(&m_bThreadRunning, TRUE);\r
-       if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
-       {\r
-               InterlockedExchange(&m_bThreadRunning, FALSE);\r
-               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
-       }\r
-       GetDlgItem(IDC_LOGLIST)->UpdateData(FALSE);\r
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-#endif\r
+       m_limit = 0;\r
+       m_LogList.Refresh();\r
+       FillLogMessageCtrl(false);\r
 }\r
 \r
-void CLogDlg::OnBnClickedNexthundred()\r
-{\r
-#if 0\r
-       UpdateData();\r
-       // we have to fetch the next X log messages.\r
-       if (m_logEntries.size() < 1)\r
-       {\r
-               // since there weren't any log messages fetched before, just\r
-               // fetch all since we don't have an 'anchor' to fetch the 'next'\r
-               // messages from.\r
-               return GetAll(true);\r
-       }\r
-       git_revnum_t rev = m_logEntries[m_logEntries.size()-1]->Rev;\r
-\r
-       if (rev < 1)\r
-               return;         // do nothing! No more revisions to get\r
-\r
-       m_startrev = rev;\r
-       m_endrev = 0;\r
-       m_bCancelled = FALSE;\r
-\r
-    // rev is is revision we already have and we will receive it again\r
-    // -> fetch one extra revision to get NumberOfLogs *new* revisions\r
-\r
-       m_limit = (int)(DWORD)CRegDWORD(_T("Software\\TortoiseGit\\NumberOfLogs"), 100) +1;\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       SetSortArrow(&m_LogList, -1, true);\r
-       InterlockedExchange(&m_bThreadRunning, TRUE);\r
-       // We need to create CStoreSelection on the heap or else\r
-       // the variable will run out of the scope before the\r
-       // thread ends. Therefore we let the thread delete\r
-       // the instance.\r
-       m_pStoreSelection = new CStoreSelection(this);\r
 \r
-       // since we fetch the log from the last revision we already have,\r
-       // we have to remove that revision entry to avoid getting it twice\r
-       m_logEntries.pop_back();\r
-       if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
-       {\r
-               InterlockedExchange(&m_bThreadRunning, FALSE);\r
-               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
-       }\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       GetDlgItem(IDC_LOGLIST)->UpdateData(FALSE);\r
-#endif\r
-}\r
 \r
 BOOL CLogDlg::Cancel()\r
 {\r
@@ -822,22 +664,12 @@ void CLogDlg::SaveSplitterPos()
 void CLogDlg::OnCancel()\r
 {\r
        // canceling means stopping the working thread if it's still running.\r
-       // we do this by using the Subversion cancel callback.\r
-       // But canceling can also mean just to close the dialog, depending on the\r
-       // text shown on the cancel button (it could simply read "OK").\r
-       CString temp, temp2;\r
-       GetDlgItemText(IDOK, temp);\r
-       temp2.LoadString(IDS_MSGBOX_CANCEL);\r
-       if ((temp.Compare(temp2)==0)||(this->IsThreadRunning()))\r
-       {\r
-               m_bCancelled = true;\r
-               return;\r
+       if (this->IsThreadRunning())\r
+       {\r
+               m_LogList.TerminateThread();\r
        }\r
        UpdateData();\r
-       if (m_bSaveStrict)\r
-               m_regLastStrict = m_bStrict;\r
-       CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseGit\\ShowAllEntry"));\r
-       reg = m_btnShow.GetCurrentEntry();\r
+       \r
        SaveSplitterPos();\r
        __super::OnCancel();\r
 }\r
@@ -868,7 +700,7 @@ CString CLogDlg::MakeShortMessage(const CString& message)
        return sShortMessage;\r
 }\r
 \r
-BOOL CLogDlg::Log(git_revnum_t rev, const CString& author, const CString& date, const CString& message, LogChangedPathArray * cpaths,  int filechanges, BOOL copies, DWORD actions, BOOL haschildren)\r
+BOOL CLogDlg::Log(git_revnum_t /*rev*/, const CString& /*author*/, const CString& /*date*/, const CString& /*message*/, LogChangedPathArray * /*cpaths*/,  int /*filechanges*/, BOOL /*copies*/, DWORD /*actions*/, BOOL /*haschildren*/)\r
 {\r
 #if 0\r
        if (rev == SVN_INVALID_REVNUM)\r
@@ -974,24 +806,27 @@ GitRev g_rev;
 \r
 void CLogDlg::CopyChangedSelectionToClipBoard()\r
 {\r
-#if 0\r
+\r
        POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
        if (pos == NULL)\r
                return; // nothing is selected, get out of here\r
 \r
        CString sPaths;\r
 \r
-       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-       if (pos)\r
+//     CGitRev* pLogEntry = reinterpret_cast<CGitRev* >(m_LogList.m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
+//     if (pos)\r
        {\r
                POSITION pos = m_ChangedFileListCtrl.GetFirstSelectedItemPosition();\r
                while (pos)\r
                {\r
                        int nItem = m_ChangedFileListCtrl.GetNextSelectedItem(pos);\r
-                       sPaths += m_currentChangedPathList[nItem].GetGitPathString();\r
+                       CTGitPath *path = (CTGitPath*)m_ChangedFileListCtrl.GetItemData(nItem);\r
+                       if(path)\r
+                               sPaths += path->GetGitPathString();\r
                        sPaths += _T("\r\n");\r
                }\r
        }\r
+#if 0\r
        else\r
        {\r
                // only one revision is selected in the log dialog top pane\r
@@ -1024,12 +859,13 @@ void CLogDlg::CopyChangedSelectionToClipBoard()
                        }\r
                }\r
        }\r
+#endif\r
        sPaths.Trim();\r
        CStringUtils::WriteAsciiStringToClipboard(sPaths, GetSafeHwnd());\r
-#endif\r
+\r
 }\r
 \r
-BOOL CLogDlg::IsDiffPossible(LogChangedPath * changedpath, git_revnum_t rev)\r
+BOOL CLogDlg::IsDiffPossible(LogChangedPath * /*changedpath*/, git_revnum_t rev)\r
 {\r
 #if 0\r
        CString added, deleted;\r
@@ -1061,7 +897,7 @@ void CLogDlg::OnContextMenu(CWnd* pWnd, CPoint point)
        }\r
        else if (pWnd == &m_ChangedFileListCtrl)\r
        {\r
-               ShowContextMenuForChangedpaths(pWnd, point);\r
+               //ShowContextMenuForChangedpaths(pWnd, point);\r
        }\r
        else if ((selCount == 1)&&(pWnd == GetDlgItem(IDC_MSGVIEW)))\r
        {\r
@@ -1086,12 +922,12 @@ void CLogDlg::OnContextMenu(CWnd* pWnd, CPoint point)
                        sMenuItemText.LoadString(IDS_SCIEDIT_SELECTALL);\r
                        popup.AppendMenu(MF_STRING | MF_ENABLED, EM_SETSEL, sMenuItemText);\r
 \r
-                       if (selIndex >= 0)\r
-                       {\r
-                               popup.AppendMenu(MF_SEPARATOR);\r
-                               sMenuItemText.LoadString(IDS_LOG_POPUP_EDITLOG);\r
-                               popup.AppendMenu(MF_STRING | MF_ENABLED, CGitLogList::ID_EDITAUTHOR, sMenuItemText);\r
-                       }\r
+                       //if (selIndex >= 0)\r
+                       //{\r
+                       //      popup.AppendMenu(MF_SEPARATOR);\r
+                       //      sMenuItemText.LoadString(IDS_LOG_POPUP_EDITLOG);\r
+                       //      popup.AppendMenu(MF_STRING | MF_ENABLED, CGitLogList::ID_EDITAUTHOR, sMenuItemText);\r
+                       //}\r
 \r
                        int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
                        switch (cmd)\r
@@ -1248,11 +1084,36 @@ LRESULT CLogDlg::OnFindDialogMessage(WPARAM /*wParam*/, LPARAM /*lParam*/)
 \r
 void CLogDlg::OnOK()\r
 {\r
-#if 0 \r
        // since the log dialog is also used to select revisions for other\r
        // dialogs, we have to do some work before closing this dialog\r
        if (GetFocus() != GetDlgItem(IDOK))\r
                return; // if the "OK" button doesn't have the focus, do nothing: this prevents closing the dialog when pressing enter\r
+\r
+       \r
+       if (this->IsThreadRunning())\r
+       {\r
+               m_LogList.TerminateThread();\r
+       }\r
+       UpdateData();\r
+       // check that one and only one row is selected\r
+       if (m_LogList.GetSelectedCount() == 1)\r
+       {\r
+               // get the selected row\r
+               POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
+               int selIndex = m_LogList.GetNextSelectedItem(pos);\r
+               if (selIndex < m_LogList.m_arShownList.GetCount())\r
+               {\r
+                       // all ok, pick up the revision\r
+                       GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(selIndex));\r
+                       // extract the hash\r
+                       m_sSelectedHash = pLogEntry->m_CommitHash;\r
+               }\r
+       }\r
+       UpdateData(FALSE);\r
+       SaveSplitterPos();\r
+       __super::OnOK();\r
+       \r
+       #if 0 \r
        if (!GetDlgItem(IDOK)->IsWindowVisible() && GetFocus() != GetDlgItem(IDCANCEL))\r
                return; // the Cancel button works as the OK button. But if the cancel button has not the focus, do nothing.\r
 \r
@@ -1335,8 +1196,6 @@ void CLogDlg::OnOK()
                }\r
        }\r
        UpdateData();\r
-       if (m_bSaveStrict)\r
-               m_regLastStrict = m_bStrict;\r
        CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseGit\\ShowAllEntry"));\r
        reg = m_btnShow.GetCurrentEntry();\r
        SaveSplitterPos();\r
@@ -1490,21 +1349,21 @@ void CLogDlg::DoDiffFromLog(INT_PTR selIndex, GitRev* rev1, GitRev* rev2, bool b
        file1.Format(_T("%s%s_%s%s"),\r
                                temppath,                                               \r
                                (*m_currentChangedArray)[selIndex].GetBaseFilename(),\r
-                               rev1->m_CommitHash.Left(6),\r
+                               rev1->m_CommitHash.ToString().Left(6),\r
                                (*m_currentChangedArray)[selIndex].GetFileExtension());\r
 \r
        CString file2;\r
        file2.Format(_T("%s\\%s_%s%s"),\r
                                temppath,                                               \r
                                (*m_currentChangedArray)[selIndex].GetBaseFilename(),\r
-                               rev2->m_CommitHash.Left(6),\r
+                               rev2->m_CommitHash.ToString().Left(6),\r
                                (*m_currentChangedArray)[selIndex].GetFileExtension());\r
 \r
        CString cmd;\r
 \r
-       cmd.Format(_T("git.cmd cat-file -p %s:%s"),rev1->m_CommitHash,(*m_currentChangedArray)[selIndex].GetGitPathString());\r
+       cmd.Format(_T("git.exe cat-file -p %s:%s"),rev1->m_CommitHash,(*m_currentChangedArray)[selIndex].GetGitPathString());\r
        g_Git.RunLogFile(cmd,file1);\r
-       cmd.Format(_T("git.cmd cat-file -p %s:%s"),rev2->m_CommitHash,(*m_currentChangedArray)[selIndex].GetGitPathString());\r
+       cmd.Format(_T("git.exe cat-file -p %s:%s"),rev2->m_CommitHash,(*m_currentChangedArray)[selIndex].GetGitPathString());\r
        g_Git.RunLogFile(cmd,file2);\r
 \r
        CAppUtils::DiffFlags flags;\r
@@ -1586,7 +1445,7 @@ void CLogDlg::DoDiffFromLog(INT_PTR selIndex, GitRev* rev1, GitRev* rev2, bool b
        EnableOKButton();\r
 }\r
 \r
-BOOL CLogDlg::Open(bool bOpenWith,CString changedpath, git_revnum_t rev)\r
+BOOL CLogDlg::Open(bool /*bOpenWith*/,CString changedpath, git_revnum_t rev)\r
 {\r
 #if 0\r
        DialogEnableWindow(IDOK, FALSE);\r
@@ -1656,7 +1515,7 @@ BOOL CLogDlg::Open(bool bOpenWith,CString changedpath, git_revnum_t rev)
        return TRUE;\r
 }\r
 \r
-void CLogDlg::EditAuthor(const CLogDataVector& logs)\r
+void CLogDlg::EditAuthor(const CLogDataVector& /*logs*/)\r
 {\r
 #if 0\r
        CString url;\r
@@ -1735,7 +1594,7 @@ void CLogDlg::EditAuthor(const CLogDataVector& logs)
 #endif\r
 }\r
 \r
-void CLogDlg::EditLogMessage(int index)\r
+void CLogDlg::EditLogMessage(int /*index*/)\r
 {\r
 #if 0\r
        CString url;\r
@@ -1816,7 +1675,7 @@ void CLogDlg::EditLogMessage(int index)
        EnableOKButton();\r
 #endif\r
 }\r
-#if 0\r
+\r
 BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)\r
 {\r
        // Skip Ctrl-C when copying text out of the log message or search filter\r
@@ -1827,7 +1686,7 @@ BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)
                {\r
                        if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
                        {\r
-                               DiffSelectedRevWithPrevious();\r
+                               m_LogList.DiffSelectedRevWithPrevious();\r
                                return TRUE;\r
                        }\r
                }\r
@@ -1844,14 +1703,16 @@ BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)
                        return TRUE;\r
        }\r
        \r
-       m_tooltips.RelayEvent(pMsg);\r
+       if(::IsWindow(m_tooltips.m_hWnd))\r
+               m_tooltips.RelayEvent(pMsg);\r
        return __super::PreTranslateMessage(pMsg);\r
 }\r
-#endif\r
+\r
 \r
 BOOL CLogDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
 {\r
-       if (this->IsThreadRunning())\r
+       //if (this->IsThreadRunning())\r
+       if(m_LogList.m_bNoDispUpdates)\r
        {\r
                // only show the wait cursor over the list control\r
                if ((pWnd)&&\r
@@ -1881,14 +1742,15 @@ void CLogDlg::OnLvnItemchangedLoglist(NMHDR *pNMHDR, LRESULT *pResult)
 {\r
        LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
        *pResult = 0;\r
-       if (this->IsThreadRunning())\r
+       //if (this->IsThreadRunning())\r
+       if(m_LogList.m_bNoDispUpdates)\r
                return;\r
        if (pNMLV->iItem >= 0)\r
        {\r
                m_nSearchIndex = pNMLV->iItem;\r
                if (pNMLV->iSubItem != 0)\r
                        return;\r
-               if ((pNMLV->iItem == m_LogList.m_arShownList.GetCount())&&(m_bStrict)&&(1/*m_bStrictStopped*/))\r
+               if ((pNMLV->iItem == m_LogList.m_arShownList.GetCount()))\r
                {\r
                        // remove the selected state\r
                        if (pNMLV->uChanged & LVIF_STATE)\r
@@ -1935,33 +1797,161 @@ void CLogDlg::OnEnLinkMsgview(NMHDR *pNMHDR, LRESULT *pResult)
        *pResult = 0;\r
 }\r
 \r
+class CDateSorter\r
+{\r
+public:\r
+       class CCommitPointer\r
+       {\r
+       public:\r
+               CCommitPointer():m_cont(NULL){}\r
+               CCommitPointer(const CCommitPointer& P_Right)\r
+               : m_cont(NULL)\r
+               {\r
+                       *this = P_Right;\r
+               }\r
+\r
+               CCommitPointer& operator = (const CCommitPointer& P_Right)\r
+               {\r
+                       if(IsPointer())\r
+                       {\r
+                               (*m_cont->m_parDates)[m_place]                  = P_Right.GetDate();\r
+                               (*m_cont->m_parFileChanges)[m_place]    = P_Right.GetChanges();\r
+                               (*m_cont->m_parAuthors)[m_place]                = P_Right.GetAuthor();\r
+                       }\r
+                       else \r
+                       {\r
+                               m_Date                                                          = P_Right.GetDate();\r
+                               m_Changes                                                       = P_Right.GetChanges();\r
+                               m_csAuthor                                                      = P_Right.GetAuthor();\r
+                       }\r
+                       return *this;\r
+               }\r
+\r
+               void Clone(const CCommitPointer& P_Right)\r
+               {\r
+                       m_cont = P_Right.m_cont;\r
+                       m_place = P_Right.m_place;\r
+                       m_Date = P_Right.m_Date;\r
+                       m_Changes = P_Right.m_Changes;\r
+                       m_csAuthor = P_Right.m_csAuthor;\r
+               }\r
+\r
+               DWORD            GetDate()              const {return IsPointer() ? (*m_cont->m_parDates)[m_place] : m_Date;}\r
+               DWORD            GetChanges()   const {return IsPointer() ? (*m_cont->m_parFileChanges)[m_place] : m_Changes;}\r
+               CString          GetAuthor()    const {return IsPointer() ? (*m_cont->m_parAuthors)[m_place] : m_csAuthor;}\r
+\r
+               bool            IsPointer() const {return m_cont != NULL;}\r
+               //When pointer\r
+               CDateSorter* m_cont;\r
+               int                      m_place;\r
+\r
+               //When element\r
+               DWORD            m_Date;\r
+               DWORD            m_Changes;\r
+               CString          m_csAuthor;\r
+\r
+       };\r
+       class iterator : public std::iterator<std::random_access_iterator_tag, CCommitPointer>\r
+       {\r
+       public:\r
+               CCommitPointer m_ptr;\r
+\r
+               iterator(){}\r
+               iterator(const iterator& P_Right){*this = P_Right;}\r
+               iterator& operator=(const iterator& P_Right)\r
+               {\r
+                       m_ptr.Clone(P_Right.m_ptr);\r
+                       return *this;\r
+               }\r
+\r
+               CCommitPointer& operator*(){return m_ptr;}\r
+               CCommitPointer* operator->(){return &m_ptr;}\r
+               const CCommitPointer& operator*()const{return m_ptr;}\r
+               const CCommitPointer* operator->()const{return &m_ptr;}\r
+\r
+               iterator& operator+=(size_t P_iOffset){m_ptr.m_place += P_iOffset;return *this;}\r
+               iterator& operator-=(size_t P_iOffset){m_ptr.m_place -= P_iOffset;return *this;}\r
+               iterator operator+(size_t P_iOffset)const{iterator it(*this); it += P_iOffset;return it;}\r
+               iterator operator-(size_t P_iOffset)const{iterator it(*this); it -= P_iOffset;return it;}\r
+\r
+               iterator& operator++(){++m_ptr.m_place;return *this;}\r
+               iterator& operator--(){--m_ptr.m_place;return *this;}\r
+               iterator operator++(int){iterator it(*this);++*this;return it;}\r
+               iterator operator--(int){iterator it(*this);--*this;return it;}\r
+\r
+               size_t operator-(const iterator& P_itRight)const{return m_ptr.m_place - P_itRight->m_place;}\r
+\r
+               bool operator<(const iterator& P_itRight)const{return m_ptr.m_place < P_itRight->m_place;}\r
+               bool operator!=(const iterator& P_itRight)const{return m_ptr.m_place != P_itRight->m_place;}\r
+               bool operator==(const iterator& P_itRight)const{return m_ptr.m_place == P_itRight->m_place;}\r
+               bool operator>(const iterator& P_itRight)const{return m_ptr.m_place > P_itRight->m_place;}\r
+       };\r
+       iterator begin()\r
+       {\r
+               iterator it;\r
+               it->m_place = 0;\r
+               it->m_cont = this;\r
+               return it;\r
+       }\r
+       iterator end()\r
+       {\r
+               iterator it;\r
+               it->m_place = m_parDates->GetCount();\r
+               it->m_cont = this;\r
+               return it;\r
+       }\r
+\r
+       CDWordArray     *       m_parDates;\r
+       CDWordArray     *       m_parFileChanges;\r
+       CStringArray *  m_parAuthors;\r
+};\r
+\r
+class CDateSorterLess\r
+{\r
+public:\r
+       bool operator () (const CDateSorter::CCommitPointer& P_Left, const CDateSorter::CCommitPointer& P_Right) const\r
+       {\r
+               return P_Left.GetDate() > P_Right.GetDate(); //Last date first\r
+       }\r
+\r
+};\r
+\r
+\r
+\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
+\r
+       CDateSorter W_Sorter;\r
+       W_Sorter.m_parAuthors           = &m_arAuthorsFiltered;\r
+       W_Sorter.m_parDates                     = &m_arDatesFiltered;\r
+       W_Sorter.m_parFileChanges       = &m_arFileChangesFiltered;\r
+       std::sort(W_Sorter.begin(), W_Sorter.end(), CDateSorterLess());\r
+\r
        CStatGraphDlg dlg;\r
        dlg.m_parAuthors = &m_arAuthorsFiltered;\r
        dlg.m_parDates = &m_arDatesFiltered;\r
@@ -1971,265 +1961,10 @@ 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
-void CLogDlg::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
-       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 themes enabled)\r
-                                               if (!theme.IsAppThemed() || !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
-                       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
-\r
-                               // Get the selected state of the\r
-                               // item being drawn.\r
-                               LVITEM   rItem;\r
-                               SecureZeroMemory(&rItem, sizeof(LVITEM));\r
-                               rItem.mask  = LVIF_STATE;\r
-                               rItem.iItem = pLVCD->nmcd.dwItemSpec;\r
-                               rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
-                               m_LogList.GetItem(&rItem);\r
-\r
-                               CRect rect;\r
-                               m_LogList.GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
-\r
-                               // Fill the background\r
-                               if (theme.IsAppThemed() && m_bVista)\r
-                               {\r
-                                       theme.Open(m_hWnd, L"Explorer");\r
-                                       int state = LISS_NORMAL;\r
-                                       if (rItem.state & LVIS_SELECTED)\r
-                                       {\r
-                                               if (::GetFocus() == m_LogList.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 (theme.IsBackgroundPartiallyTransparent(LVP_LISTDETAIL, state))\r
-                                               theme.DrawParentBackground(m_hWnd, pLVCD->nmcd.hdc, &rect);\r
-\r
-                                       theme.DrawBackground(pLVCD->nmcd.hdc, LVP_LISTDETAIL, state, &rect, NULL);\r
-                               }\r
-                               else\r
-                               {\r
-                                       HBRUSH brush;\r
-                                       if (rItem.state & LVIS_SELECTED)\r
-                                       {\r
-                                               if (::GetFocus() == m_LogList.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(pLVCD->nmcd.hdc, &rect, brush);\r
-                                       ::DeleteObject(brush);\r
-                               }\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
-#endif\r
-\r
-void CLogDlg::OnNMCustomdrawChangedFileList(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
-       // First thing - check the draw stage. If it's the control's prepaint\r
-       // stage, then tell Windows we want messages for every item.\r
-\r
-       if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )\r
-       {\r
-               *pResult = CDRF_NOTIFYITEMDRAW;\r
-       }\r
-       else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )\r
-       {\r
-               // This is the prepaint stage for an item. Here's where we set the\r
-               // item's text color. Our return value will tell Windows to draw the\r
-               // item itself, but it will use the new color we set here.\r
-\r
-               // Tell Windows to paint the control itself.\r
-               *pResult = CDRF_DODEFAULT;\r
-\r
-               COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);\r
-               bool bGrayed = false;\r
-#if 0\r
-               if ((m_cHidePaths.GetState() & 0x0003)==BST_INDETERMINATE)\r
-               {\r
-                       if ((m_currentChangedArray)&&((m_currentChangedArray->GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)))\r
-                       {\r
-                               //if ((*m_currentChangedArray)[(pLVCD->nmcd.dwItemSpec)]sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)!=0)\r
-                               {\r
-                                       crText = GetSysColor(COLOR_GRAYTEXT);\r
-                                       bGrayed = true;\r
-                               }\r
-                       }\r
-                       else if (m_currentChangedPathList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
-                       {\r
-                               //if (m_currentChangedPathList[pLVCD->nmcd.dwItemSpec].GetGitPathString().Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)!=0)\r
-                               {\r
-                                       crText = GetSysColor(COLOR_GRAYTEXT);\r
-                                       bGrayed = true;\r
-                               }\r
-                       }\r
-               }\r
-\r
-#endif\r
-               if ((!bGrayed)&&(m_currentChangedArray)&&(m_currentChangedArray->GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec))\r
-               {\r
-                       DWORD action = ((*m_currentChangedArray)[pLVCD->nmcd.dwItemSpec]).m_Action;\r
-                       if (action == CTGitPath::LOGACTIONS_MODIFIED)\r
-                               crText = m_Colors.GetColor(CColors::Modified);\r
-                       if (action == CTGitPath::LOGACTIONS_REPLACED)\r
-                               crText = m_Colors.GetColor(CColors::Deleted);\r
-                       if (action == CTGitPath::LOGACTIONS_ADDED)\r
-                               crText = m_Colors.GetColor(CColors::Added);\r
-                       if (action == CTGitPath::LOGACTIONS_DELETED)\r
-                               crText = m_Colors.GetColor(CColors::Deleted);\r
-               }\r
-\r
-               // Store the color back in the NMLVCUSTOMDRAW struct.\r
-               pLVCD->clrText = crText;\r
-       }\r
-}\r
-\r
-void CLogDlg::DoSizeV1(int delta)\r
+void CLogDlg::DoSizeV1(int delta)\r
 {\r
 \r
        RemoveAnchor(IDC_LOGLIST);\r
@@ -2329,11 +2064,15 @@ void CLogDlg::SetSplitterRange()
 \r
 LRESULT CLogDlg::OnClickedInfoIcon(WPARAM /*wParam*/, LPARAM lParam)\r
 {\r
+       // FIXME: x64 version would get this function called with unexpected parameters.\r
+       if (!lParam)\r
+               return 0;\r
+\r
        RECT * rect = (LPRECT)lParam;\r
        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
@@ -2372,7 +2111,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
@@ -2383,42 +2122,28 @@ LRESULT CLogDlg::OnClickedInfoIcon(WPARAM /*wParam*/, LPARAM lParam)
 \r
 LRESULT CLogDlg::OnClickedCancelFilter(WPARAM /*wParam*/, LPARAM /*lParam*/)\r
 {\r
-#if 0\r
+\r
        KillTimer(LOGFILTER_TIMER);\r
 \r
-       m_sFilterText.Empty();\r
+       m_LogList.m_sFilterText.Empty();\r
        UpdateData(FALSE);\r
        theApp.DoWaitCursor(1);\r
        CStoreSelection storeselection(this);\r
        FillLogMessageCtrl(false);\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       m_arShownList.RemoveAll();\r
 \r
-       // reset the time filter too\r
-       m_timFrom = (__time64_t(m_tFrom));\r
-       m_timTo = (__time64_t(m_tTo));\r
-       m_DateFrom.SetTime(&m_timFrom);\r
-       m_DateTo.SetTime(&m_timTo);\r
-       m_DateFrom.SetRange(&m_timFrom, &m_timTo);\r
-       m_DateTo.SetRange(&m_timFrom, &m_timTo);\r
+       m_LogList.RemoveFilter();\r
+\r
+       CTime begin,end;\r
+       m_LogList.GetTimeRange(begin,end);\r
+       m_DateFrom.SetTime(&begin);\r
+       m_DateTo.SetTime(&end);\r
 \r
-       for (DWORD i=0; i<m_logEntries.size(); ++i)\r
-       {\r
-               m_arShownList.Add(m_logEntries[i]);\r
-       }\r
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-       m_LogList.DeleteAllItems();\r
-       m_LogList.SetItemCountEx(ShownCountWithStopped());\r
-       m_LogList.RedrawItems(0, ShownCountWithStopped());\r
-       m_LogList.SetRedraw(false);\r
-       ResizeAllListCtrlCols();\r
-       m_LogList.SetRedraw(true);\r
        theApp.DoWaitCursor(-1);\r
        GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_HIDE);\r
        GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_SHOW);\r
        GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
        UpdateLogInfoLabel();\r
-#endif\r
+\r
        return 0L;      \r
 }\r
 \r
@@ -2426,7 +2151,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
@@ -2448,371 +2173,15 @@ void CLogDlg::SetFilterCueText()
        temp = _T("   ")+temp;\r
        m_cFilter.SetCueBanner(temp);\r
 }\r
-#if 0\r
-void CLogDlg::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 || m_bThreadRunning || 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
-       // 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
-#endif\r
-void CLogDlg::OnLvnGetdispinfoChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
-{\r
-\r
-#if 0\r
-       NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);\r
-\r
-       //Create a pointer to the item\r
-       LV_ITEM* pItem= &(pDispInfo)->item;\r
-\r
-       *pResult = 0;\r
-       if ((m_bNoDispUpdates)||(m_bThreadRunning))\r
-       {\r
-               if (pItem->mask & LVIF_TEXT)\r
-                       lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
-               return;\r
-       }\r
-       if ((m_currentChangedArray!=NULL)&&(pItem->iItem >= m_currentChangedArray->GetCount()))\r
-       {\r
-               if (pItem->mask & LVIF_TEXT)\r
-                       lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
-               return;\r
-       }\r
-       if ((m_currentChangedArray==NULL)&&(pItem->iItem >= m_currentChangedPathList.GetCount()))\r
-       {\r
-               if (pItem->mask & LVIF_TEXT)\r
-                       lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
-               return;\r
-       }\r
-       CTGitPath lcpath = NULL;\r
-       if (m_currentChangedArray)\r
-               lcpath = (*m_currentChangedArray)[pItem->iItem];\r
-       //Does the list need text information?\r
-       if (pItem->mask & LVIF_TEXT)\r
-       {\r
-               //Which column?\r
-               switch (pItem->iSubItem)\r
-               {\r
-               case this->FILELIST_ACTION:     //Action\r
-#if 0\r
-                       if (lcpath)\r
-                               lstrcpyn(pItem->pszText, (LPCTSTR)lcpath->GetAction(), pItem->cchTextMax);\r
-                       else\r
-                               lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);                            \r
-#endif\r
-                       lstrcpyn(pItem->pszText, (LPCTSTR)lcpath.GetActionName(), pItem->cchTextMax);\r
-\r
-                       break;\r
-\r
-               case this->FILELIST_ADD: //add\r
-#if 0\r
-                       if (lcpath)\r
-                               lstrcpyn(pItem->pszText, (LPCTSTR)lcpath->sPath, pItem->cchTextMax);\r
-                       else\r
-                               lstrcpyn(pItem->pszText, (LPCTSTR)m_currentChangedPathList[pItem->iItem].GetGitPathString(), pItem->cchTextMax);\r
-#endif\r
-                       lstrcpyn(pItem->pszText, (LPCTSTR)lcpath.m_StatAdd, pItem->cchTextMax);\r
-                       break;\r
-\r
-               case this->FILELIST_DEL: //del\r
-#if 0\r
-                       if (lcpath)\r
-                               lstrcpyn(pItem->pszText, (LPCTSTR)lcpath->sCopyFromPath, pItem->cchTextMax);\r
-                       else\r
-                               lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
-#endif\r
-                       lstrcpyn(pItem->pszText, (LPCTSTR)lcpath.m_StatDel, pItem->cchTextMax);\r
-                       break;\r
-               case this->FILELIST_PATH: //path\r
-#if 0\r
-                       if ((lcpath==NULL)||(lcpath->sCopyFromPath.IsEmpty()))\r
-                               lstrcpyn(pItem->pszText, _T(""), pItem->cchTextMax);\r
-                       else\r
-                               _stprintf_s(pItem->pszText, pItem->cchTextMax, _T("%ld"), lcpath->lCopyFromRev);\r
-#endif\r
-                       lstrcpyn(pItem->pszText, (LPCTSTR)lcpath.GetGitPathString(), pItem->cchTextMax);\r
-                       break;\r
-               }\r
-       }\r
-#endif\r
-       *pResult = 0;\r
-}\r
-\r
-void CLogDlg::OnEnChangeSearchedit()\r
-{\r
-#if 0\r
-       UpdateData();\r
-       if (m_sFilterText.IsEmpty())\r
-       {\r
-               CStoreSelection storeselection(this);\r
-               // clear the filter, i.e. make all entries appear\r
-               theApp.DoWaitCursor(1);\r
-               KillTimer(LOGFILTER_TIMER);\r
-               FillLogMessageCtrl(false);\r
-               InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-               m_arShownList.RemoveAll();\r
-               for (DWORD i=0; i<m_logEntries.size(); ++i)\r
-               {\r
-                       if (IsEntryInDateRange(i))\r
-                               m_arShownList.Add(m_logEntries[i]);\r
-               }\r
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-               m_LogList.DeleteAllItems();\r
-               m_LogList.SetItemCountEx(ShownCountWithStopped());\r
-               m_LogList.RedrawItems(0, ShownCountWithStopped());\r
-               m_LogList.SetRedraw(false);\r
-               ResizeAllListCtrlCols();\r
-               m_LogList.SetRedraw(true);\r
-               theApp.DoWaitCursor(-1);\r
-               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_HIDE);\r
-               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_SHOW);\r
-               GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
-               DialogEnableWindow(IDC_STATBUTTON, !(((m_bThreadRunning)||(m_arShownList.IsEmpty()))));\r
-               return;\r
-       }\r
-       if (Validate(m_sFilterText))\r
-               SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
-       else\r
-               KillTimer(LOGFILTER_TIMER);\r
-#endif\r
-}\r
-\r
-bool CLogDlg::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
 bool CLogDlg::Validate(LPCTSTR string)\r
 {\r
        if (!m_bFilterWithRegex)\r
                return true;\r
        tr1::wregex pat;\r
-       return ValidateRegexp(string, pat, false);\r
+       return m_LogList.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
@@ -2827,7 +2196,7 @@ void CLogDlg::OnTimer(UINT_PTR nIDEvent)
                CWnd * focusWnd = GetFocus();\r
                bool bSetFocusToFilterControl = ((focusWnd != GetDlgItem(IDC_DATEFROM))&&(focusWnd != GetDlgItem(IDC_DATETO))\r
                        && (focusWnd != GetDlgItem(IDC_LOGLIST)));\r
-               if (m_sFilterText.IsEmpty())\r
+               if (m_LogList.m_sFilterText.IsEmpty())\r
                {\r
                        DialogEnableWindow(IDC_STATBUTTON, !(((this->IsThreadRunning())||(m_LogList.m_arShownList.IsEmpty()))));\r
                        // do not return here!\r
@@ -2841,18 +2210,8 @@ void CLogDlg::OnTimer(UINT_PTR nIDEvent)
                FillLogMessageCtrl(false);\r
 \r
                // now start filter the log list\r
-//             InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-               RecalculateShownList(&m_LogList.m_arShownList);\r
-//             InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-\r
+               m_LogList.StartFilter();\r
 \r
-               m_LogList.DeleteAllItems();\r
-               m_LogList.SetItemCountEx(m_LogList.ShownCountWithStopped());\r
-               m_LogList.RedrawItems(0, m_LogList.ShownCountWithStopped());\r
-               m_LogList.SetRedraw(false);\r
-               m_LogList.ResizeAllListCtrlCols();\r
-               m_LogList.SetRedraw(true);\r
-               m_LogList.Invalidate();\r
                if ( m_LogList.GetItemCount()==1 )\r
                {\r
                        m_LogList.SetSelectionMark(0);\r
@@ -2876,9 +2235,9 @@ void CLogDlg::OnDtnDatetimechangeDateto(NMHDR * /*pNMHDR*/, LRESULT *pResult)
        try\r
        {\r
                CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 23, 59, 59);\r
-               if (time.GetTime() != m_tTo)\r
+               if (time.GetTime() != m_LogList.m_To.GetTime())\r
                {\r
-                       m_tTo = (DWORD)time.GetTime();\r
+                       m_LogList.m_To = (DWORD)time.GetTime();\r
                        SetTimer(LOGFILTER_TIMER, 10, NULL);\r
                }\r
        }\r
@@ -2896,9 +2255,9 @@ void CLogDlg::OnDtnDatetimechangeDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult)
        try\r
        {\r
                CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 0, 0, 0);\r
-               if (time.GetTime() != m_tFrom)\r
+               if (time.GetTime() != m_LogList.m_From.GetTime())\r
                {\r
-                       m_tFrom = (DWORD)time.GetTime();\r
+                       m_LogList.m_From = (DWORD)time.GetTime();\r
                        SetTimer(LOGFILTER_TIMER, 10, NULL);\r
                }\r
        }\r
@@ -2909,18 +2268,9 @@ 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
+CTGitPathList CLogDlg::GetChangedPathsFromSelectedRevisions(bool /*bRelativePaths*/ /* = false */, bool /*bUseFilter*/ /* = true */)\r
 {\r
        CTGitPathList pathList;\r
 #if 0\r
@@ -2964,7 +2314,7 @@ CTGitPathList CLogDlg::GetChangedPathsFromSelectedRevisions(bool bRelativePaths
        return pathList;\r
 }\r
 \r
-void CLogDlg::SortByColumn(int nSortColumn, bool bAscending)\r
+void CLogDlg::SortByColumn(int /*nSortColumn*/, bool /*bAscending*/)\r
 {\r
 #if 0\r
        switch(nSortColumn)\r
@@ -3030,6 +2380,7 @@ void CLogDlg::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
 {\r
        if (this->IsThreadRunning())\r
                return;         //no sorting while the arrays are filled\r
+#if 0\r
        LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
        const int nColumn = pNMLV->iSubItem;\r
        m_bAscending = nColumn == m_nSortColumn ? !m_bAscending : TRUE;\r
@@ -3039,16 +2390,7 @@ void CLogDlg::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
        SortShownListArray();\r
        m_LogList.Invalidate();\r
        UpdateLogInfoLabel();\r
-       // the "next 100" button only makes sense if the log messages\r
-       // are sorted by revision in descending order\r
-       if ((m_nSortColumn)||(m_bAscending))\r
-       {\r
-               DialogEnableWindow(IDC_NEXTHUNDRED, false);\r
-       }\r
-       else\r
-       {\r
-               DialogEnableWindow(IDC_NEXTHUNDRED, true);\r
-       }\r
+#endif\r
        *pResult = 0;\r
 }\r
 \r
@@ -3086,8 +2428,9 @@ void CLogDlg::SetSortArrow(CListCtrl * control, int nColumn, bool bAscending)
                pHeader->SetItem(nColumn, &HeaderItem);\r
        }\r
 }\r
-void CLogDlg::OnLvnColumnclickChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
+void CLogDlg::OnLvnColumnclickChangedFileList(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/)\r
 {\r
+#if 0\r
        if (this->IsThreadRunning())\r
                return;         //no sorting while the arrays are filled\r
        if (m_currentChangedArray == NULL)\r
@@ -3101,12 +2444,13 @@ void CLogDlg::OnLvnColumnclickChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)
        SetSortArrow(&m_ChangedFileListCtrl, m_nSortColumnPathList, m_bAscendingPathList);\r
        m_ChangedFileListCtrl.Invalidate();\r
        *pResult = 0;\r
+#endif\r
 }\r
 \r
 int CLogDlg::m_nSortColumnPathList = 0;\r
 bool CLogDlg::m_bAscendingPathList = false;\r
 \r
-int CLogDlg::SortCompare(const void * pElem1, const void * pElem2)\r
+int CLogDlg::SortCompare(const void * /*pElem1*/, const void * /*pElem2*/)\r
 {\r
 #if 0\r
        LogChangedPath * cpath1 = *((LogChangedPath**)pElem1);\r
@@ -3140,89 +2484,6 @@ int CLogDlg::SortCompare(const void * pElem1, const void * pElem2)
        return 0;\r
 }\r
 \r
-#if 0\r
-void CLogDlg::ResizeAllListCtrlCols()\r
-{\r
-\r
-       const int nMinimumWidth = ICONITEMBORDER+16*4;\r
-       int maxcol = ((CHeaderCtrl*)(m_LogList.GetDlgItem(0)))->GetItemCount()-1;\r
-       int nItemCount = m_LogList.GetItemCount();\r
-       TCHAR textbuf[MAX_PATH];\r
-       CHeaderCtrl * pHdrCtrl = (CHeaderCtrl*)(m_LogList.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 = m_LogList.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 = m_LogList.GetStringWidth(m_LogList.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
-                                               m_LogList.SendMessage(WM_SETFONT, (WPARAM)m_boldFont, NULL);\r
-                                               linewidth = m_LogList.GetStringWidth(m_LogList.GetItemText(index, col)) + 14;\r
-                                               // restore the system font\r
-                                               m_LogList.SendMessage(WM_SETFONT, NULL, NULL);\r
-                                       }\r
-                               }\r
-                               if (index == 0)\r
-                               {\r
-                                       // add the image size\r
-                                       CImageList * pImgList = m_LogList.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
-\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
-                       m_LogList.SetColumnWidth(col, cx);\r
-               }\r
-       }\r
-\r
-}\r
-#endif\r
-\r
 void CLogDlg::OnBnClickedHidepaths()\r
 {\r
        FillLogMessageCtrl();\r
@@ -3250,37 +2511,32 @@ void CLogDlg::OnBnClickedCheckStoponcopy()
        Refresh();\r
 }\r
 \r
-void CLogDlg::OnBnClickedIncludemerge()\r
-{\r
-#if 0\r
-       m_endrev = 0;\r
-\r
-       m_limit = 0;\r
-#endif\r
-       Refresh();\r
-}\r
 \r
 void CLogDlg::UpdateLogInfoLabel()\r
 {\r
-#if 0\r
-       git_revnum_t rev1 = 0;\r
-       git_revnum_t rev2 = 0;\r
+\r
+       git_revnum_t rev1 ;\r
+       git_revnum_t rev2 ;\r
        long selectedrevs = 0;\r
-       if (m_arShownList.GetCount())\r
-       {\r
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(0));\r
-               rev1 = pLogEntry->Rev;\r
-               pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_arShownList.GetCount()-1));\r
-               rev2 = pLogEntry->Rev;\r
+       int count =m_LogList.m_arShownList.GetCount();\r
+       int start = 0;\r
+       if (count)\r
+       {\r
+               if(this->m_LogList.m_bShowWC)\r
+                       start = 1;\r
+               rev1 = (reinterpret_cast<GitRev*>(m_LogList.m_arShownList.GetAt(start)))->m_CommitHash;\r
+               //pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_arShownList.GetCount()-1));\r
+               rev2 =  (reinterpret_cast<GitRev*>(m_LogList.m_arShownList.GetAt(count-1)))->m_CommitHash;\r
                selectedrevs = m_LogList.GetSelectedCount();\r
        }\r
        CString sTemp;\r
-       sTemp.Format(IDS_LOG_LOGINFOSTRING, m_arShownList.GetCount(), rev2, rev1, selectedrevs);\r
+       sTemp.Format(_T("Showing %ld revision(s), from revision %s to revision %s - %ld revision(s) selected"), count - start, rev2.Left(6), rev1.Left(6), selectedrevs);\r
        m_sLogInfo = sTemp;\r
-#endif\r
+\r
        UpdateData(FALSE);\r
 }\r
 \r
+#if 0\r
 void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)\r
 {\r
 \r
@@ -3816,6 +3072,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)
 \r
        } // if (popup.CreatePopupMenu())\r
 }\r
+#endif\r
 \r
 void CLogDlg::OnDtnDropdownDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
 {\r
@@ -3844,9 +3101,12 @@ void CLogDlg::OnSize(UINT nType, int cx, int cy)
 \r
 void CLogDlg::OnRefresh()\r
 {\r
-       if (GetDlgItem(IDC_GETALL)->IsWindowEnabled())\r
+       //if (GetDlgItem(IDC_GETALL)->IsWindowEnabled())\r
+       ShowStartRef();\r
        {\r
                m_limit = 0;\r
+               this->m_LogProgress.SetPos(0);\r
+               \r
                Refresh (true);\r
        }\r
 }\r
@@ -3907,3 +3167,146 @@ CString CLogDlg::GetAbsoluteUrlFromRelativeUrl(const CString& url)
 }\r
 \r
 \r
+void CLogDlg::OnEnChangeSearchedit()\r
+{\r
+       UpdateData();\r
+       if (m_LogList.m_sFilterText.IsEmpty())\r
+       {\r
+               CStoreSelection storeselection(this);\r
+               // clear the filter, i.e. make all entries appear\r
+               theApp.DoWaitCursor(1);\r
+               KillTimer(LOGFILTER_TIMER);\r
+               FillLogMessageCtrl(false);\r
+               m_LogList.StartFilter();\r
+#if 0\r
+               InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+               m_arShownList.RemoveAll();\r
+               for (DWORD i=0; i<m_logEntries.size(); ++i)\r
+               {\r
+                       if (IsEntryInDateRange(i))\r
+                               m_arShownList.Add(m_logEntries[i]);\r
+               }\r
+               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+               m_LogList.DeleteAllItems();\r
+               m_LogList.SetItemCountEx(ShownCountWithStopped());\r
+               m_LogList.RedrawItems(0, ShownCountWithStopped());\r
+               m_LogList.SetRedraw(false);\r
+               ResizeAllListCtrlCols();\r
+               m_LogList.SetRedraw(true);\r
+#endif\r
+               theApp.DoWaitCursor(-1);\r
+               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_HIDE);\r
+               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_SHOW);\r
+               GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
+               DialogEnableWindow(IDC_STATBUTTON, !(((this->IsThreadRunning())||(m_LogList.m_arShownList.IsEmpty()))));\r
+               return;\r
+       }\r
+       if (Validate(m_LogList.m_sFilterText))\r
+               SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
+       else\r
+               KillTimer(LOGFILTER_TIMER);\r
+\r
+}\r
+\r
+void CLogDlg::OnBnClickedAllBranch()\r
+{\r
+       this->UpdateData();\r
+\r
+       if(this->m_bAllBranch)\r
+               m_LogList.m_ShowMask|=CGit::LOG_INFO_ALL_BRANCH;\r
+       else\r
+               m_LogList.m_ShowMask&=~CGit::LOG_INFO_ALL_BRANCH;\r
+\r
+       OnRefresh();\r
+\r
+       FillLogMessageCtrl(false);\r
+}\r
+\r
+void CLogDlg::OnBnClickedBrowseRef()\r
+{\r
+       CString newRef = CBrowseRefsDlg::PickRef(false,m_LogList.GetStartRef());        \r
+       if(newRef.IsEmpty())\r
+               return;\r
+\r
+       SetStartRef(newRef);\r
+       ((CButton*)GetDlgItem(IDC_LOG_ALLBRANCH))->SetCheck(0);\r
+\r
+       OnBnClickedAllBranch();\r
+}\r
+\r
+void CLogDlg::ShowStartRef()\r
+{\r
+       //Show ref name on top\r
+       if(!::IsWindow(m_hWnd))\r
+               return;\r
+       if(m_bAllBranch)\r
+       {\r
+               m_staticRef.SetWindowText(L"<All Branches>");\r
+               m_staticRef.Invalidate(TRUE);\r
+               return;\r
+       }\r
+\r
+       CString showStartRef = m_LogList.GetStartRef();\r
+       if(showStartRef.IsEmpty())\r
+       {\r
+               //Ref name is HEAD\r
+               if( g_Git.Run(L"git symbolic-ref HEAD",&showStartRef,CP_UTF8) )\r
+                       showStartRef = _T("<No branch>");\r
+               showStartRef.Trim(L"\r\n\t ");\r
+       }\r
+\r
+\r
+       if(wcsncmp(showStartRef,L"refs/",5) == 0)\r
+               showStartRef = showStartRef.Mid(5);\r
+       if(wcsncmp(showStartRef,L"heads/",6) == 0)\r
+               showStartRef = showStartRef.Mid(6);\r
+\r
+       m_staticRef.SetWindowText(showStartRef);\r
+       m_staticRef.Invalidate(TRUE);\r
+}\r
+\r
+void CLogDlg::SetStartRef(const CString& StartRef)\r
+{\r
+       m_LogList.SetStartRef(StartRef);\r
+\r
+       ShowStartRef();\r
+}\r
+\r
+\r
+\r
+void CLogDlg::OnBnClickedFirstParent()\r
+{\r
+       this->UpdateData();\r
+\r
+       if(this->m_bFirstParent)\r
+               m_LogList.m_ShowMask|=CGit::LOG_INFO_FIRST_PARENT;\r
+       else\r
+               m_LogList.m_ShowMask&=~CGit::LOG_INFO_FIRST_PARENT;\r
+\r
+       OnRefresh();\r
+\r
+       FillLogMessageCtrl(false);\r
+\r
+}\r
+\r
+void CLogDlg::OnBnClickShowWholeProject()\r
+{\r
+       this->UpdateData();\r
+\r
+       if(this->m_bWholeProject)\r
+       {\r
+               m_LogList.m_Path.Reset();\r
+               SetWindowText(m_sTitle + _T(" - ") + CString(_T("Whole Project")));\r
+       }\r
+       else\r
+       {\r
+               m_LogList.m_Path=m_path;\r
+               if(!m_path.IsEmpty())\r
+                       SetWindowText(m_sTitle + _T(" - ") + m_path.GetGitPathString());\r
+       }\r
+       \r
+       OnRefresh();\r
+\r
+       FillLogMessageCtrl(false);\r
+\r
+}\r