OSDN Git Service

Fix Compare with preview version crash problem at log dialog.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / LogDlg.cpp
index 149cc42..e2bb8a1 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 "EditPropertiesDlg.h"\r
 #include "FileDiffDlg.h"\r
 \r
-#if (NTDDI_VERSION < NTDDI_LONGHORN)\r
-\r
-enum LISTITEMSTATES_MINE {\r
-       LISS_NORMAL = 1,\r
-       LISS_HOT = 2,\r
-       LISS_SELECTED = 3,\r
-       LISS_DISABLED = 4,\r
-       LISS_SELECTEDNOTFOCUS = 5,\r
-       LISS_HOTSELECTED = 6,\r
-};\r
-\r
-#define MCS_NOTRAILINGDATES  0x0040\r
-#define MCS_SHORTDAYSOFWEEK  0x0080\r
-#define MCS_NOSELCHANGEONNAV 0x0100\r
-\r
-#define DTM_SETMCSTYLE    (DTM_FIRST + 11)\r
-\r
-#endif\r
-\r
-#define ICONITEMBORDER 5\r
 \r
 const UINT CLogDlg::m_FindDialogMessage = RegisterWindowMessage(FINDMSGSTRING);\r
 \r
 \r
-enum LogDlgContextMenuCommands\r
-{\r
-       // needs to start with 1, since 0 is the return value if *nothing* is clicked on in the context menu\r
-       ID_COMPARE = 1,\r
-       ID_SAVEAS,\r
-       ID_COMPARETWO,\r
-       ID_UPDATE,\r
-       ID_COPY,\r
-       ID_REVERTREV,\r
-       ID_MERGEREV,\r
-       ID_GNUDIFF1,\r
-       ID_GNUDIFF2,\r
-       ID_FINDENTRY,\r
-       ID_OPEN,\r
-       ID_BLAME,\r
-       ID_REPOBROWSE,\r
-       ID_LOG,\r
-       ID_POPPROPS,\r
-       ID_EDITAUTHOR,\r
-       ID_EDITLOG,\r
-       ID_DIFF,\r
-       ID_OPENWITH,\r
-       ID_COPYCLIPBOARD,\r
-       ID_CHECKOUT,\r
-       ID_REVERTTOREV,\r
-       ID_BLAMECOMPARE,\r
-       ID_BLAMETWO,\r
-       ID_BLAMEDIFF,\r
-       ID_VIEWREV,\r
-       ID_VIEWPATHREV,\r
-       ID_EXPORT,\r
-       ID_COMPAREWITHPREVIOUS,\r
-       ID_BLAMEWITHPREVIOUS,\r
-       ID_GETMERGELOGS,\r
-       ID_REVPROPS\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_bNoDispUpdates(FALSE)\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
-       , m_regMaxBugIDColWidth(_T("Software\\TortoiseGit\\MaxBugIDColWidth"), 200)\r
+       \r
        , m_bSelectionMustBeContinuous(false)\r
        , m_bShowBugtraqColumn(false)\r
        , m_lowestRev(_T(""))\r
-       , m_bStrictStopped(false)\r
+       \r
        , m_sLogInfo(_T(""))\r
        , m_pFindDialog(NULL)\r
        , m_bCancelled(FALSE)\r
        , m_pNotifyWindow(NULL)\r
-       , m_bThreadRunning(FALSE)\r
+       \r
        , m_bAscending(FALSE)\r
-       , m_pStoreSelection(NULL)\r
+\r
        , m_limit(0)\r
        , m_childCounter(0)\r
        , m_maxChild(0)\r
@@ -144,32 +81,14 @@ CLogDlg::CLogDlg(CWnd* pParent /*=NULL*/)
        , m_bVista(false)\r
 {\r
        m_bFilterWithRegex = !!CRegDWORD(_T("Software\\TortoiseGit\\UseRegexFilter"), TRUE);\r
-       // use the default GUI font, create a copy of it and\r
-       // change the copy to BOLD (leave the rest of the font\r
-       // the same)\r
-       HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);\r
-       LOGFONT lf = {0};\r
-       GetObject(hFont, sizeof(LOGFONT), &lf);\r
-       lf.lfWeight = FW_BOLD;\r
-       m_boldFont = CreateFontIndirect(&lf);\r
+       \r
 }\r
 \r
 CLogDlg::~CLogDlg()\r
 {\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+       \r
     m_CurrentFilteredChangedArray.RemoveAll();\r
-       m_logEntries.ClearAll();\r
-       DestroyIcon(m_hModifiedIcon);\r
-       DestroyIcon(m_hReplacedIcon);\r
-       DestroyIcon(m_hAddedIcon);\r
-       DestroyIcon(m_hDeletedIcon);\r
-       if ( m_pStoreSelection )\r
-       {\r
-               delete m_pStoreSelection;\r
-               m_pStoreSelection = NULL;\r
-       }\r
-       if (m_boldFont)\r
-               DeleteObject(m_boldFont);\r
+       \r
 }\r
 \r
 void CLogDlg::DoDataExchange(CDataExchange* pDX)\r
@@ -181,7 +100,7 @@ void CLogDlg::DoDataExchange(CDataExchange* pDX)
        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
@@ -194,29 +113,28 @@ void CLogDlg::DoDataExchange(CDataExchange* pDX)
 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_NOTIFY(NM_DBLCLK, IDC_LOGLIST, OnNMDblclkLoglist)\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
-       ON_NOTIFY(NM_CUSTOMDRAW, IDC_LOGLIST, OnNMCustomdrawLoglist)\r
+       \r
        ON_MESSAGE(WM_FILTEREDIT_INFOCLICKED, OnClickedInfoIcon)\r
        ON_MESSAGE(WM_FILTEREDIT_CANCELCLICKED, OnClickedCancelFilter)\r
-       ON_NOTIFY(LVN_GETDISPINFO, IDC_LOGLIST, OnLvnGetdispinfoLoglist)\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_NOTIFY(LVN_COLUMNCLICK, IDC_LOGLIST, OnLvnColumnclick)\r
-       ON_NOTIFY(LVN_COLUMNCLICK, IDC_LOGMSG, OnLvnColumnclickChangedFileList)\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_BN_CLICKED(IDC_HIDEPATHS, OnBnClickedHidepaths)\r
-       ON_NOTIFY(LVN_ODFINDITEM, IDC_LOGLIST, OnLvnOdfinditemLoglist)\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
@@ -276,16 +194,11 @@ BOOL CLogDlg::OnInitDialog()
        GetDlgItem(IDC_MSGVIEW)->SendMessage(EM_AUTOURLDETECT, TRUE, NULL);\r
        // make the log message rich edit control send a message when the mouse pointer is over a link\r
        GetDlgItem(IDC_MSGVIEW)->SendMessage(EM_SETEVENTMASK, NULL, ENM_LINK);\r
-       m_LogList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);\r
+       //m_LogList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);\r
 \r
        // the "hide unrelated paths" checkbox should be indeterminate\r
        m_cHidePaths.SetCheck(BST_INDETERMINATE);\r
 \r
-       // load the icons for the action columns\r
-       m_hModifiedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONMODIFIED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
-       m_hReplacedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONREPLACED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
-       m_hAddedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONADDED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
-       m_hDeletedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONDELETED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
        \r
        // if there is a working copy, load the project properties\r
        // to get information about the bugtraq: integration\r
@@ -296,73 +209,14 @@ BOOL CLogDlg::OnInitDialog()
        if ((!m_ProjectProperties.sUrl.IsEmpty())||(!m_ProjectProperties.sCheckRe.IsEmpty()))\r
                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_LogList.GetSafeHwnd(), L"Explorer", NULL);\r
+       //theme.SetWindowTheme(m_ChangedFileListCtrl.GetSafeHwnd(), L"Explorer", NULL);\r
 \r
        // set up the columns\r
        m_LogList.DeleteAllItems();\r
-       int c = ((CHeaderCtrl*)(m_LogList.GetDlgItem(0)))->GetItemCount()-1;\r
-       \r
-       while (c>=0)\r
-               m_LogList.DeleteColumn(c--);\r
-       temp.LoadString(IDS_LOG_GRAPH);\r
-\r
-       m_LogList.InsertColumn(this->LOGLIST_GRAPH, temp);\r
-       \r
-#if 0  \r
-       // make the revision column right aligned\r
-       LVCOLUMN Column;\r
-       Column.mask = LVCF_FMT;\r
-       Column.fmt = LVCFMT_RIGHT;\r
-       m_LogList.SetColumn(0, &Column); \r
-#endif \r
-//     CString log;\r
-//     g_Git.GetLog(log);\r
-\r
-       temp.LoadString(IDS_LOG_ACTIONS);\r
-       m_LogList.InsertColumn(this->LOGLIST_ACTION, temp);\r
-       \r
-       temp.LoadString(IDS_LOG_MESSAGE);\r
-       m_LogList.InsertColumn(this->LOGLIST_MESSAGE, temp);\r
-       \r
-       temp.LoadString(IDS_LOG_AUTHOR);\r
-       m_LogList.InsertColumn(this->LOGLIST_AUTHOR, temp);\r
-       \r
-       temp.LoadString(IDS_LOG_DATE);\r
-       m_LogList.InsertColumn(this->LOGLIST_DATE, temp);\r
-       \r
-\r
-       if (m_bShowBugtraqColumn)\r
-       {\r
-               temp = m_ProjectProperties.sLabel;\r
-               if (temp.IsEmpty())\r
-                       temp.LoadString(IDS_LOG_BUGIDS);\r
-               m_LogList.InsertColumn(this->LOGLIST_BUG, temp);\r
-\r
-       }\r
-       \r
-       m_LogList.SetRedraw(false);\r
-       ResizeAllListCtrlCols();\r
-       m_LogList.SetRedraw(true);\r
-\r
-       m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
-       m_ChangedFileListCtrl.DeleteAllItems();\r
-       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
+       m_LogList.InsertGitColumn();\r
 \r
+       m_ChangedFileListCtrl.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |IDS_STATUSLIST_COLADD|IDS_STATUSLIST_COLDEL , _T("LogDlg"),(SVNSLC_POPALL ^ SVNSLC_POPCOMMIT),false);\r
 \r
        GetDlgItem(IDC_LOGLIST)->UpdateData(FALSE);\r
 \r
@@ -468,7 +322,7 @@ BOOL CLogDlg::OnInitDialog()
        {\r
                // the dialog is used to select revisions\r
                if (m_bSelectionMustBeContinuous)\r
-                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(IsSelectionContinuous()));\r
+                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
                else\r
                        DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
        }\r
@@ -483,7 +337,7 @@ BOOL CLogDlg::OnInitDialog()
        // 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
+       temp.LoadString(IDS_LOG_SHOW_WHOLE);\r
        m_btnShow.AddEntry(temp);\r
        m_btnShow.SetCurrentEntry((LONG)CRegDWORD(_T("Software\\TortoiseGit\\ShowAllEntry")));\r
 \r
@@ -491,20 +345,68 @@ BOOL CLogDlg::OnInitDialog()
 \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
-       InterlockedExchange(&m_bThreadRunning, TRUE);\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-       if (AfxBeginThread(LogThreadEntry, this)==NULL)\r
-       {\r
-               InterlockedExchange(&m_bThreadRunning, FALSE);\r
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-               CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
-       }\r
+       //m_tTo = 0;\r
+       //m_tFrom = (DWORD)-1;\r
+\r
+       m_LogList.m_Path=m_path;\r
+       m_LogList.FetchLogAsync(LogCallBack,this);\r
+\r
        GetDlgItem(IDC_LOGLIST)->SetFocus();\r
        return FALSE;\r
 }\r
 \r
+void CLogDlg::LogRunStatus(int cur)\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
+\r
+               // We use a progress bar while getting the logs \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_STATBUTTON, FALSE);\r
+               DialogEnableWindow(IDC_REFRESH, FALSE);\r
+               DialogEnableWindow(IDC_HIDEPATHS,FALSE);\r
+       }\r
+\r
+       if( cur == GITLOG_END)\r
+       {\r
+               \r
+               if (!m_bShowedAll)\r
+                       DialogEnableWindow(IDC_NEXTHUNDRED, TRUE);\r
+\r
+               DialogEnableWindow(IDC_GETALL, TRUE);\r
+               //DialogEnableWindow(IDC_INCLUDEMERGE, TRUE);\r
+               DialogEnableWindow(IDC_STATBUTTON, TRUE);\r
+               DialogEnableWindow(IDC_REFRESH, TRUE);\r
+\r
+//             PostMessage(WM_TIMER, LOGFILTER_TIMER);\r
+\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
+       }\r
+\r
+       m_LogProgress.SetPos(cur);\r
+}\r
 void CLogDlg::SetDlgTitle(bool bOffline)\r
 {\r
        if (m_sTitle.IsEmpty())\r
@@ -525,6 +427,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
@@ -550,7 +454,7 @@ void CLogDlg::EnableOKButton()
        {\r
                // the dialog is used to select revisions\r
                if (m_bSelectionMustBeContinuous)\r
-                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(IsSelectionContinuous()));\r
+                       DialogEnableWindow(IDOK, (m_LogList.GetSelectedCount()!=0)&&(m_LogList.IsSelectionContinuous()));\r
                else\r
                        DialogEnableWindow(IDOK, m_LogList.GetSelectedCount()!=0);\r
        }\r
@@ -569,12 +473,11 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        pMsgView->SetWindowText(_T(" "));\r
        // empty the changed files list\r
        m_ChangedFileListCtrl.SetRedraw(FALSE);\r
-       InterlockedExchange(&m_bNoDispUpdates, TRUE);\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
@@ -582,7 +485,7 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        {\r
                // force a redraw\r
                m_ChangedFileListCtrl.Invalidate();\r
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+//             InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
                m_ChangedFileListCtrl.SetRedraw(TRUE);\r
                return;\r
        }\r
@@ -593,7 +496,7 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        if (selCount == 0)\r
        {\r
                // if nothing is selected, we have nothing more to do\r
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+//             InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
                m_ChangedFileListCtrl.SetRedraw(TRUE);\r
                return;\r
        }\r
@@ -604,24 +507,30 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
                // list fully.\r
                POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
                int selIndex = m_LogList.GetNextSelectedItem(pos);\r
-               if (selIndex >= m_arShownList.GetCount())\r
+               if (selIndex >= m_LogList.m_arShownList.GetCount())\r
                {\r
-                       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+//                     InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
                        m_ChangedFileListCtrl.SetRedraw(TRUE);\r
                        return;\r
                }\r
-               GitRev* pLogEntry = reinterpret_cast<GitRev *>(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
+               GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(selIndex));\r
+\r
+               if(!pLogEntry->m_IsFull)\r
+               {\r
+                       pMsgView->SetWindowText(_T("load ..."));\r
+               }else\r
                {\r
-                       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+                       // set the log message text\r
+                       pMsgView->SetWindowText(_T("Commit:")+pLogEntry->m_CommitHash+_T("\r\n\r\n*")+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
+\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
@@ -654,7 +563,8 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
        }\r
        \r
        // redraw the views\r
-       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+//     InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+#if 0\r
        if (m_currentChangedArray)\r
        {\r
                m_ChangedFileListCtrl.SetItemCountEx(m_currentChangedArray->GetCount());\r
@@ -670,6 +580,7 @@ void CLogDlg::FillLogMessageCtrl(bool bShow /* = true*/)
                m_ChangedFileListCtrl.SetItemCountEx(0);\r
                m_ChangedFileListCtrl.Invalidate();\r
        }\r
+#endif\r
        CAppUtils::ResizeAllListCtrlCols(&m_ChangedFileListCtrl);\r
        // sort according to the settings\r
        if (m_nSortColumnPathList > 0)\r
@@ -687,53 +598,32 @@ void CLogDlg::OnBnClickedGetall()
 \r
 void CLogDlg::GetAll(bool bForceAll /* = false */)\r
 {\r
-#if 0\r
+\r
        // fetch all requested log messages, either the specified range or\r
        // really *all* available log messages.\r
-       UpdateData();\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
+       case 0: // show all branch;\r
+               m_LogList.m_bAllBranch=true;\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
+       case 1: // show whole project\r
+               m_LogList.m_Path.Reset();\r
+               SetWindowText(m_sTitle + _T(" - "));\r
                break;\r
        }\r
+       //m_LogList.m_bExitThread=TRUE;\r
+       //::WaitForSingleObject(m_LogList.m_LoadingThread->m_hThread,INFINITE);\r
+\r
+       m_LogList.TerminateThread();\r
+       \r
+       m_LogList.Clear();\r
+       m_LogList.FetchLogAsync(LogCallBack,this);\r
+#if 0\r
        m_ChangedFileListCtrl.SetItemCountEx(0);\r
        m_ChangedFileListCtrl.Invalidate();\r
        // We need to create CStoreSelection on the heap or else\r
@@ -778,58 +668,7 @@ void CLogDlg::OnBnClickedRefresh()
 \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_LogList.Refresh();\r
 }\r
 \r
 void CLogDlg::OnBnClickedNexthundred()\r
@@ -909,10 +748,18 @@ void CLogDlg::OnCancel()
        CString temp, temp2;\r
        GetDlgItemText(IDOK, temp);\r
        temp2.LoadString(IDS_MSGBOX_CANCEL);\r
-       if ((temp.Compare(temp2)==0)||(m_bThreadRunning))\r
+       if ((temp.Compare(temp2)==0)||(this->IsThreadRunning()))\r
        {\r
-               m_bCancelled = true;\r
-               return;\r
+               //m_bCancelled = true;\r
+               //return;\r
+               if(m_LogList.m_bThreadRunning)\r
+               {\r
+                       //m_LogList.m_bExitThread=true;\r
+                       //WaitForSingleObject(m_LogList.m_LoadingThread->m_hThread,INFINITE);\r
+                       m_LogList.TerminateThread();\r
+               }\r
+\r
+               //m_LogList.TerminateThread();\r
        }\r
        UpdateData();\r
        if (m_bSaveStrict)\r
@@ -1047,313 +894,11 @@ BOOL CLogDlg::Log(git_revnum_t rev, const CString& author, const CString& date,
        return TRUE;\r
 }\r
 \r
-//this is the thread function which calls the subversion function\r
-UINT CLogDlg::LogThreadEntry(LPVOID pVoid)\r
-{\r
-       return ((CLogDlg*)pVoid)->LogThread();\r
-}\r
-\r
 GitRev g_rev;\r
 //this is the thread function which calls the subversion function\r
-UINT CLogDlg::LogThread()\r
-{\r
-\r
-       InterlockedExchange(&m_bThreadRunning, TRUE);\r
-\r
-    //does the user force the cache to refresh (shift or control key down)?\r
-    bool refresh =    (GetKeyState (VK_CONTROL) < 0) \r
-                   || (GetKeyState (VK_SHIFT) < 0);\r
-\r
-       //disable the "Get All" button while we're receiving\r
-       //log messages.\r
-       DialogEnableWindow(IDC_GETALL, FALSE);\r
-       DialogEnableWindow(IDC_NEXTHUNDRED, FALSE);\r
-       DialogEnableWindow(IDC_CHECK_STOPONCOPY, FALSE);\r
-       DialogEnableWindow(IDC_INCLUDEMERGE, FALSE);\r
-       DialogEnableWindow(IDC_STATBUTTON, FALSE);\r
-       DialogEnableWindow(IDC_REFRESH, FALSE);\r
-       \r
-       CString temp;\r
-       temp.LoadString(IDS_PROGRESSWAIT);\r
-       m_LogList.ShowText(temp, true);\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
-       // We use a progress bar while getting the logs\r
-       m_LogProgress.SetRange32(0, 100);\r
-       m_LogProgress.SetPos(0);\r
-       GetDlgItem(IDC_PROGRESS)->ShowWindow(TRUE);\r
-//     git_revnum_t r = -1;\r
-       \r
-       // get the repository root url, because the changed-files-list has the\r
-       // paths shown there relative to the repository root.\r
-//     CTGitPath rootpath;\r
-//  BOOL succeeded = GetRootAndHead(m_path, rootpath, r);\r
-\r
-//    m_sRepositoryRoot = rootpath.GetGitPathString();\r
-//    m_sURL = m_path.GetGitPathString();\r
-\r
-    // we need the UUID to unambigously identify the log cache\r
-//    if (logCachePool.IsEnabled())\r
-//        m_sUUID = logCachePool.GetRepositoryInfo().GetRepositoryUUID (rootpath);\r
-\r
-    // if the log dialog is started from a working copy, we need to turn that\r
-    // local path into an url here\r
-//    if (succeeded)\r
-//    {\r
-//        if (!m_path.IsUrl())\r
-//        {\r
-//             m_sURL = GetURLFromPath(m_path);\r
-\r
-               // The URL is escaped because Git::logReceiver\r
-               // returns the path in a native format\r
-//             m_sURL = CPathUtils::PathUnescape(m_sURL);\r
-  //      }\r
-//        m_sRelativeRoot = m_sURL.Mid(CPathUtils::PathUnescape(m_sRepositoryRoot).GetLength());\r
-//             m_sSelfRelativeURL = m_sRelativeRoot;\r
-  //  }\r
-#if 0\r
-    if (succeeded && !m_mergePath.IsEmpty() && m_mergedRevs.empty())\r
-    {\r
-           // in case we got a merge path set, retrieve the merge info\r
-           // of that path and check whether one of the merge URLs\r
-           // match the URL we show the log for.\r
-           GitPool localpool(pool);\r
-           git_error_clear(Err);\r
-           apr_hash_t * mergeinfo = NULL;\r
-           if (git_client_mergeinfo_get_merged (&mergeinfo, m_mergePath.GetGitApiPath(localpool), GitRev(GitRev::REV_WC), m_pctx, localpool) == NULL)\r
-           {\r
-                   // now check the relative paths\r
-                   apr_hash_index_t *hi;\r
-                   const void *key;\r
-                   void *val;\r
-\r
-                   if (mergeinfo)\r
-                   {\r
-                           for (hi = apr_hash_first(localpool, mergeinfo); hi; hi = apr_hash_next(hi))\r
-                           {\r
-                                   apr_hash_this(hi, &key, NULL, &val);\r
-                                   if (m_sURL.Compare(CUnicodeUtils::GetUnicode((char*)key)) == 0)\r
-                                   {\r
-                                           apr_array_header_t * arr = (apr_array_header_t*)val;\r
-                                           if (val)\r
-                                           {\r
-                                                   for (long i=0; i<arr->nelts; ++i)\r
-                                                   {\r
-                                                           git_merge_range_t * pRange = APR_ARRAY_IDX(arr, i, git_merge_range_t*);\r
-                                                           if (pRange)\r
-                                                           {\r
-                                                                   for (git_revnum_t r=pRange->start+1; r<=pRange->end; ++r)\r
-                                                                   {\r
-                                                                           m_mergedRevs.insert(r);\r
-                                                                   }\r
-                                                           }\r
-                                                   }\r
-                                           }\r
-                                           break;\r
-                                   }\r
-                           }\r
-                   }\r
-           }\r
-    }\r
-\r
-    m_LogProgress.SetPos(1);\r
-    if (m_startrev == GitRev::REV_HEAD)\r
-    {\r
-           m_startrev = r;\r
-    }\r
-    if (m_endrev == GitRev::REV_HEAD)\r
-    {\r
-           m_endrev = r;\r
-    }\r
-\r
-    if (m_limit != 0)\r
-    {\r
-           m_limitcounter = m_limit;\r
-           m_LogProgress.SetRange32(0, m_limit);\r
-    }\r
-    else\r
-           m_LogProgress.SetRange32(m_endrev, m_startrev);\r
-       \r
-    if (!m_pegrev.IsValid())\r
-           m_pegrev = m_startrev;\r
-    size_t startcount = m_logEntries.size();\r
-    m_lowestRev = -1;\r
-    m_bStrictStopped = false;\r
-\r
-    if (succeeded)\r
-    {\r
-        succeeded = ReceiveLog (CTGitPathList(m_path), m_pegrev, m_startrev, m_endrev, m_limit, m_bStrict, m_bIncludeMerges, refresh);\r
-        if ((!succeeded)&&(!m_path.IsUrl()))\r
-        {\r
-               // try again with REV_WC as the start revision, just in case the path doesn't\r
-               // exist anymore in HEAD\r
-               succeeded = ReceiveLog(CTGitPathList(m_path), GitRev(), GitRev::REV_WC, m_endrev, m_limit, m_bStrict, m_bIncludeMerges, refresh);\r
-        }\r
-    }\r
-       m_LogList.ClearText();\r
-    if (!succeeded)\r
-       {\r
-               m_LogList.ShowText(GetLastErrorMessage(), true);\r
-       }\r
-       else\r
-       {\r
-               if (!m_wcRev.IsValid())\r
-               {\r
-                       // fetch the revision the wc path is on so we can mark it\r
-                       CTGitPath revWCPath = m_ProjectProperties.GetPropsPath();\r
-                       if (!m_path.IsUrl())\r
-                               revWCPath = m_path;\r
-                       if (DWORD(CRegDWORD(_T("Software\\TortoiseGit\\RecursiveLogRev"), FALSE)))\r
-                       {\r
-                               git_revnum_t minrev, maxrev;\r
-                               bool switched, modified, sparse;\r
-                               GetWCRevisionStatus(revWCPath, true, minrev, maxrev, switched, modified, sparse);\r
-                               if (maxrev)\r
-                                       m_wcRev = maxrev;\r
-                       }\r
-                       else\r
-                       {\r
-                               CTGitPath dummypath;\r
-                               GitStatus status;\r
-                               git_wc_status2_t * stat = status.GetFirstFileStatus(revWCPath, dummypath, false, git_depth_empty);\r
-                               if (stat && stat->entry && stat->entry->cmt_rev)\r
-                                       m_wcRev = stat->entry->cmt_rev;\r
-                               if (stat && stat->entry && (stat->entry->kind == git_node_dir))\r
-                                       m_wcRev = stat->entry->revision;\r
-                       }\r
-               }\r
-       }\r
-    if (m_bStrict && (m_lowestRev>1) && ((m_limit>0) ? ((startcount + m_limit)>m_logEntries.size()) : (m_endrev<m_lowestRev)))\r
-               m_bStrictStopped = true;\r
-       m_LogList.SetItemCountEx(ShownCountWithStopped());\r
-\r
-       m_timFrom = (__time64_t(m_tFrom));\r
-       m_timTo = (__time64_t(m_tTo));\r
-       m_DateFrom.SetRange(&m_timFrom, &m_timTo);\r
-       m_DateTo.SetRange(&m_timFrom, &m_timTo);\r
-       m_DateFrom.SetTime(&m_timFrom);\r
-       m_DateTo.SetTime(&m_timTo);\r
-#endif\r
-       DialogEnableWindow(IDC_GETALL, TRUE);\r
-       m_LogList.ClearText();\r
 \r
-       this->m_logEntries.ClearAll();\r
-       this->m_logEntries.ParserFromLog();\r
-       m_LogList.SetItemCountEx(this->m_logEntries.size());\r
 \r
-       this->m_arShownList.RemoveAll();\r
 \r
-       for(int i=0;i<m_logEntries.size();i++)\r
-               this->m_arShownList.Add(&m_logEntries[i]);\r
-       \r
-#if 0  \r
-       if (!m_bShowedAll)\r
-               DialogEnableWindow(IDC_NEXTHUNDRED, TRUE);\r
-#endif\r
-       DialogEnableWindow(IDC_CHECK_STOPONCOPY, TRUE);\r
-       DialogEnableWindow(IDC_INCLUDEMERGE, TRUE);\r
-       DialogEnableWindow(IDC_STATBUTTON, TRUE);\r
-       DialogEnableWindow(IDC_REFRESH, TRUE);\r
-\r
-#if 0\r
-       LogCache::CRepositoryInfo& cachedProperties = logCachePool.GetRepositoryInfo();\r
-       SetDlgTitle(cachedProperties.IsOffline (m_sUUID, m_sRepositoryRoot, false));\r
-\r
-       GetDlgItem(IDC_PROGRESS)->ShowWindow(FALSE);\r
-       m_bCancelled = true;\r
-#endif\r
-       InterlockedExchange(&m_bThreadRunning, FALSE);\r
-       m_LogList.RedrawItems(0, m_arShownList.GetCount());\r
-       m_LogList.SetRedraw(false);\r
-       ResizeAllListCtrlCols();\r
-       m_LogList.SetRedraw(true);\r
-       if ( m_pStoreSelection )\r
-       {\r
-               // Deleting the instance will restore the\r
-               // selection of the CLogDlg.\r
-               delete m_pStoreSelection;\r
-               m_pStoreSelection = NULL;\r
-       }\r
-       else\r
-       {\r
-               // If no selection has been set then this must be the first time\r
-               // the revisions are shown. Let's preselect the topmost revision.\r
-               if ( m_LogList.GetItemCount()>0 )\r
-               {\r
-                       m_LogList.SetSelectionMark(0);\r
-                       m_LogList.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\r
-               }\r
-       }\r
-\r
-       if (!GetDlgItem(IDOK)->IsWindowVisible())\r
-       {\r
-               temp.LoadString(IDS_MSGBOX_OK);\r
-               SetDlgItemText(IDCANCEL, temp);\r
-       }\r
-\r
-       RefreshCursor();\r
-       // make sure the filter is applied (if any) now, after we refreshed/fetched\r
-       // the log messages\r
-       PostMessage(WM_TIMER, LOGFILTER_TIMER);\r
-\r
-       return 0;\r
-}\r
-\r
-void CLogDlg::CopySelectionToClipBoard()\r
-{\r
-#if 0\r
-       CString sClipdata;\r
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-       if (pos != NULL)\r
-       {\r
-               CString sRev;\r
-               sRev.LoadString(IDS_LOG_REVISION);\r
-               CString sAuthor;\r
-               sAuthor.LoadString(IDS_LOG_AUTHOR);\r
-               CString sDate;\r
-               sDate.LoadString(IDS_LOG_DATE);\r
-               CString sMessage;\r
-               sMessage.LoadString(IDS_LOG_MESSAGE);\r
-               while (pos)\r
-               {\r
-                       CString sLogCopyText;\r
-                       CString sPaths;\r
-                       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-                       LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;\r
-                       for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount(); ++cpPathIndex)\r
-                       {\r
-                               LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
-                               sPaths += cpath->GetAction() + _T(" : ") + cpath->sPath;\r
-                               if (cpath->sCopyFromPath.IsEmpty())\r
-                                       sPaths += _T("\r\n");\r
-                               else\r
-                               {\r
-                                       CString sCopyFrom;\r
-                                       sCopyFrom.Format(_T(" (%s: %s, %s, %ld)\r\n"), CString(MAKEINTRESOURCE(IDS_LOG_COPYFROM)), \r
-                                               (LPCTSTR)cpath->sCopyFromPath, \r
-                                               (LPCTSTR)CString(MAKEINTRESOURCE(IDS_LOG_REVISION)), \r
-                                               (LPCTSTR)cpath->lCopyFromRev);\r
-                                       sPaths += sCopyFrom;\r
-                               }\r
-                       }\r
-                       sPaths.Trim();\r
-                       sLogCopyText.Format(_T("%s: %d\r\n%s: %s\r\n%s: %s\r\n%s:\r\n%s\r\n----\r\n%s\r\n\r\n"),\r
-                               (LPCTSTR)sRev, pLogEntry->Rev,\r
-                               (LPCTSTR)sAuthor, (LPCTSTR)pLogEntry->sAuthor,\r
-                               (LPCTSTR)sDate, (LPCTSTR)pLogEntry->sDate,\r
-                               (LPCTSTR)sMessage, (LPCTSTR)pLogEntry->sMessage,\r
-                               (LPCTSTR)sPaths);\r
-                       sClipdata +=  sLogCopyText;\r
-               }\r
-               CStringUtils::WriteAsciiStringToClipboard(sClipdata, GetSafeHwnd());\r
-       }\r
-#endif\r
-}\r
 \r
 void CLogDlg::CopyChangedSelectionToClipBoard()\r
 {\r
@@ -1440,11 +985,11 @@ void CLogDlg::OnContextMenu(CWnd* pWnd, CPoint point)
        int selCount = m_LogList.GetSelectedCount();\r
        if (pWnd == &m_LogList)\r
        {\r
-               ShowContextMenuForRevisions(pWnd, point);\r
+               //ShowContextMenuForRevisions(pWnd, point);\r
        }\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
@@ -1469,12 +1014,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, 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
@@ -1485,7 +1030,7 @@ void CLogDlg::OnContextMenu(CWnd* pWnd, CPoint point)
                        case WM_COPY:\r
                                ::SendMessage(GetDlgItem(IDC_MSGVIEW)->GetSafeHwnd(), cmd, 0, -1);\r
                                break;\r
-                       case ID_EDITAUTHOR:\r
+                       case CGitLogList::ID_EDITAUTHOR:\r
                                EditLogMessage(selIndex);\r
                                break;\r
                        }\r
@@ -1493,33 +1038,6 @@ void CLogDlg::OnContextMenu(CWnd* pWnd, CPoint point)
        }\r
 }\r
 \r
-bool CLogDlg::IsSelectionContinuous()\r
-{\r
-       if ( m_LogList.GetSelectedCount()==1 )\r
-       {\r
-               // if only one revision is selected, the selection is of course\r
-               // continuous\r
-               return true;\r
-       }\r
-\r
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-       bool bContinuous = (m_arShownList.GetCount() == (INT_PTR)m_logEntries.size());\r
-       if (bContinuous)\r
-       {\r
-               int itemindex = m_LogList.GetNextSelectedItem(pos);\r
-               while (pos)\r
-               {\r
-                       int nextindex = m_LogList.GetNextSelectedItem(pos);\r
-                       if (nextindex - itemindex > 1)\r
-                       {\r
-                               bContinuous = false;\r
-                               break;\r
-                       }\r
-                       itemindex = nextindex;\r
-               }\r
-       }\r
-       return bContinuous;\r
-}\r
 \r
 LRESULT CLogDlg::OnFindDialogMessage(WPARAM /*wParam*/, LPARAM /*lParam*/)\r
 {\r
@@ -1887,78 +1405,7 @@ void CLogDlg::DiffSelectedFile()
 }\r
 \r
 \r
-void CLogDlg::OnNMDblclkLoglist(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
-{\r
-       // a double click on an entry in the revision list has happened\r
-       *pResult = 0;\r
-\r
-  if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
-         DiffSelectedRevWithPrevious();\r
-}\r
-\r
-void CLogDlg::DiffSelectedRevWithPrevious()\r
-{\r
-#if 0\r
-       if (m_bThreadRunning)\r
-               return;\r
-       UpdateLogInfoLabel();\r
-       int selIndex = m_LogList.GetSelectionMark();\r
-       if (selIndex < 0)\r
-               return;\r
-       int selCount = m_LogList.GetSelectedCount();\r
-       if (selCount != 1)\r
-               return;\r
-\r
-       // Find selected entry in the log list\r
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-       long rev1 = pLogEntry->Rev;\r
-       long rev2 = rev1-1;\r
-       CTGitPath path = m_path;\r
-\r
-       // See how many files under the relative root were changed in selected revision\r
-       int nChanged = 0;\r
-       LogChangedPath * changed = NULL;\r
-       for (INT_PTR c = 0; c < pLogEntry->pArChangedPaths->GetCount(); ++c)\r
-       {\r
-               LogChangedPath * cpath = pLogEntry->pArChangedPaths->GetAt(c);\r
-               if (cpath  &&  cpath -> sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0)\r
-               {\r
-                       ++nChanged;\r
-                       changed = cpath;\r
-               }\r
-       }\r
-\r
-       if (m_path.IsDirectory() && nChanged == 1) \r
-       {\r
-               // We're looking at the log for a directory and only one file under dir was changed in the revision\r
-               // Do diff on that file instead of whole directory\r
-               path.AppendPathString(changed->sPath.Mid(m_sRelativeRoot.GetLength()));\r
-       } \r
-\r
-       m_bCancelled = FALSE;\r
-       DialogEnableWindow(IDOK, FALSE);\r
-       SetPromptApp(&theApp);\r
-       theApp.DoWaitCursor(1);\r
-\r
-       if (PromptShown())\r
-       {\r
-               GitDiff diff(this, m_hWnd, true);\r
-               diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-               diff.SetHEADPeg(m_LogRevision);\r
-               diff.ShowCompare(path, rev2, path, rev1);\r
-       }\r
-       else\r
-       {\r
-               CAppUtils::StartShowCompare(m_hWnd, path, rev2, path, rev1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-       }\r
-\r
-       theApp.DoWaitCursor(-1);\r
-       EnableOKButton();\r
-#endif\r
-}\r
-\r
-void CLogDlg::DoDiffFromLog(INT_PTR selIndex, GitRev* rev1, GitRev* rev2, bool blame, bool unified)\r
+void CLogDlg::DoDiffFromLog(INT_PTR selIndex, GitRev* rev1, GitRev* rev2, bool blame, bool unified)\r
 {\r
        DialogEnableWindow(IDOK, FALSE);\r
 //     SetPromptApp(&theApp);\r
@@ -1983,9 +1430,9 @@ void CLogDlg::DoDiffFromLog(INT_PTR selIndex, GitRev* rev1, GitRev* rev2, bool b
 \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
@@ -2297,7 +1744,7 @@ void CLogDlg::EditLogMessage(int index)
        EnableOKButton();\r
 #endif\r
 }\r
-\r
+#if 0\r
 BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)\r
 {\r
        // Skip Ctrl-C when copying text out of the log message or search filter\r
@@ -2328,10 +1775,12 @@ BOOL CLogDlg::PreTranslateMessage(MSG* pMsg)
        m_tooltips.RelayEvent(pMsg);\r
        return __super::PreTranslateMessage(pMsg);\r
 }\r
+#endif\r
 \r
 BOOL CLogDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
 {\r
-       if (m_bThreadRunning)\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
@@ -2361,14 +1810,15 @@ void CLogDlg::OnLvnItemchangedLoglist(NMHDR *pNMHDR, LRESULT *pResult)
 {\r
        LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
        *pResult = 0;\r
-       if (m_bThreadRunning)\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_arShownList.GetCount())&&(m_bStrict)&&(m_bStrictStopped))\r
+               if ((pNMLV->iItem == m_LogList.m_arShownList.GetCount())&&(m_bStrict)&&(1/*m_bStrictStopped*/))\r
                {\r
                        // remove the selected state\r
                        if (pNMLV->uChanged & LVIF_STATE)\r
@@ -2417,30 +1867,30 @@ void CLogDlg::OnEnLinkMsgview(NMHDR *pNMHDR, LRESULT *pResult)
 \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
        CStatGraphDlg dlg;\r
        dlg.m_parAuthors = &m_arAuthorsFiltered;\r
@@ -2451,9 +1901,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
@@ -2638,6 +2089,8 @@ void CLogDlg::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
        *pResult = CDRF_DODEFAULT;\r
 \r
 }\r
+#endif\r
+\r
 void CLogDlg::OnNMCustomdrawChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
 {\r
 \r
@@ -2645,8 +2098,8 @@ void CLogDlg::OnNMCustomdrawChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)
        // Take the default processing unless we set this to something else below.\r
        *pResult = CDRF_DODEFAULT;\r
 \r
-       if (m_bNoDispUpdates)\r
-               return;\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
@@ -2810,7 +2263,7 @@ LRESULT CLogDlg::OnClickedInfoIcon(WPARAM /*wParam*/, LPARAM lParam)
        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
@@ -2849,7 +2302,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
@@ -2860,42 +2313,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
@@ -2903,7 +2342,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
@@ -2926,512 +2365,138 @@ void CLogDlg::SetFilterCueText()
        m_cFilter.SetCueBanner(temp);\r
 }\r
 \r
-void CLogDlg::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
+bool CLogDlg::Validate(LPCTSTR string)\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
+       if (!m_bFilterWithRegex)\r
+               return true;\r
+       tr1::wregex pat;\r
+       return m_LogList.ValidateRegexp(string, pat, false);\r
+}\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
+void CLogDlg::OnTimer(UINT_PTR nIDEvent)\r
+{\r
+       if (nIDEvent == LOGFILTER_TIMER)\r
        {\r
-       case this->LOGLIST_GRAPH:       //Graphic\r
-               if (pLogEntry)\r
+               if (this->IsThreadRunning())\r
                {\r
+                       // thread still running! So just restart the timer.\r
+                       SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
+                       return;\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
-\r
-void CLogDlg::OnLvnGetdispinfoChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
-{\r
-\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
+               CWnd * focusWnd = GetFocus();\r
+               bool bSetFocusToFilterControl = ((focusWnd != GetDlgItem(IDC_DATEFROM))&&(focusWnd != GetDlgItem(IDC_DATETO))\r
+                       && (focusWnd != GetDlgItem(IDC_LOGLIST)));\r
+               if (m_LogList.m_sFilterText.IsEmpty())\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
+                       DialogEnableWindow(IDC_STATBUTTON, !(((this->IsThreadRunning())||(m_LogList.m_arShownList.IsEmpty()))));\r
+                       // do not return here!\r
+                       // we also need to run the filter if the filter text is empty:\r
+                       // 1. to clear an existing filter\r
+                       // 2. to rebuild the m_arShownList after sorting\r
                }\r
-       }\r
-\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
+               CStoreSelection storeselection(this);\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
+               // now start filter the log list\r
+               m_LogList.StartFilter();\r
+\r
+               if ( m_LogList.GetItemCount()==1 )\r
                {\r
-                       if (IsEntryInDateRange(i))\r
-                               m_arShownList.Add(m_logEntries[i]);\r
+                       m_LogList.SetSelectionMark(0);\r
+                       m_LogList.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\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
+               if (bSetFocusToFilterControl)\r
+                       GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
+               UpdateLogInfoLabel();\r
+       } // if (nIDEvent == LOGFILTER_TIMER)\r
+       DialogEnableWindow(IDC_STATBUTTON, !(((this->IsThreadRunning())||(m_LogList.m_arShownList.IsEmpty()))));\r
+       __super::OnTimer(nIDEvent);\r
 }\r
 \r
-bool CLogDlg::ValidateRegexp(LPCTSTR regexp_str, tr1::wregex& pat, bool bMatchCase /* = false */)\r
+void CLogDlg::OnDtnDatetimechangeDateto(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
 {\r
+       CTime _time;\r
+       m_DateTo.GetTime(_time);\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
+               CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 23, 59, 59);\r
+               if (time.GetTime() != m_LogList.m_To.GetTime())\r
+               {\r
+                       m_LogList.m_To = (DWORD)time.GetTime();\r
+                       SetTimer(LOGFILTER_TIMER, 10, NULL);\r
+               }\r
+       }\r
+       catch (CAtlException)\r
+       {\r
        }\r
-       catch (exception) {}\r
-       return false;\r
+       \r
+       *pResult = 0;\r
 }\r
 \r
-bool CLogDlg::Validate(LPCTSTR string)\r
+void CLogDlg::OnDtnDatetimechangeDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
 {\r
-       if (!m_bFilterWithRegex)\r
-               return true;\r
-       tr1::wregex pat;\r
-       return ValidateRegexp(string, pat, false);\r
+       CTime _time;\r
+       m_DateFrom.GetTime(_time);\r
+       try\r
+       {\r
+               CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 0, 0, 0);\r
+               if (time.GetTime() != m_LogList.m_From.GetTime())\r
+               {\r
+                       m_LogList.m_From = (DWORD)time.GetTime();\r
+                       SetTimer(LOGFILTER_TIMER, 10, NULL);\r
+               }\r
+       }\r
+       catch (CAtlException)\r
+       {\r
+       }\r
+       \r
+       *pResult = 0;\r
 }\r
 \r
-void CLogDlg::RecalculateShownList(CPtrArray * pShownlist)\r
+\r
+\r
+CTGitPathList CLogDlg::GetChangedPathsFromSelectedRevisions(bool bRelativePaths /* = false */, bool bUseFilter /* = true */)\r
 {\r
+       CTGitPathList pathList;\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 (m_sRepositoryRoot.IsEmpty() && (bRelativePaths == false))\r
+       {\r
+               m_sRepositoryRoot = GetRepositoryRoot(m_path);\r
+       }\r
+       if (m_sRepositoryRoot.IsEmpty() && (bRelativePaths == false))\r
+               return pathList;\r
+       \r
+       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
+       if (pos != NULL)\r
        {\r
-               if ((bRegex)&&(m_bFilterWithRegex))\r
+               while (pos)\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
+                       int nextpos = m_LogList.GetNextSelectedItem(pos);\r
+                       if (nextpos >= m_arShownList.GetCount())\r
+                               continue;\r
+                       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(nextpos));\r
+                       LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;\r
+                       for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount(); ++cpPathIndex)\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
+                               LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
+                               if (cpath == NULL)\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
-       if (nIDEvent == LOGFILTER_TIMER)\r
-       {\r
-               if (m_bThreadRunning)\r
-               {\r
-                       // thread still running! So just restart the timer.\r
-                       SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
-                       return;\r
-               }\r
-               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
-               {\r
-                       DialogEnableWindow(IDC_STATBUTTON, !(((m_bThreadRunning)||(m_arShownList.IsEmpty()))));\r
-                       // do not return here!\r
-                       // we also need to run the filter if the filter text is empty:\r
-                       // 1. to clear an existing filter\r
-                       // 2. to rebuild the m_arShownList after sorting\r
-               }\r
-               theApp.DoWaitCursor(1);\r
-               CStoreSelection storeselection(this);\r
-               KillTimer(LOGFILTER_TIMER);\r
-               FillLogMessageCtrl(false);\r
-\r
-               // now start filter the log list\r
-               InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
-               RecalculateShownList(&m_arShownList);\r
-               InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
-\r
-\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
-               m_LogList.Invalidate();\r
-               if ( m_LogList.GetItemCount()==1 )\r
-               {\r
-                       m_LogList.SetSelectionMark(0);\r
-                       m_LogList.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\r
-               }\r
-               theApp.DoWaitCursor(-1);\r
-               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_HIDE);\r
-               GetDlgItem(IDC_SEARCHEDIT)->ShowWindow(SW_SHOW);\r
-               if (bSetFocusToFilterControl)\r
-                       GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
-               UpdateLogInfoLabel();\r
-       } // if (nIDEvent == LOGFILTER_TIMER)\r
-       DialogEnableWindow(IDC_STATBUTTON, !(((m_bThreadRunning)||(m_arShownList.IsEmpty()))));\r
-       __super::OnTimer(nIDEvent);\r
-}\r
-\r
-void CLogDlg::OnDtnDatetimechangeDateto(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
-{\r
-       CTime _time;\r
-       m_DateTo.GetTime(_time);\r
-       try\r
-       {\r
-               CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 23, 59, 59);\r
-               if (time.GetTime() != m_tTo)\r
-               {\r
-                       m_tTo = (DWORD)time.GetTime();\r
-                       SetTimer(LOGFILTER_TIMER, 10, NULL);\r
-               }\r
-       }\r
-       catch (CAtlException)\r
-       {\r
-       }\r
-       \r
-       *pResult = 0;\r
-}\r
-\r
-void CLogDlg::OnDtnDatetimechangeDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult)\r
-{\r
-       CTime _time;\r
-       m_DateFrom.GetTime(_time);\r
-       try\r
-       {\r
-               CTime time(_time.GetYear(), _time.GetMonth(), _time.GetDay(), 0, 0, 0);\r
-               if (time.GetTime() != m_tFrom)\r
-               {\r
-                       m_tFrom = (DWORD)time.GetTime();\r
-                       SetTimer(LOGFILTER_TIMER, 10, NULL);\r
-               }\r
-       }\r
-       catch (CAtlException)\r
-       {\r
-       }\r
-       \r
-       *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
-{\r
-       CTGitPathList pathList;\r
-#if 0\r
-       \r
-       if (m_sRepositoryRoot.IsEmpty() && (bRelativePaths == false))\r
-       {\r
-               m_sRepositoryRoot = GetRepositoryRoot(m_path);\r
-       }\r
-       if (m_sRepositoryRoot.IsEmpty() && (bRelativePaths == false))\r
-               return pathList;\r
-       \r
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-       if (pos != NULL)\r
-       {\r
-               while (pos)\r
-               {\r
-                       int nextpos = m_LogList.GetNextSelectedItem(pos);\r
-                       if (nextpos >= m_arShownList.GetCount())\r
-                               continue;\r
-                       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(nextpos));\r
-                       LogChangedPathArray * cpatharray = pLogEntry->pArChangedPaths;\r
-                       for (INT_PTR cpPathIndex = 0; cpPathIndex<cpatharray->GetCount(); ++cpPathIndex)\r
-                       {\r
-                               LogChangedPath * cpath = cpatharray->GetAt(cpPathIndex);\r
-                               if (cpath == NULL)\r
-                                       continue;\r
-                               CTGitPath path;\r
-                               if (!bRelativePaths)\r
-                                       path.SetFromGit(m_sRepositoryRoot);\r
-                               path.AppendPathString(cpath->sPath);\r
-                               if ((!bUseFilter)||\r
-                                       ((m_cHidePaths.GetState() & 0x0003)!=BST_CHECKED)||\r
-                                       (cpath->sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0))\r
-                                       pathList.AddPath(path);\r
-                               \r
+                               CTGitPath path;\r
+                               if (!bRelativePaths)\r
+                                       path.SetFromGit(m_sRepositoryRoot);\r
+                               path.AppendPathString(cpath->sPath);\r
+                               if ((!bUseFilter)||\r
+                                       ((m_cHidePaths.GetState() & 0x0003)!=BST_CHECKED)||\r
+                                       (cpath->sPath.Left(m_sRelativeRoot.GetLength()).Compare(m_sRelativeRoot)==0))\r
+                                       pathList.AddPath(path);\r
+                               \r
                        }\r
                }\r
        }\r
@@ -3504,7 +2569,7 @@ void CLogDlg::SortByColumn(int nSortColumn, bool bAscending)
 \r
 void CLogDlg::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)\r
 {\r
-       if (m_bThreadRunning)\r
+       if (this->IsThreadRunning())\r
                return;         //no sorting while the arrays are filled\r
        LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
        const int nColumn = pNMLV->iSubItem;\r
@@ -3564,7 +2629,8 @@ void CLogDlg::SetSortArrow(CListCtrl * control, int nColumn, bool bAscending)
 }\r
 void CLogDlg::OnLvnColumnclickChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
 {\r
-       if (m_bThreadRunning)\r
+#if 0\r
+       if (this->IsThreadRunning())\r
                return;         //no sorting while the arrays are filled\r
        if (m_currentChangedArray == NULL)\r
                return;\r
@@ -3577,6 +2643,7 @@ 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
@@ -3595,935 +2662,169 @@ int CLogDlg::SortCompare(const void * pElem1, const void * pElem2)
        switch (m_nSortColumnPathList)\r
        {\r
        case 0: // action\r
-                       cmp = cpath2->GetAction().Compare(cpath1->GetAction());\r
-                       if (cmp)\r
-                               return cmp;\r
-                       // fall through\r
-       case 1: // path\r
-                       cmp = cpath2->sPath.CompareNoCase(cpath1->sPath);\r
-                       if (cmp)\r
-                               return cmp;\r
-                       // fall through\r
-       case 2: // copy from path\r
-                       cmp = cpath2->sCopyFromPath.Compare(cpath1->sCopyFromPath);\r
-                       if (cmp)\r
-                               return cmp;\r
-                       // fall through\r
-       case 3: // copy from revision\r
-                       return cpath2->lCopyFromRev > cpath1->lCopyFromRev;\r
-       }\r
-#endif\r
-       return 0;\r
-}\r
-\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
-\r
-void CLogDlg::OnBnClickedHidepaths()\r
-{\r
-       FillLogMessageCtrl();\r
-       m_ChangedFileListCtrl.Invalidate();\r
-}\r
-\r
-\r
-void CLogDlg::OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
-{\r
-       LPNMLVFINDITEM pFindInfo = reinterpret_cast<LPNMLVFINDITEM>(pNMHDR);\r
-       *pResult = -1;\r
-       \r
-       if (pFindInfo->lvfi.flags & LVFI_PARAM)\r
-               return; \r
-       if ((pFindInfo->iStart < 0)||(pFindInfo->iStart >= m_arShownList.GetCount()))\r
-               return;\r
-       if (pFindInfo->lvfi.psz == 0)\r
-               return;\r
-#if 0\r
-       CString sCmp = pFindInfo->lvfi.psz;\r
-       CString sRev;   \r
-       for (int i=pFindInfo->iStart; i<m_arShownList.GetCount(); ++i)\r
-       {\r
-               GitRev * pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(i));\r
-               sRev.Format(_T("%ld"), pLogEntry->Rev);\r
-               if (pFindInfo->lvfi.flags & LVFI_PARTIAL)\r
-               {\r
-                       if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)\r
-                       {\r
-                               *pResult = i;\r
-                               return;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       if (sCmp.Compare(sRev)==0)\r
-                       {\r
-                               *pResult = i;\r
-                               return;\r
-                       }\r
-               }\r
-       }\r
-       if (pFindInfo->lvfi.flags & LVFI_WRAP)\r
-       {\r
-               for (int i=0; i<pFindInfo->iStart; ++i)\r
-               {\r
-                       PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(i));\r
-                       sRev.Format(_T("%ld"), pLogEntry->Rev);\r
-                       if (pFindInfo->lvfi.flags & LVFI_PARTIAL)\r
-                       {\r
-                               if (sCmp.Compare(sRev.Left(sCmp.GetLength()))==0)\r
-                               {\r
-                                       *pResult = i;\r
-                                       return;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               if (sCmp.Compare(sRev)==0)\r
-                               {\r
-                                       *pResult = i;\r
-                                       return;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-#endif\r
-       *pResult = -1;\r
-}\r
-\r
-void CLogDlg::OnBnClickedCheckStoponcopy()\r
-{\r
-#if 0\r
-       if (!GetDlgItem(IDC_GETALL)->IsWindowEnabled())\r
-               return;\r
-\r
-       // ignore old fetch limits when switching\r
-       // between copy-following and stop-on-copy\r
-       // (otherwise stop-on-copy will limit what\r
-       // we see immediately after switching to\r
-       // copy-following)\r
-\r
-       m_endrev = 0;\r
-\r
-       // now, restart the query\r
-#endif\r
-       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
-       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
-               selectedrevs = m_LogList.GetSelectedCount();\r
-       }\r
-       CString sTemp;\r
-       sTemp.Format(IDS_LOG_LOGINFOSTRING, m_arShownList.GetCount(), rev2, rev1, selectedrevs);\r
-       m_sLogInfo = sTemp;\r
-#endif\r
-       UpdateData(FALSE);\r
-}\r
-\r
-void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point)\r
-{\r
-\r
-       int selIndex = m_LogList.GetSelectionMark();\r
-       if (selIndex < 0)\r
-               return; // nothing selected, nothing to do with a context menu\r
-\r
-       // if the user selected the info text telling about not all revisions shown due to\r
-       // the "stop on copy/rename" option, we also don't show the context menu\r
-       if ((m_bStrictStopped)&&(selIndex == m_arShownList.GetCount()))\r
-               return;\r
-\r
-       // if the context menu is invoked through the keyboard, we have to use\r
-       // a calculated position on where to anchor the menu on\r
-       if ((point.x == -1) && (point.y == -1))\r
-       {\r
-               CRect rect;\r
-               m_LogList.GetItemRect(selIndex, &rect, LVIR_LABEL);\r
-               m_LogList.ClientToScreen(&rect);\r
-               point = rect.CenterPoint();\r
-       }\r
-       m_nSearchIndex = selIndex;\r
-       m_bCancelled = FALSE;\r
-\r
-       // calculate some information the context menu commands can use\r
-//     CString pathURL = GetURLFromPath(m_path);\r
-\r
-       POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-       int indexNext = m_LogList.GetNextSelectedItem(pos);\r
-       if (indexNext < 0)\r
-               return;\r
-\r
-       GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));\r
-#if 0\r
-       GitRev revSelected = pSelLogEntry->Rev;\r
-       GitRev revPrevious = git_revnum_t(revSelected)-1;\r
-       if ((pSelLogEntry->pArChangedPaths)&&(pSelLogEntry->pArChangedPaths->GetCount() <= 2))\r
-       {\r
-               for (int i=0; i<pSelLogEntry->pArChangedPaths->GetCount(); ++i)\r
-               {\r
-                       LogChangedPath * changedpath = (LogChangedPath *)pSelLogEntry->pArChangedPaths->GetAt(i);\r
-                       if (changedpath->lCopyFromRev)\r
-                               revPrevious = changedpath->lCopyFromRev;\r
-               }\r
-       }\r
-       GitRev revSelected2;\r
-       if (pos)\r
-       {\r
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-               revSelected2 = pLogEntry->Rev;\r
-       }\r
-       bool bAllFromTheSameAuthor = true;\r
-       CString firstAuthor;\r
-       CLogDataVector selEntries;\r
-       GitRev revLowest, revHighest;\r
-       GitRevRangeArray revisionRanges;\r
-       {\r
-               POSITION pos = m_LogList.GetFirstSelectedItemPosition();\r
-               PLOGENTRYDATA pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-               revisionRanges.AddRevision(pLogEntry->Rev);\r
-               selEntries.push_back(pLogEntry);\r
-               firstAuthor = pLogEntry->sAuthor;\r
-               revLowest = pLogEntry->Rev;\r
-               revHighest = pLogEntry->Rev;\r
-               while (pos)\r
-               {\r
-                       pLogEntry = reinterpret_cast<PLOGENTRYDATA>(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos)));\r
-                       revisionRanges.AddRevision(pLogEntry->Rev);\r
-                       selEntries.push_back(pLogEntry);\r
-                       if (firstAuthor.Compare(pLogEntry->sAuthor))\r
-                               bAllFromTheSameAuthor = false;\r
-                       revLowest = (git_revnum_t(pLogEntry->Rev) > git_revnum_t(revLowest) ? revLowest : pLogEntry->Rev);\r
-                       revHighest = (git_revnum_t(pLogEntry->Rev) < git_revnum_t(revHighest) ? revHighest : pLogEntry->Rev);\r
-               }\r
-       }\r
-\r
-#endif\r
-\r
-       int FirstSelect=-1, LastSelect=-1;\r
-       pos = m_LogList.GetFirstSelectedItemPosition();\r
-       FirstSelect = m_LogList.GetNextSelectedItem(pos);\r
-       while(pos)\r
-       {\r
-               LastSelect = m_LogList.GetNextSelectedItem(pos);\r
-       }\r
-       //entry is selected, now show the popup menu\r
-       CIconMenu popup;\r
-       if (popup.CreatePopupMenu())\r
-       {\r
-               if (m_LogList.GetSelectedCount() == 1)\r
-               {\r
-#if 0\r
-                       if (!m_path.IsDirectory())\r
-                       {\r
-                               if (m_hasWC)\r
-                               {\r
-                                       popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
-                                       popup.AppendMenuIcon(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
-                               }\r
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
-                               popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
-                               popup.AppendMenu(MF_SEPARATOR, NULL);\r
-                               popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
-                               popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
-                               popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
-                               popup.AppendMenuIcon(ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
-                               popup.AppendMenu(MF_SEPARATOR, NULL);\r
-                       }\r
-                       else\r
-#endif \r
-                       {\r
-                               if (m_hasWC)\r
-                               {\r
-                                       popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
-                                       // TODO:\r
-                                       // TortoiseMerge could be improved to take a /blame switch\r
-                                       // and then not 'cat' the files from a unified diff but\r
-                                       // blame then.\r
-                                       // But until that's implemented, the context menu entry for\r
-                                       // this feature is commented out.\r
-                                       //popup.AppendMenu(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
-                               }\r
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
-                               popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
-                               popup.AppendMenuIcon(ID_BLAMEWITHPREVIOUS, IDS_LOG_POPUP_BLAMEWITHPREVIOUS, IDI_BLAME);\r
-                               popup.AppendMenu(MF_SEPARATOR, NULL);\r
-                       }\r
-\r
-//                     if (!m_ProjectProperties.sWebViewerRev.IsEmpty())\r
-//                     {\r
-//                             popup.AppendMenuIcon(ID_VIEWREV, IDS_LOG_POPUP_VIEWREV);\r
-//                     }\r
-//                     if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty())\r
-//                     {\r
-//                             popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
-//                     }\r
-//                     if ((!m_ProjectProperties.sWebViewerPathRev.IsEmpty())||\r
-//                             (!m_ProjectProperties.sWebViewerRev.IsEmpty()))\r
-//                     {\r
-//                             popup.AppendMenu(MF_SEPARATOR, NULL);\r
-//                     }\r
-\r
-//                     popup.AppendMenuIcon(ID_REPOBROWSE, IDS_LOG_BROWSEREPO, IDI_REPOBROWSE);\r
-//                     popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPY);\r
-//                     if (m_hasWC)\r
-//                             popup.AppendMenuIcon(ID_UPDATE, IDS_LOG_POPUP_UPDATE, IDI_UPDATE);\r
-                       if (m_hasWC)\r
-                               popup.AppendMenuIcon(ID_REVERTTOREV, IDS_LOG_POPUP_REVERTTOREV, IDI_REVERT);\r
-                       if (m_hasWC)\r
-                               popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
-//                     if (m_hasWC)\r
-//                             popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE);\r
-                       popup.AppendMenuIcon(ID_CHECKOUT, IDS_MENUCHECKOUT, IDI_CHECKOUT);\r
-                       popup.AppendMenuIcon(ID_EXPORT, IDS_MENUEXPORT, IDI_EXPORT);\r
-                       popup.AppendMenu(MF_SEPARATOR, NULL);\r
-               }\r
-               else if (m_LogList.GetSelectedCount() >= 2)\r
-               {\r
-                       bool bAddSeparator = false;\r
-                       if (IsSelectionContinuous() || (m_LogList.GetSelectedCount() == 2))\r
-                       {\r
-                               popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);\r
-                       }\r
-                       if (m_LogList.GetSelectedCount() == 2)\r
-                       {\r
-                               popup.AppendMenuIcon(ID_BLAMETWO, IDS_LOG_POPUP_BLAMEREVS, IDI_BLAME);\r
-                               popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);\r
-                               bAddSeparator = true;\r
-                       }\r
-                       if (m_hasWC)\r
-                       {\r
-                               popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREVS, IDI_REVERT);\r
-//                             if (m_hasWC)\r
-//                                     popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREVS, IDI_MERGE);\r
-                               bAddSeparator = true;\r
-                       }\r
-                       if (bAddSeparator)\r
-                               popup.AppendMenu(MF_SEPARATOR, NULL);\r
-               }\r
-#if 0\r
-//             if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor))\r
-//             {\r
-//                     popup.AppendMenuIcon(ID_EDITAUTHOR, IDS_LOG_POPUP_EDITAUTHOR);\r
-//             }\r
-//             if (m_LogList.GetSelectedCount() == 1)\r
-//             {\r
-//                     popup.AppendMenuIcon(ID_EDITLOG, IDS_LOG_POPUP_EDITLOG);\r
-//                     popup.AppendMenuIcon(ID_REVPROPS, IDS_REPOBROWSE_SHOWREVPROP, IDI_PROPERTIES); // "Show Revision Properties"\r
-//                     popup.AppendMenu(MF_SEPARATOR, NULL);\r
-//             }\r
-#endif\r
-               if (m_LogList.GetSelectedCount() != 0)\r
-               {\r
-                       popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
-               }\r
-               popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
-\r
-               int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
-               DialogEnableWindow(IDOK, FALSE);\r
-//             SetPromptApp(&theApp);\r
-               theApp.DoWaitCursor(1);\r
-               bool bOpenWith = false;\r
-\r
-               switch (cmd)\r
-               {\r
-                       case ID_GNUDIFF1:\r
-                       {\r
-                               CString tempfile=GetTempFile();\r
-                               CString cmd;\r
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
-                               cmd.Format(_T("git.cmd diff-tree -r -p --stat %s"),r1->m_CommitHash);\r
-                               g_Git.RunLogFile(cmd,tempfile);\r
-                               CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r1->m_Subject);\r
-                       }\r
-                       break;\r
-\r
-                       case ID_GNUDIFF2:\r
-                       {\r
-                               CString tempfile=GetTempFile();\r
-                               CString cmd;\r
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
-                               GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
-                               cmd.Format(_T("git.cmd diff-tree -r -p --stat %s %s"),r1->m_CommitHash,r2->m_CommitHash);\r
-                               g_Git.RunLogFile(cmd,tempfile);\r
-                               CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r2->m_CommitHash.Left(6));\r
-\r
-                       }\r
-                       break;\r
-\r
-               case ID_COMPARETWO:\r
-                       {\r
-                               GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
-                               GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
-                               CFileDiffDlg dlg;\r
-                               dlg.SetDiff(NULL,*r1,*r2);\r
-                               dlg.DoModal();\r
-                               \r
-                       }\r
-                       break;\r
-\r
-#if 0\r
-               case ID_GNUDIFF1:\r
-                       {\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, this->m_hWnd, true);\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowUnifiedDiff(m_path, revPrevious, m_path, revSelected);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revPrevious, m_path, revSelected, GitRev(), m_LogRevision);\r
-                       }\r
-                       break;\r
-\r
-               case ID_GNUDIFF2:\r
-                       {\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, this->m_hWnd, true);\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowUnifiedDiff(m_path, revSelected2, m_path, revSelected);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revSelected2, m_path, revSelected, GitRev(), m_LogRevision);\r
-                       }\r
-                       break;\r
-               case ID_REVERTREV:\r
-                       {\r
-                               // we need an URL to complete this command, so error out if we can't get an URL\r
-                               if (pathURL.IsEmpty())\r
-                               {\r
-                                       CString strMessage;\r
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));\r
-                                       break;          //exit\r
-                               }\r
-                               CString msg;\r
-                               msg.Format(IDS_LOG_REVERT_CONFIRM, m_path.GetWinPath());\r
-                               if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
-                               {\r
-                                       CGitProgressDlg dlg;\r
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
-                                       dlg.SetPathList(CTGitPathList(m_path));\r
-                                       dlg.SetUrl(pathURL);\r
-                                       dlg.SetSecondUrl(pathURL);\r
-                                       revisionRanges.AdjustForMerge(true);\r
-                                       dlg.SetRevisionRanges(revisionRanges);\r
-                                       dlg.SetPegRevision(m_LogRevision);\r
-                                       dlg.DoModal();\r
-                               }\r
-                       }\r
-                       break;\r
-               case ID_MERGEREV:\r
-                       {\r
-                               // we need an URL to complete this command, so error out if we can't get an URL\r
-                               if (pathURL.IsEmpty())\r
-                               {\r
-                                       CString strMessage;\r
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));\r
-                                       break;          //exit\r
-                               }\r
-\r
-                               CString path = m_path.GetWinPathString();\r
-                               bool bGotSavePath = false;\r
-                               if ((m_LogList.GetSelectedCount() == 1)&&(!m_path.IsDirectory()))\r
-                               {\r
-                                       bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());\r
-                               }\r
-                               else\r
-                               {\r
-                                       CBrowseFolder folderBrowser;\r
-                                       folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));\r
-                                       bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);\r
-                               }\r
-                               if (bGotSavePath)\r
-                               {\r
-                                       CGitProgressDlg dlg;\r
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
-                                       dlg.SetPathList(CTGitPathList(CTGitPath(path)));\r
-                                       dlg.SetUrl(pathURL);\r
-                                       dlg.SetSecondUrl(pathURL);\r
-                                       revisionRanges.AdjustForMerge(false);\r
-                                       dlg.SetRevisionRanges(revisionRanges);\r
-                                       dlg.SetPegRevision(m_LogRevision);\r
-                                       dlg.DoModal();\r
-                               }\r
-                       }\r
-                       break;\r
-               case ID_REVERTTOREV:\r
-                       {\r
-                               // we need an URL to complete this command, so error out if we can't get an URL\r
-                               if (pathURL.IsEmpty())\r
-                               {\r
-                                       CString strMessage;\r
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));\r
-                                       break;          //exit\r
-                               }\r
-\r
-                               CString msg;\r
-                               msg.Format(IDS_LOG_REVERTTOREV_CONFIRM, m_path.GetWinPath());\r
-                               if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
-                               {\r
-                                       CGitProgressDlg dlg;\r
-                                       dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
-                                       dlg.SetPathList(CTGitPathList(m_path));\r
-                                       dlg.SetUrl(pathURL);\r
-                                       dlg.SetSecondUrl(pathURL);\r
-                                       GitRevRangeArray revarray;\r
-                                       revarray.AddRevRange(GitRev::REV_HEAD, revSelected);\r
-                                       dlg.SetRevisionRanges(revarray);\r
-                                       dlg.SetPegRevision(m_LogRevision);\r
-                                       dlg.DoModal();\r
-                               }\r
-                       }\r
-                       break;\r
-               case ID_COPY:\r
-                       {\r
-                               // we need an URL to complete this command, so error out if we can't get an URL\r
-                               if (pathURL.IsEmpty())\r
-                               {\r
-                                       CString strMessage;\r
-                                       strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
-                                       CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
-                                       TRACE(_T("could not retrieve the URL of the folder!\n"));\r
-                                       break;          //exit\r
-                               }\r
-\r
-                               CCopyDlg dlg;\r
-                               dlg.m_URL = pathURL;\r
-                               dlg.m_path = m_path;\r
-                               dlg.m_CopyRev = revSelected;\r
-                               if (dlg.DoModal() == IDOK)\r
-                               {\r
-                                       // should we show a progress dialog here? Copies are done really fast\r
-                                       // and without much network traffic.\r
-                                       if (!Copy(CTGitPathList(CTGitPath(pathURL)), CTGitPath(dlg.m_URL), dlg.m_CopyRev, dlg.m_CopyRev, dlg.m_sLogMessage))\r
-                                               CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
-                                       else\r
-                                               CMessageBox::Show(this->m_hWnd, IDS_LOG_COPY_SUCCESS, IDS_APPNAME, MB_ICONINFORMATION);\r
-                               }\r
-                       } \r
-                       break;\r
-               case ID_COMPARE:\r
-                       {\r
-                               //user clicked on the menu item "compare with working copy"\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, m_hWnd, true);\r
-                                       diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                       }\r
-                       break;\r
-               case ID_COMPARETWO:\r
-                       {\r
-                               GitRev r1 = revSelected;\r
-                               GitRev r2 = revSelected2;\r
-                               if (m_LogList.GetSelectedCount() > 2)\r
-                               {\r
-                                       r1 = revHighest;\r
-                                       r2 = revLowest;\r
-                               }\r
-                               //user clicked on the menu item "compare revisions"\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, m_hWnd, true);\r
-                                       diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(CTGitPath(pathURL), r2, CTGitPath(pathURL), r1);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), r2, CTGitPath(pathURL), r1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                       }\r
-                       break;\r
-               case ID_COMPAREWITHPREVIOUS:\r
-                       {\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, m_hWnd, true);\r
-                                       diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                       }\r
-                       break;\r
-               case ID_BLAMECOMPARE:\r
-                       {\r
-                               //user clicked on the menu item "compare with working copy"\r
-                               //now first get the revision which is selected\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, this->m_hWnd, true);\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), false, true);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);\r
-                       }\r
-                       break;\r
-               case ID_BLAMETWO:\r
-                       {\r
-                               //user clicked on the menu item "compare and blame revisions"\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, this->m_hWnd, true);\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
-                       }\r
-                       break;\r
-               case ID_BLAMEWITHPREVIOUS:\r
-                       {\r
-                               //user clicked on the menu item "Compare and Blame with previous revision"\r
-                               if (PromptShown())\r
-                               {\r
-                                       GitDiff diff(this, this->m_hWnd, true);\r
-                                       diff.SetHEADPeg(m_LogRevision);\r
-                                       diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
-                               }\r
-                               else\r
-                                       CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
-                       }\r
-                       break;\r
-               case ID_SAVEAS:\r
-                       {\r
-                               //now first get the revision which is selected\r
-                               CString revFilename;\r
-                               if (m_hasWC)\r
-                               {\r
-                                       CString strWinPath = m_path.GetWinPathString();\r
-                                       int rfind = strWinPath.ReverseFind('.');\r
-                                       if (rfind > 0)\r
-                                               revFilename.Format(_T("%s-%ld%s"), (LPCTSTR)strWinPath.Left(rfind), (LONG)revSelected, (LPCTSTR)strWinPath.Mid(rfind));\r
-                                       else\r
-                                               revFilename.Format(_T("%s-%ld"), (LPCTSTR)strWinPath, revSelected);\r
-                               }\r
-                               if (CAppUtils::FileOpenSave(revFilename, NULL, IDS_LOG_POPUP_SAVE, IDS_COMMONFILEFILTER, false, m_hWnd))\r
-                               {\r
-                                       CTGitPath tempfile;\r
-                                       tempfile.SetFromWin(revFilename);\r
-                                       CProgressDlg progDlg;\r
-                                       progDlg.SetTitle(IDS_APPNAME);\r
-                                       progDlg.SetAnimation(IDR_DOWNLOAD);\r
-                                       CString sInfoLine;\r
-                                       sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
-                                       progDlg.SetLine(1, sInfoLine, true);\r
-                                       SetAndClearProgressInfo(&progDlg);\r
-                                       progDlg.ShowModeless(m_hWnd);\r
-                                       if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\r
-                                       {\r
-                                               // try again with another peg revision\r
-                                               if (!Cat(m_path, revSelected, revSelected, tempfile))\r
-                                               {\r
-                                                       progDlg.Stop();\r
-                                                       SetAndClearProgressInfo((HWND)NULL);\r
-                                                       CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
-                                                       EnableOKButton();\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                                       progDlg.Stop();\r
-                                       SetAndClearProgressInfo((HWND)NULL);\r
-                               }\r
-                       }\r
-                       break;\r
-               case ID_OPENWITH:\r
-                       bOpenWith = true;\r
-               case ID_OPEN:\r
+                       cmp = cpath2->GetAction().Compare(cpath1->GetAction());\r
+                       if (cmp)\r
+                               return cmp;\r
+                       // fall through\r
+       case 1: // path\r
+                       cmp = cpath2->sPath.CompareNoCase(cpath1->sPath);\r
+                       if (cmp)\r
+                               return cmp;\r
+                       // fall through\r
+       case 2: // copy from path\r
+                       cmp = cpath2->sCopyFromPath.Compare(cpath1->sCopyFromPath);\r
+                       if (cmp)\r
+                               return cmp;\r
+                       // fall through\r
+       case 3: // copy from revision\r
+                       return cpath2->lCopyFromRev > cpath1->lCopyFromRev;\r
+       }\r
+#endif\r
+       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
-                               CProgressDlg progDlg;\r
-                               progDlg.SetTitle(IDS_APPNAME);\r
-                               progDlg.SetAnimation(IDR_DOWNLOAD);\r
-                               CString sInfoLine;\r
-                               sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
-                               progDlg.SetLine(1, sInfoLine, true);\r
-                               SetAndClearProgressInfo(&progDlg);\r
-                               progDlg.ShowModeless(m_hWnd);\r
-                               CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path, revSelected);\r
-                               bool bSuccess = true;\r
-                               if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\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
-                                       bSuccess = false;\r
-                                       // try again, but with the selected revision as the peg revision\r
-                                       if (!Cat(m_path, revSelected, revSelected, tempfile))\r
+                                       GitRev * pCurLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index));\r
+                                       if ((pCurLogEntry)&&(pCurLogEntry->m_CommitHash == m_wcRev.m_CommitHash))\r
                                        {\r
-                                               progDlg.Stop();\r
-                                               SetAndClearProgressInfo((HWND)NULL);\r
-                                               CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
-                                               EnableOKButton();\r
-                                               break;\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
-                                       bSuccess = true;\r
                                }\r
-                               if (bSuccess)\r
+                               if (index == 0)\r
                                {\r
-                                       progDlg.Stop();\r
-                                       SetAndClearProgressInfo((HWND)NULL);\r
-                                       SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
-                                       int ret = 0;\r
-                                       if (!bOpenWith)\r
-                                               ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);\r
-                                       if ((ret <= HINSTANCE_ERROR)||bOpenWith)\r
+                                       // add the image size\r
+                                       CImageList * pImgList = m_LogList.GetImageList(LVSIL_SMALL);\r
+                                       if ((pImgList)&&(pImgList->GetImageCount()))\r
                                        {\r
-                                               CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
-                                               cmd += tempfile.GetWinPathString() + _T(" ");\r
-                                               CAppUtils::LaunchApplication(cmd, NULL, false);\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
-                       break;\r
-               case ID_BLAME:\r
+                       // Adjust columns "Actions" containing icons\r
+                       if (col == this->LOGLIST_ACTION)\r
                        {\r
-                               CBlameDlg dlg;\r
-                               dlg.EndRev = revSelected;\r
-                               if (dlg.DoModal() == IDOK)\r
+                               if (cx < nMinimumWidth)\r
                                {\r
-                                       CBlame blame;\r
-                                       CString tempfile;\r
-                                       CString logfile;\r
-                                       tempfile = blame.BlameToTempFile(m_path, dlg.StartRev, dlg.EndRev, dlg.EndRev, logfile, _T(""), dlg.m_bIncludeMerge, TRUE, TRUE);\r
-                                       if (!tempfile.IsEmpty())\r
-                                       {\r
-                                               if (dlg.m_bTextView)\r
-                                               {\r
-                                                       //open the default text editor for the result file\r
-                                                       CAppUtils::StartTextViewer(tempfile);\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");\r
-                                                       if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))\r
-                                                       {\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
-                                       }\r
+                                       cx = nMinimumWidth;\r
                                }\r
                        }\r
-                       break;\r
-               case ID_UPDATE:\r
-                       {\r
-                               CString sCmd;\r
-                               CString url = _T("tgit:")+pathURL;\r
-                               sCmd.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),\r
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
-                                       (LPCTSTR)m_path.GetWinPath(), (LONG)revSelected);\r
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                       }\r
-                       break;\r
-               case ID_FINDENTRY:\r
+                       \r
+                       if (col == this->LOGLIST_MESSAGE)\r
                        {\r
-                               m_nSearchIndex = m_LogList.GetSelectionMark();\r
-                               if (m_nSearchIndex < 0)\r
-                                       m_nSearchIndex = 0;\r
-                               if (m_pFindDialog)\r
-                               {\r
-                                       break;\r
-                               }\r
-                               else\r
+                               if (cx > LOGLIST_MESSAGE_MAX)\r
                                {\r
-                                       m_pFindDialog = new CFindReplaceDialog();\r
-                                       m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this);                                                                        \r
+                                       cx = LOGLIST_MESSAGE_MAX;\r
                                }\r
-                       }\r
-                       break;\r
-               case ID_REPOBROWSE:\r
-                       {\r
-                               CString sCmd;\r
-                               sCmd.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),\r
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
-                                       (LPCTSTR)pathURL, (LPCTSTR)revSelected.ToString());\r
 \r
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                       }\r
-                       break;\r
-               case ID_EDITLOG:\r
-                       {\r
-                               EditLogMessage(selIndex);\r
-                       }\r
-                       break;\r
-               case ID_EDITAUTHOR:\r
-                       {\r
-                               EditAuthor(selEntries);\r
-                       }\r
-                       break;\r
-               case ID_REVPROPS:\r
-                       {\r
-                               CEditPropertiesDlg dlg;\r
-                               dlg.SetProjectProperties(&m_ProjectProperties);\r
-                               CTGitPathList escapedlist;\r
-                               dlg.SetPathList(CTGitPathList(CTGitPath(pathURL)));\r
-                               dlg.SetRevision(revSelected);\r
-                               dlg.RevProps(true);\r
-                               dlg.DoModal();\r
-                       }\r
-                       break;\r
-               case ID_COPYCLIPBOARD:\r
-                       {\r
-                               CopySelectionToClipBoard();\r
-                       }\r
-                       break;\r
-               case ID_EXPORT:\r
-                       {\r
-                               CString sCmd;\r
-                               sCmd.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),\r
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
-                                       (LPCTSTR)pathURL, (LONG)revSelected);\r
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                       }\r
-                       break;\r
-               case ID_CHECKOUT:\r
-                       {\r
-                               CString sCmd;\r
-                               CString url = _T("tgit:")+pathURL;\r
-                               sCmd.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),\r
-                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
-                                       (LPCTSTR)url, (LONG)revSelected);\r
-                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                       }\r
-                       break;\r
-               case ID_VIEWREV:\r
-                       {\r
-                               CString url = m_ProjectProperties.sWebViewerRev;\r
-                               url = GetAbsoluteUrlFromRelativeUrl(url);\r
-                               url.Replace(_T("%REVISION%"), revSelected.ToString());\r
-                               if (!url.IsEmpty())\r
-                                       ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        \r
                        }\r
-                       break;\r
-               case ID_VIEWPATHREV:\r
+                       // keep the bug id column small\r
+                       if ((col == 4)&&(m_bShowBugtraqColumn))\r
                        {\r
-                               CString relurl = pathURL;\r
-                               CString sRoot = GetRepositoryRoot(CTGitPath(relurl));\r
-                               relurl = relurl.Mid(sRoot.GetLength());\r
-                               CString url = m_ProjectProperties.sWebViewerPathRev;\r
-                               url = GetAbsoluteUrlFromRelativeUrl(url);\r
-                               url.Replace(_T("%REVISION%"), revSelected.ToString());\r
-                               url.Replace(_T("%PATH%"), relurl);\r
-                               if (!url.IsEmpty())\r
-                                       ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);                                        \r
+                               if (cx > (int)(DWORD)m_regMaxBugIDColWidth)\r
+                               {\r
+                                       cx = (int)(DWORD)m_regMaxBugIDColWidth;\r
+                               }\r
                        }\r
-                       break;\r
+\r
+                       m_LogList.SetColumnWidth(col, cx);\r
+               }\r
+       }\r
+\r
+}\r
 #endif\r
-               default:\r
-                       break;\r
-               } // switch (cmd)\r
-               theApp.DoWaitCursor(-1);\r
-               EnableOKButton();\r
-       } // if (popup.CreatePopupMenu())\r
+\r
+void CLogDlg::OnBnClickedHidepaths()\r
+{\r
+       FillLogMessageCtrl();\r
+       m_ChangedFileListCtrl.Invalidate();\r
+}\r
+\r
+\r
+\r
+void CLogDlg::OnBnClickedCheckStoponcopy()\r
+{\r
+#if 0\r
+       if (!GetDlgItem(IDC_GETALL)->IsWindowEnabled())\r
+               return;\r
+\r
+       // ignore old fetch limits when switching\r
+       // between copy-following and stop-on-copy\r
+       // (otherwise stop-on-copy will limit what\r
+       // we see immediately after switching to\r
+       // copy-following)\r
+\r
+       m_endrev = 0;\r
+\r
+       // now, restart the query\r
+#endif\r
+       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
+\r
+       git_revnum_t rev1 ;\r
+       git_revnum_t rev2 ;\r
+       long selectedrevs = 0;\r
+       int count =m_LogList.m_arShownList.GetCount();\r
+       if (count)\r
+       {\r
+               rev1 = (reinterpret_cast<GitRev*>(m_LogList.m_arShownList.GetAt(0)))->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(_T("Showing %ld revision(s), from revision %s to revision %s - %ld revision(s) selected"), count, rev2.Left(6), rev1.Left(6), selectedrevs);\r
+       m_sLogInfo = sTemp;\r
+\r
+       UpdateData(FALSE);\r
 }\r
 \r
+#if 0\r
 void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)\r
 {\r
 \r
@@ -4548,9 +2849,9 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)
 \r
        bool bOneRev = true;\r
        int sel=m_LogList.GetNextSelectedItem(pos);\r
-       GitRev * pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(sel));\r
+       GitRev * pLogEntry = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(sel));\r
        GitRev * rev1 = pLogEntry;\r
-       GitRev * rev2 = reinterpret_cast<GitRev *>(m_arShownList.GetAt(sel+1));\r
+       GitRev * rev2 = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(sel+1));\r
 #if 0\r
        bool bOneRev = true;\r
        if (pos)\r
@@ -4639,40 +2940,40 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)
                {\r
 //                     if ((!bOneRev)||(IsDiffPossible(changedlogpaths[0], rev1)))\r
                        {\r
-                               popup.AppendMenuIcon(ID_DIFF, IDS_LOG_POPUP_DIFF, IDI_DIFF);\r
-                               popup.AppendMenuIcon(ID_BLAMEDIFF, IDS_LOG_POPUP_BLAMEDIFF, IDI_BLAME);\r
-                               popup.SetDefaultItem(ID_DIFF, FALSE);\r
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_DIFF, IDS_LOG_POPUP_DIFF, IDI_DIFF);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_BLAMEDIFF, IDS_LOG_POPUP_BLAMEDIFF, IDI_BLAME);\r
+                               popup.SetDefaultItem(CGitLogList::ID_DIFF, FALSE);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
                                bEntryAdded = true;\r
                        }\r
 //                     if (rev2 == rev1-1)\r
                        {\r
                                if (bEntryAdded)\r
                                        popup.AppendMenu(MF_SEPARATOR, NULL);\r
-                               popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
-                               popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
-                               popup.AppendMenuIcon(ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_BLAME, IDS_LOG_POPUP_BLAME, IDI_BLAME);\r
                                popup.AppendMenu(MF_SEPARATOR, NULL);\r
                                if (m_hasWC)\r
-                                       popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
-                               popup.AppendMenuIcon(ID_POPPROPS, IDS_REPOBROWSE_SHOWPROP, IDI_PROPERTIES);                     // "Show Properties"\r
-                               popup.AppendMenuIcon(ID_LOG, IDS_MENULOG, IDI_LOG);                                             // "Show Log"                           \r
-                               popup.AppendMenuIcon(ID_GETMERGELOGS, IDS_LOG_POPUP_GETMERGELOGS, IDI_LOG);             // "Show merge log"\r
-                               popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
+                                       popup.AppendMenuIcon(CGitLogList::ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT);\r
+                               popup.AppendMenuIcon(CGitLogList::ID_POPPROPS, IDS_REPOBROWSE_SHOWPROP, IDI_PROPERTIES);                        // "Show Properties"\r
+                               popup.AppendMenuIcon(CGitLogList::ID_LOG, IDS_MENULOG, IDI_LOG);                                                // "Show Log"                           \r
+                               popup.AppendMenuIcon(CGitLogList::ID_GETMERGELOGS, IDS_LOG_POPUP_GETMERGELOGS, IDI_LOG);                // "Show merge log"\r
+                               popup.AppendMenuIcon(CGitLogList::ID_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
                                bEntryAdded = true;\r
                                if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty())\r
                                {\r
                                        popup.AppendMenu(MF_SEPARATOR, NULL);\r
-                                       popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
+                                       popup.AppendMenuIcon(CGitLogList::ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV);\r
                                }\r
                                if (popup.GetDefaultItem(0,FALSE)==-1)\r
-                                       popup.SetDefaultItem(ID_OPEN, FALSE);\r
+                                       popup.SetDefaultItem(CGitLogList::ID_OPEN, FALSE);\r
                        }\r
                }\r
                else if (changedlogpaths.size())\r
                {\r
                        // more than one entry is selected\r
-                       popup.AppendMenuIcon(ID_SAVEAS, IDS_LOG_POPUP_SAVE);\r
+                       popup.AppendMenuIcon(CGitLogList::ID_SAVEAS, IDS_LOG_POPUP_SAVE);\r
                        bEntryAdded = true;\r
                }\r
 \r
@@ -4685,7 +2986,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point)
                \r
                switch (cmd)\r
                {\r
-               case ID_DIFF:\r
+               case CGitLogList::ID_DIFF:\r
                        {\r
                                DoDiffFromLog(selIndex, rev1, rev2, false, false);\r
                        }\r
@@ -5059,6 +3360,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
@@ -5113,7 +3415,7 @@ void CLogDlg::OnEditCopy()
        if (GetFocus() == &m_ChangedFileListCtrl)\r
                CopyChangedSelectionToClipBoard();\r
        else\r
-               CopySelectionToClipBoard();\r
+               m_LogList.CopySelectionToClipBoard();\r
 }\r
 \r
 CString CLogDlg::GetAbsoluteUrlFromRelativeUrl(const CString& url)\r
@@ -5150,35 +3452,43 @@ CString CLogDlg::GetAbsoluteUrlFromRelativeUrl(const CString& url)
 }\r
 \r
 \r
-int CLogDataVector::ParserFromLog()\r
+void CLogDlg::OnEnChangeSearchedit()\r
 {\r
-       CString log;\r
-       GitRev rev;\r
-       g_Git.GetLog(log);\r
-\r
-       CString begin;\r
-       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
-       \r
-       if(log.GetLength()==0)\r
-               return 0;\r
-       \r
-       int start=4;\r
-       int length;\r
-       int next =1;\r
-       while( next>0 )\r
+       UpdateData();\r
+       if (m_LogList.m_sFilterText.IsEmpty())\r
        {\r
-               next=log.Find(begin,start);\r
-               if(next >0 )\r
-                       length = next - start+4;\r
-               else\r
-                       length = log.GetLength()-start+4;\r
-\r
-               CString onelog =log;\r
-               onelog=log.Mid(start -4,length);\r
-               rev.ParserFromLog(onelog);\r
-               this->push_back(rev);\r
-               start = next +4;\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
-       return 0;\r
-}\r
+}
\ No newline at end of file