1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013 - TortoiseGit
4 // Copyright (C) 2003-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "StandAloneDlg.h"
24 #include "ProjectProperties.h"
26 #include "GitStatus.h"
28 //#include "..\IBugTraqProvider\IBugTraqProvider_h.h"
31 #include "UnicodeUtils.h"
33 typedef int (__cdecl
*GENERICCOMPAREFN
)(const void * elem1
, const void * elem2
);
34 struct git_transfer_progress
;
37 * \ingroup TortoiseProc
38 * Options which can be used to configure the way the dialog box works
43 ProgOptRecursive
= 0x01,
44 ProgOptNonRecursive
= 0x00,
45 /// Don't actually do the merge - just practice it
47 ProgOptIgnoreExternals
= 0x08,
48 ProgOptKeeplocks
= 0x10,
49 /// for locking this means steal the lock, for unlocking it means breaking the lock
50 ProgOptLockForce
= 0x20,
51 ProgOptSwitchAfterCopy
= 0x40,
52 ProgOptIncludeIgnored
= 0x80,
53 ProgOptIgnoreAncestry
= 0x100,
54 ProgOptEolDefault
= 0x200,
55 ProgOptEolCRLF
= 0x400,
57 ProgOptEolCR
= 0x1000,
58 ProgOptSkipConflictCheck
= 0x2000,
59 ProgOptRecordOnly
= 0x4000
69 } ProgressCloseOptions
;
71 #define WM_SHOWCONFLICTRESOLVER (WM_APP + 100)
76 git_wc_notify_sendmail_start
,
77 git_wc_notify_sendmail_error
,
78 git_wc_notify_sendmail_retry
,
79 git_wc_notify_sendmail_done
,
80 git_wc_notify_resolved
,
83 git_wc_notify_checkout
,
84 git_wc_notify_update_ref
,
86 }git_wc_notify_action_t
;
89 SENDMAIL_ATTACHMENT
=0x1,
90 SENDMAIL_COMBINED
=0x2,
94 * \ingroup TortoiseProc
95 * Handles different Subversion commands and shows the notify messages
96 * in a listbox. Since several Subversion commands have similar notify
97 * messages they are grouped together in this single class.
99 class CGitProgressDlg
: public CResizableStandAloneDialog
105 GitProgress_Checkout
,
112 GitProgress_SendMail
,
118 DECLARE_DYNAMIC(CGitProgressDlg
)
122 CGitProgressDlg(CWnd
* pParent
= NULL
);
123 virtual ~CGitProgressDlg();
126 void SetCommand(Command cmd
) {m_Command
= cmd
;}
127 void SetAutoClose(DWORD ac
) {m_dwCloseOnEnd
= ac
;}
128 void SetOptions(DWORD opts
) {m_options
= opts
;}
129 void SetPathList(const CTGitPathList
& pathList
) {m_targetPathList
= pathList
;}
130 void SetUrl(const CString
& url
) {m_url
.SetFromUnknown(url
);}
131 void SetSecondUrl(const CString
& url
) {m_url2
.SetFromUnknown(url
);}
132 void SetCommitMessage(const CString
& msg
) {m_sMessage
= msg
;}
133 void SetIsBare(bool b
) { m_bBare
= b
; }
134 void SetNoCheckout(bool b
){ m_bNoCheckout
= b
; }
135 void SetRefSpec(CString
&spec
){ m_RefSpec
= spec
; }
136 void SetAutoTag(int tag
){ m_AutoTag
= tag
; }
138 // void SetRevision(const GitRev& rev) {m_Revision = rev;}
139 // void SetRevisionEnd(const GitRev& rev) {m_RevisionEnd = rev;}
141 void SetDiffOptions(const CString
& opts
) {m_diffoptions
= opts
;}
142 void SetSendMailOption(CString
&TO
, CString
&CC
,CString
&Subject
,DWORD flags
){m_SendMailTO
=TO
;m_SendMailSubject
=Subject
; m_SendMailCC
=CC
;this->m_SendMailFlags
= flags
;}
143 void SetDepth(git_depth_t depth
= git_depth_unknown
) {m_depth
= depth
;}
144 void SetPegRevision(GitRev pegrev
= GitRev()) {m_pegRev
= pegrev
;}
145 void SetProjectProperties(ProjectProperties props
) {m_ProjectProperties
= props
;}
146 void SetChangeList(const CString
& changelist
, bool keepchangelist
) {m_changelist
= changelist
; m_keepchangelist
= keepchangelist
;}
147 void SetSelectedList(const CTGitPathList
& selPaths
);
148 // void SetRevisionRanges(const GitRevRangeArray& revArray) {m_revisionArray = revArray;}
149 // void SetBugTraqProvider(const CComPtr<IBugTraqProvider> pBugtraqProvider) { m_BugTraqProvider = pBugtraqProvider;}
151 * If the number of items for which the operation is done on is known
152 * beforehand, that number can be set here. It is then used to show a more
153 * accurate progress bar during the operation.
155 void SetItemCount(long count
) {if(count
) m_itemCountTotal
= count
;}
157 bool SetBackgroundImage(UINT nID
);
159 bool DidErrorsOccur() {return m_bErrorsOccurred
;}
161 enum { IDD
= IDD_SVNPROGRESS
};
164 class NotificationData
168 : color(::GetSysColor(COLOR_WINDOWTEXT
))
169 , action((git_wc_notify_action_t
)-1)
170 , bConflictedActionItem(false)
173 git_wc_notify_action_t action
;
175 action((git_wc_notify_action_t
)-1),
177 content_state(git_wc_notify_state_inapplicable
),
178 prop_state(git_wc_notify_state_inapplicable
),
181 bConflictedActionItem(false),
184 // lock_state(git_wc_notify_lock_state_unchanged)
186 // merge_range.end = 0;
187 // merge_range.start = 0;
191 // The text we put into the first column (the Git action for normal items, just text for aux items)
192 CString sActionColumnText
;
195 // CString changelistname;
197 // git_node_kind_t kind;
198 // CString mime_type;
199 // git_wc_notify_state_t content_state;
200 // git_wc_notify_state_t prop_state;
201 // git_wc_notify_lock_state_t lock_state;
202 // git_merge_range_t merge_range;
205 // CString owner; ///< lock owner
206 bool bConflictedActionItem
; // Is this item a conflict?
207 bool bAuxItem
; // Set if this item is not a true 'Git action'
208 CString sPathColumnText
;
215 //Need update in the future implement the virtual methods from Git base class
216 virtual BOOL
Notify(const CTGitPath
& path
,
217 git_wc_notify_action_t action
,
219 CString
*strErr
=NULL
221 git_node_kind_t kind, const CString& mime_type,
222 git_wc_notify_state_t content_state,
223 git_wc_notify_state_t prop_state, LONG rev,
224 const git_lock_t * lock, git_wc_notify_lock_state_t lock_state,
225 const CString& changelistname,
226 git_merge_range_t * range,
227 git_error_t * err, apr_pool_t * pool*/
229 virtual BOOL
Notify(const git_wc_notify_action_t action
, const git_transfer_progress
*stat
);
230 virtual BOOL
Notify(const git_wc_notify_action_t action
, CString str
, const git_oid
*a
, const git_oid
*b
);
232 // virtual git_wc_conflict_choice_t ConflictResolveCallback(const git_wc_conflict_description_t *description, CString& mergedfile);
234 static int FetchCallback(const git_transfer_progress
*stats
, void *payload
)
236 return !((CGitProgressDlg
*)payload
) -> Notify(git_wc_notify_fetch
, stats
);
239 static void CheckoutCallback(const char *path
, size_t cur
, size_t tot
, void *payload
)
241 CTGitPath tpath
= CUnicodeUtils::GetUnicode(CStringA(path
), CP_UTF8
);
242 ((CGitProgressDlg
*)payload
) -> m_itemCountTotal
= tot
;
243 ((CGitProgressDlg
*)payload
) -> m_itemCount
= cur
;
244 ((CGitProgressDlg
*)payload
) -> Notify(tpath
, git_wc_notify_checkout
);
247 static void RemoteProgressCallback(const char *str
, int len
, void *data
)
250 progText
= CUnicodeUtils::GetUnicode(CStringA(str
, len
));
251 ((CGitProgressDlg
*)data
) -> SetDlgItemText(IDC_PROGRESSLABEL
, progText
);
253 static int RemoteCompletionCallback(git_remote_completion_type
/*type*/, void * /*data*/)
257 static int RemoteUpdatetipsCallback(const char *refname
, const git_oid
*a
, const git_oid
*b
, void *data
)
260 str
= CUnicodeUtils::GetUnicode(refname
);
261 ((CGitProgressDlg
*)data
) -> Notify(git_wc_notify_update_ref
, str
, a
, b
);
265 virtual BOOL
OnInitDialog();
266 virtual BOOL
Cancel();
267 virtual void OnCancel();
268 virtual BOOL
PreTranslateMessage(MSG
* pMsg
);
269 virtual void DoDataExchange(CDataExchange
* pDX
);
271 afx_msg
void OnNMCustomdrawSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
272 afx_msg
void OnLvnGetdispinfoSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
273 afx_msg
void OnNMDblclkSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
274 afx_msg
void OnBnClickedLogbutton();
275 afx_msg
void OnBnClickedOk();
276 afx_msg
void OnBnClickedNoninteractive();
277 afx_msg
void OnHdnItemclickSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
278 afx_msg BOOL
OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
);
279 afx_msg
void OnClose();
280 afx_msg
void OnContextMenu(CWnd
* pWnd
, CPoint point
);
281 afx_msg LRESULT
OnGitProgress(WPARAM wParam
, LPARAM lParam
);
282 afx_msg
void OnTimer(UINT_PTR nIDEvent
);
283 afx_msg
void OnEnSetfocusInfotext();
284 afx_msg
void OnLvnBegindragSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
285 afx_msg
void OnSize(UINT nType
, int cx
, int cy
);
286 afx_msg LRESULT
OnTaskbarBtnCreated(WPARAM wParam
, LPARAM lParam
);
287 afx_msg LRESULT
OnCtlColorStatic(WPARAM wParam
, LPARAM lParam
);
288 afx_msg HBRUSH
OnCtlColor(CDC
* pDC
, CWnd
* pWnd
, UINT nCtlColor
);
289 LRESULT
OnShowConflictResolver(WPARAM
, LPARAM
);
291 DECLARE_MESSAGE_MAP()
294 static bool SortCompare(const NotificationData
* pElem1
, const NotificationData
* pElem2
);
296 static BOOL m_bAscending
;
297 static int m_nSortedColumn
;
298 CStringList m_ExtStack
;
301 static UINT
ProgressThreadEntry(LPVOID pVoid
);
302 UINT
ProgressThread();
304 void ReportGitError();
305 void ReportError(const CString
& sError
);
306 void ReportWarning(const CString
& sWarning
);
307 void ReportNotification(const CString
& sNotification
);
308 void ReportCmd(const CString
& sCmd
);
309 void ReportString(CString sMessage
, const CString
& sMsgKind
, COLORREF color
= ::GetSysColor(COLOR_WINDOWTEXT
));
310 void AddItemToList();
311 CString
BuildInfoString();
312 CString
GetPathFromColumnText(const CString
& sColumnText
);
315 * Resizes the columns of the progress list so that the headings are visible.
317 void ResizeColumns();
319 /// Predicate function to tell us if a notification data item is auxiliary or not
320 static bool NotificationDataIsAux(const NotificationData
* pData
);
322 // the commands to execute
323 bool CmdAdd(CString
& sWindowTitle
, bool& localoperation
);
324 bool CmdCheckout(CString
& sWindowTitle
, bool& localoperation
);
325 bool CmdCopy(CString
& sWindowTitle
, bool& localoperation
);
326 bool CmdExport(CString
& sWindowTitle
, bool& localoperation
);
327 bool CmdRename(CString
& sWindowTitle
, bool& localoperation
);
328 bool CmdResolve(CString
& sWindowTitle
, bool& localoperation
);
329 bool CmdRevert(CString
& sWindowTitle
, bool& localoperation
);
330 bool CmdSwitch(CString
& sWindowTitle
, bool& localoperation
);
331 bool CmdSendMail(CString
& sWindowTitle
, bool& localoperation
);
332 bool CmdClone(CString
& sWindowTitle
, bool& localoperation
);
333 bool CmdFetch(CString
& sWindowTitle
, bool& localoperation
);
336 typedef std::map
<CStringA
, git_revnum_t
> StringRevMap
;
337 typedef std::vector
<NotificationData
*> NotificationDataVect
;
340 CString m_mergedfile
;
341 NotificationDataVect m_arData
;
342 CAnimateCtrl m_Animate
;
343 CWinThread
* m_pThread
;
344 volatile LONG m_bThreadRunning
;
346 ProjectProperties m_ProjectProperties
;
347 CListCtrl m_ProgList
;
349 int m_options
; // Use values from the ProgressOptions enum
351 CTGitPathList m_targetPathList
;
352 CTGitPathList m_selectedPaths
;
356 CString m_diffoptions
;
358 GitRev m_RevisionEnd
;
360 // GitRevRangeArray m_revisionArray;
361 CString m_changelist
;
362 bool m_keepchangelist
;
364 DWORD m_dwCloseOnEnd
;
366 CTGitPath m_basePath
;
367 StringRevMap m_UpdateStartRevMap
;
368 StringRevMap m_FinishedRevMap
;
370 TCHAR m_columnbuf
[MAX_PATH
];
374 bool m_bErrorsOccurred
;
375 bool m_bMergesAddsDeletesOccurred
;
379 int nEnsureVisibleCount
;
381 CString m_sTotalBytesTransferred
;
382 size_t m_TotalBytesTransferred
;
386 bool m_bFinishedItemAdded
;
390 int m_itemCountTotal
;
392 bool m_AlwaysConflicted
;
394 DWORD m_SendMailFlags
;
395 CString m_SendMailTO
;
396 CString m_SendMailCC
;
397 CString m_SendMailSubject
;
399 /// CComPtr<IBugTraqProvider> m_BugTraqProvider;
400 CComPtr
<ITaskbarList3
> m_pTaskbarList
;
402 // some strings different methods can use
409 CBrush m_background_brush
;