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 "StandAloneDlg.h"
\r
22 #include "TGitPath.h"
\r
23 #include "ProjectProperties.h"
\r
25 #include "GitStatus.h"
\r
27 //#include "..\IBugTraqProvider\IBugTraqProvider_h.h"
\r
30 typedef int (__cdecl *GENERICCOMPAREFN)(const void * elem1, const void * elem2);
\r
33 * \ingroup TortoiseProc
\r
34 * Options which can be used to configure the way the dialog box works
\r
39 ProgOptRecursive = 0x01,
\r
40 ProgOptNonRecursive = 0x00,
\r
41 /// Don't actually do the merge - just practice it
\r
42 ProgOptDryRun = 0x04,
\r
43 ProgOptIgnoreExternals = 0x08,
\r
44 ProgOptKeeplocks = 0x10,
\r
45 /// for locking this means steal the lock, for unlocking it means breaking the lock
\r
46 ProgOptLockForce = 0x20,
\r
47 ProgOptSwitchAfterCopy = 0x40,
\r
48 ProgOptIncludeIgnored = 0x80,
\r
49 ProgOptIgnoreAncestry = 0x100,
\r
50 ProgOptEolDefault = 0x200,
\r
51 ProgOptEolCRLF = 0x400,
\r
52 ProgOptEolLF = 0x800,
\r
53 ProgOptEolCR = 0x1000,
\r
54 ProgOptSkipConflictCheck = 0x2000,
\r
55 ProgOptRecordOnly = 0x4000
\r
65 } ProgressCloseOptions;
\r
67 #define WM_SHOWCONFLICTRESOLVER (WM_APP + 100)
\r
72 git_wc_notify_sendmail_start,
\r
73 git_wc_notify_sendmail_error,
\r
74 git_wc_notify_sendmail_retry,
\r
75 git_wc_notify_sendmail_done,
\r
76 git_wc_notify_resolved,
\r
77 git_wc_notify_revert,
\r
79 }git_wc_notify_action_t;
\r
82 SENDMAIL_ATTACHMENT=0x1,
\r
83 SENDMAIL_COMBINED =0x2
\r
86 * \ingroup TortoiseProc
\r
87 * Handles different Subversion commands and shows the notify messages
\r
88 * in a listbox. Since several Subversion commands have similar notify
\r
89 * messages they are grouped together in this single class.
\r
91 class CGitProgressDlg : public CResizableStandAloneDialog
\r
97 GitProgress_Checkout,
\r
100 GitProgress_Export,
\r
101 GitProgress_Import,
\r
104 GitProgress_MergeReintegrate,
\r
105 GitProgress_MergeAll,
\r
106 GitProgress_Rename,
\r
107 GitProgress_Resolve,
\r
108 GitProgress_Revert,
\r
109 GitProgress_Switch,
\r
110 GitProgress_Unlock,
\r
111 GitProgress_Update,
\r
112 GitProgress_SendMail,
\r
116 DECLARE_DYNAMIC(CGitProgressDlg)
\r
120 CGitProgressDlg(CWnd* pParent = NULL);
\r
121 virtual ~CGitProgressDlg();
\r
124 void SetCommand(Command cmd) {m_Command = cmd;}
\r
125 void SetAutoClose(DWORD ac) {m_dwCloseOnEnd = ac;}
\r
126 void SetOptions(DWORD opts) {m_options = opts;}
\r
127 void SetPathList(const CTGitPathList& pathList) {m_targetPathList = pathList;}
\r
128 void SetUrl(const CString& url) {m_url.SetFromUnknown(url);}
\r
129 void SetSecondUrl(const CString& url) {m_url2.SetFromUnknown(url);}
\r
130 void SetCommitMessage(const CString& msg) {m_sMessage = msg;}
\r
132 // void SetRevision(const GitRev& rev) {m_Revision = rev;}
\r
133 // void SetRevisionEnd(const GitRev& rev) {m_RevisionEnd = rev;}
\r
135 void SetDiffOptions(const CString& opts) {m_diffoptions = opts;}
\r
136 void SetSendMailOption(CString &TO, CString &CC,CString &Subject,DWORD flags){m_SendMailTO=TO;m_SendMailSubject=Subject; m_SendMailCC=CC;this->m_SendMailFlags = flags;}
\r
137 void SetDepth(git_depth_t depth = git_depth_unknown) {m_depth = depth;}
\r
138 void SetPegRevision(GitRev pegrev = GitRev()) {m_pegRev = pegrev;}
\r
139 void SetProjectProperties(ProjectProperties props) {m_ProjectProperties = props;}
\r
140 void SetChangeList(const CString& changelist, bool keepchangelist) {m_changelist = changelist; m_keepchangelist = keepchangelist;}
\r
141 void SetSelectedList(const CTGitPathList& selPaths);
\r
142 // void SetRevisionRanges(const GitRevRangeArray& revArray) {m_revisionArray = revArray;}
\r
143 // void SetBugTraqProvider(const CComPtr<IBugTraqProvider> pBugtraqProvider) { m_BugTraqProvider = pBugtraqProvider;}
\r
145 * If the number of items for which the operation is done on is known
\r
146 * beforehand, that number can be set here. It is then used to show a more
\r
147 * accurate progress bar during the operation.
\r
149 void SetItemCount(long count) {if(count) m_itemCountTotal = count;}
\r
151 bool SetBackgroundImage(UINT nID);
\r
153 bool DidErrorsOccur() {return m_bErrorsOccurred;}
\r
155 enum { IDD = IDD_SVNPROGRESS };
\r
158 class NotificationData
\r
161 NotificationData(){} ;
\r
162 git_wc_notify_action_t action;
\r
164 action((git_wc_notify_action_t)-1),
\r
165 kind(git_node_none),
\r
166 content_state(git_wc_notify_state_inapplicable),
\r
167 prop_state(git_wc_notify_state_inapplicable),
\r
170 color(::GetSysColor(COLOR_WINDOWTEXT)),
\r
171 bConflictedActionItem(false),
\r
174 // lock_state(git_wc_notify_lock_state_unchanged)
\r
176 // merge_range.end = 0;
\r
177 // merge_range.start = 0;
\r
181 // The text we put into the first column (the Git action for normal items, just text for aux items)
\r
182 CString sActionColumnText;
\r
184 CTGitPath basepath;
\r
185 CString changelistname;
\r
187 /// git_wc_notify_action_t action;
\r
188 // git_node_kind_t kind;
\r
190 // git_wc_notify_state_t content_state;
\r
191 // git_wc_notify_state_t prop_state;
\r
192 // git_wc_notify_lock_state_t lock_state;
\r
193 // git_merge_range_t merge_range;
\r
196 CString owner; ///< lock owner
\r
197 bool bConflictedActionItem; // Is this item a conflict?
\r
198 bool bAuxItem; // Set if this item is not a true 'Git action'
\r
199 CString sPathColumnText;
\r
204 //Need update in the future implement the virtual methods from Git base class
\r
205 virtual BOOL Notify(const CTGitPath& path,
\r
206 git_wc_notify_action_t action,
\r
208 CString *strErr =NULL
\r
210 git_node_kind_t kind, const CString& mime_type,
\r
211 git_wc_notify_state_t content_state,
\r
212 git_wc_notify_state_t prop_state, LONG rev,
\r
213 const git_lock_t * lock, git_wc_notify_lock_state_t lock_state,
\r
214 const CString& changelistname,
\r
215 git_merge_range_t * range,
\r
216 git_error_t * err, apr_pool_t * pool*/
\r
219 // virtual git_wc_conflict_choice_t ConflictResolveCallback(const git_wc_conflict_description_t *description, CString& mergedfile);
\r
220 virtual BOOL OnInitDialog();
\r
221 virtual BOOL Cancel();
\r
222 virtual void OnCancel();
\r
223 virtual BOOL PreTranslateMessage(MSG* pMsg);
\r
224 virtual void DoDataExchange(CDataExchange* pDX);
\r
226 afx_msg void OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult);
\r
227 afx_msg void OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult);
\r
228 afx_msg void OnNMDblclkSvnprogress(NMHDR *pNMHDR, LRESULT *pResult);
\r
229 afx_msg void OnBnClickedLogbutton();
\r
230 afx_msg void OnBnClickedOk();
\r
231 afx_msg void OnBnClickedNoninteractive();
\r
232 afx_msg void OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult);
\r
233 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
\r
234 afx_msg void OnClose();
\r
235 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
\r
236 afx_msg LRESULT OnGitProgress(WPARAM wParam, LPARAM lParam);
\r
237 afx_msg void OnTimer(UINT_PTR nIDEvent);
\r
238 afx_msg void OnEnSetfocusInfotext();
\r
239 afx_msg void OnLvnBegindragSvnprogress(NMHDR *pNMHDR, LRESULT *pResult);
\r
240 afx_msg void OnSize(UINT nType, int cx, int cy);
\r
241 LRESULT OnShowConflictResolver(WPARAM, LPARAM);
\r
243 DECLARE_MESSAGE_MAP()
\r
246 static bool SortCompare(const NotificationData* pElem1, const NotificationData* pElem2);
\r
248 static BOOL m_bAscending;
\r
249 static int m_nSortedColumn;
\r
250 CStringList m_ExtStack;
\r
253 static UINT ProgressThreadEntry(LPVOID pVoid);
\r
254 UINT ProgressThread();
\r
255 virtual void OnOK();
\r
256 void ReportGitError();
\r
257 void ReportError(const CString& sError);
\r
258 void ReportWarning(const CString& sWarning);
\r
259 void ReportNotification(const CString& sNotification);
\r
260 void ReportCmd(const CString& sCmd);
\r
261 void ReportString(CString sMessage, const CString& sMsgKind, COLORREF color = ::GetSysColor(COLOR_WINDOWTEXT));
\r
262 void AddItemToList();
\r
263 CString BuildInfoString();
\r
264 CString GetPathFromColumnText(const CString& sColumnText);
\r
267 * Resizes the columns of the progress list so that the headings are visible.
\r
269 void ResizeColumns();
\r
271 /// Predicate function to tell us if a notification data item is auxiliary or not
\r
272 static bool NotificationDataIsAux(const NotificationData* pData);
\r
274 // the commands to execute
\r
275 bool CmdAdd(CString& sWindowTitle, bool& localoperation);
\r
276 bool CmdCheckout(CString& sWindowTitle, bool& localoperation);
\r
277 bool CmdCommit(CString& sWindowTitle, bool& localoperation);
\r
278 bool CmdCopy(CString& sWindowTitle, bool& localoperation);
\r
279 bool CmdExport(CString& sWindowTitle, bool& localoperation);
\r
280 bool CmdImport(CString& sWindowTitle, bool& localoperation);
\r
281 bool CmdLock(CString& sWindowTitle, bool& localoperation);
\r
282 bool CmdMerge(CString& sWindowTitle, bool& localoperation);
\r
283 bool CmdMergeAll(CString& sWindowTitle, bool& localoperation);
\r
284 bool CmdMergeReintegrate(CString& sWindowTitle, bool& localoperation);
\r
285 bool CmdRename(CString& sWindowTitle, bool& localoperation);
\r
286 bool CmdResolve(CString& sWindowTitle, bool& localoperation);
\r
287 bool CmdRevert(CString& sWindowTitle, bool& localoperation);
\r
288 bool CmdSwitch(CString& sWindowTitle, bool& localoperation);
\r
289 bool CmdUnlock(CString& sWindowTitle, bool& localoperation);
\r
290 bool CmdUpdate(CString& sWindowTitle, bool& localoperation);
\r
291 bool CmdSendMail(CString& sWindowTitle, bool& localoperation);
\r
294 typedef std::map<CStringA, git_revnum_t> StringRevMap;
\r
295 typedef std::vector<NotificationData *> NotificationDataVect;
\r
298 CString m_mergedfile;
\r
299 NotificationDataVect m_arData;
\r
301 CWinThread* m_pThread;
\r
302 volatile LONG m_bThreadRunning;
\r
304 ProjectProperties m_ProjectProperties;
\r
305 CListCtrl m_ProgList;
\r
307 int m_options; // Use values from the ProgressOptions enum
\r
308 git_depth_t m_depth;
\r
309 CTGitPathList m_targetPathList;
\r
310 CTGitPathList m_selectedPaths;
\r
313 CString m_sMessage;
\r
314 CString m_diffoptions;
\r
316 GitRev m_RevisionEnd;
\r
318 // GitRevRangeArray m_revisionArray;
\r
319 CString m_changelist;
\r
320 bool m_keepchangelist;
\r
322 DWORD m_dwCloseOnEnd;
\r
324 CTGitPath m_basePath;
\r
325 StringRevMap m_UpdateStartRevMap;
\r
326 StringRevMap m_FinishedRevMap;
\r
328 TCHAR m_columnbuf[MAX_PATH];
\r
332 bool m_bErrorsOccurred;
\r
333 bool m_bMergesAddsDeletesOccurred;
\r
336 BOOL bSecondResized;
\r
337 int nEnsureVisibleCount;
\r
339 CString m_sTotalBytesTransferred;
\r
343 bool m_bLockWarning;
\r
344 bool m_bLockExists;
\r
345 bool m_bFinishedItemAdded;
\r
346 bool m_bLastVisible;
\r
349 int m_itemCountTotal;
\r
351 bool m_AlwaysConflicted;
\r
353 DWORD m_SendMailFlags;
\r
354 CString m_SendMailTO;
\r
355 CString m_SendMailCC;
\r
356 CString m_SendMailSubject;
\r
358 /// CComPtr<IBugTraqProvider> m_BugTraqProvider;
\r
360 // some strings different methods can use
\r
361 CString sIgnoredIncluded;
\r
362 CString sExtExcluded;
\r
363 CString sExtIncluded;
\r
364 CString sIgnoreAncestry;
\r
365 CString sRespectAncestry;
\r
367 CString sRecordOnly;
\r