1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2014 - 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.
25 #include "UnicodeUtils.h"
27 #include "../TortoiseShell/resource.h"
28 #include "LoglistCommonResource.h"
32 * \ingroup TortoiseProc
33 * Options which can be used to configure the way the dialog box works
38 /// Don't actually do the merge - just practice it
43 struct git_transfer_progress
;
44 #define WM_SHOWCONFLICTRESOLVER (WM_APP + 100)
45 #define WM_PROG_CMD_FINISH (WM_APP + 200)
46 #define WM_PROG_CMD_START (WM_APP + 201)
48 class ProgressCommand
;
49 class CGitProgressList
: public CListCtrl
51 DECLARE_DYNAMIC(CGitProgressList
)
55 virtual ~CGitProgressList();
57 void SetCommand(ProgressCommand
* command
) { ATLASSERT(command
); m_Command
= command
; }
58 void SetOptions(DWORD opts
) {m_options
= opts
;}
61 * If the number of items for which the operation is done on is known
62 * beforehand, that number can be set here. It is then used to show a more
63 * accurate progress bar during the operation.
65 void SetItemCountTotal(long count
) { if(count
) m_itemCountTotal
= count
; }
66 void SetItemProgress(long count
) { m_itemCount
= count
;} // do not use SetItemCount here as this overrides the ListBox method
67 bool SetBackgroundImage(UINT nID
);
68 bool DidErrorsOccur() {return m_bErrorsOccurred
;}
69 bool m_bErrorsOccurred
;
70 CWnd
*m_pProgressLabelCtrl
;
72 CAnimateCtrl
*m_pAnimate
;
73 CProgressCtrl
*m_pProgControl
;
74 ProgressCommand
*m_Command
;
76 volatile BOOL
IsCancelled() {return m_bCancelled
;}
77 volatile LONG
IsRunning() {return m_bThreadRunning
;}
78 CWinThread
* m_pThread
;
83 typedef std::vector
<std::function
<void()>> ContextMenuActionList
;
85 class NotificationData
89 : color(::GetSysColor(COLOR_WINDOWTEXT
))
93 NotificationData(const CTGitPath
&path
, UINT actionTextId
)
97 sActionColumnText
.LoadString(actionTextId
);
100 virtual ~NotificationData() {};
102 virtual void SetColorCode(CColors
& /*colors*/) {};
103 virtual void GetContextMenu(CIconMenu
& /*popup*/, ContextMenuActionList
& /*actions*/) {};
105 // The text we put into the first column (the Git action for normal items, just text for aux items)
106 CString sActionColumnText
;
109 bool bAuxItem
; // Set if this item is not a true 'Git action'
110 CString sPathColumnText
;
113 class WC_File_NotificationData
: public NotificationData
119 git_wc_notify_resolved
,
120 git_wc_notify_revert
,
121 git_wc_notify_checkout
,
122 } git_wc_notify_action_t
;
124 WC_File_NotificationData(const CTGitPath
& path
, git_wc_notify_action_t action
)
127 this->action
= action
;
129 sPathColumnText
= path
.GetGitPathString();
133 case git_wc_notify_add
:
134 sActionColumnText
.LoadString(IDS_SVNACTION_ADD
);
136 case git_wc_notify_resolved
:
137 sActionColumnText
.LoadString(IDS_SVNACTION_RESOLVE
);
139 case git_wc_notify_revert
:
140 sActionColumnText
.LoadString(IDS_SVNACTION_REVERT
);
142 case git_wc_notify_checkout
:
143 sActionColumnText
.LoadString(IDS_PROGRS_CMD_CHECKOUT
);
149 virtual void SetColorCode(CColors
& colors
)
153 case git_wc_notify_checkout
: // fall-through
154 case git_wc_notify_add
:
155 color
= colors
.GetColor(CColors::Added
);
163 git_wc_notify_action_t action
;
165 virtual void GetContextMenu(CIconMenu
& popup
, ContextMenuActionList
& actions
)
167 if ((action
== git_wc_notify_add
) ||
168 (action
== git_wc_notify_revert
) ||
169 (action
== git_wc_notify_resolved
) ||
170 (action
== git_wc_notify_checkout
))
172 actions
.push_back([&]()
174 CString cmd
= _T("/command:log");
175 CString sPath
= g_Git
.CombinePath(path
);
176 cmd
+= _T(" /path:\"") + sPath
+ _T("\"");
177 CAppUtils::RunTortoiseGitProc(cmd
);
179 popup
.AppendMenuIcon(actions
.size(), IDS_MENULOG
, IDI_LOG
);
181 popup
.AppendMenu(MF_SEPARATOR
, NULL
);
182 auto open
= [&](bool openWith
)
185 CString sWinPath
= g_Git
.CombinePath(path
);
187 ret
= (int)ShellExecute(nullptr, NULL
, (LPCTSTR
)sWinPath
, NULL
, NULL
, SW_SHOWNORMAL
);
188 if ((ret
<= HINSTANCE_ERROR
) || openWith
)
190 CString cmd
= _T("RUNDLL32 Shell32,OpenAs_RunDLL ");
192 CAppUtils::LaunchApplication(cmd
, NULL
, false);
195 actions
.push_back([open
]{ open(false); });
196 popup
.AppendMenuIcon(actions
.size(), IDS_LOG_POPUP_OPEN
, IDI_OPEN
);
197 actions
.push_back([open
]{ open(true); });
198 popup
.AppendMenuIcon(actions
.size(), IDS_LOG_POPUP_OPENWITH
, IDI_OPEN
);
200 actions
.push_back([&]{ CAppUtils::ExploreTo(nullptr, g_Git
.CombinePath(path
)); });
201 popup
.AppendMenuIcon(actions
.size(), IDS_STATUSLIST_CONTEXT_EXPLORE
, IDI_EXPLORER
);
206 void AddNotify(NotificationData
* data
, CColors::Colors color
= CColors::COLOR_END
);
207 BOOL
UpdateProgress(const git_transfer_progress
* stat
);
209 void SetProgressLabelText(const CString
& str
);
212 DECLARE_MESSAGE_MAP()
215 void SetWindowTitle(UINT id
, const CString
& urlorpath
, CString
& dialogname
);
218 afx_msg
void OnNMCustomdrawSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
219 afx_msg
void OnLvnGetdispinfoSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
220 afx_msg
void OnNMDblclkSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
221 afx_msg
void OnHdnItemclickSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
222 afx_msg
void OnContextMenu(CWnd
* pWnd
, CPoint point
);
223 afx_msg
void OnTimer(UINT_PTR nIDEvent
);
224 afx_msg
void OnSize(UINT nType
, int cx
, int cy
);
225 LRESULT
OnShowConflictResolver(WPARAM
, LPARAM
);
226 afx_msg
void OnLvnBegindragSvnprogress(NMHDR
*pNMHDR
, LRESULT
*pResult
);
229 static bool SortCompare(const NotificationData
* pElem1
, const NotificationData
* pElem2
);
231 static BOOL m_bAscending
;
232 static int m_nSortedColumn
;
235 static UINT
ProgressThreadEntry(LPVOID pVoid
);
236 UINT
ProgressThread();
239 void ReportGitError();
240 void ReportUserCanceled();
241 void ReportError(const CString
& sError
);
242 void ReportWarning(const CString
& sWarning
);
243 void ReportNotification(const CString
& sNotification
);
244 void ReportCmd(const CString
& sCmd
);
245 void ReportString(CString sMessage
, const CString
& sMsgKind
, COLORREF color
= ::GetSysColor(COLOR_WINDOWTEXT
));
248 void AddItemToList();
249 CString
BuildInfoString();
252 * Resizes the columns of the progress list so that the headings are visible.
254 void ResizeColumns();
256 /// Predicate function to tell us if a notification data item is auxiliary or not
257 static bool NotificationDataIsAux(const NotificationData
* pData
);
260 typedef std::vector
<NotificationData
*> NotificationDataVect
;
262 NotificationDataVect m_arData
;
264 volatile LONG m_bThreadRunning
;
266 int m_options
; // Use values from the ProgressOptions enum
269 TCHAR m_columnbuf
[MAX_PATH
];
272 volatile BOOL m_bCancelled
;
277 int nEnsureVisibleCount
;
279 CString m_sTotalBytesTransferred
;
280 size_t m_TotalBytesTransferred
;
284 bool m_bFinishedItemAdded
;
289 int m_itemCountTotal
;
292 CComPtr
<ITaskbarList3
> m_pTaskbarList
;
294 void ShowProgressBar();
297 afx_msg
void OnClose();
298 virtual BOOL
PreTranslateMessage(MSG
* pMsg
);
301 class ProgressCommand
304 CTGitPathList m_targetPathList
;
307 void SetPathList(CTGitPathList
& pathList
) { m_targetPathList
= pathList
; }
308 virtual bool Run(CGitProgressList
* list
, CString
& sWindowTitle
, int& m_itemCountTotal
, int& m_itemCount
) = 0;
309 virtual bool ShowCommitButton() { return false; }
310 virtual bool NeedsCommit() { return false; }
311 virtual ~ProgressCommand() {}