1 // TortoiseGit - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseGit
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 #include "resource.h"
\r
23 #include "ProjectProperties.h"
\r
24 #include "StandAloneDlg.h"
\r
25 #include "TGitPath.h"
\r
26 #include "registry.h"
\r
27 #include "SplitterControl.h"
\r
29 #include "MenuButton.h"
\r
30 #include "LogDlgHelper.h"
\r
31 #include "FilterEdit.h"
\r
33 #include "Tooltip.h"
\r
34 #include "HintListCtrl.h"
\r
37 using namespace std;
\r
40 #define MERGE_REVSELECTSTART 1
\r
41 #define MERGE_REVSELECTEND 2
\r
42 #define MERGE_REVSELECTSTARTEND 3 ///< both
\r
43 #define MERGE_REVSELECTMINUSONE 4 ///< first with N-1
\r
45 #define LOGFILTER_ALL 1
\r
46 #define LOGFILTER_MESSAGES 2
\r
47 #define LOGFILTER_PATHS 3
\r
48 #define LOGFILTER_AUTHORS 4
\r
49 #define LOGFILTER_REVS 5
\r
50 #define LOGFILTER_REGEX 6
\r
51 #define LOGFILTER_BUGID 7
\r
54 #define LOGFILTER_TIMER 101
\r
56 typedef int (__cdecl *GENERICCOMPAREFN)(const void * elem1, const void * elem2);
\r
59 * \ingroup TortoiseProc
\r
60 * Shows log messages of a single file or folder in a listbox.
\r
62 class CLogDlg : public CResizableStandAloneDialog, public Git, IFilterEditValidator
\r
64 DECLARE_DYNAMIC(CLogDlg)
\r
66 friend class CStoreSelection;
\r
69 CLogDlg(CWnd* pParent = NULL); // standard constructor
\r
73 void SetParams(const CTGitPath& path, GitRev pegrev, GitRev startrev, GitRev endrev, int limit,
\r
74 BOOL bStrict = CRegDWORD(_T("Software\\TortoiseGit\\LastLogStrict"), FALSE), BOOL bSaveStrict = TRUE);
\r
75 void SetIncludeMerge(bool bInclude = true) {m_bIncludeMerges = bInclude;}
\r
76 void SetProjectPropertiesPath(const CTGitPath& path) {m_ProjectProperties.ReadProps(path);}
\r
77 bool IsThreadRunning() {return !!m_bThreadRunning;}
\r
78 void SetDialogTitle(const CString& sTitle) {m_sTitle = sTitle;}
\r
79 void SetSelect(bool bSelect) {m_bSelect = bSelect;}
\r
80 void ContinuousSelection(bool bCont = true) {m_bSelectionMustBeContinuous = bCont;}
\r
81 void SetMergePath(const CTGitPath& mergepath) {m_mergePath = mergepath;}
\r
83 const GitRevRangeArray& GetSelectedRevRanges() {return m_selectedRevs;}
\r
86 enum { IDD = IDD_LOGMESSAGE };
\r
89 //implement the virtual methods from Git base class
\r
90 virtual BOOL Log(svn_revnum_t rev, const CString& author, const CString& date, const CString& message, LogChangedPathArray * cpaths, apr_time_t time, int filechanges, BOOL copies, DWORD actions, BOOL haschildren);
\r
91 virtual BOOL Cancel();
\r
92 virtual bool Validate(LPCTSTR string);
\r
94 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
\r
96 afx_msg LRESULT OnFindDialogMessage(WPARAM wParam, LPARAM lParam);
\r
97 afx_msg LRESULT OnClickedInfoIcon(WPARAM wParam, LPARAM lParam);
\r
98 afx_msg LRESULT OnClickedCancelFilter(WPARAM wParam, LPARAM lParam);
\r
99 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
\r
100 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
\r
101 afx_msg void OnBnClickedGetall();
\r
102 afx_msg void OnNMDblclkChangedFileList(NMHDR *pNMHDR, LRESULT *pResult);
\r
103 afx_msg void OnNMDblclkLoglist(NMHDR *pNMHDR, LRESULT *pResult);
\r
104 afx_msg void OnLvnItemchangedLoglist(NMHDR *pNMHDR, LRESULT *pResult);
\r
105 afx_msg void OnBnClickedHelp();
\r
106 afx_msg void OnEnLinkMsgview(NMHDR *pNMHDR, LRESULT *pResult);
\r
107 afx_msg void OnBnClickedStatbutton();
\r
108 afx_msg void OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult);
\r
109 afx_msg void OnNMCustomdrawChangedFileList(NMHDR *pNMHDR, LRESULT *pResult);
\r
110 afx_msg void OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult);
\r
111 afx_msg void OnLvnGetdispinfoChangedFileList(NMHDR *pNMHDR, LRESULT *pResult);
\r
112 afx_msg void OnEnChangeSearchedit();
\r
113 afx_msg void OnTimer(UINT_PTR nIDEvent);
\r
114 afx_msg void OnDtnDatetimechangeDateto(NMHDR *pNMHDR, LRESULT *pResult);
\r
115 afx_msg void OnDtnDatetimechangeDatefrom(NMHDR *pNMHDR, LRESULT *pResult);
\r
116 afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult);
\r
117 afx_msg void OnLvnColumnclickChangedFileList(NMHDR *pNMHDR, LRESULT *pResult);
\r
118 afx_msg void OnBnClickedNexthundred();
\r
119 afx_msg void OnBnClickedHidepaths();
\r
120 afx_msg void OnBnClickedCheckStoponcopy();
\r
121 afx_msg void OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult);
\r
122 afx_msg void OnDtnDropdownDatefrom(NMHDR *pNMHDR, LRESULT *pResult);
\r
123 afx_msg void OnDtnDropdownDateto(NMHDR *pNMHDR, LRESULT *pResult);
\r
124 afx_msg void OnSize(UINT nType, int cx, int cy);
\r
125 afx_msg void OnBnClickedIncludemerge();
\r
126 afx_msg void OnBnClickedRefresh();
\r
127 afx_msg void OnRefresh();
\r
128 afx_msg void OnFind();
\r
129 afx_msg void OnFocusFilter();
\r
130 afx_msg void OnEditCopy();
\r
132 virtual void OnCancel();
\r
133 virtual void OnOK();
\r
134 virtual BOOL OnInitDialog();
\r
135 virtual BOOL PreTranslateMessage(MSG* pMsg);
\r
137 void FillLogMessageCtrl(bool bShow = true);
\r
138 void DoDiffFromLog(INT_PTR selIndex, svn_revnum_t rev1, svn_revnum_t rev2, bool blame, bool unified);
\r
140 DECLARE_MESSAGE_MAP()
\r
143 static UINT LogThreadEntry(LPVOID pVoid);
\r
145 void Refresh (bool autoGoOnline = false);
\r
146 BOOL IsDiffPossible(LogChangedPath * changedpath, svn_revnum_t rev);
\r
147 BOOL Open(bool bOpenWith, CString changedpath, svn_revnum_t rev);
\r
148 void EditAuthor(const CLogDataVector& logs);
\r
149 void EditLogMessage(int index);
\r
150 void DoSizeV1(int delta);
\r
151 void DoSizeV2(int delta);
\r
152 void AdjustMinSize();
\r
153 void SetSplitterRange();
\r
154 void SetFilterCueText();
\r
155 BOOL IsEntryInDateRange(int i);
\r
156 void CopySelectionToClipBoard();
\r
157 void CopyChangedSelectionToClipBoard();
\r
158 CTGitPathList GetChangedPathsFromSelectedRevisions(bool bRelativePaths = false, bool bUseFilter = true);
\r
159 void SortShownListArray();
\r
160 void RecalculateShownList(CPtrArray * pShownlist);
\r
161 void SetSortArrow(CListCtrl * control, int nColumn, bool bAscending);
\r
162 void SortByColumn(int nSortColumn, bool bAscending);
\r
163 bool IsSelectionContinuous();
\r
164 void EnableOKButton();
\r
165 void GetAll(bool bForceAll = false);
\r
166 void UpdateLogInfoLabel();
\r
167 void SaveSplitterPos();
\r
168 bool ValidateRegexp(LPCTSTR regexp_str, tr1::wregex& pat, bool bMatchCase);
\r
169 void CheckRegexpTooltip();
\r
170 void GetChangedPaths(std::vector<CString>& changedpaths, std::vector<LogChangedPath*>& changedlogpaths);
\r
171 void DiffSelectedFile();
\r
172 void DiffSelectedRevWithPrevious();
\r
173 void SetDlgTitle(bool bOffline);
\r
174 CString GetAbsoluteUrlFromRelativeUrl(const CString& url);
\r
177 * Extracts part of commit message suitable for displaying in revision list.
\r
179 CString MakeShortMessage(const CString& message);
\r
180 inline int ShownCountWithStopped() const { return (int)m_arShownList.GetCount() + (m_bStrictStopped ? 1 : 0); }
\r
183 virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
\r
184 static int __cdecl SortCompare(const void * pElem1, const void * pElem2); ///< sort callback function
\r
186 void ResizeAllListCtrlCols();
\r
188 void ShowContextMenuForRevisions(CWnd* pWnd, CPoint point);
\r
189 void ShowContextMenuForChangedpaths(CWnd* pWnd, CPoint point);
\r
191 CWnd * m_pNotifyWindow;
\r
192 ProjectProperties m_ProjectProperties;
\r
196 CString m_sRelativeRoot;
\r
197 CString m_sRepositoryRoot;
\r
198 CString m_sSelfRelativeURL;
\r
200 CString m_sUUID; ///< empty if the log cache is not used
\r
201 CHintListCtrl m_LogList;
\r
202 CListCtrl m_ChangedFileListCtrl;
\r
203 CFilterEdit m_cFilter;
\r
204 CProgressCtrl m_LogProgress;
\r
205 CMenuButton m_btnShow;
\r
207 CTGitPath m_mergePath;
\r
210 GitRev m_LogRevision;
\r
213 GitRevRangeArray m_selectedRevs;
\r
214 GitRevRangeArray m_selectedRevsOneRange;
\r
215 bool m_bSelectionMustBeContinuous;
\r
218 volatile LONG m_bThreadRunning;
\r
220 bool m_bStrictStopped;
\r
221 BOOL m_bIncludeMerges;
\r
222 svn_revnum_t m_lowestRev;
\r
223 BOOL m_bSaveStrict;
\r
224 LogChangedPathArray * m_currentChangedArray;
\r
225 LogChangedPathArray m_CurrentFilteredChangedArray;
\r
226 CTGitPathList m_currentChangedPathList;
\r
227 CPtrArray m_arShownList;
\r
229 int m_nSearchIndex;
\r
230 bool m_bFilterWithRegex;
\r
231 static const UINT m_FindDialogMessage;
\r
232 CFindReplaceDialog *m_pFindDialog;
\r
234 CString m_sMessageBuf;
\r
235 CSplitterControl m_wndSplitter1;
\r
236 CSplitterControl m_wndSplitter2;
\r
237 CRect m_DlgOrigRect;
\r
238 CRect m_MsgViewOrigRect;
\r
239 CRect m_LogListOrigRect;
\r
240 CRect m_ChgOrigRect;
\r
241 CString m_sFilterText;
\r
242 int m_nSelectedFilter;
\r
243 volatile LONG m_bNoDispUpdates;
\r
244 CDateTimeCtrl m_DateFrom;
\r
245 CDateTimeCtrl m_DateTo;
\r
249 int m_limitcounter;
\r
252 static int m_nSortColumnPathList;
\r
253 static bool m_bAscendingPathList;
\r
254 CRegDWORD m_regLastStrict;
\r
255 CRegDWORD m_regMaxBugIDColWidth;
\r
256 CButton m_cHidePaths;
\r
260 bool m_bShowBugtraqColumn;
\r
261 CString m_sLogInfo;
\r
262 std::set<svn_revnum_t> m_mergedRevs;
\r
264 CToolTips m_tooltips;
\r
269 CImageList m_imgList;
\r
270 HICON m_hModifiedIcon;
\r
271 HICON m_hReplacedIcon;
\r
272 HICON m_hAddedIcon;
\r
273 HICON m_hDeletedIcon;
\r
275 DWORD m_childCounter;
\r
279 CStoreSelection* m_pStoreSelection;
\r
280 CLogDataVector m_logEntries;
\r
285 static UINT WM_REVSELECTED = RegisterWindowMessage(_T("TORTOISEGit_REVSELECTED_MSG"));
\r
286 static UINT WM_REVLIST = RegisterWindowMessage(_T("TORTOISEGit_REVLIST_MSG"));
\r
287 static UINT WM_REVLISTONERANGE = RegisterWindowMessage(_T("TORTOISEGit_REVLISTONERANGE_MSG"));
\r