OSDN Git Service

2d5a88878bb8034c06179cf7dce9c33fa0cd5625
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / SVNProgressDlg.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \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
9 \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
14 \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
18 //\r
19 #include "stdafx.h"\r
20 #include "TortoiseProc.h"\r
21 #include "messagebox.h"\r
22 #include "SVNProgressDlg.h"\r
23 #include "LogDlg.h"\r
24 #include "TGitPath.h"\r
25 #include "Registry.h"\r
26 #include "GitStatus.h"\r
27 #include "AppUtils.h"\r
28 #include "PathUtils.h"\r
29 #include "StringUtils.h"\r
30 #include "TempFile.h"\r
31 #include "UnicodeUtils.h"\r
32 #include "SoundUtils.h"\r
33 #include "GitDiff.h"\r
34 #include "Hooks.h"\r
35 #include "DropFiles.h"\r
36 //#include "GitLogHelper.h"\r
37 #include "RegHistory.h"\r
38 //#include "ConflictResolveDlg.h"\r
39 #include "LogFile.h"\r
40 #include "ShellUpdater.h"\r
41 #include "IconMenu.h"\r
42 #include "BugTraqAssociations.h"\r
43 #include "patch.h"\r
44 \r
45 static UINT WM_GITPROGRESS = RegisterWindowMessage(_T("TORTOISEGIT_GITPROGRESS_MSG"));\r
46 \r
47 BOOL    CGitProgressDlg::m_bAscending = FALSE;\r
48 int             CGitProgressDlg::m_nSortedColumn = -1;\r
49 \r
50 #define TRANSFERTIMER   100\r
51 #define VISIBLETIMER    101\r
52 \r
53 enum SVNProgressDlgContextMenuCommands\r
54 {\r
55         // needs to start with 1, since 0 is the return value if *nothing* is clicked on in the context menu\r
56         ID_COMPARE = 1,\r
57         ID_EDITCONFLICT,\r
58         ID_CONFLICTRESOLVE,\r
59         ID_CONFLICTUSETHEIRS,\r
60         ID_CONFLICTUSEMINE,\r
61         ID_LOG,\r
62         ID_OPEN,\r
63         ID_OPENWITH,\r
64         ID_EXPLORE,\r
65         ID_COPY\r
66 };\r
67 \r
68 IMPLEMENT_DYNAMIC(CGitProgressDlg, CResizableStandAloneDialog)\r
69 CGitProgressDlg::CGitProgressDlg(CWnd* pParent /*=NULL*/)\r
70         : CResizableStandAloneDialog(CGitProgressDlg::IDD, pParent)\r
71 #if 0\r
72         , m_Revision(_T("HEAD"))\r
73         //, m_RevisionEnd(0)\r
74         , m_bLockWarning(false)\r
75         , m_bLockExists(false)\r
76         , m_bCancelled(FALSE)\r
77         , m_bThreadRunning(FALSE)\r
78         , m_nConflicts(0)\r
79         , m_bErrorsOccurred(FALSE)\r
80         , m_bMergesAddsDeletesOccurred(FALSE)\r
81         , m_pThread(NULL)\r
82         , m_options(ProgOptNone)\r
83         , m_dwCloseOnEnd((DWORD)-1)\r
84         , m_bFinishedItemAdded(false)\r
85         , m_bLastVisible(false)\r
86 //      , m_depth(svn_depth_unknown)\r
87         , m_itemCount(-1)\r
88         , m_itemCountTotal(-1)\r
89         , m_AlwaysConflicted(false)\r
90         , m_BugTraqProvider(NULL)\r
91         , sIgnoredIncluded(MAKEINTRESOURCE(IDS_PROGRS_IGNOREDINCLUDED))\r
92         , sExtExcluded(MAKEINTRESOURCE(IDS_PROGRS_EXTERNALSEXCLUDED))\r
93         , sExtIncluded(MAKEINTRESOURCE(IDS_PROGRS_EXTERNALSINCLUDED))\r
94         , sIgnoreAncestry(MAKEINTRESOURCE(IDS_PROGRS_IGNOREANCESTRY))\r
95         , sRespectAncestry(MAKEINTRESOURCE(IDS_PROGRS_RESPECTANCESTRY))\r
96         , sDryRun(MAKEINTRESOURCE(IDS_PROGRS_DRYRUN))\r
97         , sRecordOnly(MAKEINTRESOURCE(IDS_MERGE_RECORDONLY))\r
98 #endif\r
99 {\r
100 }\r
101 \r
102 CGitProgressDlg::~CGitProgressDlg()\r
103 {\r
104         for (size_t i=0; i<m_arData.size(); i++)\r
105         {\r
106                 delete m_arData[i];\r
107         } \r
108         if(m_pThread != NULL)\r
109         {\r
110                 delete m_pThread;\r
111         }\r
112 }\r
113 \r
114 void CGitProgressDlg::DoDataExchange(CDataExchange* pDX)\r
115 {\r
116         CResizableStandAloneDialog::DoDataExchange(pDX);\r
117         DDX_Control(pDX, IDC_SVNPROGRESS, m_ProgList);\r
118 }\r
119 \r
120 BEGIN_MESSAGE_MAP(CGitProgressDlg, CResizableStandAloneDialog)\r
121         ON_BN_CLICKED(IDC_LOGBUTTON, OnBnClickedLogbutton)\r
122         ON_NOTIFY(NM_CUSTOMDRAW, IDC_SVNPROGRESS, OnNMCustomdrawSvnprogress)\r
123         ON_WM_CLOSE()\r
124         ON_NOTIFY(NM_DBLCLK, IDC_SVNPROGRESS, OnNMDblclkSvnprogress)\r
125         ON_NOTIFY(HDN_ITEMCLICK, 0, OnHdnItemclickSvnprogress)\r
126         ON_WM_SETCURSOR()\r
127         ON_WM_CONTEXTMENU()\r
128         ON_REGISTERED_MESSAGE(WM_GITPROGRESS, OnGitProgress)\r
129         ON_WM_TIMER()\r
130         ON_EN_SETFOCUS(IDC_INFOTEXT, &CGitProgressDlg::OnEnSetfocusInfotext)\r
131         ON_NOTIFY(LVN_BEGINDRAG, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnBegindragSvnprogress)\r
132         ON_WM_SIZE()\r
133         ON_NOTIFY(LVN_GETDISPINFO, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnGetdispinfoSvnprogress)\r
134         ON_BN_CLICKED(IDC_NONINTERACTIVE, &CGitProgressDlg::OnBnClickedNoninteractive)\r
135         ON_MESSAGE(WM_SHOWCONFLICTRESOLVER, OnShowConflictResolver)\r
136 END_MESSAGE_MAP()\r
137 \r
138 BOOL CGitProgressDlg::Cancel()\r
139 {\r
140         return m_bCancelled;\r
141 }\r
142 \r
143 LRESULT CGitProgressDlg::OnShowConflictResolver(WPARAM /*wParam*/, LPARAM lParam)\r
144 {\r
145 #if 0\r
146         CConflictResolveDlg dlg(this);\r
147         const svn_wc_conflict_description_t *description = (svn_wc_conflict_description_t *)lParam;\r
148         if (description)\r
149         {\r
150                 dlg.SetConflictDescription(description);\r
151                 if (dlg.DoModal() == IDOK)\r
152                 {\r
153                         if (dlg.GetResult() == svn_wc_conflict_choose_postpone)\r
154                         {\r
155                                 // if the result is conflicted and the dialog returned IDOK,\r
156                                 // that means we should not ask again in case of a conflict\r
157                                 m_AlwaysConflicted = true;\r
158                                 ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_SETCHECK, BST_CHECKED, 0);\r
159                         }\r
160                 }\r
161                 m_mergedfile = dlg.GetMergedFile();\r
162                 m_bCancelled = dlg.IsCancelled();\r
163                 return dlg.GetResult();\r
164         }\r
165 \r
166         return svn_wc_conflict_choose_postpone;\r
167 #endif\r
168         return 0;\r
169 }\r
170 #if 0\r
171 svn_wc_conflict_choice_t CGitProgressDlg::ConflictResolveCallback(const svn_wc_conflict_description_t *description, CString& mergedfile)\r
172 {\r
173         // we only bother the user when merging\r
174         if (((m_Command == GitProgress_Merge)||(m_Command == GitProgress_MergeAll)||(m_Command == GitProgress_MergeReintegrate))&&(!m_AlwaysConflicted)&&(description))\r
175         {\r
176                 // we're in a worker thread here. That means we must not show a dialog from the thread\r
177                 // but let the UI thread do it.\r
178                 // To do that, we send a message to the UI thread and let it show the conflict resolver dialog.\r
179                 LRESULT dlgResult = ::SendMessage(GetSafeHwnd(), WM_SHOWCONFLICTRESOLVER, 0, (LPARAM)description);\r
180                 mergedfile = m_mergedfile;\r
181                 return (svn_wc_conflict_choice_t)dlgResult;\r
182         }\r
183 \r
184         return svn_wc_conflict_choose_postpone;\r
185 }\r
186 #endif\r
187 void CGitProgressDlg::AddItemToList()\r
188 {\r
189         int totalcount = m_ProgList.GetItemCount();\r
190 \r
191         m_ProgList.SetItemCountEx(totalcount+1, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);\r
192         // make columns width fit\r
193         if (iFirstResized < 30)\r
194         {\r
195                 // only resize the columns for the first 30 or so entries.\r
196                 // after that, don't resize them anymore because that's an\r
197                 // expensive function call and the columns will be sized\r
198                 // close enough already.\r
199                 ResizeColumns();\r
200                 iFirstResized++;\r
201         }\r
202 \r
203         // Make sure the item is *entirely* visible even if the horizontal\r
204         // scroll bar is visible.\r
205         int count = m_ProgList.GetCountPerPage();\r
206         if (totalcount <= (m_ProgList.GetTopIndex() + count + nEnsureVisibleCount + 2))\r
207         {\r
208                 nEnsureVisibleCount++;\r
209                 m_bLastVisible = true;\r
210         }\r
211         else\r
212         {\r
213                 nEnsureVisibleCount = 0;\r
214                 if (IsIconic() == 0)\r
215                         m_bLastVisible = false;\r
216         }\r
217 }\r
218 \r
219 \r
220 BOOL CGitProgressDlg::Notify(const CTGitPath& path, git_wc_notify_action_t action\r
221                                                          /*\r
222                                                          svn_node_kind_t kind, const CString& mime_type, \r
223                                                          svn_wc_notify_state_t content_state, \r
224                                                          svn_wc_notify_state_t prop_state, LONG rev,\r
225                                                          const svn_lock_t * lock, svn_wc_notify_lock_state_t lock_state,\r
226                                                          const CString& changelistname,\r
227                                                          svn_merge_range_t * range,\r
228                                                          svn_error_t * err, apr_pool_t * pool\r
229                                                          */)\r
230 {\r
231         bool bNoNotify = false;\r
232         bool bDoAddData = true;\r
233         NotificationData * data = new NotificationData();\r
234         data->path = path;\r
235         data->action = action;\r
236         data->sPathColumnText=path.GetGitPathString();\r
237 #if 0\r
238         data->kind = kind;\r
239         data->mime_type = mime_type;\r
240         data->content_state = content_state;\r
241         data->prop_state = prop_state;\r
242         data->rev = rev;\r
243         data->lock_state = lock_state;\r
244         data->changelistname = changelistname;\r
245         if ((lock)&&(lock->owner))\r
246                 data->owner = CUnicodeUtils::GetUnicode(lock->owner);\r
247         data->sPathColumnText = path.GetUIPathString();\r
248         if (!m_basePath.IsEmpty())\r
249                 data->basepath = m_basePath;\r
250         if (range)\r
251                 data->merge_range = *range;\r
252 #endif\r
253         switch (data->action)\r
254         {\r
255         case git_wc_notify_add:\r
256         //case svn_wc_notify_update_add:\r
257         //      if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted))\r
258         //      {\r
259         //              data->color = m_Colors.GetColor(CColors::Conflict);\r
260         //              data->bConflictedActionItem = true;\r
261         //              data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED);\r
262         //              m_nConflicts++;\r
263         //      }\r
264         //      else\r
265         //      {\r
266         //              m_bMergesAddsDeletesOccurred = true;\r
267                         data->sActionColumnText.LoadString(IDS_SVNACTION_ADD);\r
268                         data->color = m_Colors.GetColor(CColors::Added);\r
269         //      }\r
270                 break;\r
271         case git_wc_notify_sendmail:\r
272                 data->sActionColumnText.LoadString(IDS_SVNACTION_SENDMAIL);\r
273                 data->color = m_Colors.GetColor(CColors::Modified);\r
274                 break;\r
275         \r
276         case git_wc_notify_resolved:\r
277                 data->sActionColumnText.LoadString(IDS_SVNACTION_RESOLVE);\r
278                 break;\r
279 \r
280 #if 0\r
281         case svn_wc_notify_commit_added:\r
282                 data->sActionColumnText.LoadString(IDS_SVNACTION_ADDING);\r
283                 data->color = m_Colors.GetColor(CColors::Added);\r
284                 break;\r
285         case svn_wc_notify_copy:\r
286                 data->sActionColumnText.LoadString(IDS_SVNACTION_COPY);\r
287                 break;\r
288         case svn_wc_notify_commit_modified:\r
289                 data->sActionColumnText.LoadString(IDS_SVNACTION_MODIFIED);\r
290                 data->color = m_Colors.GetColor(CColors::Modified);\r
291                 break;\r
292         case svn_wc_notify_delete:\r
293         case svn_wc_notify_update_delete:\r
294                 data->sActionColumnText.LoadString(IDS_SVNACTION_DELETE);\r
295                 m_bMergesAddsDeletesOccurred = true;\r
296                 data->color = m_Colors.GetColor(CColors::Deleted);\r
297                 break;\r
298         case svn_wc_notify_commit_deleted:\r
299                 data->sActionColumnText.LoadString(IDS_SVNACTION_DELETING);\r
300                 data->color = m_Colors.GetColor(CColors::Deleted);\r
301                 break;\r
302         case svn_wc_notify_restore:\r
303                 data->sActionColumnText.LoadString(IDS_SVNACTION_RESTORE);\r
304                 break;\r
305         case svn_wc_notify_revert:\r
306                 data->sActionColumnText.LoadString(IDS_SVNACTION_REVERT);\r
307                 break;\r
308         case svn_wc_notify_update_replace:\r
309         case svn_wc_notify_commit_replaced:\r
310                 data->sActionColumnText.LoadString(IDS_SVNACTION_REPLACED);\r
311                 data->color = m_Colors.GetColor(CColors::Deleted);\r
312                 break;\r
313         case svn_wc_notify_exists:\r
314                 if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted))\r
315                 {\r
316                         data->color = m_Colors.GetColor(CColors::Conflict);\r
317                         data->bConflictedActionItem = true;\r
318                         m_nConflicts++;\r
319                         data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED);\r
320                 }\r
321                 else if ((data->content_state == svn_wc_notify_state_merged) || (data->prop_state == svn_wc_notify_state_merged))\r
322                 {\r
323                         data->color = m_Colors.GetColor(CColors::Merged);\r
324                         m_bMergesAddsDeletesOccurred = true;\r
325                         data->sActionColumnText.LoadString(IDS_SVNACTION_MERGED);\r
326                 }\r
327                 else\r
328                         data->sActionColumnText.LoadString(IDS_SVNACTION_EXISTS);\r
329                 break;\r
330         case svn_wc_notify_update_update:\r
331                 // if this is an inoperative dir change, don't show the notification.\r
332                 // an inoperative dir change is when a directory gets updated without\r
333                 // any real change in either text or properties.\r
334                 if ((kind == svn_node_dir)\r
335                         && ((prop_state == svn_wc_notify_state_inapplicable)\r
336                         || (prop_state == svn_wc_notify_state_unknown)\r
337                         || (prop_state == svn_wc_notify_state_unchanged)))\r
338                 {\r
339                         bNoNotify = true;\r
340                         break;\r
341                 }\r
342                 if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted))\r
343                 {\r
344                         data->color = m_Colors.GetColor(CColors::Conflict);\r
345                         data->bConflictedActionItem = true;\r
346                         m_nConflicts++;\r
347                         data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED);\r
348                 }\r
349                 else if ((data->content_state == svn_wc_notify_state_merged) || (data->prop_state == svn_wc_notify_state_merged))\r
350                 {\r
351                         data->color = m_Colors.GetColor(CColors::Merged);\r
352                         m_bMergesAddsDeletesOccurred = true;\r
353                         data->sActionColumnText.LoadString(IDS_SVNACTION_MERGED);\r
354                 }\r
355                 else if (((data->content_state != svn_wc_notify_state_unchanged)&&(data->content_state != svn_wc_notify_state_unknown)) || \r
356                         ((data->prop_state != svn_wc_notify_state_unchanged)&&(data->prop_state != svn_wc_notify_state_unknown)))\r
357                 {\r
358                         data->sActionColumnText.LoadString(IDS_SVNACTION_UPDATE);\r
359                 }\r
360                 else\r
361                 {\r
362                         bNoNotify = true;\r
363                         break;\r
364                 }\r
365                 if (lock_state == svn_wc_notify_lock_state_unlocked)\r
366                 {\r
367                         CString temp(MAKEINTRESOURCE(IDS_SVNACTION_UNLOCKED));\r
368                         data->sActionColumnText += _T(", ") + temp;\r
369                 }\r
370                 break;\r
371 \r
372         case svn_wc_notify_update_external:\r
373                 // For some reason we build a list of externals...\r
374                 m_ExtStack.AddHead(path.GetUIPathString());\r
375                 data->sActionColumnText.LoadString(IDS_SVNACTION_EXTERNAL);\r
376                 data->bAuxItem = true;\r
377                 break;\r
378 \r
379         case svn_wc_notify_update_completed:\r
380                 {\r
381                         data->sActionColumnText.LoadString(IDS_SVNACTION_COMPLETED);\r
382                         data->bAuxItem = true;\r
383                         bool bEmpty = !!m_ExtStack.IsEmpty();\r
384                         if (!bEmpty)\r
385                                 data->sPathColumnText.Format(IDS_PROGRS_PATHATREV, (LPCTSTR)m_ExtStack.RemoveHead(), rev);\r
386                         else\r
387                                 data->sPathColumnText.Format(IDS_PROGRS_ATREV, rev);\r
388 \r
389                         if ((m_nConflicts>0)&&(bEmpty))\r
390                         {\r
391                                 // We're going to add another aux item - let's shove this current onto the list first\r
392                                 // I don't really like this, but it will do for the moment.\r
393                                 m_arData.push_back(data);\r
394                                 AddItemToList();\r
395 \r
396                                 data = new NotificationData();\r
397                                 data->bAuxItem = true;\r
398                                 data->sActionColumnText.LoadString(IDS_PROGRS_CONFLICTSOCCURED_WARNING);\r
399                                 data->sPathColumnText.LoadString(IDS_PROGRS_CONFLICTSOCCURED);\r
400                                 data->color = m_Colors.GetColor(CColors::Conflict);\r
401                                 CSoundUtils::PlayTSVNWarning();\r
402                                 // This item will now be added after the switch statement\r
403                         }\r
404                         if (!m_basePath.IsEmpty())\r
405                                 m_FinishedRevMap[m_basePath.GetSVNApiPath(pool)] = rev;\r
406                         m_RevisionEnd = rev;\r
407                         m_bFinishedItemAdded = true;\r
408                 }\r
409                 break;\r
410         case svn_wc_notify_commit_postfix_txdelta:\r
411                 data->sActionColumnText.LoadString(IDS_SVNACTION_POSTFIX);\r
412                 break;\r
413         case svn_wc_notify_failed_revert:\r
414                 data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDREVERT);\r
415                 break;\r
416         case svn_wc_notify_status_completed:\r
417         case svn_wc_notify_status_external:\r
418                 data->sActionColumnText.LoadString(IDS_SVNACTION_STATUS);\r
419                 break;\r
420         case svn_wc_notify_skip:\r
421                 if ((content_state == svn_wc_notify_state_missing)||(content_state == svn_wc_notify_state_obstructed)||(content_state == svn_wc_notify_state_conflicted))\r
422                 {\r
423                         data->sActionColumnText.LoadString(IDS_SVNACTION_SKIPMISSING);\r
424 \r
425                         // The color settings dialog describes the red color with\r
426                         // "possible or real conflict / obstructed" which also applies to\r
427                         // skipped targets during a merge. So we just use the same color.\r
428                         data->color = m_Colors.GetColor(CColors::Conflict);\r
429                 }\r
430                 else\r
431                         data->sActionColumnText.LoadString(IDS_SVNACTION_SKIP);\r
432                 break;\r
433         case svn_wc_notify_locked:\r
434                 if ((lock)&&(lock->owner))\r
435                         data->sActionColumnText.Format(IDS_SVNACTION_LOCKEDBY, (LPCTSTR)CUnicodeUtils::GetUnicode(lock->owner));\r
436                 break;\r
437         case svn_wc_notify_unlocked:\r
438                 data->sActionColumnText.LoadString(IDS_SVNACTION_UNLOCKED);\r
439                 break;\r
440         case svn_wc_notify_failed_lock:\r
441                 data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDLOCK);\r
442                 m_arData.push_back(data);\r
443                 AddItemToList();\r
444                 ReportError(SVN::GetErrorString(err));\r
445                 bDoAddData = false;\r
446                 if (err->apr_err == SVN_ERR_FS_OUT_OF_DATE)\r
447                         m_bLockWarning = true;\r
448                 if (err->apr_err == SVN_ERR_FS_PATH_ALREADY_LOCKED)\r
449                         m_bLockExists = true;\r
450                 break;\r
451         case svn_wc_notify_failed_unlock:\r
452                 data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDUNLOCK);\r
453                 m_arData.push_back(data);\r
454                 AddItemToList();\r
455                 ReportError(SVN::GetErrorString(err));\r
456                 bDoAddData = false;\r
457                 if (err->apr_err == SVN_ERR_FS_OUT_OF_DATE)\r
458                         m_bLockWarning = true;\r
459                 break;\r
460         case svn_wc_notify_changelist_set:\r
461                 data->sActionColumnText.Format(IDS_SVNACTION_CHANGELISTSET, (LPCTSTR)data->changelistname);\r
462                 break;\r
463         case svn_wc_notify_changelist_clear:\r
464                 data->sActionColumnText.LoadString(IDS_SVNACTION_CHANGELISTCLEAR);\r
465                 break;\r
466         case svn_wc_notify_changelist_moved:\r
467                 data->sActionColumnText.Format(IDS_SVNACTION_CHANGELISTMOVED, (LPCTSTR)data->changelistname);\r
468                 break;\r
469         case svn_wc_notify_foreign_merge_begin:\r
470         case svn_wc_notify_merge_begin:\r
471                 if (range == NULL)\r
472                         data->sActionColumnText.LoadString(IDS_SVNACTION_MERGEBEGINNONE);\r
473                 else if ((data->merge_range.start == data->merge_range.end) || (data->merge_range.start == data->merge_range.end - 1))\r
474                         data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINSINGLE, data->merge_range.end);\r
475                 else if (data->merge_range.start - 1 == data->merge_range.end)\r
476                         data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINSINGLEREVERSE, data->merge_range.start);\r
477                 else if (data->merge_range.start < data->merge_range.end)\r
478                         data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINMULTIPLE, data->merge_range.start + 1, data->merge_range.end);\r
479                 else\r
480                         data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINMULTIPLEREVERSE, data->merge_range.start, data->merge_range.end + 1);\r
481                 data->bAuxItem = true;\r
482                 break;\r
483 #endif\r
484         default:\r
485                 break;\r
486         } // switch (data->action)\r
487 \r
488         if (bNoNotify)\r
489                 delete data;\r
490         else\r
491         {\r
492                 if (bDoAddData)\r
493                 {\r
494                         m_arData.push_back(data);\r
495                         AddItemToList();\r
496                         if (/*(!data->bAuxItem)&&*/(m_itemCount > 0))\r
497                         {\r
498                                 m_itemCount--;\r
499 \r
500                                 CProgressCtrl * progControl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESSBAR);\r
501                                 progControl->ShowWindow(SW_SHOW);\r
502                                 progControl->SetPos(m_itemCountTotal - m_itemCount);\r
503                                 progControl->SetRange32(0, m_itemCountTotal);\r
504                         }\r
505                 }\r
506                 //if ((action == svn_wc_notify_commit_postfix_txdelta)&&(bSecondResized == FALSE))\r
507                 //{\r
508                 //      ResizeColumns();\r
509                 //      bSecondResized = TRUE;\r
510                 //}\r
511         }\r
512 \r
513         return TRUE;\r
514 }\r
515 \r
516 \r
517 CString CGitProgressDlg::BuildInfoString()\r
518 {\r
519         CString infotext;\r
520 #if 0\r
521         \r
522         CString temp;\r
523         int added = 0;\r
524         int copied = 0;\r
525         int deleted = 0;\r
526         int restored = 0;\r
527         int reverted = 0;\r
528         int resolved = 0;\r
529         int conflicted = 0;\r
530         int updated = 0;\r
531         int merged = 0;\r
532         int modified = 0;\r
533         int skipped = 0;\r
534         int replaced = 0;\r
535 \r
536         for (size_t i=0; i<m_arData.size(); ++i)\r
537         {\r
538                 const NotificationData * dat = m_arData[i];\r
539                 switch (dat->action)\r
540                 {\r
541                 case svn_wc_notify_add:\r
542                 case svn_wc_notify_update_add:\r
543                 case svn_wc_notify_commit_added:\r
544                         if (dat->bConflictedActionItem)\r
545                                 conflicted++;\r
546                         else\r
547                                 added++;\r
548                         break;\r
549                 case svn_wc_notify_copy:\r
550                         copied++;\r
551                         break;\r
552                 case svn_wc_notify_delete:\r
553                 case svn_wc_notify_update_delete:\r
554                 case svn_wc_notify_commit_deleted:\r
555                         deleted++;\r
556                         break;\r
557                 case svn_wc_notify_restore:\r
558                         restored++;\r
559                         break;\r
560                 case svn_wc_notify_revert:\r
561                         reverted++;\r
562                         break;\r
563                 case svn_wc_notify_resolved:\r
564                         resolved++;\r
565                         break;\r
566                 case svn_wc_notify_update_update:\r
567                         if (dat->bConflictedActionItem)\r
568                                 conflicted++;\r
569                         else if ((dat->content_state == svn_wc_notify_state_merged) || (dat->prop_state == svn_wc_notify_state_merged))\r
570                                 merged++;\r
571                         else\r
572                                 updated++;\r
573                         break;\r
574                 case svn_wc_notify_commit_modified:\r
575                         modified++;\r
576                         break;\r
577                 case svn_wc_notify_skip:\r
578                         skipped++;\r
579                         break;\r
580                 case svn_wc_notify_commit_replaced:\r
581                         replaced++;\r
582                         break;\r
583                 }\r
584         }\r
585         if (conflicted)\r
586         {\r
587                 temp.LoadString(IDS_SVNACTION_CONFLICTED);\r
588                 infotext += temp;\r
589                 temp.Format(_T(":%d "), conflicted);\r
590                 infotext += temp;\r
591         }\r
592         if (skipped)\r
593         {\r
594                 temp.LoadString(IDS_SVNACTION_SKIP);\r
595                 infotext += temp;\r
596                 infotext.AppendFormat(_T(":%d "), skipped);\r
597         }\r
598         if (merged)\r
599         {\r
600                 temp.LoadString(IDS_SVNACTION_MERGED);\r
601                 infotext += temp;\r
602                 infotext.AppendFormat(_T(":%d "), merged);\r
603         }\r
604         if (added)\r
605         {\r
606                 temp.LoadString(IDS_SVNACTION_ADD);\r
607                 infotext += temp;\r
608                 infotext.AppendFormat(_T(":%d "), added);\r
609         }\r
610         if (deleted)\r
611         {\r
612                 temp.LoadString(IDS_SVNACTION_DELETE);\r
613                 infotext += temp;\r
614                 infotext.AppendFormat(_T(":%d "), deleted);\r
615         }\r
616         if (modified)\r
617         {\r
618                 temp.LoadString(IDS_SVNACTION_MODIFIED);\r
619                 infotext += temp;\r
620                 infotext.AppendFormat(_T(":%d "), modified);\r
621         }\r
622         if (copied)\r
623         {\r
624                 temp.LoadString(IDS_SVNACTION_COPY);\r
625                 infotext += temp;\r
626                 infotext.AppendFormat(_T(":%d "), copied);\r
627         }\r
628         if (replaced)\r
629         {\r
630                 temp.LoadString(IDS_SVNACTION_REPLACED);\r
631                 infotext += temp;\r
632                 infotext.AppendFormat(_T(":%d "), replaced);\r
633         }\r
634         if (updated)\r
635         {\r
636                 temp.LoadString(IDS_SVNACTION_UPDATE);\r
637                 infotext += temp;\r
638                 infotext.AppendFormat(_T(":%d "), updated);\r
639         }\r
640         if (restored)\r
641         {\r
642                 temp.LoadString(IDS_SVNACTION_RESTORE);\r
643                 infotext += temp;\r
644                 infotext.AppendFormat(_T(":%d "), restored);\r
645         }\r
646         if (reverted)\r
647         {\r
648                 temp.LoadString(IDS_SVNACTION_REVERT);\r
649                 infotext += temp;\r
650                 infotext.AppendFormat(_T(":%d "), reverted);\r
651         }\r
652         if (resolved)\r
653         {\r
654                 temp.LoadString(IDS_SVNACTION_RESOLVE);\r
655                 infotext += temp;\r
656                 infotext.AppendFormat(_T(":%d "), resolved);\r
657         }\r
658 #endif\r
659         return infotext;\r
660 }\r
661 \r
662 void CGitProgressDlg::SetSelectedList(const CTGitPathList& selPaths)\r
663 {\r
664         m_selectedPaths = selPaths;\r
665 }\r
666 \r
667 void CGitProgressDlg::ResizeColumns()\r
668 {\r
669         m_ProgList.SetRedraw(FALSE);\r
670 \r
671         TCHAR textbuf[MAX_PATH];\r
672 \r
673         int maxcol = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1;\r
674         for (int col = 0; col <= maxcol; col++)\r
675         {\r
676                 // find the longest width of all items\r
677                 int count = m_ProgList.GetItemCount();\r
678                 HDITEM hdi = {0};\r
679                 hdi.mask = HDI_TEXT;\r
680                 hdi.pszText = textbuf;\r
681                 hdi.cchTextMax = sizeof(textbuf);\r
682                 ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItem(col, &hdi);\r
683                 int cx = m_ProgList.GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin\r
684 \r
685                 for (int index = 0; index<count; ++index)\r
686                 {\r
687                         // get the width of the string and add 12 pixels for the column separator and margins\r
688                         int linewidth = cx;\r
689                         switch (col)\r
690                         {\r
691                         case 0:\r
692                                 linewidth = m_ProgList.GetStringWidth(m_arData[index]->sActionColumnText) + 12;\r
693                                 break;\r
694                         case 1:\r
695                                 linewidth = m_ProgList.GetStringWidth(m_arData[index]->sPathColumnText) + 12;\r
696                                 break;\r
697                         case 2:\r
698                                 linewidth = m_ProgList.GetStringWidth(m_arData[index]->mime_type) + 12;\r
699                                 break;\r
700                         }\r
701                         if (cx < linewidth)\r
702                                 cx = linewidth;\r
703                 }\r
704                 m_ProgList.SetColumnWidth(col, cx);\r
705         }\r
706 \r
707         m_ProgList.SetRedraw(TRUE);     \r
708 }\r
709 \r
710 BOOL CGitProgressDlg::OnInitDialog()\r
711 {\r
712         __super::OnInitDialog();\r
713 \r
714         m_ProgList.SetExtendedStyle (LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);\r
715 \r
716         m_ProgList.DeleteAllItems();\r
717         int c = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1;\r
718         while (c>=0)\r
719                 m_ProgList.DeleteColumn(c--);\r
720         CString temp;\r
721         temp.LoadString(IDS_PROGRS_ACTION);\r
722         m_ProgList.InsertColumn(0, temp);\r
723         temp.LoadString(IDS_PROGRS_PATH);\r
724         m_ProgList.InsertColumn(1, temp);\r
725         temp.LoadString(IDS_PROGRS_MIMETYPE);\r
726         m_ProgList.InsertColumn(2, temp);\r
727 \r
728         m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
729         if (m_pThread==NULL)\r
730         {\r
731                 ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));\r
732         }\r
733         else\r
734         {\r
735                 m_pThread->m_bAutoDelete = FALSE;\r
736                 m_pThread->ResumeThread();\r
737         }\r
738 \r
739         UpdateData(FALSE);\r
740 \r
741         // Call this early so that the column headings aren't hidden before any\r
742         // text gets added.\r
743         ResizeColumns();\r
744 \r
745         SetTimer(VISIBLETIMER, 300, NULL);\r
746 \r
747         AddAnchor(IDC_SVNPROGRESS, TOP_LEFT, BOTTOM_RIGHT);\r
748         AddAnchor(IDC_PROGRESSLABEL, BOTTOM_LEFT, BOTTOM_CENTER);\r
749         AddAnchor(IDC_PROGRESSBAR, BOTTOM_CENTER, BOTTOM_RIGHT);\r
750         AddAnchor(IDC_INFOTEXT, BOTTOM_LEFT, BOTTOM_RIGHT);\r
751         AddAnchor(IDC_NONINTERACTIVE, BOTTOM_LEFT, BOTTOM_RIGHT);\r
752         AddAnchor(IDCANCEL, BOTTOM_RIGHT);\r
753         AddAnchor(IDOK, BOTTOM_RIGHT);\r
754         AddAnchor(IDC_LOGBUTTON, BOTTOM_RIGHT);\r
755         //SetPromptParentWindow(this->m_hWnd);\r
756         if (hWndExplorer)\r
757                 CenterWindow(CWnd::FromHandle(hWndExplorer));\r
758         EnableSaveRestore(_T("SVNProgressDlg"));\r
759         return TRUE;\r
760 }\r
761 \r
762 bool CGitProgressDlg::SetBackgroundImage(UINT nID)\r
763 {\r
764         return CAppUtils::SetListCtrlBackgroundImage(m_ProgList.GetSafeHwnd(), nID);\r
765 }\r
766 \r
767 #if 0\r
768 void CGitProgressDlg::ReportSVNError()\r
769 {\r
770         ReportError(GetLastErrorMessage());\r
771 }\r
772 #endif\r
773 \r
774 void CGitProgressDlg::ReportError(const CString& sError)\r
775 {\r
776         CSoundUtils::PlayTGitError();\r
777         ReportString(sError, CString(MAKEINTRESOURCE(IDS_ERR_ERROR)), m_Colors.GetColor(CColors::Conflict));\r
778         m_bErrorsOccurred = true;\r
779 }\r
780 \r
781 void CGitProgressDlg::ReportWarning(const CString& sWarning)\r
782 {\r
783         CSoundUtils::PlayTGitWarning();\r
784         ReportString(sWarning, CString(MAKEINTRESOURCE(IDS_WARN_WARNING)), m_Colors.GetColor(CColors::Conflict));\r
785 }\r
786 \r
787 void CGitProgressDlg::ReportNotification(const CString& sNotification)\r
788 {\r
789         CSoundUtils::PlayTGitNotification();\r
790         ReportString(sNotification, CString(MAKEINTRESOURCE(IDS_WARN_NOTE)));\r
791 }\r
792 \r
793 void CGitProgressDlg::ReportCmd(const CString& sCmd)\r
794 {\r
795         ReportString(sCmd, CString(MAKEINTRESOURCE(IDS_PROGRS_CMDINFO)), m_Colors.GetColor(CColors::Cmd));\r
796 }\r
797 \r
798 void CGitProgressDlg::ReportString(CString sMessage, const CString& sMsgKind, COLORREF color)\r
799 {\r
800         // instead of showing a dialog box with the error message or notification,\r
801         // just insert the error text into the list control.\r
802         // that way the user isn't 'interrupted' by a dialog box popping up!\r
803 \r
804         // the message may be split up into different lines\r
805         // so add a new entry for each line of the message\r
806         while (!sMessage.IsEmpty())\r
807         {\r
808                 NotificationData * data = new NotificationData();\r
809                 data->bAuxItem = true;\r
810                 data->sActionColumnText = sMsgKind;\r
811                 if (sMessage.Find('\n')>=0)\r
812                         data->sPathColumnText = sMessage.Left(sMessage.Find('\n'));\r
813                 else\r
814                         data->sPathColumnText = sMessage;               \r
815                 data->sPathColumnText.Trim(_T("\n\r"));\r
816                 data->color = color;\r
817                 if (sMessage.Find('\n')>=0)\r
818                 {\r
819                         sMessage = sMessage.Mid(sMessage.Find('\n'));\r
820                         sMessage.Trim(_T("\n\r"));\r
821                 }\r
822                 else\r
823                         sMessage.Empty();\r
824                 m_arData.push_back(data);\r
825                 AddItemToList();\r
826         }\r
827 }\r
828 \r
829 UINT CGitProgressDlg::ProgressThreadEntry(LPVOID pVoid)\r
830 {\r
831         return ((CGitProgressDlg*)pVoid)->ProgressThread();\r
832 }\r
833 \r
834 UINT CGitProgressDlg::ProgressThread()\r
835 {\r
836         // The SetParams function should have loaded something for us\r
837 \r
838         CString temp;\r
839         CString sWindowTitle;\r
840         bool localoperation = false;\r
841         bool bSuccess = false;\r
842         m_AlwaysConflicted = false;\r
843 \r
844         DialogEnableWindow(IDOK, FALSE);\r
845         DialogEnableWindow(IDCANCEL, TRUE);\r
846 //      SetAndClearProgressInfo(m_hWnd);\r
847         m_itemCount = m_itemCountTotal;\r
848 \r
849         InterlockedExchange(&m_bThreadRunning, TRUE);\r
850         iFirstResized = 0;\r
851         bSecondResized = FALSE;\r
852         m_bFinishedItemAdded = false;\r
853         CTime startTime = CTime::GetCurrentTime();\r
854         switch (m_Command)\r
855         {\r
856         case GitProgress_Add:\r
857                 bSuccess = CmdAdd(sWindowTitle, localoperation);\r
858                 break;\r
859         case GitProgress_Checkout:\r
860                 bSuccess = CmdCheckout(sWindowTitle, localoperation);\r
861                 break;\r
862         case GitProgress_Commit:\r
863                 bSuccess = CmdCommit(sWindowTitle, localoperation);\r
864                 break;\r
865         case GitProgress_Copy:\r
866                 bSuccess = CmdCopy(sWindowTitle, localoperation);\r
867                 break;\r
868         case GitProgress_Export:\r
869                 bSuccess = CmdExport(sWindowTitle, localoperation);\r
870                 break;\r
871         case GitProgress_Import:\r
872                 bSuccess = CmdImport(sWindowTitle, localoperation);\r
873                 break;\r
874         case GitProgress_Lock:\r
875                 bSuccess = CmdLock(sWindowTitle, localoperation);\r
876                 break;\r
877         case GitProgress_Merge:\r
878                 bSuccess = CmdMerge(sWindowTitle, localoperation);\r
879                 break;\r
880         case GitProgress_MergeAll:\r
881                 bSuccess = CmdMergeAll(sWindowTitle, localoperation);\r
882                 break;\r
883         case GitProgress_MergeReintegrate:\r
884                 bSuccess = CmdMergeReintegrate(sWindowTitle, localoperation);\r
885                 break;\r
886         case GitProgress_Rename:\r
887                 bSuccess = CmdRename(sWindowTitle, localoperation);\r
888                 break;\r
889         case GitProgress_Resolve:\r
890                 bSuccess = CmdResolve(sWindowTitle, localoperation);\r
891                 break;\r
892         case GitProgress_Revert:\r
893                 bSuccess = CmdRevert(sWindowTitle, localoperation);\r
894                 break;\r
895         case GitProgress_Switch:\r
896                 bSuccess = CmdSwitch(sWindowTitle, localoperation);\r
897                 break;\r
898         case GitProgress_Unlock:\r
899                 bSuccess = CmdUnlock(sWindowTitle, localoperation);\r
900                 break;\r
901         case GitProgress_Update:\r
902                 bSuccess = CmdUpdate(sWindowTitle, localoperation);\r
903                 break;\r
904         case GitProgress_SendMail:\r
905                 bSuccess = CmdSendMail(sWindowTitle, localoperation);\r
906                 break;\r
907         }\r
908         if (!bSuccess)\r
909                 temp.LoadString(IDS_PROGRS_TITLEFAILED);\r
910         else\r
911                 temp.LoadString(IDS_PROGRS_TITLEFIN);\r
912         sWindowTitle = sWindowTitle + _T(" ") + temp;\r
913         SetWindowText(sWindowTitle);\r
914 \r
915         KillTimer(TRANSFERTIMER);\r
916         KillTimer(VISIBLETIMER);\r
917 \r
918         DialogEnableWindow(IDCANCEL, FALSE);\r
919         DialogEnableWindow(IDOK, TRUE);\r
920 \r
921         CString info = BuildInfoString();\r
922         if (!bSuccess)\r
923                 info.LoadString(IDS_PROGRS_INFOFAILED);\r
924         SetDlgItemText(IDC_INFOTEXT, info);\r
925         ResizeColumns();\r
926         SendMessage(DM_SETDEFID, IDOK);\r
927         GetDlgItem(IDOK)->SetFocus();   \r
928 \r
929         CString sFinalInfo;\r
930         if (!m_sTotalBytesTransferred.IsEmpty())\r
931         {\r
932                 CTimeSpan time = CTime::GetCurrentTime() - startTime;\r
933                 temp.Format(IDS_PROGRS_TIME, (LONG)time.GetTotalMinutes(), (LONG)time.GetSeconds());\r
934                 sFinalInfo.Format(IDS_PROGRS_FINALINFO, m_sTotalBytesTransferred, (LPCTSTR)temp);\r
935                 SetDlgItemText(IDC_PROGRESSLABEL, sFinalInfo);\r
936         }\r
937         else\r
938                 GetDlgItem(IDC_PROGRESSLABEL)->ShowWindow(SW_HIDE);\r
939 \r
940         GetDlgItem(IDC_PROGRESSBAR)->ShowWindow(SW_HIDE);\r
941 \r
942         if (!m_bFinishedItemAdded)\r
943         {\r
944                 // there's no "finished: xxx" line at the end. We add one here to make\r
945                 // sure the user sees that the command is actually finished.\r
946                 NotificationData * data = new NotificationData();\r
947                 data->bAuxItem = true;\r
948                 data->sActionColumnText.LoadString(IDS_PROGRS_FINISHED);\r
949                 m_arData.push_back(data);\r
950                 AddItemToList();\r
951         }\r
952 \r
953         int count = m_ProgList.GetItemCount();\r
954         if ((count > 0)&&(m_bLastVisible))\r
955                 m_ProgList.EnsureVisible(count-1, FALSE);\r
956 \r
957         CLogFile logfile;\r
958         if (logfile.Open())\r
959         {\r
960                 logfile.AddTimeLine();\r
961                 for (size_t i=0; i<m_arData.size(); i++)\r
962                 {\r
963                         NotificationData * data = m_arData[i];\r
964                         temp.Format(_T("%-20s : %s"), (LPCTSTR)data->sActionColumnText, (LPCTSTR)data->sPathColumnText);\r
965                         logfile.AddLine(temp);\r
966                 }\r
967                 if (!sFinalInfo.IsEmpty())\r
968                         logfile.AddLine(sFinalInfo);\r
969                 logfile.Close();\r
970         }\r
971 \r
972         m_bCancelled = TRUE;\r
973         InterlockedExchange(&m_bThreadRunning, FALSE);\r
974         RefreshCursor();\r
975 \r
976         DWORD dwAutoClose = CRegStdWORD(_T("Software\\TortoiseGit\\AutoClose"));\r
977         if (m_options & ProgOptDryRun)\r
978                 dwAutoClose = 0;                // dry run means progress dialog doesn't auto close at all\r
979         if (!m_bLastVisible)\r
980                 dwAutoClose = 0;\r
981         if (m_dwCloseOnEnd != (DWORD)-1)\r
982                 dwAutoClose = m_dwCloseOnEnd;           // command line value has priority over setting value\r
983         if ((dwAutoClose == CLOSE_NOERRORS)&&(!m_bErrorsOccurred))\r
984                 PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd);\r
985         if ((dwAutoClose == CLOSE_NOCONFLICTS)&&(!m_bErrorsOccurred)&&(m_nConflicts==0))\r
986                 PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd);\r
987         if ((dwAutoClose == CLOSE_NOMERGES)&&(!m_bErrorsOccurred)&&(m_nConflicts==0)&&(!m_bMergesAddsDeletesOccurred))\r
988                 PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd);\r
989         if ((dwAutoClose == CLOSE_LOCAL)&&(!m_bErrorsOccurred)&&(m_nConflicts==0)&&(localoperation))\r
990                 PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd);\r
991 \r
992         //Don't do anything here which might cause messages to be sent to the window\r
993         //The window thread is probably now blocked in OnOK if we've done an auto close\r
994         return 0;\r
995 }\r
996 \r
997 void CGitProgressDlg::OnBnClickedLogbutton()\r
998 {\r
999 #if 0\r
1000         if (m_targetPathList.GetCount() != 1)\r
1001                 return;\r
1002         StringRevMap::iterator it = m_UpdateStartRevMap.begin();\r
1003         svn_revnum_t rev = -1;\r
1004         if (it != m_UpdateStartRevMap.end())\r
1005         {\r
1006                 rev = it->second;\r
1007         }\r
1008         CLogDlg dlg;\r
1009         dlg.SetParams(m_targetPathList[0], m_RevisionEnd, m_RevisionEnd, rev, 0, TRUE);\r
1010         dlg.DoModal();\r
1011 #endif\r
1012 }\r
1013 \r
1014 \r
1015 void CGitProgressDlg::OnClose()\r
1016 {\r
1017         if (m_bCancelled)\r
1018         {\r
1019                 TerminateThread(m_pThread->m_hThread, (DWORD)-1);\r
1020                 InterlockedExchange(&m_bThreadRunning, FALSE);\r
1021         }\r
1022         else\r
1023         {\r
1024                 m_bCancelled = TRUE;\r
1025                 return;\r
1026         }\r
1027         DialogEnableWindow(IDCANCEL, TRUE);\r
1028         __super::OnClose();\r
1029 }\r
1030 \r
1031 void CGitProgressDlg::OnOK()\r
1032 {\r
1033         if ((m_bCancelled)&&(!m_bThreadRunning))\r
1034         {\r
1035                 // I have made this wait a sensible amount of time (10 seconds) for the thread to finish\r
1036                 // You must be careful in the thread that after posting the WM_COMMAND/IDOK message, you \r
1037                 // don't do any more operations on the window which might require message passing\r
1038                 // If you try to send windows messages once we're waiting here, then the thread can't finished\r
1039                 // because the Window's message loop is blocked at this wait\r
1040                 WaitForSingleObject(m_pThread->m_hThread, 10000);\r
1041                 __super::OnOK();\r
1042         }\r
1043         m_bCancelled = TRUE;\r
1044 }\r
1045 \r
1046 void CGitProgressDlg::OnCancel()\r
1047 {\r
1048         if ((m_bCancelled)&&(!m_bThreadRunning))\r
1049                 __super::OnCancel();\r
1050         m_bCancelled = TRUE;\r
1051 }\r
1052 \r
1053 void CGitProgressDlg::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult)\r
1054 {\r
1055         NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);\r
1056 \r
1057         if (pDispInfo)\r
1058         {\r
1059                 if (pDispInfo->item.mask & LVIF_TEXT)\r
1060                 {\r
1061                         if (pDispInfo->item.iItem < (int)m_arData.size())\r
1062                         {\r
1063                                 const NotificationData * data = m_arData[pDispInfo->item.iItem];\r
1064                                 switch (pDispInfo->item.iSubItem)\r
1065                                 {\r
1066                                 case 0:\r
1067                                         lstrcpyn(m_columnbuf, data->sActionColumnText, MAX_PATH);\r
1068                                         break;\r
1069                                 case 1:\r
1070                                         lstrcpyn(m_columnbuf, data->sPathColumnText, pDispInfo->item.cchTextMax);\r
1071                                         if (!data->bAuxItem)\r
1072                                         {\r
1073                                                 int cWidth = m_ProgList.GetColumnWidth(1);\r
1074                                                 cWidth = max(12, cWidth-12);\r
1075                                                 CDC * pDC = m_ProgList.GetDC();\r
1076                         if (pDC != NULL)\r
1077                         {\r
1078                                                     CFont * pFont = pDC->SelectObject(m_ProgList.GetFont());\r
1079                                                     PathCompactPath(pDC->GetSafeHdc(), m_columnbuf, cWidth);\r
1080                                                     pDC->SelectObject(pFont);\r
1081                                                         ReleaseDC(pDC);\r
1082                         }\r
1083                                         }\r
1084                                         break;\r
1085                                 case 2:\r
1086                                         lstrcpyn(m_columnbuf, data->mime_type, MAX_PATH);\r
1087                                         break;\r
1088                                 default:\r
1089                                         m_columnbuf[0] = 0;\r
1090                                 }\r
1091                                 pDispInfo->item.pszText = m_columnbuf;\r
1092                         }\r
1093                 }\r
1094         }\r
1095         *pResult = 0;\r
1096 }\r
1097 \r
1098 void CGitProgressDlg::OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult)\r
1099 {\r
1100         NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );\r
1101 \r
1102         // Take the default processing unless we set this to something else below.\r
1103         *pResult = CDRF_DODEFAULT;\r
1104 \r
1105         // First thing - check the draw stage. If it's the control's prepaint\r
1106         // stage, then tell Windows we want messages for every item.\r
1107 \r
1108         if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )\r
1109         {\r
1110                 *pResult = CDRF_NOTIFYITEMDRAW;\r
1111         }\r
1112         else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )\r
1113         {\r
1114                 // This is the prepaint stage for an item. Here's where we set the\r
1115                 // item's text color. Our return value will tell Windows to draw the\r
1116                 // item itself, but it will use the new color we set here.\r
1117 \r
1118                 // Tell Windows to paint the control itself.\r
1119                 *pResult = CDRF_DODEFAULT;\r
1120 \r
1121                 ASSERT(pLVCD->nmcd.dwItemSpec <  m_arData.size());\r
1122                 if(pLVCD->nmcd.dwItemSpec >= m_arData.size())\r
1123                 {\r
1124                         return;\r
1125                 }\r
1126                 const NotificationData * data = m_arData[pLVCD->nmcd.dwItemSpec];\r
1127                 ASSERT(data != NULL);\r
1128                 if (data == NULL)\r
1129                         return;\r
1130 \r
1131                 // Store the color back in the NMLVCUSTOMDRAW struct.\r
1132                 pLVCD->clrText = data->color;\r
1133         }\r
1134 }\r
1135 \r
1136 void CGitProgressDlg::OnNMDblclkSvnprogress(NMHDR *pNMHDR, LRESULT *pResult)\r
1137 {\r
1138 #if 0\r
1139         LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
1140         *pResult = 0;\r
1141         if (pNMLV->iItem < 0)\r
1142                 return;\r
1143         if (m_options & ProgOptDryRun)\r
1144                 return; //don't do anything in a dry-run.\r
1145 \r
1146         const NotificationData * data = m_arData[pNMLV->iItem];\r
1147         if (data == NULL)\r
1148                 return;\r
1149 \r
1150         if (data->bConflictedActionItem)\r
1151         {\r
1152                 // We've double-clicked on a conflicted item - do a three-way merge on it\r
1153                 SVNDiff::StartConflictEditor(data->path);\r
1154         }\r
1155         else if ((data->action == svn_wc_notify_update_update) && ((data->content_state == svn_wc_notify_state_merged)||(GitProgress_Merge == m_Command)) || (data->action == svn_wc_notify_resolved))\r
1156         {\r
1157                 // This is a modified file which has been merged on update. Diff it against base\r
1158                 CTGitPath temporaryFile;\r
1159                 SVNDiff diff(this, this->m_hWnd, true);\r
1160                 diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
1161                 svn_revnum_t baseRev = 0;\r
1162                 diff.DiffFileAgainstBase(data->path, baseRev);\r
1163         }\r
1164         else if ((!data->bAuxItem)&&(data->path.Exists())&&(!data->path.IsDirectory()))\r
1165         {\r
1166                 bool bOpenWith = false;\r
1167                 int ret = (int)ShellExecute(m_hWnd, NULL, data->path.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);\r
1168                 if (ret <= HINSTANCE_ERROR)\r
1169                         bOpenWith = true;\r
1170                 if (bOpenWith)\r
1171                 {\r
1172                         CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
1173                         cmd += data->path.GetWinPathString() + _T(" ");\r
1174                         CAppUtils::LaunchApplication(cmd, NULL, false);\r
1175                 }\r
1176         }\r
1177 #endif\r
1178 }\r
1179 \r
1180 void CGitProgressDlg::OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult)\r
1181 {\r
1182         LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);\r
1183         if (m_bThreadRunning)\r
1184                 return;\r
1185         if (m_nSortedColumn == phdr->iItem)\r
1186                 m_bAscending = !m_bAscending;\r
1187         else\r
1188                 m_bAscending = TRUE;\r
1189         m_nSortedColumn = phdr->iItem;\r
1190         Sort();\r
1191 \r
1192         CString temp;\r
1193         m_ProgList.SetRedraw(FALSE);\r
1194         m_ProgList.DeleteAllItems();\r
1195         m_ProgList.SetItemCountEx (static_cast<int>(m_arData.size()));\r
1196 \r
1197         m_ProgList.SetRedraw(TRUE);\r
1198 \r
1199         *pResult = 0;\r
1200 }\r
1201 \r
1202 bool CGitProgressDlg::NotificationDataIsAux(const NotificationData* pData)\r
1203 {\r
1204         return pData->bAuxItem;\r
1205 }\r
1206 \r
1207 LRESULT CGitProgressDlg::OnGitProgress(WPARAM /*wParam*/, LPARAM lParam)\r
1208 {\r
1209 #if 0\r
1210         SVNProgress * pProgressData = (SVNProgress *)lParam;\r
1211         CProgressCtrl * progControl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESSBAR);\r
1212         if ((pProgressData->total > 1000)&&(!progControl->IsWindowVisible()))\r
1213         {\r
1214                 progControl->ShowWindow(SW_SHOW);\r
1215         }\r
1216         if (((pProgressData->total < 0)&&(pProgressData->progress > 1000)&&(progControl->IsWindowVisible()))&&(m_itemCountTotal<0))\r
1217         {\r
1218                 progControl->ShowWindow(SW_HIDE);\r
1219         }\r
1220         if (!GetDlgItem(IDC_PROGRESSLABEL)->IsWindowVisible())\r
1221                 GetDlgItem(IDC_PROGRESSLABEL)->ShowWindow(SW_SHOW);\r
1222         SetTimer(TRANSFERTIMER, 2000, NULL);\r
1223         if ((pProgressData->total > 0)&&(pProgressData->progress > 1000))\r
1224         {\r
1225                 progControl->SetPos((int)pProgressData->progress);\r
1226                 progControl->SetRange32(0, (int)pProgressData->total);\r
1227         }\r
1228         CString progText;\r
1229         if (pProgressData->overall_total < 1024)\r
1230                 m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALBYTESTRANSFERRED, pProgressData->overall_total);  \r
1231         else if (pProgressData->overall_total < 1200000)\r
1232                 m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALTRANSFERRED, pProgressData->overall_total / 1024);\r
1233         else\r
1234                 m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALMBTRANSFERRED, (double)((double)pProgressData->overall_total / 1024000.0));\r
1235         progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)pProgressData->SpeedString);\r
1236         SetDlgItemText(IDC_PROGRESSLABEL, progText);\r
1237 #endif\r
1238         return 0;\r
1239 }\r
1240 \r
1241 void CGitProgressDlg::OnTimer(UINT_PTR nIDEvent)\r
1242 {\r
1243         if (nIDEvent == TRANSFERTIMER)\r
1244         {\r
1245                 CString progText;\r
1246                 CString progSpeed;\r
1247                 progSpeed.Format(IDS_SVN_PROGRESS_BYTES_SEC, 0);\r
1248                 progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)progSpeed);\r
1249                 SetDlgItemText(IDC_PROGRESSLABEL, progText);\r
1250                 KillTimer(TRANSFERTIMER);\r
1251         }\r
1252         if (nIDEvent == VISIBLETIMER)\r
1253         {\r
1254                 if (nEnsureVisibleCount)\r
1255                         m_ProgList.EnsureVisible(m_ProgList.GetItemCount()-1, false);\r
1256                 nEnsureVisibleCount = 0;\r
1257         }\r
1258 }\r
1259 \r
1260 void CGitProgressDlg::Sort()\r
1261 {\r
1262         if(m_arData.size() < 2)\r
1263         {\r
1264                 return;\r
1265         }\r
1266 \r
1267         // We need to sort the blocks which lie between the auxiliary entries\r
1268         // This is so that any aux data stays where it was\r
1269         NotificationDataVect::iterator actionBlockBegin;\r
1270         NotificationDataVect::iterator actionBlockEnd = m_arData.begin();       // We start searching from here\r
1271 \r
1272         for(;;)\r
1273         {\r
1274                 // Search to the start of the non-aux entry in the next block\r
1275                 actionBlockBegin = std::find_if(actionBlockEnd, m_arData.end(), std::not1(std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux)));\r
1276                 if(actionBlockBegin == m_arData.end())\r
1277                 {\r
1278                         // There are no more actions\r
1279                         break;\r
1280                 }\r
1281                 // Now search to find the end of the block\r
1282                 actionBlockEnd = std::find_if(actionBlockBegin+1, m_arData.end(), std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux));\r
1283                 // Now sort the block\r
1284                 std::sort(actionBlockBegin, actionBlockEnd, &CGitProgressDlg::SortCompare);\r
1285         }\r
1286 }\r
1287 \r
1288 bool CGitProgressDlg::SortCompare(const NotificationData * pData1, const NotificationData * pData2)\r
1289 {\r
1290         int result = 0;\r
1291         switch (m_nSortedColumn)\r
1292         {\r
1293         case 0:         //action column\r
1294                 result = pData1->sActionColumnText.Compare(pData2->sActionColumnText);\r
1295                 break;\r
1296         case 1:         //path column\r
1297                 // Compare happens after switch()\r
1298                 break;\r
1299         case 2:         //mime-type column\r
1300                 result = pData1->mime_type.Compare(pData2->mime_type);\r
1301                 break;\r
1302         default:\r
1303                 break;\r
1304         }\r
1305 \r
1306         // Sort by path if everything else is equal\r
1307         if (result == 0)\r
1308         {\r
1309                 result = CTGitPath::Compare(pData1->path, pData2->path);\r
1310         }\r
1311 \r
1312         if (!m_bAscending)\r
1313                 result = -result;\r
1314         return result < 0;\r
1315 }\r
1316 \r
1317 BOOL CGitProgressDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
1318 {\r
1319         if (!GetDlgItem(IDOK)->IsWindowEnabled())\r
1320         {\r
1321                 // only show the wait cursor over the list control\r
1322                 if ((pWnd)&&(pWnd == GetDlgItem(IDC_SVNPROGRESS)))\r
1323                 {\r
1324                         HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));\r
1325                         SetCursor(hCur);\r
1326                         return TRUE;\r
1327                 }\r
1328         }\r
1329         HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));\r
1330         SetCursor(hCur);\r
1331         return CResizableStandAloneDialog::OnSetCursor(pWnd, nHitTest, message);\r
1332 }\r
1333 \r
1334 BOOL CGitProgressDlg::PreTranslateMessage(MSG* pMsg)\r
1335 {\r
1336         if (pMsg->message == WM_KEYDOWN)\r
1337         {\r
1338                 if (pMsg->wParam == VK_ESCAPE)\r
1339                 {\r
1340                         // pressing the ESC key should close the dialog. But since we disabled the escape\r
1341                         // key (so the user doesn't get the idea that he could simply undo an e.g. update)\r
1342                         // this won't work.\r
1343                         // So if the user presses the ESC key, change it to VK_RETURN so the dialog gets\r
1344                         // the impression that the OK button was pressed.\r
1345                         if ((!m_bThreadRunning)&&(!GetDlgItem(IDCANCEL)->IsWindowEnabled())\r
1346                                 &&(GetDlgItem(IDOK)->IsWindowEnabled())&&(GetDlgItem(IDOK)->IsWindowVisible()))\r
1347                         {\r
1348                                 // since we convert ESC to RETURN, make sure the OK button has the focus.\r
1349                                 GetDlgItem(IDOK)->SetFocus();\r
1350                                 pMsg->wParam = VK_RETURN;\r
1351                         }\r
1352                 }\r
1353                 if (pMsg->wParam == 'A')\r
1354                 {\r
1355                         if (GetKeyState(VK_CONTROL)&0x8000)\r
1356                         {\r
1357                                 // Ctrl-A -> select all\r
1358                                 m_ProgList.SetSelectionMark(0);\r
1359                                 for (int i=0; i<m_ProgList.GetItemCount(); ++i)\r
1360                                 {\r
1361                                         m_ProgList.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);\r
1362                                 }\r
1363                         }\r
1364                 }\r
1365                 if ((pMsg->wParam == 'C')||(pMsg->wParam == VK_INSERT))\r
1366                 {\r
1367                         int selIndex = m_ProgList.GetSelectionMark();\r
1368                         if (selIndex >= 0)\r
1369                         {\r
1370                                 if (GetKeyState(VK_CONTROL)&0x8000)\r
1371                                 {\r
1372                                         //Ctrl-C -> copy to clipboard\r
1373                                         CString sClipdata;\r
1374                                         POSITION pos = m_ProgList.GetFirstSelectedItemPosition();\r
1375                                         if (pos != NULL)\r
1376                                         {\r
1377                                                 while (pos)\r
1378                                                 {\r
1379                                                         int nItem = m_ProgList.GetNextSelectedItem(pos);\r
1380                                                         CString sAction = m_ProgList.GetItemText(nItem, 0);\r
1381                                                         CString sPath = m_ProgList.GetItemText(nItem, 1);\r
1382                                                         CString sMime = m_ProgList.GetItemText(nItem, 2);\r
1383                                                         CString sLogCopyText;\r
1384                                                         sLogCopyText.Format(_T("%s: %s  %s\r\n"),\r
1385                                                                 (LPCTSTR)sAction, (LPCTSTR)sPath, (LPCTSTR)sMime);\r
1386                                                         sClipdata +=  sLogCopyText;\r
1387                                                 }\r
1388                                                 CStringUtils::WriteAsciiStringToClipboard(sClipdata);\r
1389                                         }\r
1390                                 }\r
1391                         }\r
1392                 } \r
1393         } // if (pMsg->message == WM_KEYDOWN)\r
1394         return __super::PreTranslateMessage(pMsg);\r
1395 }\r
1396 \r
1397 void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point)\r
1398 {\r
1399 #if 0\r
1400         if (m_options & ProgOptDryRun)\r
1401                 return; // don't do anything in a dry-run.\r
1402 \r
1403         if (pWnd == &m_ProgList)\r
1404         {\r
1405                 int selIndex = m_ProgList.GetSelectionMark();\r
1406                 if ((point.x == -1) && (point.y == -1))\r
1407                 {\r
1408                         // Menu was invoked from the keyboard rather than by right-clicking\r
1409                         CRect rect;\r
1410                         m_ProgList.GetItemRect(selIndex, &rect, LVIR_LABEL);\r
1411                         m_ProgList.ClientToScreen(&rect);\r
1412                         point = rect.CenterPoint();\r
1413                 }\r
1414 \r
1415                 if ((selIndex >= 0)&&(!m_bThreadRunning))\r
1416                 {\r
1417                         // entry is selected, thread has finished with updating so show the popup menu\r
1418                         CIconMenu popup;\r
1419                         if (popup.CreatePopupMenu())\r
1420                         {\r
1421                                 bool bAdded = false;\r
1422                                 NotificationData * data = m_arData[selIndex];\r
1423                                 if ((data)&&(!data->path.IsDirectory()))\r
1424                                 {\r
1425                                         if (data->action == svn_wc_notify_update_update || data->action == svn_wc_notify_resolved)\r
1426                                         {\r
1427                                                 if (m_ProgList.GetSelectedCount() == 1)\r
1428                                                 {\r
1429                                                         popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
1430                                                         bAdded = true;\r
1431                                                 }\r
1432                                         }\r
1433                                                 if (data->bConflictedActionItem)\r
1434                                                 {\r
1435                                                         if (m_ProgList.GetSelectedCount() == 1)\r
1436                                                         {\r
1437                                                                 popup.AppendMenuIcon(ID_EDITCONFLICT, IDS_MENUCONFLICT,IDI_CONFLICT);\r
1438                                                                 popup.SetDefaultItem(ID_EDITCONFLICT, FALSE);\r
1439                                                                 popup.AppendMenuIcon(ID_CONFLICTRESOLVE, IDS_SVNPROGRESS_MENUMARKASRESOLVED,IDI_RESOLVE);\r
1440                                                         }\r
1441                                                         popup.AppendMenuIcon(ID_CONFLICTUSETHEIRS, IDS_SVNPROGRESS_MENUUSETHEIRS,IDI_RESOLVE);\r
1442                                                         popup.AppendMenuIcon(ID_CONFLICTUSEMINE, IDS_SVNPROGRESS_MENUUSEMINE,IDI_RESOLVE);\r
1443                                                 }\r
1444                                                 else if ((data->content_state == svn_wc_notify_state_merged)||(GitProgress_Merge == m_Command)||(data->action == svn_wc_notify_resolved))\r
1445                                                         popup.SetDefaultItem(ID_COMPARE, FALSE);\r
1446                                         \r
1447                                         if (m_ProgList.GetSelectedCount() == 1)\r
1448                                         {\r
1449                                                 if ((data->action == svn_wc_notify_add)||\r
1450                                                         (data->action == svn_wc_notify_update_add)||\r
1451                                                         (data->action == svn_wc_notify_commit_added)||\r
1452                                                         (data->action == svn_wc_notify_commit_modified)||\r
1453                                                         (data->action == svn_wc_notify_restore)||\r
1454                                                         (data->action == svn_wc_notify_revert)||\r
1455                                                         (data->action == svn_wc_notify_resolved)||\r
1456                                                         (data->action == svn_wc_notify_commit_replaced)||\r
1457                                                         (data->action == svn_wc_notify_commit_modified)||\r
1458                                                         (data->action == svn_wc_notify_commit_postfix_txdelta)||\r
1459                                                         (data->action == svn_wc_notify_update_update))\r
1460                                                 {\r
1461                                                         popup.AppendMenuIcon(ID_LOG, IDS_MENULOG,IDI_LOG);\r
1462                                                         if (data->action == svn_wc_notify_update_update)\r
1463                                                                 popup.AppendMenu(MF_SEPARATOR, NULL);\r
1464                                                         popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN);\r
1465                                                         popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
1466                                                         bAdded = true;\r
1467                                                 }\r
1468                                         }\r
1469                                 } // if ((data)&&(!data->path.IsDirectory()))\r
1470                                 if (m_ProgList.GetSelectedCount() == 1)\r
1471                                 {\r
1472                                         if (data)\r
1473                                         {\r
1474                                                 CString sPath = GetPathFromColumnText(data->sPathColumnText);\r
1475                                                 if ((!sPath.IsEmpty())&&(!SVN::PathIsURL(CTGitPath(sPath))))\r
1476                                                 {\r
1477                                                         CTGitPath path = CTGitPath(sPath);\r
1478                                                         if (path.GetDirectory().Exists())\r
1479                                                         {\r
1480                                                                 popup.AppendMenuIcon(ID_EXPLORE, IDS_SVNPROGRESS_MENUOPENPARENT, IDI_EXPLORER);\r
1481                                                                 bAdded = true;\r
1482                                                         }\r
1483                                                 }\r
1484                                         }\r
1485                                 }\r
1486                                 if (m_ProgList.GetSelectedCount() > 0)\r
1487                                 {\r
1488                                         if (bAdded)\r
1489                                                 popup.AppendMenu(MF_SEPARATOR, NULL);\r
1490                                         popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPYTOCLIPBOARD,IDI_COPYCLIP);\r
1491                                         bAdded = true;\r
1492                                 }\r
1493                                 if (bAdded)\r
1494                                 {\r
1495                                         int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
1496                                         DialogEnableWindow(IDOK, FALSE);\r
1497                                         this->SetPromptApp(&theApp);\r
1498                                         theApp.DoWaitCursor(1);\r
1499                                         bool bOpenWith = false;\r
1500                                         switch (cmd)\r
1501                                         {\r
1502                                         case ID_COPY:\r
1503                                                 {\r
1504                                                         CString sLines;\r
1505                                                         POSITION pos = m_ProgList.GetFirstSelectedItemPosition();\r
1506                                                         while (pos)\r
1507                                                         {\r
1508                                                                 int nItem = m_ProgList.GetNextSelectedItem(pos);\r
1509                                                                 NotificationData * data = m_arData[nItem];\r
1510                                                                 if (data)\r
1511                                                                 {\r
1512                                                                         sLines += data->sPathColumnText;\r
1513                                                                         sLines += _T("\r\n");\r
1514                                                                 }\r
1515                                                         }\r
1516                                                         sLines.TrimRight();\r
1517                                                         if (!sLines.IsEmpty())\r
1518                                                         {\r
1519                                                                 CStringUtils::WriteAsciiStringToClipboard(sLines, GetSafeHwnd());\r
1520                                                         }\r
1521                                                 }\r
1522                                                 break;\r
1523                                         case ID_EXPLORE:\r
1524                                                 {\r
1525                                                         CString sPath = GetPathFromColumnText(data->sPathColumnText);\r
1526 \r
1527                                                         CTGitPath path = CTGitPath(sPath);\r
1528                                                         ShellExecute(m_hWnd, _T("explore"), path.GetDirectory().GetWinPath(), NULL, path.GetDirectory().GetWinPath(), SW_SHOW);\r
1529                                                 }\r
1530                                                 break;\r
1531                                         case ID_COMPARE:\r
1532                                                 {\r
1533                                                         svn_revnum_t rev = -1;\r
1534                                                         StringRevMap::iterator it = m_UpdateStartRevMap.end();\r
1535                                                         if (data->basepath.IsEmpty())\r
1536                                                                 it = m_UpdateStartRevMap.begin();\r
1537                                                         else\r
1538                                                                 it = m_UpdateStartRevMap.find(data->basepath.GetSVNApiPath(pool));\r
1539                                                         if (it != m_UpdateStartRevMap.end())\r
1540                                                                 rev = it->second;\r
1541                                                         // if the file was merged during update, do a three way diff between OLD, MINE, THEIRS\r
1542                                                         if (data->content_state == svn_wc_notify_state_merged)\r
1543                                                         {\r
1544                                                                 CTGitPath basefile = CTempFiles::Instance().GetTempFilePath(false, data->path, rev);\r
1545                                                                 CTGitPath newfile = CTempFiles::Instance().GetTempFilePath(false, data->path, SVNRev::REV_HEAD);\r
1546                                                                 SVN svn;\r
1547                                                                 if (!svn.Cat(data->path, SVNRev(SVNRev::REV_WC), rev, basefile))\r
1548                                                                 {\r
1549                                                                         CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
1550                                                                         DialogEnableWindow(IDOK, TRUE);\r
1551                                                                         break;\r
1552                                                                 }\r
1553                                                                 // If necessary, convert the line-endings on the file before diffing\r
1554                                                                 if ((DWORD)CRegDWORD(_T("Software\\TortoiseGit\\ConvertBase"), TRUE))\r
1555                                                                 {\r
1556                                                                         CTGitPath temporaryFile = CTempFiles::Instance().GetTempFilePath(false, data->path, SVNRev::REV_BASE);\r
1557                                                                         if (!svn.Cat(data->path, SVNRev(SVNRev::REV_BASE), SVNRev(SVNRev::REV_BASE), temporaryFile))\r
1558                                                                         {\r
1559                                                                                 temporaryFile.Reset();\r
1560                                                                                 break;\r
1561                                                                         }\r
1562                                                                         else\r
1563                                                                         {\r
1564                                                                                 newfile = temporaryFile;\r
1565                                                                         }\r
1566                                                                 }\r
1567 \r
1568                                                                 SetFileAttributes(newfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
1569                                                                 SetFileAttributes(basefile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
1570                                                                 CString revname, wcname, basename;\r
1571                                                                 revname.Format(_T("%s Revision %ld"), (LPCTSTR)data->path.GetUIFileOrDirectoryName(), rev);\r
1572                                                                 wcname.Format(IDS_DIFF_WCNAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName());\r
1573                                                                 basename.Format(IDS_DIFF_BASENAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName());\r
1574                                                                 CAppUtils::StartExtMerge(basefile, newfile, data->path, data->path, basename, revname, wcname, CString(), true);\r
1575                                                         }\r
1576                                                         else\r
1577                                                         {\r
1578                                                                 CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, data->path, rev);\r
1579                                                                 SVN svn;\r
1580                                                                 if (!svn.Cat(data->path, SVNRev(SVNRev::REV_WC), rev, tempfile))\r
1581                                                                 {\r
1582                                                                         CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
1583                                                                         DialogEnableWindow(IDOK, TRUE);\r
1584                                                                         break;\r
1585                                                                 }\r
1586                                                                 else\r
1587                                                                 {\r
1588                                                                         SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
1589                                                                         CString revname, wcname;\r
1590                                                                         revname.Format(_T("%s Revision %ld"), (LPCTSTR)data->path.GetUIFileOrDirectoryName(), rev);\r
1591                                                                         wcname.Format(IDS_DIFF_WCNAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName());\r
1592                                                                         CAppUtils::StartExtDiff(\r
1593                                                                                 tempfile, data->path, revname, wcname,\r
1594                                                                                 CAppUtils::DiffFlags().AlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000)));\r
1595                                                                 }\r
1596                                                         }\r
1597                                                 }\r
1598                                                 break;\r
1599                                         case ID_EDITCONFLICT:\r
1600                                                 {\r
1601                                                         CString sPath = GetPathFromColumnText(data->sPathColumnText);\r
1602                                                         SVNDiff::StartConflictEditor(CTGitPath(sPath));\r
1603                                                 }\r
1604                                                 break;\r
1605                                         case ID_CONFLICTUSETHEIRS:\r
1606                                         case ID_CONFLICTUSEMINE:\r
1607                                         case ID_CONFLICTRESOLVE:\r
1608                                                 {\r
1609                                                         svn_wc_conflict_choice_t result = svn_wc_conflict_choose_merged;\r
1610                                                         switch (cmd)\r
1611                                                         {\r
1612                                                         case ID_CONFLICTUSETHEIRS:\r
1613                                                                 result = svn_wc_conflict_choose_theirs_full;\r
1614                                                                 break;\r
1615                                                         case ID_CONFLICTUSEMINE:\r
1616                                                                 result = svn_wc_conflict_choose_mine_full;\r
1617                                                                 break;\r
1618                                                         case ID_CONFLICTRESOLVE:\r
1619                                                                 result = svn_wc_conflict_choose_merged;\r
1620                                                                 break;\r
1621                                                         }\r
1622                                                         SVN svn;\r
1623                                                         POSITION pos = m_ProgList.GetFirstSelectedItemPosition();\r
1624                                                         CString sResolvedPaths;\r
1625                                                         while (pos)\r
1626                                                         {\r
1627                                                                 int nItem = m_ProgList.GetNextSelectedItem(pos);\r
1628                                                                 NotificationData * data = m_arData[nItem];\r
1629                                                                 if (data)\r
1630                                                                 {\r
1631                                                                         if (data->bConflictedActionItem)\r
1632                                                                         {\r
1633                                                                                 if (!svn.Resolve(data->path, result, FALSE))\r
1634                                                                                 {\r
1635                                                                                         CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
1636                                                                                         DialogEnableWindow(IDOK, TRUE);\r
1637                                                                                         break;\r
1638                                                                                 }\r
1639                                                                                 else\r
1640                                                                                 {\r
1641                                                                                         data->color = ::GetSysColor(COLOR_WINDOWTEXT);\r
1642                                                                                         data->action = svn_wc_notify_resolved;\r
1643                                                                                         data->sActionColumnText.LoadString(IDS_SVNACTION_RESOLVE);\r
1644                                                                                         data->bConflictedActionItem = false;\r
1645                                                                                         m_nConflicts--;\r
1646 \r
1647                                                                                         if (m_nConflicts==0)\r
1648                                                                                         {\r
1649                                                                                                 // When the last conflict is resolved we remove\r
1650                                                                                                 // the warning which we assume is in the last line.\r
1651                                                                                                 int nIndex = m_ProgList.GetItemCount()-1;\r
1652                                                                                                 VERIFY(m_ProgList.DeleteItem(nIndex));\r
1653 \r
1654                                                                                                 delete m_arData[nIndex];\r
1655                                                                                                 m_arData.pop_back();\r
1656                                                                                         }\r
1657                                                                                         sResolvedPaths += data->path.GetWinPathString() + _T("\n");\r
1658                                                                                 }\r
1659                                                                         }\r
1660                                                                 }\r
1661                                                         }\r
1662                                                         m_ProgList.Invalidate();\r
1663                                                         CString info = BuildInfoString();\r
1664                                                         SetDlgItemText(IDC_INFOTEXT, info);\r
1665 \r
1666                                                         if (!sResolvedPaths.IsEmpty())\r
1667                                                         {\r
1668                                                                 CString msg;\r
1669                                                                 msg.Format(IDS_SVNPROGRESS_RESOLVED, (LPCTSTR)sResolvedPaths);\r
1670                                                                 CMessageBox::Show(m_hWnd, msg, _T("TortoiseSVN"), MB_OK | MB_ICONINFORMATION);\r
1671                                                         }\r
1672                                                 }\r
1673                                                 break;\r
1674                                         case ID_LOG:\r
1675                                                 {\r
1676                                                         CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseGit\\NumberOfLogs"), 100);\r
1677                                                         int limit = (int)(DWORD)reg;\r
1678                                                         svn_revnum_t rev = m_RevisionEnd;\r
1679                                                         if (!data->basepath.IsEmpty())\r
1680                                                         {\r
1681                                                                 StringRevMap::iterator it = m_FinishedRevMap.find(data->basepath.GetSVNApiPath(pool));\r
1682                                                                 if (it != m_FinishedRevMap.end())\r
1683                                                                         rev = it->second;\r
1684                                                         }\r
1685                                                         CLogDlg dlg;\r
1686                                                         // fetch the log from HEAD, not the revision we updated to:\r
1687                                                         // the path might be inside an external folder which has its own\r
1688                                                         // revisions.\r
1689                                                         CString sPath = GetPathFromColumnText(data->sPathColumnText);\r
1690                                                         dlg.SetParams(CTGitPath(sPath), SVNRev(), SVNRev::REV_HEAD, 1, limit, TRUE);\r
1691                                                         dlg.DoModal();\r
1692                                                 }\r
1693                                                 break;\r
1694                                         case ID_OPENWITH:\r
1695                                                 bOpenWith = true;\r
1696                                         case ID_OPEN:\r
1697                                                 {\r
1698                                                         int ret = 0;\r
1699                                                         CString sWinPath = GetPathFromColumnText(data->sPathColumnText);\r
1700                                                         if (!bOpenWith)\r
1701                                                                 ret = (int)ShellExecute(this->m_hWnd, NULL, (LPCTSTR)sWinPath, NULL, NULL, SW_SHOWNORMAL);\r
1702                                                         if ((ret <= HINSTANCE_ERROR)||bOpenWith)\r
1703                                                         {\r
1704                                                                 CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
1705                                                                 cmd += sWinPath + _T(" ");\r
1706                                                                 CAppUtils::LaunchApplication(cmd, NULL, false);\r
1707                                                         }\r
1708                                                 }\r
1709                                         }\r
1710                                         DialogEnableWindow(IDOK, TRUE);\r
1711                                         theApp.DoWaitCursor(-1);\r
1712                                 } // if (bAdded)\r
1713                         }\r
1714                 }\r
1715         }\r
1716 #endif\r
1717 }\r
1718 \r
1719 void CGitProgressDlg::OnEnSetfocusInfotext()\r
1720 {\r
1721         CString sTemp;\r
1722         GetDlgItemText(IDC_INFOTEXT, sTemp);\r
1723         if (sTemp.IsEmpty())\r
1724                 GetDlgItem(IDC_INFOTEXT)->HideCaret();\r
1725 }\r
1726 \r
1727 void CGitProgressDlg::OnLvnBegindragSvnprogress(NMHDR* , LRESULT *pResult)\r
1728 {\r
1729         //LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);\r
1730 #if 0\r
1731         int selIndex = m_ProgList.GetSelectionMark();\r
1732         if (selIndex < 0)\r
1733                 return;\r
1734 \r
1735         CDropFiles dropFiles; // class for creating DROPFILES struct\r
1736 \r
1737         int index;\r
1738         POSITION pos = m_ProgList.GetFirstSelectedItemPosition();\r
1739         while ( (index = m_ProgList.GetNextSelectedItem(pos)) >= 0 )\r
1740         {\r
1741                 NotificationData * data = m_arData[index];\r
1742 \r
1743                 if ( data->kind==svn_node_file || data->kind==svn_node_dir )\r
1744                 {\r
1745                         CString sPath = GetPathFromColumnText(data->sPathColumnText);\r
1746 \r
1747                         dropFiles.AddFile( sPath );\r
1748                 }\r
1749         }\r
1750 \r
1751         if ( dropFiles.GetCount()>0 )\r
1752         {\r
1753                 dropFiles.CreateStructure();\r
1754         }\r
1755 #endif\r
1756         *pResult = 0;\r
1757 }\r
1758 \r
1759 void CGitProgressDlg::OnSize(UINT nType, int cx, int cy)\r
1760 {\r
1761         CResizableStandAloneDialog::OnSize(nType, cx, cy);\r
1762         if ((nType == SIZE_RESTORED)&&(m_bLastVisible))\r
1763         {\r
1764                 if(!m_ProgList.m_hWnd)\r
1765                         return;\r
1766 \r
1767                 int count = m_ProgList.GetItemCount();\r
1768                 if (count > 0)\r
1769                         m_ProgList.EnsureVisible(count-1, false);\r
1770         }\r
1771 }\r
1772 \r
1773 //////////////////////////////////////////////////////////////////////////\r
1774 /// commands\r
1775 //////////////////////////////////////////////////////////////////////////\r
1776 bool CGitProgressDlg::CmdAdd(CString& sWindowTitle, bool& localoperation)\r
1777 {\r
1778 \r
1779         localoperation = true;\r
1780         sWindowTitle.LoadString(IDS_PROGRS_TITLE_ADD);\r
1781         SetWindowText(sWindowTitle);\r
1782         SetBackgroundImage(IDI_ADD_BKG);\r
1783         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_ADD)));\r
1784 \r
1785         for(int i=0;i<m_targetPathList.GetCount();i++)\r
1786         {\r
1787                 CString cmd,out;\r
1788                 cmd.Format(_T("git.exe add -f \"%s\""),m_targetPathList[i].GetGitPathString());\r
1789                 if(g_Git.Run(cmd,&out,CP_ACP))\r
1790                 {\r
1791                         CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
1792                         m_bErrorsOccurred=true;\r
1793                         return false;\r
1794                 }\r
1795                 Notify(m_targetPathList[i],git_wc_notify_add);\r
1796         }\r
1797 #if 0\r
1798         if (!Add(m_targetPathList, &m_ProjectProperties, svn_depth_empty, FALSE, TRUE, TRUE))\r
1799         {\r
1800                 ReportSVNError();\r
1801                 return false;\r
1802         }\r
1803 #endif\r
1804         //CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList);\r
1805         m_bErrorsOccurred=false;\r
1806         return true;\r
1807 }\r
1808 \r
1809 bool CGitProgressDlg::CmdCheckout(CString& sWindowTitle, bool& /*localoperation*/)\r
1810 {\r
1811 #if 0\r
1812         ASSERT(m_targetPathList.GetCount() == 1);\r
1813         sWindowTitle.LoadString(IDS_PROGRS_TITLE_CHECKOUT);\r
1814         SetBackgroundImage(IDI_CHECKOUT_BKG);\r
1815         CTGitPathList urls;\r
1816         urls.LoadFromAsteriskSeparatedString(m_url.GetSVNPathString());\r
1817         CTGitPath checkoutdir = m_targetPathList[0];\r
1818         for (int i=0; i<urls.GetCount(); ++i)\r
1819         {\r
1820                 sWindowTitle = urls[i].GetUIFileOrDirectoryName()+_T(" - ")+sWindowTitle;\r
1821                 SetWindowText(sWindowTitle);\r
1822                 checkoutdir = m_targetPathList[0];\r
1823                 if (urls.GetCount() > 1)\r
1824                 {\r
1825                         CString fileordir = urls[i].GetFileOrDirectoryName();\r
1826                         fileordir = CPathUtils::PathUnescape(fileordir);\r
1827                         checkoutdir.AppendPathString(fileordir);\r
1828                 }\r
1829                 CString sCmdInfo;\r
1830                 sCmdInfo.Format(IDS_PROGRS_CMD_CHECKOUT, \r
1831                         (LPCTSTR)urls[i].GetSVNPathString(), (LPCTSTR)m_Revision.ToString(), \r
1832                         (LPCTSTR)SVNStatus::GetDepthString(m_depth), \r
1833                         m_options & ProgOptIgnoreExternals ? (LPCTSTR)sExtExcluded : (LPCTSTR)sExtIncluded);\r
1834                 ReportCmd(sCmdInfo);\r
1835 \r
1836                 if (!Checkout(urls[i], checkoutdir, m_Revision, m_Revision, m_depth, m_options & ProgOptIgnoreExternals))\r
1837                 {\r
1838                         if (m_ProgList.GetItemCount()!=0)\r
1839                         {\r
1840                                 ReportSVNError();\r
1841                                 return false;\r
1842                         }\r
1843                         // if the checkout fails with the peg revision set to the checkout revision,\r
1844                         // try again with HEAD as the peg revision.\r
1845                         else\r
1846                         {\r
1847                                 if (!Checkout(urls[i], checkoutdir, SVNRev::REV_HEAD, m_Revision, m_depth, m_options & ProgOptIgnoreExternals))\r
1848                                 {\r
1849                                         ReportSVNError();\r
1850                                         return false;\r
1851                                 }\r
1852                         }\r
1853                 }\r
1854         }\r
1855 #endif\r
1856         return true;\r
1857 }\r
1858 \r
1859 bool CGitProgressDlg::CmdCommit(CString& sWindowTitle, bool& /*localoperation*/)\r
1860 {\r
1861 #if 0\r
1862         sWindowTitle.LoadString(IDS_PROGRS_TITLE_COMMIT);\r
1863         SetWindowText(sWindowTitle);\r
1864         SetBackgroundImage(IDI_COMMIT_BKG);\r
1865         if (m_targetPathList.GetCount()==0)\r
1866         {\r
1867                 SetWindowText(sWindowTitle);\r
1868 \r
1869                 DialogEnableWindow(IDCANCEL, FALSE);\r
1870                 DialogEnableWindow(IDOK, TRUE);\r
1871 \r
1872                 InterlockedExchange(&m_bThreadRunning, FALSE);\r
1873                 return true;\r
1874         }\r
1875         if (m_targetPathList.GetCount()==1)\r
1876         {\r
1877                 sWindowTitle = m_targetPathList[0].GetUIFileOrDirectoryName()+_T(" - ")+sWindowTitle;\r
1878                 SetWindowText(sWindowTitle);\r
1879         }\r
1880         BOOL isTag = FALSE;\r
1881         BOOL bURLFetched = FALSE;\r
1882         CString url;\r
1883         for (int i=0; i<m_targetPathList.GetCount(); ++i)\r
1884         {\r
1885                 if (bURLFetched == FALSE)\r
1886                 {\r
1887                         url = GetURLFromPath(m_targetPathList[i]);\r
1888                         if (!url.IsEmpty())\r
1889                                 bURLFetched = TRUE;\r
1890                         CString urllower = url;\r
1891                         urllower.MakeLower();\r
1892                         // test if the commit goes to a tag.\r
1893                         // now since Subversion doesn't force users to\r
1894                         // create tags in the recommended /tags/ folder\r
1895                         // only a warning is shown. This won't work if the tags\r
1896                         // are stored in a non-recommended place, but the check\r
1897                         // still helps those who do.\r
1898                         if (urllower.Find(_T("/tags/"))>=0)\r
1899                                 isTag = TRUE;\r
1900                         break;\r
1901                 }\r
1902         }\r
1903         if (isTag)\r
1904         {\r
1905                 if (CMessageBox::Show(m_hWnd, IDS_PROGRS_COMMITT_TRUNK, IDS_APPNAME, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION)==IDNO)\r
1906                         return false;\r
1907         }\r
1908         DWORD exitcode = 0;\r
1909         CString error;\r
1910         if (CHooks::Instance().PreCommit(m_selectedPaths, m_depth, m_sMessage, exitcode, error))\r
1911         {\r
1912                 if (exitcode)\r
1913                 {\r
1914                         CString temp;\r
1915                         temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);\r
1916                         ReportError(temp);\r
1917                         return false;\r
1918                 }\r
1919         }\r
1920 \r
1921         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_COMMIT)));\r
1922         CStringArray changelists;\r
1923     if (!m_changelist.IsEmpty())\r
1924             changelists.Add(m_changelist);\r
1925         bool commitSuccessful = true;\r
1926         if (!Commit(m_targetPathList, m_sMessage, changelists, m_keepchangelist, \r
1927                 m_depth, m_options & ProgOptKeeplocks))\r
1928         {\r
1929                 ReportSVNError();\r
1930                 error = GetLastErrorMessage();\r
1931                 // if a non-recursive commit failed with SVN_ERR_UNSUPPORTED_FEATURE,\r
1932                 // that means a folder deletion couldn't be committed.\r
1933                 if ((m_Revision != 0)&&(Err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))\r
1934                 {\r
1935                         ReportError(CString(MAKEINTRESOURCE(IDS_PROGRS_NONRECURSIVEHINT)));\r
1936                 }\r
1937                 commitSuccessful = false;\r
1938                 return false;\r
1939         }\r
1940         if (!PostCommitErr.IsEmpty())\r
1941         {\r
1942                 ReportWarning(PostCommitErr);\r
1943         }\r
1944         if (commitSuccessful)\r
1945         {\r
1946                 if (m_BugTraqProvider)\r
1947                 {\r
1948                         CComPtr<IBugTraqProvider2> pProvider = NULL;\r
1949                         HRESULT hr = m_BugTraqProvider.QueryInterface(&pProvider);\r
1950                         if (SUCCEEDED(hr))\r
1951                         {\r
1952                                 BSTR commonRoot = SysAllocString(m_targetPathList.GetCommonRoot().GetDirectory().GetWinPath());\r
1953                                 SAFEARRAY *pathList = SafeArrayCreateVector(VT_BSTR, 0, m_targetPathList.GetCount());\r
1954 \r
1955                                 for (LONG index = 0; index < m_targetPathList.GetCount(); ++index)\r
1956                                         SafeArrayPutElement(pathList, &index, m_targetPathList[index].GetSVNPathString().AllocSysString());\r
1957 \r
1958                                 BSTR logMessage = m_sMessage.AllocSysString();\r
1959 \r
1960                                 BSTR temp = NULL;\r
1961                                 if (FAILED(hr = pProvider->OnCommitFinished(GetSafeHwnd(), \r
1962                                         commonRoot,\r
1963                                         pathList,\r
1964                                         logMessage,\r
1965                                         (LONG)m_RevisionEnd,\r
1966                                         &temp)))\r
1967                                 {\r
1968                                         CString sErr = temp;\r
1969                                         if (!sErr.IsEmpty())\r
1970                                                 ReportError(temp);\r
1971                                 }\r
1972 \r
1973                                 SysFreeString(temp);\r
1974                         }\r
1975                 }\r
1976         }\r
1977         if (CHooks::Instance().PostCommit(m_selectedPaths, m_depth, m_RevisionEnd, m_sMessage, exitcode, error))\r
1978         {\r
1979                 if (exitcode)\r
1980                 {\r
1981                         CString temp;\r
1982                         temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);\r
1983                         ReportError(temp);\r
1984                         return false;\r
1985                 }\r
1986         }\r
1987 #endif\r
1988         return true;\r
1989 }\r
1990 \r
1991 bool CGitProgressDlg::CmdCopy(CString& sWindowTitle, bool& /*localoperation*/)\r
1992 {\r
1993 #if 0\r
1994         ASSERT(m_targetPathList.GetCount() == 1);\r
1995         sWindowTitle.LoadString(IDS_PROGRS_TITLE_COPY);\r
1996         SetWindowText(sWindowTitle);\r
1997         SetBackgroundImage(IDI_COPY_BKG);\r
1998 \r
1999         CString sCmdInfo;\r
2000         sCmdInfo.Format(IDS_PROGRS_CMD_COPY, \r
2001                 m_targetPathList[0].IsUrl() ? (LPCTSTR)m_targetPathList[0].GetSVNPathString() : m_targetPathList[0].GetWinPath(),\r
2002                 (LPCTSTR)m_url.GetSVNPathString(), (LPCTSTR)m_Revision.ToString());\r
2003         ReportCmd(sCmdInfo);\r
2004 \r
2005         if (!Copy(m_targetPathList, m_url, m_Revision, m_pegRev, m_sMessage))\r
2006         {\r
2007                 ReportSVNError();\r
2008                 return false;\r
2009         }\r
2010         if (m_options & ProgOptSwitchAfterCopy)\r
2011         {\r
2012                 sCmdInfo.Format(IDS_PROGRS_CMD_SWITCH, \r
2013                         m_targetPathList[0].GetWinPath(),\r
2014                         (LPCTSTR)m_url.GetSVNPathString(), (LPCTSTR)m_Revision.ToString());\r
2015                 ReportCmd(sCmdInfo);\r
2016                 if (!Switch(m_targetPathList[0], m_url, SVNRev::REV_HEAD, SVNRev::REV_HEAD, m_depth, TRUE, m_options & ProgOptIgnoreExternals))\r
2017                 {\r
2018                         if (!Switch(m_targetPathList[0], m_url, SVNRev::REV_HEAD, m_Revision, m_depth, TRUE, m_options & ProgOptIgnoreExternals))\r
2019                         {\r
2020                                 ReportSVNError();\r
2021                                 return false;\r
2022                         }\r
2023                 }\r
2024         }\r
2025         else\r
2026         {\r
2027                 if (SVN::PathIsURL(m_url))\r
2028                 {\r
2029                         CString sMsg(MAKEINTRESOURCE(IDS_PROGRS_COPY_WARNING));\r
2030                         ReportNotification(sMsg);\r
2031                 }\r
2032         }\r
2033 #endif\r
2034         return true;\r
2035 }\r
2036 \r
2037 bool CGitProgressDlg::CmdExport(CString& sWindowTitle, bool& /*localoperation*/)\r
2038 {\r
2039 #if 0\r
2040         ASSERT(m_targetPathList.GetCount() == 1);\r
2041         sWindowTitle.LoadString(IDS_PROGRS_TITLE_EXPORT);\r
2042         sWindowTitle = m_url.GetUIFileOrDirectoryName()+_T(" - ")+sWindowTitle;\r
2043         SetWindowText(sWindowTitle);\r
2044         SetBackgroundImage(IDI_EXPORT_BKG);\r
2045         CString eol;\r
2046         if (m_options & ProgOptEolCRLF)\r
2047                 eol = _T("CRLF");\r
2048         if (m_options & ProgOptEolLF)\r
2049                 eol = _T("LF");\r
2050         if (m_options & ProgOptEolCR)\r
2051                 eol = _T("CR");\r
2052         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_EXPORT)));\r
2053         if (!Export(m_url, m_targetPathList[0], m_Revision, m_Revision, TRUE, m_options & ProgOptIgnoreExternals, m_depth, NULL, FALSE, eol))\r
2054         {\r
2055                 ReportSVNError();\r
2056                 return false;\r
2057         }\r
2058 #endif\r
2059         return true;\r
2060 }\r
2061 \r
2062 bool CGitProgressDlg::CmdImport(CString& sWindowTitle, bool& /*localoperation*/)\r
2063 {\r
2064 #if 0\r
2065         ASSERT(m_targetPathList.GetCount() == 1);\r
2066         sWindowTitle.LoadString(IDS_PROGRS_TITLE_IMPORT);\r
2067         sWindowTitle = m_targetPathList[0].GetUIFileOrDirectoryName()+_T(" - ")+sWindowTitle;\r
2068         SetWindowText(sWindowTitle);\r
2069         SetBackgroundImage(IDI_IMPORT_BKG);\r
2070         CString sCmdInfo;\r
2071         sCmdInfo.Format(IDS_PROGRS_CMD_IMPORT, \r
2072                 m_targetPathList[0].GetWinPath(), (LPCTSTR)m_url.GetSVNPathString(), \r
2073                 m_options & ProgOptIncludeIgnored ? (LPCTSTR)(_T(", ") + sIgnoredIncluded) : _T(""));\r
2074         ReportCmd(sCmdInfo);\r
2075         if (!Import(m_targetPathList[0], m_url, m_sMessage, &m_ProjectProperties, svn_depth_infinity, m_options & ProgOptIncludeIgnored ? true : false, false))\r
2076         {\r
2077                 ReportSVNError();\r
2078                 return false;\r
2079         }\r
2080 #endif\r
2081         return true;\r
2082 }\r
2083 \r
2084 bool CGitProgressDlg::CmdLock(CString& sWindowTitle, bool& /*localoperation*/)\r
2085 {\r
2086 #if 0\r
2087         sWindowTitle.LoadString(IDS_PROGRS_TITLE_LOCK);\r
2088         SetWindowText(sWindowTitle);\r
2089         SetBackgroundImage(IDI_LOCK_BKG);\r
2090         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_LOCK)));\r
2091         if (!Lock(m_targetPathList, m_options & ProgOptLockForce, m_sMessage))\r
2092         {\r
2093                 ReportSVNError();\r
2094                 return false;\r
2095         }\r
2096         CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList);\r
2097         if (m_bLockWarning)\r
2098         {\r
2099                 // the lock failed, because the file was outdated.\r
2100                 // ask the user whether to update the file and try again\r
2101                 if (CMessageBox::Show(m_hWnd, IDS_WARN_LOCKOUTDATED, IDS_APPNAME, MB_ICONQUESTION|MB_YESNO)==IDYES)\r
2102                 {\r
2103                         ReportString(CString(MAKEINTRESOURCE(IDS_SVNPROGRESS_UPDATEANDRETRY)), CString(MAKEINTRESOURCE(IDS_WARN_NOTE)));\r
2104                         if (!Update(m_targetPathList, SVNRev::REV_HEAD, svn_depth_files, false, true))\r
2105                         {\r
2106                                 ReportSVNError();\r
2107                                 return false;\r
2108                         }\r
2109                         if (!Lock(m_targetPathList, m_options & ProgOptLockForce, m_sMessage))\r
2110                         {\r
2111                                 ReportSVNError();\r
2112                                 return false;\r
2113                         }\r
2114                 }\r
2115         }\r
2116         if (m_bLockExists)\r
2117         {\r
2118                 // the locking failed because there already is a lock.\r
2119                 // if the locking-dialog is skipped in the settings, tell the\r
2120                 // user how to steal the lock anyway (i.e., how to get the lock\r
2121                 // dialog back without changing the settings)\r
2122                 if (!DWORD(CRegDWORD(_T("Software\\TortoiseGit\\ShowLockDlg"), TRUE)))\r
2123                 {\r
2124                         ReportString(CString(MAKEINTRESOURCE(IDS_SVNPROGRESS_LOCKHINT)), CString(MAKEINTRESOURCE(IDS_WARN_NOTE)));\r
2125                 }\r
2126                 return false;\r
2127         }\r
2128 #endif\r
2129         return true;\r
2130 }\r
2131 \r
2132 bool CGitProgressDlg::CmdMerge(CString& sWindowTitle, bool& /*localoperation*/)\r
2133 {\r
2134 #if 0\r
2135         bool bFailed = false;\r
2136         ASSERT(m_targetPathList.GetCount() == 1);\r
2137         sWindowTitle.LoadString(IDS_PROGRS_TITLE_MERGE);\r
2138         SetBackgroundImage(IDI_MERGE_BKG);\r
2139         if (m_options & ProgOptDryRun)\r
2140         {\r
2141                 sWindowTitle += _T(" ") + sDryRun;\r
2142         }\r
2143         if (m_options & ProgOptRecordOnly)\r
2144         {\r
2145                 sWindowTitle += _T(" ") + sRecordOnly;\r
2146         }\r
2147         SetWindowText(sWindowTitle);\r
2148 \r
2149         GetDlgItem(IDC_INFOTEXT)->ShowWindow(SW_HIDE);\r
2150         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_SHOW);\r
2151         CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE);\r
2152         if (DWORD(nonint))\r
2153         {\r
2154                 ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_SETCHECK, BST_CHECKED, 0);\r
2155                 m_AlwaysConflicted = true;\r
2156         }\r
2157         // we only accept a revision list to merge for peg merges\r
2158         ATLASSERT((m_revisionArray.GetCount()==0) || (m_revisionArray.GetCount() && (m_url.IsEquivalentTo(m_url2))));\r
2159 \r
2160         if (m_url.IsEquivalentTo(m_url2))\r
2161         {\r
2162                 CString sSuggestedMessage;\r
2163                 CString sMergedLogMessage;\r
2164                 CString sSeparator = CRegString(_T("Software\\TortoiseGit\\MergeLogSeparator"), _T("........"));\r
2165                 CString temp;\r
2166 \r
2167                 // Merging revisions %s of %s to %s into %s, %s%s\r
2168                 CString sCmdInfo;\r
2169                 sCmdInfo.Format(IDS_PROGRS_CMD_MERGEPEG, \r
2170                         (LPCTSTR)m_revisionArray.ToListString(),\r
2171                         (LPCTSTR)m_url.GetSVNPathString(),\r
2172                         m_targetPathList[0].GetWinPath(),\r
2173                         m_options & ProgOptIgnoreAncestry ? (LPCTSTR)sIgnoreAncestry : (LPCTSTR)sRespectAncestry,\r
2174                         m_options & ProgOptDryRun ? ((LPCTSTR)_T(", ") + sDryRun) : _T(""));\r
2175                 ReportCmd(sCmdInfo);\r
2176 \r
2177                 if (!PegMerge(m_url, m_revisionArray, \r
2178                         m_pegRev.IsValid() ? m_pegRev : (m_url.IsUrl() ? SVNRev::REV_HEAD : SVNRev(SVNRev::REV_WC)),\r
2179                         m_targetPathList[0], true, m_depth, m_diffoptions, !!(m_options & ProgOptIgnoreAncestry), !!(m_options & ProgOptDryRun), !!(m_options & ProgOptRecordOnly)))\r
2180                 {\r
2181                         // if the merge fails with the peg revision set,\r
2182                         // try again with HEAD as the peg revision.\r
2183                         if (!PegMerge(m_url, m_revisionArray, SVNRev::REV_HEAD,\r
2184                                 m_targetPathList[0], true, m_depth, m_diffoptions, !!(m_options & ProgOptIgnoreAncestry), !!(m_options & ProgOptDryRun), !!(m_options & ProgOptRecordOnly)))\r
2185                         {\r
2186                                 ReportSVNError();\r
2187                                 bFailed = true;\r
2188                         }\r
2189                 }\r
2190         }\r
2191         else\r
2192         {\r
2193                 CString sCmdInfo;\r
2194                 sCmdInfo.Format(IDS_PROGRS_CMD_MERGEURL, \r
2195                         (LPCTSTR)m_url.GetSVNPathString(), (LPCTSTR)m_Revision.ToString(), \r
2196                         (LPCTSTR)m_url2.GetSVNPathString(), (LPCTSTR)m_RevisionEnd.ToString(),\r
2197                         m_targetPathList[0].GetWinPath(),\r
2198                         m_options & ProgOptIgnoreAncestry ? (LPCTSTR)sIgnoreAncestry : (LPCTSTR)sRespectAncestry,\r
2199                         m_options & ProgOptDryRun ? ((LPCTSTR)_T(", ") + sDryRun) : _T(""));\r
2200                 ReportCmd(sCmdInfo);\r
2201 \r
2202                 if (!Merge(m_url, m_Revision, m_url2, m_RevisionEnd, m_targetPathList[0], \r
2203                         true, m_depth, m_diffoptions, !!(m_options & ProgOptIgnoreAncestry), !!(m_options & ProgOptDryRun), !!(m_options & ProgOptRecordOnly)))\r
2204                 {\r
2205                         ReportSVNError();\r
2206                         bFailed = true;\r
2207                 }\r
2208         }\r
2209         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_HIDE);\r
2210         GetDlgItem(IDC_INFOTEXT)->ShowWindow(SW_SHOW);\r
2211         return !bFailed;\r
2212 #endif\r
2213         return true;\r
2214 }\r
2215 \r
2216 bool CGitProgressDlg::CmdMergeAll(CString& sWindowTitle, bool& /*localoperation*/)\r
2217 {\r
2218 #if 0\r
2219         ASSERT(m_targetPathList.GetCount() == 1);\r
2220         sWindowTitle.LoadString(IDS_PROGRS_TITLE_MERGE);\r
2221         SetBackgroundImage(IDI_MERGE_BKG);\r
2222         SetWindowText(sWindowTitle);\r
2223 \r
2224         ATLASSERT(m_targetPathList.GetCount() == 1);\r
2225 \r
2226         CString sCmdInfo;\r
2227         sCmdInfo.LoadString(IDS_PROGRS_INFOGETTINGINFO);\r
2228         ReportCmd(sCmdInfo);\r
2229         CTGitPathList suggestedSources;\r
2230         if (!SuggestMergeSources(m_targetPathList[0], m_Revision, suggestedSources))\r
2231         {\r
2232                 ReportSVNError();\r
2233                 return false;\r
2234         }\r
2235 \r
2236         if (suggestedSources.GetCount() == 0)\r
2237         {\r
2238                 CString sErr;\r
2239                 sErr.Format(IDS_PROGRS_MERGEALLNOSOURCES, m_targetPathList[0].GetWinPath());\r
2240                 ReportError(sErr);\r
2241                 return false;\r
2242         }\r
2243         sCmdInfo.Format(IDS_PROGRS_CMD_MERGEALL, \r
2244                 (LPCTSTR)suggestedSources[0].GetSVNPathString(),\r
2245                 m_targetPathList[0].GetWinPath(),\r
2246                 m_options & ProgOptIgnoreAncestry ? (LPCTSTR)sIgnoreAncestry : (LPCTSTR)sRespectAncestry);\r
2247         ReportCmd(sCmdInfo);\r
2248 \r
2249         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_SHOW);\r
2250         CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE);\r
2251         if (DWORD(nonint))\r
2252         {\r
2253                 ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_SETCHECK, BST_CHECKED, 0);\r
2254                 m_AlwaysConflicted = true;\r
2255         }\r
2256 \r
2257         SVNRevRangeArray revarray;\r
2258         if (!PegMerge(suggestedSources[0], revarray, \r
2259                 SVNRev::REV_HEAD,\r
2260                 m_targetPathList[0], true, m_depth, m_diffoptions, !!(m_options & ProgOptIgnoreAncestry), FALSE))\r
2261         {\r
2262                 GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_HIDE);\r
2263                 ReportSVNError();\r
2264                 return false;\r
2265         }\r
2266 \r
2267         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_HIDE);\r
2268 #endif\r
2269         return true;\r
2270 }\r
2271 \r
2272 bool CGitProgressDlg::CmdMergeReintegrate(CString& sWindowTitle, bool& /*localoperation*/)\r
2273 {\r
2274 #if 0\r
2275         ASSERT(m_targetPathList.GetCount() == 1);\r
2276         sWindowTitle.LoadString(IDS_PROGRS_TITLE_MERGEREINTEGRATE);\r
2277         SetBackgroundImage(IDI_MERGE_BKG);\r
2278         SetWindowText(sWindowTitle);\r
2279 \r
2280         CString sCmdInfo;\r
2281         sCmdInfo.Format(IDS_PROGRS_CMD_MERGEREINTEGRATE, \r
2282                 (LPCTSTR)m_url.GetSVNPathString(),\r
2283                 m_targetPathList[0].GetWinPath());\r
2284         ReportCmd(sCmdInfo);\r
2285 \r
2286         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_SHOW);\r
2287         CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE);\r
2288         if (DWORD(nonint))\r
2289         {\r
2290                 ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_SETCHECK, BST_CHECKED, 0);\r
2291                 m_AlwaysConflicted = true;\r
2292         }\r
2293 \r
2294         if (!MergeReintegrate(m_url, SVNRev::REV_HEAD, m_targetPathList[0], !!(m_options & ProgOptDryRun), m_diffoptions))\r
2295         {\r
2296                 ReportSVNError();\r
2297                 GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_HIDE);\r
2298                 return false;\r
2299         }\r
2300 \r
2301         GetDlgItem(IDC_NONINTERACTIVE)->ShowWindow(SW_HIDE);\r
2302 #endif\r
2303         return true;\r
2304 }\r
2305 \r
2306 bool CGitProgressDlg::CmdRename(CString& sWindowTitle, bool& localoperation)\r
2307 {\r
2308 #if 0\r
2309         ASSERT(m_targetPathList.GetCount() == 1);\r
2310         if ((!m_targetPathList[0].IsUrl())&&(!m_url.IsUrl()))\r
2311                 localoperation = true;\r
2312         sWindowTitle.LoadString(IDS_PROGRS_TITLE_RENAME);\r
2313         SetWindowText(sWindowTitle);\r
2314         SetBackgroundImage(IDI_RENAME_BKG);\r
2315         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_RENAME)));\r
2316         if (!Move(m_targetPathList, m_url, m_Revision, m_sMessage))\r
2317         {\r
2318                 ReportSVNError();\r
2319                 return false;\r
2320         }\r
2321 #endif\r
2322         return true;\r
2323 }\r
2324 \r
2325 bool CGitProgressDlg::CmdResolve(CString& sWindowTitle, bool& localoperation)\r
2326 {\r
2327 \r
2328         localoperation = true;\r
2329         ASSERT(m_targetPathList.GetCount() == 1);\r
2330         sWindowTitle.LoadString(IDS_PROGRS_TITLE_RESOLVE);\r
2331         SetWindowText(sWindowTitle);\r
2332         SetBackgroundImage(IDI_RESOLVE_BKG);\r
2333         // check if the file may still have conflict markers in it.\r
2334         BOOL bMarkers = FALSE;\r
2335 \r
2336         for(int i=0;i<m_targetPathList.GetCount();i++)\r
2337         {\r
2338                 CString cmd,out,tempmergefile;\r
2339                 cmd.Format(_T("git.exe add -f \"%s\""),m_targetPathList[i].GetGitPathString());\r
2340                 if(g_Git.Run(cmd,&out,CP_ACP))\r
2341                 {\r
2342                         CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
2343                         m_bErrorsOccurred=true;\r
2344                         return false;\r
2345                 }\r
2346                 \r
2347 \r
2348                 try\r
2349                 {\r
2350                         tempmergefile = CAppUtils::GetMergeTempFile(_T("LOCAL"),(CTGitPath &)m_targetPathList[i]);\r
2351                         CFile::Remove(tempmergefile);\r
2352                 }catch(...)\r
2353                 {\r
2354                 }\r
2355                 \r
2356                 try\r
2357                 {\r
2358                         tempmergefile = CAppUtils::GetMergeTempFile(_T("REMOTE"),(CTGitPath &)m_targetPathList[i]);\r
2359                         CFile::Remove(tempmergefile);\r
2360                 }catch(...)\r
2361                 {\r
2362                 }\r
2363 \r
2364                 try\r
2365                 {\r
2366                         tempmergefile = CAppUtils::GetMergeTempFile(_T("BASE"),(CTGitPath &)m_targetPathList[i]);\r
2367                         CFile::Remove(tempmergefile);\r
2368                 }catch(...)\r
2369                 {\r
2370                 }\r
2371                 \r
2372 \r
2373                 Notify(m_targetPathList[i],git_wc_notify_resolved);\r
2374         }\r
2375 #if 0\r
2376         if ((m_options & ProgOptSkipConflictCheck) == 0)\r
2377         {\r
2378                 try\r
2379                 {\r
2380                         for (INT_PTR fileindex=0; (fileindex<m_targetPathList.GetCount()) && (bMarkers==FALSE); ++fileindex)\r
2381                         {\r
2382                                 if (!m_targetPathList[fileindex].IsDirectory())\r
2383                                 {\r
2384                                         CStdioFile file(m_targetPathList[fileindex].GetWinPath(), CFile::typeBinary | CFile::modeRead);\r
2385                                         CString strLine = _T("");\r
2386                                         while (file.ReadString(strLine))\r
2387                                         {\r
2388                                                 if (strLine.Find(_T("<<<<<<<"))==0)\r
2389                                                 {\r
2390                                                         bMarkers = TRUE;\r
2391                                                         break;\r
2392                                                 }\r
2393                                         }\r
2394                                         file.Close();\r
2395                                 }\r
2396                         }\r
2397                 } \r
2398                 catch (CFileException* pE)\r
2399                 {\r
2400                         TRACE(_T("CFileException in Resolve!\n"));\r
2401                         TCHAR error[10000] = {0};\r
2402                         pE->GetErrorMessage(error, 10000);\r
2403                         ReportError(error);\r
2404                         pE->Delete();\r
2405                         return false;\r
2406                 }\r
2407         }\r
2408         if (bMarkers)\r
2409         {\r
2410                 if (CMessageBox::Show(m_hWnd, IDS_PROGRS_REVERTMARKERS, IDS_APPNAME, MB_YESNO | MB_ICONQUESTION)==IDYES)\r
2411                 {\r
2412                         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_RESOLVE)));\r
2413                         for (INT_PTR fileindex=0; fileindex<m_targetPathList.GetCount(); ++fileindex)\r
2414                                 Resolve(m_targetPathList[fileindex], svn_wc_conflict_choose_merged, true);\r
2415                 }\r
2416         }\r
2417         else\r
2418         {\r
2419                 ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_RESOLVE)));\r
2420                 for (INT_PTR fileindex=0; fileindex<m_targetPathList.GetCount(); ++fileindex)\r
2421                         Resolve(m_targetPathList[fileindex], svn_wc_conflict_choose_merged, true);\r
2422         }\r
2423 #endif\r
2424         CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList);\r
2425 \r
2426         return true;\r
2427 }\r
2428 \r
2429 bool CGitProgressDlg::CmdRevert(CString& sWindowTitle, bool& localoperation)\r
2430 {\r
2431 #if 0\r
2432         localoperation = true;\r
2433         sWindowTitle.LoadString(IDS_PROGRS_TITLE_REVERT);\r
2434         SetWindowText(sWindowTitle);\r
2435         SetBackgroundImage(IDI_REVERT_BKG);\r
2436 \r
2437         CTGitPathList delList = m_selectedPaths;\r
2438         if (DWORD(CRegDWORD(_T("Software\\TortoiseGit\\RevertWithRecycleBin"), TRUE)))\r
2439                 delList.DeleteAllFiles(true);\r
2440 \r
2441         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_REVERT)));\r
2442         if (!Revert(m_targetPathList, CStringArray(), !!(m_options & ProgOptRecursive)))\r
2443         {\r
2444                 ReportSVNError();\r
2445                 return false;\r
2446         }\r
2447         CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList);\r
2448 #endif\r
2449         return true;\r
2450 }\r
2451 \r
2452 bool CGitProgressDlg::CmdSwitch(CString& sWindowTitle, bool& /*localoperation*/)\r
2453 {\r
2454 #if 0\r
2455         ASSERT(m_targetPathList.GetCount() == 1);\r
2456         SVNStatus st;\r
2457         sWindowTitle.LoadString(IDS_PROGRS_TITLE_SWITCH);\r
2458         SetWindowText(sWindowTitle);\r
2459         SetBackgroundImage(IDI_SWITCH_BKG);\r
2460         LONG rev = 0;\r
2461         if (st.GetStatus(m_targetPathList[0]) != (-2))\r
2462         {\r
2463                 if (st.status->entry != NULL)\r
2464                 {\r
2465                         rev = st.status->entry->revision;\r
2466                 }\r
2467         }\r
2468 \r
2469         CString sCmdInfo;\r
2470         sCmdInfo.Format(IDS_PROGRS_CMD_SWITCH, \r
2471                 m_targetPathList[0].GetWinPath(), (LPCTSTR)m_url.GetSVNPathString(),\r
2472                 (LPCTSTR)m_Revision.ToString());\r
2473         ReportCmd(sCmdInfo);\r
2474 \r
2475         bool depthIsSticky = true;\r
2476         if (m_depth == svn_depth_unknown)\r
2477                 depthIsSticky = false;\r
2478         if (!Switch(m_targetPathList[0], m_url, m_Revision, m_Revision, m_depth, depthIsSticky, m_options & ProgOptIgnoreExternals))\r
2479         {\r
2480                 ReportSVNError();\r
2481                 return false;\r
2482         }\r
2483         m_UpdateStartRevMap[m_targetPathList[0].GetSVNApiPath(pool)] = rev;\r
2484         if ((m_RevisionEnd >= 0)&&(rev >= 0)\r
2485                 &&((LONG)m_RevisionEnd > (LONG)rev))\r
2486         {\r
2487                 GetDlgItem(IDC_LOGBUTTON)->ShowWindow(SW_SHOW);\r
2488         }\r
2489 #endif\r
2490         return true;\r
2491 }\r
2492 \r
2493 bool CGitProgressDlg::CmdUnlock(CString& sWindowTitle, bool& /*localoperation*/)\r
2494 {\r
2495 #if 0\r
2496         sWindowTitle.LoadString(IDS_PROGRS_TITLE_UNLOCK);\r
2497         SetWindowText(sWindowTitle);\r
2498         SetBackgroundImage(IDI_UNLOCK_BKG);\r
2499         ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_UNLOCK)));\r
2500         if (!Unlock(m_targetPathList, m_options & ProgOptLockForce))\r
2501         {\r
2502                 ReportSVNError();\r
2503                 return false;\r
2504         }\r
2505         CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList);\r
2506 #endif\r
2507         return true;\r
2508 }\r
2509 \r
2510 bool CGitProgressDlg::CmdUpdate(CString& sWindowTitle, bool& /*localoperation*/)\r