CGitLogList::CGitLogList():CHintListCtrl()\r
,m_regMaxBugIDColWidth(_T("Software\\TortoiseGit\\MaxBugIDColWidth"), 200)\r
,m_nSearchIndex(0)\r
+ ,m_bNoDispUpdates(FALSE)\r
+ , m_bThreadRunning(FALSE)\r
+ , m_bStrictStopped(false)\r
+ , m_pStoreSelection(NULL)\r
{\r
// use the default GUI font, create a copy of it and\r
// change the copy to BOLD (leave the rest of the font\r
lf.lfWeight = FW_BOLD;\r
m_boldFont = CreateFontIndirect(&lf);\r
\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
+\r
}\r
\r
CGitLogList::~CGitLogList()\r
{\r
+ InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+\r
DestroyIcon(m_hModifiedIcon);\r
DestroyIcon(m_hReplacedIcon);\r
DestroyIcon(m_hAddedIcon);\r
if (m_boldFont)\r
DeleteObject(m_boldFont);\r
\r
+ if ( m_pStoreSelection )\r
+ {\r
+ delete m_pStoreSelection;\r
+ m_pStoreSelection = NULL;\r
+ }\r
}\r
\r
\r
BEGIN_MESSAGE_MAP(CGitLogList, CHintListCtrl)\r
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawLoglist)\r
- ON_NOTIFY(LVN_GETDISPINFO, 0, OnLvnGetdispinfoLoglist)\r
+ ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfoLoglist)\r
ON_WM_CONTEXTMENU()\r
- ON_NOTIFY(NM_DBLCLK, 0, OnNMDblclkLoglist)\r
- ON_NOTIFY(LVN_ODFINDITEM, IDC_LOGLIST, OnLvnOdfinditemLoglist)\r
+ ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclkLoglist)\r
+ ON_NOTIFY_REFLECT(LVN_ODFINDITEM,OnLvnOdfinditemLoglist)\r
+ ON_WM_CREATE()\r
END_MESSAGE_MAP()\r
\r
int CGitLogList:: OnCreate(LPCREATESTRUCT lpCreateStruct)\r
{\r
+ PreSubclassWindow();\r
+ return CHintListCtrl::OnCreate(lpCreateStruct);\r
+}\r
+\r
+void CGitLogList::PreSubclassWindow()\r
+{\r
SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_SUBITEMIMAGES);\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
- return CHintListCtrl::OnCreate(lpCreateStruct);\r
+ m_Theme.SetWindowTheme(GetSafeHwnd(), L"Explorer", NULL);\r
+ CHintListCtrl::PreSubclassWindow();\r
}\r
\r
void CGitLogList::InsertGitColumn()\r
\r
if (CRegDWORD(_T("Software\\TortoiseGit\\DiffByDoubleClickInLog"), FALSE))\r
DiffSelectedRevWithPrevious();\r
+}\r
+\r
+int CGitLogList::FetchLogAsync(CALLBACK_PROCESS *proc,void * data)\r
+{\r
+ m_ProcCallBack=proc;\r
+ m_ProcData=data;\r
+\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
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+//this is the thread function which calls the subversion function\r
+UINT CGitLogList::LogThreadEntry(LPVOID pVoid)\r
+{\r
+ return ((CGitLogList*)pVoid)->LogThread();\r
+}\r
+\r
+\r
+UINT CGitLogList::LogThread()\r
+{\r
+\r
+ if(m_ProcCallBack)\r
+ m_ProcCallBack(m_ProcData,GITLOG_START);\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
+\r
+ CString temp;\r
+ temp.LoadString(IDS_PROGRESSWAIT);\r
+ ShowText(temp, true);\r
+\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
+ FillGitLog();\r
+ \r
+ InterlockedExchange(&m_bThreadRunning, FALSE);\r
+\r
+ RedrawItems(0, m_arShownList.GetCount());\r
+ SetRedraw(false);\r
+ ResizeAllListCtrlCols();\r
+ SetRedraw(true);\r
+\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 ( GetItemCount()>0 )\r
+ {\r
+ SetSelectionMark(0);\r
+ SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);\r
+ }\r
+ }\r
+\r
+ //RefreshCursor();\r
+ // make sure the filter is applied (if any) now, after we refreshed/fetched\r
+ // the log messages\r
+\r
+ InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+\r
+ if(m_ProcCallBack)\r
+ m_ProcCallBack(m_ProcData,GITLOG_END);\r
+\r
+ return 0;\r
}
\ No newline at end of file
, 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_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
\r
CLogDlg::~CLogDlg()\r
{\r
- InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+ \r
m_CurrentFilteredChangedArray.RemoveAll();\r
\r
\r
- if ( m_pStoreSelection )\r
- {\r
- delete m_pStoreSelection;\r
- m_pStoreSelection = NULL;\r
- }\r
+\r
\r
}\r
\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
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_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
+ m_LogList.InsertGitColumn();\r
\r
m_ChangedFileListCtrl.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER );\r
m_ChangedFileListCtrl.DeleteAllItems();\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
+\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
+ }\r
+\r
+ if( cur == GITLOG_END)\r
+ {\r
+ \r
+ if (!m_bShowedAll)\r
+ DialogEnableWindow(IDC_NEXTHUNDRED, TRUE);\r
+\r
+ DialogEnableWindow(IDC_CHECK_STOPONCOPY, 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
+ }\r
+}\r
void CLogDlg::SetDlgTitle(bool bOffline)\r
{\r
if (m_sTitle.IsEmpty())\r
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.DeleteAllItems();\r
{\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
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
// 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
+ GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_LogList.m_arShownList.GetAt(selIndex));\r
\r
// set the log message text\r
pMsgView->SetWindowText(_T("*")+pLogEntry->m_Subject+_T("\n\n")+pLogEntry->m_Body);\r
m_currentChangedArray = &(pLogEntry->m_Files);\r
if (m_currentChangedArray == NULL)\r
{\r
- InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+// InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
m_ChangedFileListCtrl.SetRedraw(TRUE);\r
return;\r
}\r
}\r
\r
// redraw the views\r
- InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+// InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
if (m_currentChangedArray)\r
{\r
m_ChangedFileListCtrl.SetItemCountEx(m_currentChangedArray->GetCount());\r
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
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.FillGitLog();\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
- m_LogList.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
\r
\r
\r
BOOL CLogDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
{\r
- if (m_bThreadRunning)\r
+ if (this->IsThreadRunning())\r
{\r
// only show the wait cursor over the list control\r
if ((pWnd)&&\r
{\r
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
*pResult = 0;\r
- if (m_bThreadRunning)\r
+ if (this->IsThreadRunning())\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
// 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
void CLogDlg::OnLvnGetdispinfoChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
{\r
\r
+#if 0\r
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);\r
\r
//Create a pointer to the item\r
break;\r
}\r
}\r
-\r
+#endif\r
*pResult = 0;\r
}\r
\r
{\r
if (nIDEvent == LOGFILTER_TIMER)\r
{\r
- if (m_bThreadRunning)\r
+ if (this->IsThreadRunning())\r
{\r
// thread still running! So just restart the timer.\r
SetTimer(LOGFILTER_TIMER, 1000, NULL);\r
&& (focusWnd != GetDlgItem(IDC_LOGLIST)));\r
if (m_sFilterText.IsEmpty())\r
{\r
- DialogEnableWindow(IDC_STATBUTTON, !(((m_bThreadRunning)||(m_arShownList.IsEmpty()))));\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
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
+// InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+ RecalculateShownList(&m_LogList.m_arShownList);\r
+// InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
\r
\r
m_LogList.DeleteAllItems();\r
GetDlgItem(IDC_SEARCHEDIT)->SetFocus();\r
UpdateLogInfoLabel();\r
} // if (nIDEvent == LOGFILTER_TIMER)\r
- DialogEnableWindow(IDC_STATBUTTON, !(((m_bThreadRunning)||(m_arShownList.IsEmpty()))));\r
+ DialogEnableWindow(IDC_STATBUTTON, !(((this->IsThreadRunning())||(m_LogList.m_arShownList.IsEmpty()))));\r
__super::OnTimer(nIDEvent);\r
}\r
\r
\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
}\r
void CLogDlg::OnLvnColumnclickChangedFileList(NMHDR *pNMHDR, LRESULT *pResult)\r
{\r
- if (m_bThreadRunning)\r
+ if (this->IsThreadRunning())\r
return; //no sorting while the arrays are filled\r
if (m_currentChangedArray == NULL)\r
return;\r
\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