From 05026a570063d272a18542298e8164f59e0aca87 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 14 Feb 2013 11:49:14 +0800 Subject: [PATCH] GitProgressDlg: Move most part of function to GitProgressList Create GitProgressList control to finish real task. So GitProgressList can be shared in other dialog. But OnCreate function is not called in this commit Signed-off-by: Frank Li Signed-off-by: Sven Strickroth --- src/Git/GitStatusListCtrl.cpp | 2 +- src/TortoiseProc/AppUtils.cpp | 4 +- src/TortoiseProc/Commands/AddCommand.cpp | 3 +- src/TortoiseProc/Commands/CloneCommand.cpp | 4 +- src/TortoiseProc/Commands/DropCopyAddCommand.cpp | 2 +- src/TortoiseProc/Commands/ResolveCommand.cpp | 4 +- src/TortoiseProc/Commands/RevertCommand.cpp | 3 +- src/TortoiseProc/GitProgressDlg.cpp | 2918 ++------------------ src/TortoiseProc/GitProgressDlg.h | 527 +--- .../{GitProgressDlg.cpp => GitProgressList.cpp} | 729 ++--- .../{GitProgressDlg.h => GitProgressList.h} | 111 +- src/TortoiseProc/MassiveGitTask.cpp | 2 +- src/TortoiseProc/MassiveGitTask.h | 8 +- src/TortoiseProc/TortoiseProc.vcxproj | 2 + src/TortoiseProc/TortoiseProc.vcxproj.filters | 6 + 15 files changed, 754 insertions(+), 3571 deletions(-) rewrite src/TortoiseProc/GitProgressDlg.cpp (91%) rewrite src/TortoiseProc/GitProgressDlg.h (77%) copy src/TortoiseProc/{GitProgressDlg.cpp => GitProgressList.cpp} (80%) copy src/TortoiseProc/{GitProgressDlg.h => GitProgressList.h} (83%) diff --git a/src/Git/GitStatusListCtrl.cpp b/src/Git/GitStatusListCtrl.cpp index c74c83604..7af929252 100644 --- a/src/Git/GitStatusListCtrl.cpp +++ b/src/Git/GitStatusListCtrl.cpp @@ -1978,7 +1978,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point) FillListOfSelectedItemPaths(paths, true); CGitProgressDlg progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_Add); + progDlg.SetCommand(CGitProgressList::GitProgress_Add); progDlg.SetPathList(paths); progDlg.SetItemCount(paths.GetCount()); progDlg.DoModal(); diff --git a/src/TortoiseProc/AppUtils.cpp b/src/TortoiseProc/AppUtils.cpp index 7394d3f68..8f173c37b 100644 --- a/src/TortoiseProc/AppUtils.cpp +++ b/src/TortoiseProc/AppUtils.cpp @@ -2002,7 +2002,7 @@ bool CAppUtils::SendPatchMail(CTGitPathList &list,bool autoclose) CGitProgressDlg progDlg; theApp.m_pMainWnd = &progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_SendMail); + progDlg.SetCommand(CGitProgressList::GitProgress_SendMail); progDlg.SetAutoClose(autoclose); @@ -2228,7 +2228,7 @@ bool CAppUtils::Fetch(CString remoteName, bool allowRebase, bool autoClose) CGitProgressDlg gitdlg; if (!dlg.m_bAllRemotes) gitdlg.SetUrl(url); - gitdlg.SetCommand(CGitProgressDlg::GitProgress_Fetch); + gitdlg.SetCommand(CGitProgressList::GitProgress_Fetch); gitdlg.SetAutoTag(dlg.m_bFetchTags ? GIT_REMOTE_DOWNLOAD_TAGS_ALL : GIT_REMOTE_DOWNLOAD_TAGS_NONE); if (!dlg.m_bAllRemotes) gitdlg.SetRefSpec(dlg.m_RemoteBranchName); diff --git a/src/TortoiseProc/Commands/AddCommand.cpp b/src/TortoiseProc/Commands/AddCommand.cpp index e1a7e59f5..6a4d19823 100644 --- a/src/TortoiseProc/Commands/AddCommand.cpp +++ b/src/TortoiseProc/Commands/AddCommand.cpp @@ -1,5 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control +// Copyright (C) 2008-2013 - TortoiseGit // Copyright (C) 2007-2008 - TortoiseSVN // This program is free software; you can redistribute it and/or @@ -59,7 +60,7 @@ bool AddCommand::Execute() return FALSE; CGitProgressDlg progDlg; theApp.m_pMainWnd = &progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_Add); + progDlg.SetCommand(CGitProgressList::GitProgress_Add); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetPathList(dlg.m_pathList); diff --git a/src/TortoiseProc/Commands/CloneCommand.cpp b/src/TortoiseProc/Commands/CloneCommand.cpp index 94063f054..e76391832 100644 --- a/src/TortoiseProc/Commands/CloneCommand.cpp +++ b/src/TortoiseProc/Commands/CloneCommand.cpp @@ -1,6 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2008-2012 - TortoiseGit +// Copyright (C) 2008-2013 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -151,7 +151,7 @@ bool CloneCommand::Execute() CTGitPathList list; g_Git.m_CurrentDir = dir; list.AddPath(CTGitPath(dir)); - GitDlg.SetCommand(CGitProgressDlg::GitProgress_Clone); + GitDlg.SetCommand(CGitProgressList::GitProgress_Clone); GitDlg.SetUrl(url); GitDlg.SetPathList(list); GitDlg.SetIsBare(!!dlg.m_bBare); diff --git a/src/TortoiseProc/Commands/DropCopyAddCommand.cpp b/src/TortoiseProc/Commands/DropCopyAddCommand.cpp index ed124c05c..404448d82 100644 --- a/src/TortoiseProc/Commands/DropCopyAddCommand.cpp +++ b/src/TortoiseProc/Commands/DropCopyAddCommand.cpp @@ -73,7 +73,7 @@ bool DropCopyAddCommand::Execute() //now add all the newly copied files to the working copy CGitProgressDlg progDlg; theApp.m_pMainWnd = &progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_Add); + progDlg.SetCommand(CGitProgressList::GitProgress_Add); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetPathList(copiedFiles); diff --git a/src/TortoiseProc/Commands/ResolveCommand.cpp b/src/TortoiseProc/Commands/ResolveCommand.cpp index a464f9d1d..10ef2fee1 100644 --- a/src/TortoiseProc/Commands/ResolveCommand.cpp +++ b/src/TortoiseProc/Commands/ResolveCommand.cpp @@ -1,6 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2012 - TortoiseGit +// Copyright (C) 2009-2013 - TortoiseGit // Copyright (C) 2007-2008 - TortoiseSVN // This program is free software; you can redistribute it and/or @@ -55,7 +55,7 @@ bool ResolveCommand::Execute() { CGitProgressDlg progDlg(CWnd::FromHandle(hWndExplorer)); theApp.m_pMainWnd = &progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_Resolve); + progDlg.SetCommand(CGitProgressList::GitProgress_Resolve); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetOptions(parser.HasKey(_T("skipcheck")) ? ProgOptSkipConflictCheck : ProgOptNone); diff --git a/src/TortoiseProc/Commands/RevertCommand.cpp b/src/TortoiseProc/Commands/RevertCommand.cpp index aba2496b9..5c8c9d48c 100644 --- a/src/TortoiseProc/Commands/RevertCommand.cpp +++ b/src/TortoiseProc/Commands/RevertCommand.cpp @@ -1,5 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control +// Copyright (C) 2008-2013 - TortoiseGit // Copyright (C) 2007-2008 - TortoiseSVN // This program is free software; you can redistribute it and/or @@ -34,7 +35,7 @@ bool RevertCommand::Execute() CGitProgressDlg progDlg; theApp.m_pMainWnd = &progDlg; - progDlg.SetCommand(CGitProgressDlg::GitProgress_Revert); + progDlg.SetCommand(CGitProgressList::GitProgress_Revert); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetOptions(dlg.m_bRecursive ? ProgOptRecursive : ProgOptNonRecursive); diff --git a/src/TortoiseProc/GitProgressDlg.cpp b/src/TortoiseProc/GitProgressDlg.cpp dissimilarity index 91% index 77a1d3a2b..3c2cde644 100644 --- a/src/TortoiseProc/GitProgressDlg.cpp +++ b/src/TortoiseProc/GitProgressDlg.cpp @@ -1,2641 +1,277 @@ -// TortoiseGit - a Windows shell extension for easy version control - -// Copyright (C) 2008-2013 - TortoiseGit -// Copyright (C) 2003-2008 - TortoiseSVN - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -#include "stdafx.h" -#include "TortoiseProc.h" -#include "messagebox.h" -#include "GITProgressDlg.h" -#include "LogDlg.h" -#include "TGitPath.h" -#include "registry.h" -#include "GitStatus.h" -#include "AppUtils.h" -#include "PathUtils.h" -#include "StringUtils.h" -#include "TempFile.h" -#include "UnicodeUtils.h" -#include "SoundUtils.h" -#include "GitDiff.h" -#include "Hooks.h" -#include "DropFiles.h" -//#include "GitLogHelper.h" -#include "RegHistory.h" -//#include "ConflictResolveDlg.h" -#include "LogFile.h" -#include "ShellUpdater.h" -#include "IconMenu.h" -#include "BugTraqAssociations.h" -#include "patch.h" -#include "MassiveGitTask.h" -#include "SmartHandle.h" - -static UINT WM_GITPROGRESS = RegisterWindowMessage(_T("TORTOISEGIT_GITPROGRESS_MSG")); - -BOOL CGitProgressDlg::m_bAscending = FALSE; -int CGitProgressDlg::m_nSortedColumn = -1; - -#define TRANSFERTIMER 100 -#define VISIBLETIMER 101 - -enum GITProgressDlgContextMenuCommands -{ - // needs to start with 1, since 0 is the return value if *nothing* is clicked on in the context menu - ID_COMPARE = 1, - ID_EDITCONFLICT, - ID_CONFLICTRESOLVE, - ID_CONFLICTUSETHEIRS, - ID_CONFLICTUSEMINE, - ID_LOG, - ID_OPEN, - ID_OPENWITH, - ID_EXPLORE, - ID_COPY -}; - -IMPLEMENT_DYNAMIC(CGitProgressDlg, CResizableStandAloneDialog) -CGitProgressDlg::CGitProgressDlg(CWnd* pParent /*=NULL*/) - : CResizableStandAloneDialog(CGitProgressDlg::IDD, pParent) - , m_bCancelled(FALSE) - , m_pThread(NULL) - , m_bErrorsOccurred(false) - , m_bBare(false) - , m_bNoCheckout(false) - , m_AutoTag(GIT_REMOTE_DOWNLOAD_TAGS_AUTO) - , m_options(ProgOptNone) -#if 0 - , m_Revision(_T("HEAD")) - //, m_RevisionEnd(0) - , m_bLockWarning(false) - , m_bLockExists(false) - , m_bThreadRunning(FALSE) - , m_nConflicts(0) - , m_bMergesAddsDeletesOccurred(FALSE) - , m_dwCloseOnEnd((DWORD)-1) - , m_bFinishedItemAdded(false) - , m_bLastVisible(false) -// , m_depth(svn_depth_unknown) - , m_itemCount(-1) - , m_itemCountTotal(-1) - , m_AlwaysConflicted(false) - , m_BugTraqProvider(NULL) - , sDryRun(MAKEINTRESOURCE(IDS_PROGRS_DRYRUN)) - , sRecordOnly(MAKEINTRESOURCE(IDS_MERGE_RECORDONLY)) -#endif -{ -} - -CGitProgressDlg::~CGitProgressDlg() -{ - for (size_t i = 0; i < m_arData.size(); ++i) - { - delete m_arData[i]; - } - if(m_pThread != NULL) - { - delete m_pThread; - } -} - -void CGitProgressDlg::DoDataExchange(CDataExchange* pDX) -{ - CResizableStandAloneDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_SVNPROGRESS, m_ProgList); - DDX_Control(pDX, IDC_TITLE_ANIMATE, m_Animate); -} - -BEGIN_MESSAGE_MAP(CGitProgressDlg, CResizableStandAloneDialog) - ON_BN_CLICKED(IDC_LOGBUTTON, OnBnClickedLogbutton) - ON_NOTIFY(NM_CUSTOMDRAW, IDC_SVNPROGRESS, OnNMCustomdrawSvnprogress) - ON_WM_CLOSE() - ON_NOTIFY(NM_DBLCLK, IDC_SVNPROGRESS, OnNMDblclkSvnprogress) - ON_NOTIFY(HDN_ITEMCLICK, 0, OnHdnItemclickSvnprogress) - ON_WM_SETCURSOR() - ON_WM_CONTEXTMENU() - ON_REGISTERED_MESSAGE(WM_GITPROGRESS, OnGitProgress) - ON_WM_TIMER() - ON_EN_SETFOCUS(IDC_INFOTEXT, &CGitProgressDlg::OnEnSetfocusInfotext) - ON_NOTIFY(LVN_BEGINDRAG, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnBegindragSvnprogress) - ON_WM_SIZE() - ON_NOTIFY(LVN_GETDISPINFO, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnGetdispinfoSvnprogress) - ON_BN_CLICKED(IDC_NONINTERACTIVE, &CGitProgressDlg::OnBnClickedNoninteractive) - ON_MESSAGE(WM_SHOWCONFLICTRESOLVER, OnShowConflictResolver) - ON_REGISTERED_MESSAGE(WM_TASKBARBTNCREATED, OnTaskbarBtnCreated) - ON_WM_CTLCOLOR() -END_MESSAGE_MAP() - -BOOL CGitProgressDlg::Cancel() -{ - return m_bCancelled; -} - -LRESULT CGitProgressDlg::OnShowConflictResolver(WPARAM /*wParam*/, LPARAM /*lParam*/) -{ -#if 0 - CConflictResolveDlg dlg(this); - const svn_wc_conflict_description_t *description = (svn_wc_conflict_description_t *)lParam; - if (description) - { - dlg.SetConflictDescription(description); - if (m_pTaskbarList) - { - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED); - } - if (dlg.DoModal() == IDOK) - { - if (dlg.GetResult() == svn_wc_conflict_choose_postpone) - { - // if the result is conflicted and the dialog returned IDOK, - // that means we should not ask again in case of a conflict - m_AlwaysConflicted = true; - ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_SETCHECK, BST_CHECKED, 0); - } - } - m_mergedfile = dlg.GetMergedFile(); - m_bCancelled = dlg.IsCancelled(); - if (m_pTaskbarList) - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_INDETERMINATE); - return dlg.GetResult(); - } - - return svn_wc_conflict_choose_postpone; -#endif - return 0; -} -#if 0 -svn_wc_conflict_choice_t CGitProgressDlg::ConflictResolveCallback(const svn_wc_conflict_description_t *description, CString& mergedfile) -{ - // we only bother the user when merging - if (((m_Command == GitProgress_Merge)||(m_Command == GitProgress_MergeAll)||(m_Command == GitProgress_MergeReintegrate))&&(!m_AlwaysConflicted)&&(description)) - { - // we're in a worker thread here. That means we must not show a dialog from the thread - // but let the UI thread do it. - // To do that, we send a message to the UI thread and let it show the conflict resolver dialog. - LRESULT dlgResult = ::SendMessage(GetSafeHwnd(), WM_SHOWCONFLICTRESOLVER, 0, (LPARAM)description); - mergedfile = m_mergedfile; - return (svn_wc_conflict_choice_t)dlgResult; - } - - return svn_wc_conflict_choose_postpone; -} -#endif -void CGitProgressDlg::AddItemToList() -{ - int totalcount = m_ProgList.GetItemCount(); - - m_ProgList.SetItemCountEx(totalcount+1, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL); - // make columns width fit - if (iFirstResized < 30) - { - // only resize the columns for the first 30 or so entries. - // after that, don't resize them anymore because that's an - // expensive function call and the columns will be sized - // close enough already. - ResizeColumns(); - ++iFirstResized; - } - - // Make sure the item is *entirely* visible even if the horizontal - // scroll bar is visible. - int count = m_ProgList.GetCountPerPage(); - if (totalcount <= (m_ProgList.GetTopIndex() + count + nEnsureVisibleCount + 2)) - { - ++nEnsureVisibleCount; - m_bLastVisible = true; - } - else - { - nEnsureVisibleCount = 0; - if (IsIconic() == 0) - m_bLastVisible = false; - } -} - - -BOOL CGitProgressDlg::Notify(const CTGitPath& path, git_wc_notify_action_t action, - int /*status*/ , - CString *strErr - /* - svn_node_kind_t kind, const CString& mime_type, - svn_wc_notify_state_t content_state, - svn_wc_notify_state_t prop_state, LONG rev, - const svn_lock_t * lock, svn_wc_notify_lock_state_t lock_state, - const CString& changelistname, - svn_merge_range_t * range, - svn_error_t * err, apr_pool_t * pool - */) -{ - bool bNoNotify = false; - bool bDoAddData = true; - NotificationData * data = new NotificationData(); - data->path = path; - data->action = action; - data->sPathColumnText=path.GetGitPathString(); - data->bAuxItem = false; - - this->m_Animate.ShowWindow(SW_HIDE); - -#if 0 - data->kind = kind; - data->mime_type = mime_type; - data->content_state = content_state; - data->prop_state = prop_state; - data->rev = rev; - data->lock_state = lock_state; - data->changelistname = changelistname; - if ((lock)&&(lock->owner)) - data->owner = CUnicodeUtils::GetUnicode(lock->owner); - data->sPathColumnText = path.GetUIPathString(); - if (!m_basePath.IsEmpty()) - data->basepath = m_basePath; - if (range) - data->merge_range = *range; -#endif - switch (data->action) - { - case git_wc_notify_add: - //case svn_wc_notify_update_add: - // if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted)) - // { - // data->color = m_Colors.GetColor(CColors::Conflict); - // data->bConflictedActionItem = true; - // data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED); - // ++m_nConflicts; - // } - // else - // { - // m_bMergesAddsDeletesOccurred = true; - data->sActionColumnText.LoadString(IDS_SVNACTION_ADD); - data->color = m_Colors.GetColor(CColors::Added); - // } - break; - case git_wc_notify_sendmail_start: - data->bAuxItem = true; - data->sActionColumnText.LoadString(IDS_SVNACTION_SENDMAIL_START); - data->color = m_Colors.GetColor(CColors::Modified); - break; - - case git_wc_notify_sendmail_error: - data->bAuxItem = true; - data->sActionColumnText.LoadString(IDS_SVNACTION_SENDMAIL_ERROR); - if(strErr) - data->sPathColumnText = *strErr; - else - data->sPathColumnText.Empty(); - data->color = m_Colors.GetColor(CColors::Modified); - break; - - case git_wc_notify_sendmail_done: - - data->sActionColumnText.LoadString(IDS_SVNACTION_SENDMAIL_DONE); - data->sPathColumnText.Empty(); - data->color = m_Colors.GetColor(CColors::Modified); - break; - - case git_wc_notify_sendmail_retry: - data->sActionColumnText.LoadString(IDS_SVNACTION_SENDMAIL_RETRY); - data->sPathColumnText.Empty(); - data->color = m_Colors.GetColor(CColors::Modified); - break; - - - case git_wc_notify_resolved: - data->sActionColumnText.LoadString(IDS_SVNACTION_RESOLVE); - break; - - case git_wc_notify_revert: - data->sActionColumnText.LoadString(IDS_SVNACTION_REVERT); - break; - - case git_wc_notify_checkout: - data->sActionColumnText.LoadString(IDS_PROGRS_CMD_CHECKOUT); - data->color = m_Colors.GetColor(CColors::Added); - data->bAuxItem = false; - break; - -#if 0 - case svn_wc_notify_commit_added: - data->sActionColumnText.LoadString(IDS_SVNACTION_ADDING); - data->color = m_Colors.GetColor(CColors::Added); - break; - case svn_wc_notify_copy: - data->sActionColumnText.LoadString(IDS_SVNACTION_COPY); - break; - case svn_wc_notify_commit_modified: - data->sActionColumnText.LoadString(IDS_SVNACTION_MODIFIED); - data->color = m_Colors.GetColor(CColors::Modified); - break; - case svn_wc_notify_delete: - case svn_wc_notify_update_delete: - data->sActionColumnText.LoadString(IDS_SVNACTION_DELETE); - m_bMergesAddsDeletesOccurred = true; - data->color = m_Colors.GetColor(CColors::Deleted); - break; - case svn_wc_notify_commit_deleted: - data->sActionColumnText.LoadString(IDS_SVNACTION_DELETING); - data->color = m_Colors.GetColor(CColors::Deleted); - break; - case svn_wc_notify_restore: - data->sActionColumnText.LoadString(IDS_SVNACTION_RESTORE); - break; - - case svn_wc_notify_update_replace: - case svn_wc_notify_commit_replaced: - data->sActionColumnText.LoadString(IDS_SVNACTION_REPLACED); - data->color = m_Colors.GetColor(CColors::Deleted); - break; - case svn_wc_notify_exists: - if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted)) - { - data->color = m_Colors.GetColor(CColors::Conflict); - data->bConflictedActionItem = true; - ++m_nConflicts; - data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED); - } - else if ((data->content_state == svn_wc_notify_state_merged) || (data->prop_state == svn_wc_notify_state_merged)) - { - data->color = m_Colors.GetColor(CColors::Merged); - m_bMergesAddsDeletesOccurred = true; - data->sActionColumnText.LoadString(IDS_SVNACTION_MERGED); - } - else - data->sActionColumnText.LoadString(IDS_SVNACTION_EXISTS); - break; - case svn_wc_notify_update_update: - // if this is an inoperative dir change, don't show the notification. - // an inoperative dir change is when a directory gets updated without - // any real change in either text or properties. - if ((kind == svn_node_dir) - && ((prop_state == svn_wc_notify_state_inapplicable) - || (prop_state == svn_wc_notify_state_unknown) - || (prop_state == svn_wc_notify_state_unchanged))) - { - bNoNotify = true; - break; - } - if ((data->content_state == svn_wc_notify_state_conflicted) || (data->prop_state == svn_wc_notify_state_conflicted)) - { - data->color = m_Colors.GetColor(CColors::Conflict); - data->bConflictedActionItem = true; - ++m_nConflicts; - data->sActionColumnText.LoadString(IDS_SVNACTION_CONFLICTED); - } - else if ((data->content_state == svn_wc_notify_state_merged) || (data->prop_state == svn_wc_notify_state_merged)) - { - data->color = m_Colors.GetColor(CColors::Merged); - m_bMergesAddsDeletesOccurred = true; - data->sActionColumnText.LoadString(IDS_SVNACTION_MERGED); - } - else if (((data->content_state != svn_wc_notify_state_unchanged)&&(data->content_state != svn_wc_notify_state_unknown)) || - ((data->prop_state != svn_wc_notify_state_unchanged)&&(data->prop_state != svn_wc_notify_state_unknown))) - { - data->sActionColumnText.LoadString(IDS_SVNACTION_UPDATE); - } - else - { - bNoNotify = true; - break; - } - if (lock_state == svn_wc_notify_lock_state_unlocked) - { - CString temp(MAKEINTRESOURCE(IDS_SVNACTION_UNLOCKED)); - data->sActionColumnText += _T(", ") + temp; - } - break; - - case svn_wc_notify_update_external: - // For some reason we build a list of externals... - m_ExtStack.AddHead(path.GetUIPathString()); - data->sActionColumnText.LoadString(IDS_SVNACTION_EXTERNAL); - data->bAuxItem = true; - break; - - case svn_wc_notify_update_completed: - { - data->sActionColumnText.LoadString(IDS_SVNACTION_COMPLETED); - data->bAuxItem = true; - bool bEmpty = !!m_ExtStack.IsEmpty(); - if (!bEmpty) - data->sPathColumnText.Format(IDS_PROGRS_PATHATREV, (LPCTSTR)m_ExtStack.RemoveHead(), rev); - else - data->sPathColumnText.Format(IDS_PROGRS_ATREV, rev); - - if ((m_nConflicts>0)&&(bEmpty)) - { - // We're going to add another aux item - let's shove this current onto the list first - // I don't really like this, but it will do for the moment. - m_arData.push_back(data); - AddItemToList(); - - data = new NotificationData(); - data->bAuxItem = true; - data->sActionColumnText.LoadString(IDS_PROGRS_CONFLICTSOCCURED_WARNING); - data->sPathColumnText.LoadString(IDS_PROGRS_CONFLICTSOCCURED); - data->color = m_Colors.GetColor(CColors::Conflict); - CSoundUtils::PlayTSVNWarning(); - // This item will now be added after the switch statement - } - if (!m_basePath.IsEmpty()) - m_FinishedRevMap[m_basePath.GetSVNApiPath(pool)] = rev; - m_RevisionEnd = rev; - m_bFinishedItemAdded = true; - } - break; - case svn_wc_notify_commit_postfix_txdelta: - data->sActionColumnText.LoadString(IDS_SVNACTION_POSTFIX); - break; - case svn_wc_notify_failed_revert: - data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDREVERT); - break; - case svn_wc_notify_status_completed: - case svn_wc_notify_status_external: - data->sActionColumnText.LoadString(IDS_SVNACTION_STATUS); - break; - case svn_wc_notify_skip: - if ((content_state == svn_wc_notify_state_missing)||(content_state == svn_wc_notify_state_obstructed)||(content_state == svn_wc_notify_state_conflicted)) - { - data->sActionColumnText.LoadString(IDS_SVNACTION_SKIPMISSING); - - // The color settings dialog describes the red color with - // "possible or real conflict / obstructed" which also applies to - // skipped targets during a merge. So we just use the same color. - data->color = m_Colors.GetColor(CColors::Conflict); - } - else - data->sActionColumnText.LoadString(IDS_SVNACTION_SKIP); - break; - case svn_wc_notify_locked: - if ((lock)&&(lock->owner)) - data->sActionColumnText.Format(IDS_SVNACTION_LOCKEDBY, (LPCTSTR)CUnicodeUtils::GetUnicode(lock->owner)); - break; - case svn_wc_notify_unlocked: - data->sActionColumnText.LoadString(IDS_SVNACTION_UNLOCKED); - break; - case svn_wc_notify_failed_lock: - data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDLOCK); - m_arData.push_back(data); - AddItemToList(); - ReportError(SVN::GetErrorString(err)); - bDoAddData = false; - if (err->apr_err == SVN_ERR_FS_OUT_OF_DATE) - m_bLockWarning = true; - if (err->apr_err == SVN_ERR_FS_PATH_ALREADY_LOCKED) - m_bLockExists = true; - break; - case svn_wc_notify_failed_unlock: - data->sActionColumnText.LoadString(IDS_SVNACTION_FAILEDUNLOCK); - m_arData.push_back(data); - AddItemToList(); - ReportError(SVN::GetErrorString(err)); - bDoAddData = false; - if (err->apr_err == SVN_ERR_FS_OUT_OF_DATE) - m_bLockWarning = true; - break; - case svn_wc_notify_changelist_set: - data->sActionColumnText.Format(IDS_SVNACTION_CHANGELISTSET, (LPCTSTR)data->changelistname); - break; - case svn_wc_notify_changelist_clear: - data->sActionColumnText.LoadString(IDS_SVNACTION_CHANGELISTCLEAR); - break; - case svn_wc_notify_changelist_moved: - data->sActionColumnText.Format(IDS_SVNACTION_CHANGELISTMOVED, (LPCTSTR)data->changelistname); - break; - case svn_wc_notify_foreign_merge_begin: - case svn_wc_notify_merge_begin: - if (range == NULL) - data->sActionColumnText.LoadString(IDS_SVNACTION_MERGEBEGINNONE); - else if ((data->merge_range.start == data->merge_range.end) || (data->merge_range.start == data->merge_range.end - 1)) - data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINSINGLE, data->merge_range.end); - else if (data->merge_range.start - 1 == data->merge_range.end) - data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINSINGLEREVERSE, data->merge_range.start); - else if (data->merge_range.start < data->merge_range.end) - data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINMULTIPLE, data->merge_range.start + 1, data->merge_range.end); - else - data->sActionColumnText.Format(IDS_SVNACTION_MERGEBEGINMULTIPLEREVERSE, data->merge_range.start, data->merge_range.end + 1); - data->bAuxItem = true; - break; -#endif - default: - break; - } // switch (data->action) - - if (bNoNotify) - delete data; - else - { - if (bDoAddData) - { - m_arData.push_back(data); - AddItemToList(); - if ((!data->bAuxItem) && (m_itemCount > 0)) - { - CProgressCtrl * progControl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESSBAR); - progControl->ShowWindow(SW_SHOW); - progControl->SetPos(m_itemCount); - progControl->SetRange32(0, m_itemCountTotal); - if (m_pTaskbarList) - { - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); - m_pTaskbarList->SetProgressValue(m_hWnd, m_itemCountTotal - m_itemCount, m_itemCountTotal); - m_pTaskbarList->SetProgressValue(m_hWnd, m_itemCount, m_itemCountTotal); - } - } - } - //if ((action == svn_wc_notify_commit_postfix_txdelta)&&(bSecondResized == FALSE)) - //{ - // ResizeColumns(); - // bSecondResized = TRUE; - //} - } - - return TRUE; -} - - -CString CGitProgressDlg::BuildInfoString() -{ - CString infotext; - if(this->m_Command == GitProgress_Resolve) - infotext = _T("You need commit your change after resolve conflict"); -#if 0 - - CString temp; - int added = 0; - int copied = 0; - int deleted = 0; - int restored = 0; - int reverted = 0; - int resolved = 0; - int conflicted = 0; - int updated = 0; - int merged = 0; - int modified = 0; - int skipped = 0; - int replaced = 0; - - for (size_t i=0; iaction) - { - case svn_wc_notify_add: - case svn_wc_notify_update_add: - case svn_wc_notify_commit_added: - if (dat->bConflictedActionItem) - ++conflicted; - else - ++added; - break; - case svn_wc_notify_copy: - ++copied; - break; - case svn_wc_notify_delete: - case svn_wc_notify_update_delete: - case svn_wc_notify_commit_deleted: - ++deleted; - break; - case svn_wc_notify_restore: - ++restored; - break; - case svn_wc_notify_revert: - ++reverted; - break; - case svn_wc_notify_resolved: - ++resolved; - break; - case svn_wc_notify_update_update: - if (dat->bConflictedActionItem) - ++conflicted; - else if ((dat->content_state == svn_wc_notify_state_merged) || (dat->prop_state == svn_wc_notify_state_merged)) - ++merged; - else - ++updated; - break; - case svn_wc_notify_commit_modified: - ++modified; - break; - case svn_wc_notify_skip: - ++skipped; - break; - case svn_wc_notify_commit_replaced: - ++replaced; - break; - } - } - if (conflicted) - { - temp.LoadString(IDS_SVNACTION_CONFLICTED); - infotext += temp; - temp.Format(_T(":%d "), conflicted); - infotext += temp; - } - if (skipped) - { - temp.LoadString(IDS_SVNACTION_SKIP); - infotext += temp; - infotext.AppendFormat(_T(":%d "), skipped); - } - if (merged) - { - temp.LoadString(IDS_SVNACTION_MERGED); - infotext += temp; - infotext.AppendFormat(_T(":%d "), merged); - } - if (added) - { - temp.LoadString(IDS_SVNACTION_ADD); - infotext += temp; - infotext.AppendFormat(_T(":%d "), added); - } - if (deleted) - { - temp.LoadString(IDS_SVNACTION_DELETE); - infotext += temp; - infotext.AppendFormat(_T(":%d "), deleted); - } - if (modified) - { - temp.LoadString(IDS_SVNACTION_MODIFIED); - infotext += temp; - infotext.AppendFormat(_T(":%d "), modified); - } - if (copied) - { - temp.LoadString(IDS_SVNACTION_COPY); - infotext += temp; - infotext.AppendFormat(_T(":%d "), copied); - } - if (replaced) - { - temp.LoadString(IDS_SVNACTION_REPLACED); - infotext += temp; - infotext.AppendFormat(_T(":%d "), replaced); - } - if (updated) - { - temp.LoadString(IDS_SVNACTION_UPDATE); - infotext += temp; - infotext.AppendFormat(_T(":%d "), updated); - } - if (restored) - { - temp.LoadString(IDS_SVNACTION_RESTORE); - infotext += temp; - infotext.AppendFormat(_T(":%d "), restored); - } - if (reverted) - { - temp.LoadString(IDS_SVNACTION_REVERT); - infotext += temp; - infotext.AppendFormat(_T(":%d "), reverted); - } - if (resolved) - { - temp.LoadString(IDS_SVNACTION_RESOLVE); - infotext += temp; - infotext.AppendFormat(_T(":%d "), resolved); - } -#endif - return infotext; -} - -void CGitProgressDlg::SetSelectedList(const CTGitPathList& selPaths) -{ - m_selectedPaths = selPaths; -} - -void CGitProgressDlg::ResizeColumns() -{ - m_ProgList.SetRedraw(FALSE); - - TCHAR textbuf[MAX_PATH]; - - int maxcol = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1; - for (int col = 0; col <= maxcol; ++col) - { - // find the longest width of all items - int count = m_ProgList.GetItemCount(); - HDITEM hdi = {0}; - hdi.mask = HDI_TEXT; - hdi.pszText = textbuf; - hdi.cchTextMax = sizeof(textbuf); - ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItem(col, &hdi); - int cx = m_ProgList.GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin - - for (int index = 0; indexsActionColumnText) + 12; - break; - case 1: - linewidth = m_ProgList.GetStringWidth(m_arData[index]->sPathColumnText) + 12; - break; - } - if (cx < linewidth) - cx = linewidth; - } - m_ProgList.SetColumnWidth(col, cx); - } - - m_ProgList.SetRedraw(TRUE); -} - -BOOL CGitProgressDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - // Let the TaskbarButtonCreated message through the UIPI filter. If we don't - // do this, Explorer would be unable to send that message to our window if we - // were running elevated. It's OK to make the call all the time, since if we're - // not elevated, this is a no-op. - CHANGEFILTERSTRUCT cfs = { sizeof(CHANGEFILTERSTRUCT) }; - typedef BOOL STDAPICALLTYPE ChangeWindowMessageFilterExDFN(HWND hWnd, UINT message, DWORD action, PCHANGEFILTERSTRUCT pChangeFilterStruct); - CAutoLibrary hUser = AtlLoadSystemLibraryUsingFullPath(_T("user32.dll")); - if (hUser) - { - ChangeWindowMessageFilterExDFN *pfnChangeWindowMessageFilterEx = (ChangeWindowMessageFilterExDFN*)GetProcAddress(hUser, "ChangeWindowMessageFilterEx"); - if (pfnChangeWindowMessageFilterEx) - { - pfnChangeWindowMessageFilterEx(m_hWnd, WM_TASKBARBTNCREATED, MSGFLT_ALLOW, &cfs); - } - } - m_pTaskbarList.Release(); - if (FAILED(m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList))) - m_pTaskbarList = nullptr; - - m_ProgList.SetExtendedStyle (LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); - - m_ProgList.DeleteAllItems(); - int c = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1; - while (c>=0) - m_ProgList.DeleteColumn(c--); - CString temp; - temp.LoadString(IDS_PROGRS_ACTION); - m_ProgList.InsertColumn(0, temp); - temp.LoadString(IDS_PROGRS_PATH); - m_ProgList.InsertColumn(1, temp); - - m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); - if (m_pThread==NULL) - { - ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED))); - } - else - { - m_pThread->m_bAutoDelete = FALSE; - m_pThread->ResumeThread(); - } - - UpdateData(FALSE); - - // Call this early so that the column headings aren't hidden before any - // text gets added. - ResizeColumns(); - - SetTimer(VISIBLETIMER, 300, NULL); - - AddAnchor(IDC_SVNPROGRESS, TOP_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_PROGRESSLABEL, BOTTOM_LEFT, BOTTOM_CENTER); - AddAnchor(IDC_PROGRESSBAR, BOTTOM_CENTER, BOTTOM_RIGHT); - AddAnchor(IDC_INFOTEXT, BOTTOM_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_NONINTERACTIVE, BOTTOM_LEFT, BOTTOM_RIGHT); - AddAnchor(IDCANCEL, BOTTOM_RIGHT); - AddAnchor(IDOK, BOTTOM_RIGHT); - AddAnchor(IDC_LOGBUTTON, BOTTOM_RIGHT); - //SetPromptParentWindow(this->m_hWnd); - - m_Animate.Open(IDR_DOWNLOAD); - - if (hWndExplorer) - CenterWindow(CWnd::FromHandle(hWndExplorer)); - EnableSaveRestore(_T("GITProgressDlg")); - - m_background_brush.CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - return TRUE; -} - -bool CGitProgressDlg::SetBackgroundImage(UINT nID) -{ - return CAppUtils::SetListCtrlBackgroundImage(m_ProgList.GetSafeHwnd(), nID); -} - -void CGitProgressDlg::ReportGitError() -{ - ReportError(CGit::GetLibGit2LastErr()); -} - -void CGitProgressDlg::ReportError(const CString& sError) -{ - CSoundUtils::PlayTGitError(); - ReportString(sError, CString(MAKEINTRESOURCE(IDS_ERR_ERROR)), m_Colors.GetColor(CColors::Conflict)); - m_bErrorsOccurred = true; -} - -void CGitProgressDlg::ReportWarning(const CString& sWarning) -{ - CSoundUtils::PlayTGitWarning(); - ReportString(sWarning, CString(MAKEINTRESOURCE(IDS_WARN_WARNING)), m_Colors.GetColor(CColors::Conflict)); -} - -void CGitProgressDlg::ReportNotification(const CString& sNotification) -{ - CSoundUtils::PlayTGitNotification(); - ReportString(sNotification, CString(MAKEINTRESOURCE(IDS_WARN_NOTE))); -} - -void CGitProgressDlg::ReportCmd(const CString& sCmd) -{ - ReportString(sCmd, CString(MAKEINTRESOURCE(IDS_PROGRS_CMDINFO)), m_Colors.GetColor(CColors::Cmd)); -} - -void CGitProgressDlg::ReportString(CString sMessage, const CString& sMsgKind, COLORREF color) -{ - // instead of showing a dialog box with the error message or notification, - // just insert the error text into the list control. - // that way the user isn't 'interrupted' by a dialog box popping up! - - // the message may be split up into different lines - // so add a new entry for each line of the message - while (!sMessage.IsEmpty()) - { - NotificationData * data = new NotificationData(); - data->bAuxItem = true; - data->sActionColumnText = sMsgKind; - if (sMessage.Find('\n')>=0) - data->sPathColumnText = sMessage.Left(sMessage.Find('\n')); - else - data->sPathColumnText = sMessage; - data->sPathColumnText.Trim(_T("\n\r")); - data->color = color; - if (sMessage.Find('\n')>=0) - { - sMessage = sMessage.Mid(sMessage.Find('\n')); - sMessage.Trim(_T("\n\r")); - } - else - sMessage.Empty(); - m_arData.push_back(data); - AddItemToList(); - } -} - -UINT CGitProgressDlg::ProgressThreadEntry(LPVOID pVoid) -{ - return ((CGitProgressDlg*)pVoid)->ProgressThread(); -} - -UINT CGitProgressDlg::ProgressThread() -{ - // The SetParams function should have loaded something for us - - CString temp; - CString sWindowTitle; - bool localoperation = false; - bool bSuccess = false; - m_AlwaysConflicted = false; - - DialogEnableWindow(IDOK, FALSE); - DialogEnableWindow(IDCANCEL, TRUE); -// SetAndClearProgressInfo(m_hWnd); - m_itemCount = m_itemCountTotal; - - InterlockedExchange(&m_bThreadRunning, TRUE); - iFirstResized = 0; - bSecondResized = FALSE; - m_bFinishedItemAdded = false; - CTime startTime = CTime::GetCurrentTime(); - - if (m_pTaskbarList) - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_INDETERMINATE); - - switch (m_Command) - { - case GitProgress_Add: - bSuccess = CmdAdd(sWindowTitle, localoperation); - break; - case GitProgress_Copy: - bSuccess = CmdCopy(sWindowTitle, localoperation); - break; - case GitProgress_Export: - bSuccess = CmdExport(sWindowTitle, localoperation); - break; - case GitProgress_Rename: - bSuccess = CmdRename(sWindowTitle, localoperation); - break; - case GitProgress_Resolve: - bSuccess = CmdResolve(sWindowTitle, localoperation); - break; - case GitProgress_Revert: - bSuccess = CmdRevert(sWindowTitle, localoperation); - break; - case GitProgress_Switch: - bSuccess = CmdSwitch(sWindowTitle, localoperation); - break; - case GitProgress_SendMail: - bSuccess = CmdSendMail(sWindowTitle, localoperation); - break; - case GitProgress_Clone: - bSuccess = CmdClone(sWindowTitle, localoperation); - break; - case GitProgress_Fetch: - bSuccess = CmdFetch(sWindowTitle, localoperation); - break; - } - if (!bSuccess) - temp.LoadString(IDS_PROGRS_TITLEFAILED); - else - temp.LoadString(IDS_PROGRS_TITLEFIN); - sWindowTitle = sWindowTitle + _T(" ") + temp; - SetWindowText(sWindowTitle); - - KillTimer(TRANSFERTIMER); - KillTimer(VISIBLETIMER); - - if (m_pTaskbarList) - { - if (DidErrorsOccur()) - { - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR); - m_pTaskbarList->SetProgressValue(m_hWnd, 100, 100); - } - else - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS); - } - - DialogEnableWindow(IDCANCEL, FALSE); - DialogEnableWindow(IDOK, TRUE); - - CString info = BuildInfoString(); - if (!bSuccess) - info.LoadString(IDS_PROGRS_INFOFAILED); - SetDlgItemText(IDC_INFOTEXT, info); - ResizeColumns(); - CWnd * pWndOk = GetDlgItem(IDOK); - if (pWndOk && ::IsWindow(pWndOk->GetSafeHwnd())) - { - SendMessage(DM_SETDEFID, IDOK); - GetDlgItem(IDOK)->SetFocus(); - } - - CString sFinalInfo; - if (!m_sTotalBytesTransferred.IsEmpty()) - { - CTimeSpan time = CTime::GetCurrentTime() - startTime; - temp.Format(IDS_PROGRS_TIME, (LONG)time.GetTotalMinutes(), (LONG)time.GetSeconds()); - sFinalInfo.Format(IDS_PROGRS_FINALINFO, m_sTotalBytesTransferred, (LPCTSTR)temp); - SetDlgItemText(IDC_PROGRESSLABEL, sFinalInfo); - } - else - GetDlgItem(IDC_PROGRESSLABEL)->ShowWindow(SW_HIDE); - - GetDlgItem(IDC_PROGRESSBAR)->ShowWindow(SW_HIDE); - - if (!m_bFinishedItemAdded) - { - // there's no "finished: xxx" line at the end. We add one here to make - // sure the user sees that the command is actually finished. - NotificationData * data = new NotificationData(); - data->bAuxItem = true; - data->sActionColumnText.LoadString(IDS_PROGRS_FINISHED); - m_arData.push_back(data); - AddItemToList(); - } - - int count = m_ProgList.GetItemCount(); - if ((count > 0)&&(m_bLastVisible)) - m_ProgList.EnsureVisible(count-1, FALSE); - - CLogFile logfile; - if (logfile.Open()) - { - logfile.AddTimeLine(); - for (size_t i = 0; i < m_arData.size(); ++i) - { - NotificationData * data = m_arData[i]; - temp.Format(_T("%-20s : %s"), (LPCTSTR)data->sActionColumnText, (LPCTSTR)data->sPathColumnText); - logfile.AddLine(temp); - } - if (!sFinalInfo.IsEmpty()) - logfile.AddLine(sFinalInfo); - logfile.Close(); - } - - m_bCancelled = TRUE; - InterlockedExchange(&m_bThreadRunning, FALSE); - RefreshCursor(); - -#if 0 - DWORD dwAutoClose = CRegStdDWORD(_T("Software\\TortoiseGit\\AutoClose"), CLOSE_MANUAL); - if (m_options & ProgOptDryRun) - dwAutoClose = 0; // dry run means progress dialog doesn't auto close at all - if (!m_bLastVisible) - dwAutoClose = 0; - if (m_dwCloseOnEnd != (DWORD)-1) - dwAutoClose = m_dwCloseOnEnd; // command line value has priority over setting value - if ((dwAutoClose == CLOSE_NOERRORS)&&(!m_bErrorsOccurred)) - PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd); - if ((dwAutoClose == CLOSE_NOCONFLICTS)&&(!m_bErrorsOccurred)&&(m_nConflicts==0)) - PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd); - if ((dwAutoClose == CLOSE_NOMERGES)&&(!m_bErrorsOccurred)&&(m_nConflicts==0)&&(!m_bMergesAddsDeletesOccurred)) - PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd); - if ((dwAutoClose == CLOSE_LOCAL)&&(!m_bErrorsOccurred)&&(m_nConflicts==0)&&(localoperation)) - PostMessage(WM_COMMAND, 1, (LPARAM)GetDlgItem(IDOK)->m_hWnd); -#endif - - //Don't do anything here which might cause messages to be sent to the window - //The window thread is probably now blocked in OnOK if we've done an auto close - return 0; -} - -void CGitProgressDlg::OnBnClickedLogbutton() -{ - switch(this->m_Command) - { - case GitProgress_Add: - case GitProgress_Resolve: - { - CString cmd = _T(" /command:commit"); - cmd += _T(" /path:\"")+g_Git.m_CurrentDir+_T("\""); - - CAppUtils::RunTortoiseGitProc(cmd); - this->EndDialog(IDOK); - break; - } - } -#if 0 - if (m_targetPathList.GetCount() != 1) - return; - StringRevMap::iterator it = m_UpdateStartRevMap.begin(); - svn_revnum_t rev = -1; - if (it != m_UpdateStartRevMap.end()) - { - rev = it->second; - } - CLogDlg dlg; - dlg.SetParams(m_targetPathList[0], m_RevisionEnd, m_RevisionEnd, rev, 0, TRUE); - dlg.DoModal(); -#endif -} - - -void CGitProgressDlg::OnClose() -{ - if (m_bCancelled) - { - TerminateThread(m_pThread->m_hThread, (DWORD)-1); - InterlockedExchange(&m_bThreadRunning, FALSE); - } - else - { - m_bCancelled = TRUE; - return; - } - DialogEnableWindow(IDCANCEL, TRUE); - __super::OnClose(); -} - -void CGitProgressDlg::OnOK() -{ - if ((m_bCancelled)&&(!m_bThreadRunning)) - { - // I have made this wait a sensible amount of time (10 seconds) for the thread to finish - // You must be careful in the thread that after posting the WM_COMMAND/IDOK message, you - // don't do any more operations on the window which might require message passing - // If you try to send windows messages once we're waiting here, then the thread can't finished - // because the Window's message loop is blocked at this wait - WaitForSingleObject(m_pThread->m_hThread, 10000); - __super::OnOK(); - } - m_bCancelled = TRUE; -} - -void CGitProgressDlg::OnCancel() -{ - if ((m_bCancelled)&&(!m_bThreadRunning)) - __super::OnCancel(); - m_bCancelled = TRUE; -} - -void CGitProgressDlg::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) -{ - NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); - - if (pDispInfo) - { - if (pDispInfo->item.mask & LVIF_TEXT) - { - if (pDispInfo->item.iItem < (int)m_arData.size()) - { - const NotificationData * data = m_arData[pDispInfo->item.iItem]; - switch (pDispInfo->item.iSubItem) - { - case 0: - lstrcpyn(m_columnbuf, data->sActionColumnText, MAX_PATH); - break; - case 1: - lstrcpyn(m_columnbuf, data->sPathColumnText, pDispInfo->item.cchTextMax); - if (!data->bAuxItem) - { - int cWidth = m_ProgList.GetColumnWidth(1); - cWidth = max(12, cWidth-12); - CDC * pDC = m_ProgList.GetDC(); - if (pDC != NULL) - { - CFont * pFont = pDC->SelectObject(m_ProgList.GetFont()); - PathCompactPath(pDC->GetSafeHdc(), m_columnbuf, cWidth); - pDC->SelectObject(pFont); - ReleaseDC(pDC); - } - } - break; - default: - m_columnbuf[0] = 0; - } - pDispInfo->item.pszText = m_columnbuf; - } - } - } - *pResult = 0; -} - -void CGitProgressDlg::OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) -{ - NMLVCUSTOMDRAW* pLVCD = reinterpret_cast( pNMHDR ); - - // Take the default processing unless we set this to something else below. - *pResult = CDRF_DODEFAULT; - - // First thing - check the draw stage. If it's the control's prepaint - // stage, then tell Windows we want messages for every item. - - if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage ) - { - *pResult = CDRF_NOTIFYITEMDRAW; - } - else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage ) - { - // This is the prepaint stage for an item. Here's where we set the - // item's text color. Our return value will tell Windows to draw the - // item itself, but it will use the new color we set here. - - // Tell Windows to paint the control itself. - *pResult = CDRF_DODEFAULT; - - ASSERT(pLVCD->nmcd.dwItemSpec < m_arData.size()); - if(pLVCD->nmcd.dwItemSpec >= m_arData.size()) - { - return; - } - const NotificationData * data = m_arData[pLVCD->nmcd.dwItemSpec]; - ASSERT(data != NULL); - if (data == NULL) - return; - - // Store the color back in the NMLVCUSTOMDRAW struct. - pLVCD->clrText = data->color; - } -} - -void CGitProgressDlg::OnNMDblclkSvnprogress(NMHDR * /*pNMHDR*/, LRESULT * /*pResult*/) -{ -#if 0 - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); - *pResult = 0; - if (pNMLV->iItem < 0) - return; - if (m_options & ProgOptDryRun) - return; //don't do anything in a dry-run. - - const NotificationData * data = m_arData[pNMLV->iItem]; - if (data == NULL) - return; - - if (data->bConflictedActionItem) - { - // We've double-clicked on a conflicted item - do a three-way merge on it - SVNDiff::StartConflictEditor(data->path); - } - 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)) - { - // This is a modified file which has been merged on update. Diff it against base - CTGitPath temporaryFile; - SVNDiff diff(this, this->m_hWnd, true); - diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000)); - svn_revnum_t baseRev = 0; - diff.DiffFileAgainstBase(data->path, baseRev); - } - else if ((!data->bAuxItem)&&(data->path.Exists())&&(!data->path.IsDirectory())) - { - bool bOpenWith = false; - int ret = (int)ShellExecute(m_hWnd, NULL, data->path.GetWinPath(), NULL, NULL, SW_SHOWNORMAL); - if (ret <= HINSTANCE_ERROR) - bOpenWith = true; - if (bOpenWith) - { - CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL "); - cmd += data->path.GetWinPathString() + _T(" "); - CAppUtils::LaunchApplication(cmd, NULL, false); - } - } -#endif -} - -void CGitProgressDlg::OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) -{ - LPNMHEADER phdr = reinterpret_cast(pNMHDR); - if (m_bThreadRunning) - return; - if (m_nSortedColumn == phdr->iItem) - m_bAscending = !m_bAscending; - else - m_bAscending = TRUE; - m_nSortedColumn = phdr->iItem; - Sort(); - - CString temp; - m_ProgList.SetRedraw(FALSE); - m_ProgList.DeleteAllItems(); - m_ProgList.SetItemCountEx (static_cast(m_arData.size())); - - m_ProgList.SetRedraw(TRUE); - - *pResult = 0; -} - -bool CGitProgressDlg::NotificationDataIsAux(const NotificationData* pData) -{ - return pData->bAuxItem; -} -BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t action, CString str, const git_oid *a, const git_oid *b) -{ - NotificationData * data = new NotificationData(); - data->action = action; - data->bAuxItem = false; - - if (action == git_wc_notify_update_ref) - { - data->m_NewHash = b->id; - data->m_OldHash = a->id; - data->sActionColumnText.LoadString(IDS_GITACTION_UPDATE_REF); - data->sPathColumnText.Format(_T("%s\t %s -> %s"), str, - data->m_OldHash.ToString().Left(g_Git.GetShortHASHLength()), - data->m_NewHash.ToString().Left(g_Git.GetShortHASHLength())); - - } - - m_arData.push_back(data); - AddItemToList(); - - m_Animate.Stop(); - m_Animate.ShowWindow(SW_HIDE); - return TRUE; -} -BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t /*action*/, const git_transfer_progress *stat) -{ - static unsigned int start = 0; - unsigned int dt = GetCurrentTime() - start; - size_t ds; - double speed = 0; - - if (m_bCancelled) - return FALSE; - - if (dt > 100) - { - start = GetCurrentTime(); - ds = stat->received_bytes - m_TotalBytesTransferred; - speed = ds * 1000.0/dt; - m_TotalBytesTransferred = stat->received_bytes; - } - else - { - return TRUE; - } - - CProgressCtrl * progControl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESSBAR); - - int progress; - progress = stat->received_objects + stat->indexed_objects; - - if ((stat->total_objects > 1000) && (!progControl->IsWindowVisible())) - { - progControl->ShowWindow(SW_SHOW); - if (m_pTaskbarList) - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); - } - if (!GetDlgItem(IDC_PROGRESSLABEL)->IsWindowVisible()) - GetDlgItem(IDC_PROGRESSLABEL)->ShowWindow(SW_SHOW); - - progControl->SetPos(progress); - progControl->SetRange32(0, 2 * stat->total_objects); - if (m_pTaskbarList) - { - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); - m_pTaskbarList->SetProgressValue(m_hWnd, progress, stat->total_objects); - } - - CString progText; - if (stat->received_bytes < 1024) - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALBYTESTRANSFERRED, (int64_t)stat->received_bytes); - else if (stat->received_bytes < 1200000) - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALTRANSFERRED, (int64_t)stat->received_bytes / 1024); - else - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALMBTRANSFERRED, (double)((double)stat->received_bytes / 1024000.0)); - - CString str; - if(speed < 1024) - str.Format(_T("%fB/s"), speed); - else if(speed < 1024 * 1024) - str.Format(_T("%.2fKB/s"), speed / 1024); - else - str.Format(_T("%.2fMB/s"), speed / 1024000.0); - - progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)str); - SetDlgItemText(IDC_PROGRESSLABEL, progText); - - return TRUE; -} - -LRESULT CGitProgressDlg::OnGitProgress(WPARAM /*wParam*/, LPARAM /*lParam*/) -{ -#if 0 - SVNProgress * pProgressData = (SVNProgress *)lParam; - CProgressCtrl * progControl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESSBAR); - if ((pProgressData->total > 1000)&&(!progControl->IsWindowVisible())) - { - progControl->ShowWindow(SW_SHOW); - if (m_pTaskbarList) - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); - } - if (((pProgressData->total < 0)&&(pProgressData->progress > 1000)&&(progControl->IsWindowVisible()))&&(m_itemCountTotal<0)) - { - progControl->ShowWindow(SW_HIDE); - if (m_pTaskbarList) - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_INDETERMINATE); - } - if (!GetDlgItem(IDC_PROGRESSLABEL)->IsWindowVisible()) - GetDlgItem(IDC_PROGRESSLABEL)->ShowWindow(SW_SHOW); - SetTimer(TRANSFERTIMER, 2000, NULL); - if ((pProgressData->total > 0)&&(pProgressData->progress > 1000)) - { - progControl->SetPos((int)pProgressData->progress); - progControl->SetRange32(0, (int)pProgressData->total); - if (m_pTaskbarList) - { - m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); - m_pTaskbarList->SetProgressValue(m_hWnd, pProgressData->progress, pProgressData->total); - } - } - CString progText; - if (pProgressData->overall_total < 1024) - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALBYTESTRANSFERRED, pProgressData->overall_total); - else if (pProgressData->overall_total < 1200000) - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALTRANSFERRED, pProgressData->overall_total / 1024); - else - m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALMBTRANSFERRED, (double)((double)pProgressData->overall_total / 1024000.0)); - progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)pProgressData->SpeedString); - SetDlgItemText(IDC_PROGRESSLABEL, progText); -#endif - return 0; -} - -void CGitProgressDlg::OnTimer(UINT_PTR nIDEvent) -{ - if (nIDEvent == TRANSFERTIMER) - { - CString progText; - CString progSpeed; - progSpeed.Format(IDS_SVN_PROGRESS_BYTES_SEC, 0); - progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)progSpeed); - SetDlgItemText(IDC_PROGRESSLABEL, progText); - KillTimer(TRANSFERTIMER); - } - if (nIDEvent == VISIBLETIMER) - { - if (nEnsureVisibleCount) - m_ProgList.EnsureVisible(m_ProgList.GetItemCount()-1, false); - nEnsureVisibleCount = 0; - } -} - -void CGitProgressDlg::Sort() -{ - if(m_arData.size() < 2) - { - return; - } - - // We need to sort the blocks which lie between the auxiliary entries - // This is so that any aux data stays where it was - NotificationDataVect::iterator actionBlockBegin; - NotificationDataVect::iterator actionBlockEnd = m_arData.begin(); // We start searching from here - - for(;;) - { - // Search to the start of the non-aux entry in the next block - actionBlockBegin = std::find_if(actionBlockEnd, m_arData.end(), std::not1(std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux))); - if(actionBlockBegin == m_arData.end()) - { - // There are no more actions - break; - } - // Now search to find the end of the block - actionBlockEnd = std::find_if(actionBlockBegin+1, m_arData.end(), std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux)); - // Now sort the block - std::sort(actionBlockBegin, actionBlockEnd, &CGitProgressDlg::SortCompare); - } -} - -bool CGitProgressDlg::SortCompare(const NotificationData * pData1, const NotificationData * pData2) -{ - int result = 0; - switch (m_nSortedColumn) - { - case 0: //action column - result = pData1->sActionColumnText.Compare(pData2->sActionColumnText); - break; - case 1: //path column - // Compare happens after switch() - break; - default: - break; - } - - // Sort by path if everything else is equal - if (result == 0) - { - result = CTGitPath::Compare(pData1->path, pData2->path); - } - - if (!m_bAscending) - result = -result; - return result < 0; -} - -BOOL CGitProgressDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) -{ - if (!GetDlgItem(IDOK)->IsWindowEnabled()) - { - // only show the wait cursor over the list control - if ((pWnd)&&(pWnd == GetDlgItem(IDC_SVNPROGRESS))) - { - HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)); - SetCursor(hCur); - return TRUE; - } - } - HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); - SetCursor(hCur); - return CResizableStandAloneDialog::OnSetCursor(pWnd, nHitTest, message); -} - -BOOL CGitProgressDlg::PreTranslateMessage(MSG* pMsg) -{ - if (pMsg->message == WM_KEYDOWN) - { - if (pMsg->wParam == VK_ESCAPE) - { - // pressing the ESC key should close the dialog. But since we disabled the escape - // key (so the user doesn't get the idea that he could simply undo an e.g. update) - // this won't work. - // So if the user presses the ESC key, change it to VK_RETURN so the dialog gets - // the impression that the OK button was pressed. - if ((!m_bThreadRunning)&&(!GetDlgItem(IDCANCEL)->IsWindowEnabled()) - &&(GetDlgItem(IDOK)->IsWindowEnabled())&&(GetDlgItem(IDOK)->IsWindowVisible())) - { - // since we convert ESC to RETURN, make sure the OK button has the focus. - GetDlgItem(IDOK)->SetFocus(); - pMsg->wParam = VK_RETURN; - } - } - if (pMsg->wParam == 'A') - { - if (GetKeyState(VK_CONTROL)&0x8000) - { - // Ctrl-A -> select all - m_ProgList.SetSelectionMark(0); - for (int i=0; iwParam == 'C')||(pMsg->wParam == VK_INSERT)) - { - int selIndex = m_ProgList.GetSelectionMark(); - if (selIndex >= 0) - { - if (GetKeyState(VK_CONTROL)&0x8000) - { - //Ctrl-C -> copy to clipboard - CString sClipdata; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - if (pos != NULL) - { - while (pos) - { - int nItem = m_ProgList.GetNextSelectedItem(pos); - CString sAction = m_ProgList.GetItemText(nItem, 0); - CString sPath = m_ProgList.GetItemText(nItem, 1); - CString sMime = m_ProgList.GetItemText(nItem, 2); - CString sLogCopyText; - sLogCopyText.Format(_T("%s: %s %s\r\n"), - (LPCTSTR)sAction, (LPCTSTR)sPath, (LPCTSTR)sMime); - sClipdata += sLogCopyText; - } - CStringUtils::WriteAsciiStringToClipboard(sClipdata); - } - } - } - } - } // if (pMsg->message == WM_KEYDOWN) - return __super::PreTranslateMessage(pMsg); -} - -void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) -{ - if (m_options & ProgOptDryRun) - return; // don't do anything in a dry-run. - - if (pWnd == &m_ProgList) - { - int selIndex = m_ProgList.GetSelectionMark(); - if ((point.x == -1) && (point.y == -1)) - { - // Menu was invoked from the keyboard rather than by right-clicking - CRect rect; - m_ProgList.GetItemRect(selIndex, &rect, LVIR_LABEL); - m_ProgList.ClientToScreen(&rect); - point = rect.CenterPoint(); - } - - if ((selIndex >= 0)&&(!m_bThreadRunning)) - { - // entry is selected, thread has finished with updating so show the popup menu - CIconMenu popup; - if (popup.CreatePopupMenu()) - { - bool bAdded = false; - NotificationData * data = m_arData[selIndex]; - if ((data)&&(!data->path.IsDirectory())) - { -/* - if (data->action == svn_wc_notify_update_update || data->action == svn_wc_notify_resolved) - { - if (m_ProgList.GetSelectedCount() == 1) - { - popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF); - bAdded = true; - } - } - - if (data->bConflictedActionItem) - { - if (m_ProgList.GetSelectedCount() == 1) - { - popup.AppendMenuIcon(ID_EDITCONFLICT, IDS_MENUCONFLICT,IDI_CONFLICT); - popup.SetDefaultItem(ID_EDITCONFLICT, FALSE); - popup.AppendMenuIcon(ID_CONFLICTRESOLVE, IDS_SVNPROGRESS_MENUMARKASRESOLVED,IDI_RESOLVE); - } - popup.AppendMenuIcon(ID_CONFLICTUSETHEIRS, IDS_SVNPROGRESS_MENUUSETHEIRS,IDI_RESOLVE); - popup.AppendMenuIcon(ID_CONFLICTUSEMINE, IDS_SVNPROGRESS_MENUUSEMINE,IDI_RESOLVE); - } - else if ((data->content_state == svn_wc_notify_state_merged)||(GitProgress_Merge == m_Command)||(data->action == svn_wc_notify_resolved)) - popup.SetDefaultItem(ID_COMPARE, FALSE); -*/ - if (m_ProgList.GetSelectedCount() == 1) - { - if ((data->action == git_wc_notify_add)|| - (data->action == git_wc_notify_revert)|| - (data->action == git_wc_notify_resolved)|| - (data->action == git_wc_notify_checkout)|| - (data->action == git_wc_notify_update_ref)) - { - popup.AppendMenuIcon(ID_LOG, IDS_MENULOG,IDI_LOG); - popup.AppendMenu(MF_SEPARATOR, NULL); - popup.AppendMenuIcon(ID_OPEN, IDS_LOG_POPUP_OPEN, IDI_OPEN); - popup.AppendMenuIcon(ID_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN); - bAdded = true; - } - } - } // if ((data)&&(!data->path.IsDirectory())) - if (m_ProgList.GetSelectedCount() == 1) - { - if (data) - { - CString sPath = GetPathFromColumnText(data->sPathColumnText); - CTGitPath path = CTGitPath(sPath); - if (!sPath.IsEmpty()) - { - if (path.GetDirectory().Exists()) - { - popup.AppendMenuIcon(ID_EXPLORE, IDS_SVNPROGRESS_MENUOPENPARENT, IDI_EXPLORER); - bAdded = true; - } - } - } - } - if (m_ProgList.GetSelectedCount() > 0) - { - if (bAdded) - popup.AppendMenu(MF_SEPARATOR, NULL); - popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPYTOCLIPBOARD,IDI_COPYCLIP); - bAdded = true; - } - if (bAdded) - { - int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); - DialogEnableWindow(IDOK, FALSE); - //this->SetPromptApp(&theApp); - theApp.DoWaitCursor(1); - bool bOpenWith = false; - switch (cmd) - { - case ID_COPY: - { - CString sLines; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - while (pos) - { - int nItem = m_ProgList.GetNextSelectedItem(pos); - NotificationData * data = m_arData[nItem]; - if (data) - { - sLines += data->sPathColumnText; - sLines += _T("\r\n"); - } - } - sLines.TrimRight(); - if (!sLines.IsEmpty()) - { - CStringUtils::WriteAsciiStringToClipboard(sLines, GetSafeHwnd()); - } - } - break; - case ID_EXPLORE: - { - CString sPath = GetPathFromColumnText(data->sPathColumnText); - - CTGitPath path = CTGitPath(sPath); - ShellExecute(m_hWnd, _T("explore"), path.GetDirectory().GetWinPath(), NULL, path.GetDirectory().GetWinPath(), SW_SHOW); - } - break; -#if 0 - case ID_COMPARE: - { - svn_revnum_t rev = -1; - StringRevMap::iterator it = m_UpdateStartRevMap.end(); - if (data->basepath.IsEmpty()) - it = m_UpdateStartRevMap.begin(); - else - it = m_UpdateStartRevMap.find(data->basepath.GetSVNApiPath(pool)); - if (it != m_UpdateStartRevMap.end()) - rev = it->second; - // if the file was merged during update, do a three way diff between OLD, MINE, THEIRS - if (data->content_state == svn_wc_notify_state_merged) - { - CTGitPath basefile = CTempFiles::Instance().GetTempFilePath(false, data->path, rev); - CTGitPath newfile = CTempFiles::Instance().GetTempFilePath(false, data->path, SVNRev::REV_HEAD); - SVN svn; - if (!svn.Cat(data->path, SVNRev(SVNRev::REV_WC), rev, basefile)) - { - CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); - DialogEnableWindow(IDOK, TRUE); - break; - } - // If necessary, convert the line-endings on the file before diffing - if ((DWORD)CRegDWORD(_T("Software\\TortoiseGit\\ConvertBase"), TRUE)) - { - CTGitPath temporaryFile = CTempFiles::Instance().GetTempFilePath(false, data->path, SVNRev::REV_BASE); - if (!svn.Cat(data->path, SVNRev(SVNRev::REV_BASE), SVNRev(SVNRev::REV_BASE), temporaryFile)) - { - temporaryFile.Reset(); - break; - } - else - { - newfile = temporaryFile; - } - } - - SetFileAttributes(newfile.GetWinPath(), FILE_ATTRIBUTE_READONLY); - SetFileAttributes(basefile.GetWinPath(), FILE_ATTRIBUTE_READONLY); - CString revname, wcname, basename; - revname.Format(_T("%s Revision %ld"), (LPCTSTR)data->path.GetUIFileOrDirectoryName(), rev); - wcname.Format(IDS_DIFF_WCNAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName()); - basename.Format(IDS_DIFF_BASENAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName()); - CAppUtils::StartExtMerge(basefile, newfile, data->path, data->path, basename, revname, wcname, CString(), true); - } - else - { - CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, data->path, rev); - SVN svn; - if (!svn.Cat(data->path, SVNRev(SVNRev::REV_WC), rev, tempfile)) - { - CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); - DialogEnableWindow(IDOK, TRUE); - break; - } - else - { - SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY); - CString revname, wcname; - revname.Format(_T("%s Revision %ld"), (LPCTSTR)data->path.GetUIFileOrDirectoryName(), rev); - wcname.Format(IDS_DIFF_WCNAME, (LPCTSTR)data->path.GetUIFileOrDirectoryName()); - CAppUtils::StartExtDiff( - tempfile, data->path, revname, wcname, - CAppUtils::DiffFlags().AlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000))); - } - } - } - break; - case ID_EDITCONFLICT: - { - CString sPath = GetPathFromColumnText(data->sPathColumnText); - SVNDiff::StartConflictEditor(CTGitPath(sPath)); - } - break; - case ID_CONFLICTUSETHEIRS: - case ID_CONFLICTUSEMINE: - case ID_CONFLICTRESOLVE: - { - svn_wc_conflict_choice_t result = svn_wc_conflict_choose_merged; - switch (cmd) - { - case ID_CONFLICTUSETHEIRS: - result = svn_wc_conflict_choose_theirs_full; - break; - case ID_CONFLICTUSEMINE: - result = svn_wc_conflict_choose_mine_full; - break; - case ID_CONFLICTRESOLVE: - result = svn_wc_conflict_choose_merged; - break; - } - SVN svn; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - CString sResolvedPaths; - while (pos) - { - int nItem = m_ProgList.GetNextSelectedItem(pos); - NotificationData * data = m_arData[nItem]; - if (data) - { - if (data->bConflictedActionItem) - { - if (!svn.Resolve(data->path, result, FALSE)) - { - CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); - DialogEnableWindow(IDOK, TRUE); - break; - } - else - { - data->color = ::GetSysColor(COLOR_WINDOWTEXT); - data->action = svn_wc_notify_resolved; - data->sActionColumnText.LoadString(IDS_SVNACTION_RESOLVE); - data->bConflictedActionItem = false; - m_nConflicts--; - - if (m_nConflicts==0) - { - // When the last conflict is resolved we remove - // the warning which we assume is in the last line. - int nIndex = m_ProgList.GetItemCount()-1; - VERIFY(m_ProgList.DeleteItem(nIndex)); - - delete m_arData[nIndex]; - m_arData.pop_back(); - } - sResolvedPaths += data->path.GetWinPathString() + _T("\n"); - } - } - } - } - m_ProgList.Invalidate(); - CString info = BuildInfoString(); - SetDlgItemText(IDC_INFOTEXT, info); - - if (!sResolvedPaths.IsEmpty()) - { - CString msg; - msg.Format(IDS_SVNPROGRESS_RESOLVED, (LPCTSTR)sResolvedPaths); - CMessageBox::Show(m_hWnd, msg, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); - } - } - break; -#endif - case ID_LOG: - { - CString cmd = _T("/command:log"); - CString sPath = GetPathFromColumnText(data->sPathColumnText); - if(data->action == git_wc_notify_update_ref) - { - cmd += _T(" /path:\"") + GetPathFromColumnText(CString()) + _T("\""); - if (!data->m_OldHash.IsEmpty()) - cmd += _T(" /startrev:") + data->m_OldHash.ToString(); - if (!data->m_NewHash.IsEmpty()) - cmd += _T(" /endrev:") + data->m_NewHash.ToString(); - } - else - cmd += _T(" /path:\"") + sPath + _T("\""); - CAppUtils::RunTortoiseGitProc(cmd); - } - break; - case ID_OPENWITH: - bOpenWith = true; - case ID_OPEN: - { - int ret = 0; - CString sWinPath = GetPathFromColumnText(data->sPathColumnText); - if (!bOpenWith) - ret = (int)ShellExecute(this->m_hWnd, NULL, (LPCTSTR)sWinPath, NULL, NULL, SW_SHOWNORMAL); - if ((ret <= HINSTANCE_ERROR)||bOpenWith) - { - CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL "); - cmd += sWinPath + _T(" "); - CAppUtils::LaunchApplication(cmd, NULL, false); - } - } - } - DialogEnableWindow(IDOK, TRUE); - theApp.DoWaitCursor(-1); - } // if (bAdded) - } - } - } -} - -void CGitProgressDlg::OnEnSetfocusInfotext() -{ - CString sTemp; - GetDlgItemText(IDC_INFOTEXT, sTemp); - if (sTemp.IsEmpty()) - GetDlgItem(IDC_INFOTEXT)->HideCaret(); -} - -void CGitProgressDlg::OnLvnBegindragSvnprogress(NMHDR* , LRESULT *pResult) -{ - //LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); -#if 0 - int selIndex = m_ProgList.GetSelectionMark(); - if (selIndex < 0) - return; - - CDropFiles dropFiles; // class for creating DROPFILES struct - - int index; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - while ( (index = m_ProgList.GetNextSelectedItem(pos)) >= 0 ) - { - NotificationData * data = m_arData[index]; - - if ( data->kind==svn_node_file || data->kind==svn_node_dir ) - { - CString sPath = GetPathFromColumnText(data->sPathColumnText); - - dropFiles.AddFile( sPath ); - } - } - - if ( dropFiles.GetCount()>0 ) - { - dropFiles.CreateStructure(); - } -#endif - *pResult = 0; -} - -void CGitProgressDlg::OnSize(UINT nType, int cx, int cy) -{ - CResizableStandAloneDialog::OnSize(nType, cx, cy); - if ((nType == SIZE_RESTORED)&&(m_bLastVisible)) - { - if(!m_ProgList.m_hWnd) - return; - - int count = m_ProgList.GetItemCount(); - if (count > 0) - m_ProgList.EnsureVisible(count-1, false); - } -} - -////////////////////////////////////////////////////////////////////////// -/// commands -////////////////////////////////////////////////////////////////////////// -bool CGitProgressDlg::CmdAdd(CString& sWindowTitle, bool& localoperation) -{ - localoperation = true; - sWindowTitle.LoadString(IDS_PROGRS_TITLE_ADD); - CAppUtils::SetWindowTitle(m_hWnd, m_targetPathList.GetCommonRoot().GetUIPathString(), sWindowTitle); - SetBackgroundImage(IDI_ADD_BKG); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_ADD))); - - if (CRegDWORD(_T("Software\\TortoiseGit\\UseLibgit2"), TRUE) == TRUE) - { - git_repository *repo = NULL; - git_index *index; - - CStringA gitdir = CUnicodeUtils::GetMulti(CTGitPath(g_Git.m_CurrentDir).GetGitPathString(), CP_UTF8); - if (git_repository_open(&repo, gitdir.GetBuffer())) - { - gitdir.ReleaseBuffer(); - ReportGitError(); - return false; - } - gitdir.ReleaseBuffer(); - - git_config * config; - git_config_new(&config); - - CStringA projectConfigA = CUnicodeUtils::GetMulti(g_Git.GetGitLocalConfig(), CP_UTF8); - if (git_config_add_file_ondisk(config, projectConfigA.GetBuffer(), 4, FALSE)) - { - projectConfigA.ReleaseBuffer(); - ReportGitError(); - git_config_free(config); - git_repository_free(repo); - return false; - } - projectConfigA.ReleaseBuffer(); - CString globalConfig = g_Git.GetGitGlobalConfig(); - if (PathFileExists(globalConfig)) - { - CStringA globalConfigA = CUnicodeUtils::GetMulti(globalConfig, CP_UTF8); - if (git_config_add_file_ondisk(config, globalConfigA.GetBuffer(), 3, FALSE)) - { - globalConfigA.ReleaseBuffer(); - ReportGitError(); - git_config_free(config); - git_repository_free(repo); - return false; - } - globalConfigA.ReleaseBuffer(); - } - CString globalXDGConfig = g_Git.GetGitGlobalXDGConfig(); - if (PathFileExists(globalXDGConfig)) - { - CStringA globalXDGConfigA = CUnicodeUtils::GetMulti(globalXDGConfig, CP_UTF8); - if (git_config_add_file_ondisk(config, globalXDGConfigA.GetBuffer(), 2, FALSE)) - { - globalXDGConfigA.ReleaseBuffer(); - ReportGitError(); - git_config_free(config); - git_repository_free(repo); - return false; - } - globalXDGConfigA.ReleaseBuffer(); - } - CString systemConfig = g_Git.GetGitSystemConfig(); - if (!systemConfig.IsEmpty()) - { - CStringA systemConfigA = CUnicodeUtils::GetMulti(systemConfig, CP_UTF8); - if (git_config_add_file_ondisk(config, systemConfigA.GetBuffer(), 1, FALSE)) - { - systemConfigA.ReleaseBuffer(); - ReportGitError(); - git_config_free(config); - git_repository_free(repo); - return false; - } - systemConfigA.ReleaseBuffer(); - } - - git_repository_set_config(repo, config); - - if (git_repository_index(&index, repo)) - { - ReportGitError(); - git_repository_free(repo); - return false; - } - if (git_index_read(index)) - { - ReportGitError(); - git_index_free(index); - git_repository_free(repo); - return false; - } - - for (int i = 0; i < m_targetPathList.GetCount(); ++i) - { - if (git_index_add_bypath(index, CStringA(CUnicodeUtils::GetMulti(m_targetPathList[i].GetGitPathString(), CP_UTF8)).GetBuffer())) - { - ReportGitError(); - git_index_free(index); - git_repository_free(repo); - return false; - } - Notify(m_targetPathList[i],git_wc_notify_add); - } - - if (git_index_write(index)) - { - ReportGitError(); - git_index_free(index); - git_repository_free(repo); - return false; - } - - git_index_free(index); - git_repository_free(repo); - } - else - { - CMassiveGitTask mgt(L"add -f"); - mgt.ExecuteWithNotify(&m_targetPathList, m_bCancelled, git_wc_notify_add, this, &CGitProgressDlg::Notify); - } - - CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList); - - this->GetDlgItem(IDC_LOGBUTTON)->SetWindowText(_T("Commit ...")); - this->GetDlgItem(IDC_LOGBUTTON)->ShowWindow(SW_SHOW); - return true; -} - -bool CGitProgressDlg::CmdCopy(CString& /*sWindowTitle*/, bool& /*localoperation*/) -{ -#if 0 - ASSERT(m_targetPathList.GetCount() == 1); - sWindowTitle.LoadString(IDS_PROGRS_TITLE_COPY); - SetWindowText(sWindowTitle); // needs to be updated, see TSVN rev. 21375 - SetBackgroundImage(IDI_COPY_BKG); - - CString sCmdInfo; - sCmdInfo.Format(IDS_PROGRS_CMD_COPY, - m_targetPathList[0].IsUrl() ? (LPCTSTR)m_targetPathList[0].GetSVNPathString() : m_targetPathList[0].GetWinPath(), - (LPCTSTR)m_url.GetSVNPathString(), (LPCTSTR)m_Revision.ToString()); - ReportCmd(sCmdInfo); - - if (!Copy(m_targetPathList, m_url, m_Revision, m_pegRev, m_sMessage)) - { - ReportSVNError(); - return false; - } - if (m_options & ProgOptSwitchAfterCopy) - { - sCmdInfo.Format(IDS_PROGRS_CMD_SWITCH, - m_targetPathList[0].GetWinPath(), - (LPCTSTR)m_url.GetSVNPathString(), (LPCTSTR)m_Revision.ToString()); - ReportCmd(sCmdInfo); - if (!Switch(m_targetPathList[0], m_url, SVNRev::REV_HEAD, SVNRev::REV_HEAD, m_depth, TRUE, m_options & ProgOptIgnoreExternals)) - { - if (!Switch(m_targetPathList[0], m_url, SVNRev::REV_HEAD, m_Revision, m_depth, TRUE, m_options & ProgOptIgnoreExternals)) - { - ReportSVNError(); - return false; - } - } - } - else - { - if (SVN::PathIsURL(m_url)) - { - CString sMsg(MAKEINTRESOURCE(IDS_PROGRS_COPY_WARNING)); - ReportNotification(sMsg); - } - } -#endif - return true; -} - -bool CGitProgressDlg::CmdExport(CString& /*sWindowTitle*/, bool& /*localoperation*/) -{ -#if 0 - ASSERT(m_targetPathList.GetCount() == 1); - sWindowTitle.LoadString(IDS_PROGRS_TITLE_EXPORT); - sWindowTitle = m_url.GetUIFileOrDirectoryName()+_T(" - ")+sWindowTitle; - SetWindowText(sWindowTitle); // needs to be updated, see TSVN rev. 21375 - SetBackgroundImage(IDI_EXPORT_BKG); - CString eol; - if (m_options & ProgOptEolCRLF) - eol = _T("CRLF"); - if (m_options & ProgOptEolLF) - eol = _T("LF"); - if (m_options & ProgOptEolCR) - eol = _T("CR"); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_EXPORT))); - if (!Export(m_url, m_targetPathList[0], m_Revision, m_Revision, TRUE, m_options & ProgOptIgnoreExternals, m_depth, NULL, FALSE, eol)) - { - ReportSVNError(); - return false; - } -#endif - return true; -} - -bool CGitProgressDlg::CmdRename(CString& /*sWindowTitle*/, bool& /*localoperation*/) -{ -#if 0 - ASSERT(m_targetPathList.GetCount() == 1); - if ((!m_targetPathList[0].IsUrl())&&(!m_url.IsUrl())) - localoperation = true; - sWindowTitle.LoadString(IDS_PROGRS_TITLE_RENAME); - SetWindowText(sWindowTitle); // needs to be updated, see TSVN rev. 21375 - SetBackgroundImage(IDI_RENAME_BKG); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_RENAME))); - if (!Move(m_targetPathList, m_url, m_Revision, m_sMessage)) - { - ReportSVNError(); - return false; - } -#endif - return true; -} - -bool CGitProgressDlg::CmdResolve(CString& sWindowTitle, bool& localoperation) -{ - - localoperation = true; - ASSERT(m_targetPathList.GetCount() == 1); - sWindowTitle.LoadString(IDS_PROGRS_TITLE_RESOLVE); - CAppUtils::SetWindowTitle(m_hWnd, m_targetPathList.GetCommonRoot().GetUIPathString(), sWindowTitle); - SetBackgroundImage(IDI_RESOLVE_BKG); - // check if the file may still have conflict markers in it. - //BOOL bMarkers = FALSE; - - for (int i = 0; i < m_targetPathList.GetCount(); ++i) - { - CString cmd,out,tempmergefile; - cmd.Format(_T("git.exe add -f -- \"%s\""),m_targetPathList[i].GetGitPathString()); - if (g_Git.Run(cmd, &out, CP_UTF8)) - { - CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR); - m_bErrorsOccurred=true; - return false; - } - - CAppUtils::RemoveTempMergeFile((CTGitPath &)m_targetPathList[i]); - - Notify(m_targetPathList[i],git_wc_notify_resolved); - } -#if 0 - if ((m_options & ProgOptSkipConflictCheck) == 0) - { - try - { - for (INT_PTR fileindex=0; (fileindexGetErrorMessage(error, 10000); - ReportError(error); - pE->Delete(); - return false; - } - } - if (bMarkers) - { - if (CMessageBox::Show(m_hWnd, IDS_PROGRS_REVERTMARKERS, IDS_APPNAME, MB_YESNO | MB_ICONQUESTION)==IDYES) - { - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_RESOLVE))); - for (INT_PTR fileindex=0; fileindexGetDlgItem(IDC_LOGBUTTON)->SetWindowText(CString(MAKEINTRESOURCE(IDS_COMMITBUTTON))); - this->GetDlgItem(IDC_LOGBUTTON)->ShowWindow(SW_SHOW); - - return true; -} - -bool CGitProgressDlg::CmdRevert(CString& sWindowTitle, bool& localoperation) -{ - - localoperation = true; - sWindowTitle.LoadString(IDS_PROGRS_TITLE_REVERT); - CAppUtils::SetWindowTitle(m_hWnd, m_targetPathList.GetCommonRoot().GetUIPathString(), sWindowTitle); - SetBackgroundImage(IDI_REVERT_BKG); - - CTGitPathList delList; - for (int i = 0; i < m_selectedPaths.GetCount(); ++i) - { - CTGitPath path; - int action; - path.SetFromWin(g_Git.m_CurrentDir+_T("\\")+m_selectedPaths[i].GetWinPath()); - action = m_selectedPaths[i].m_Action; - /* rename file can't delete because it needs original file*/ - if((!(action & CTGitPath::LOGACTIONS_ADDED)) && - (!(action & CTGitPath::LOGACTIONS_REPLACED))) - delList.AddPath(path); - } - if (DWORD(CRegDWORD(_T("Software\\TortoiseGit\\RevertWithRecycleBin"), TRUE))) - delList.DeleteAllFiles(true); - - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_REVERT))); - for (int i = 0; i < m_selectedPaths.GetCount(); ++i) - { - if(g_Git.Revert(_T("HEAD"), (CTGitPath&)m_selectedPaths[i])) - { - CMessageBox::Show(NULL,_T("Revert Fail"),_T("TortoiseGit"),MB_OK|MB_ICONERROR); - m_bErrorsOccurred=true; - return false; - } - Notify(m_selectedPaths[i],git_wc_notify_revert); - } - - CShellUpdater::Instance().AddPathsForUpdate(m_selectedPaths); - - return true; -} - -bool CGitProgressDlg::CmdSwitch(CString& /*sWindowTitle*/, bool& /*localoperation*/) -{ -#if 0 - ASSERT(m_targetPathList.GetCount() == 1); - SVNStatus st; - sWindowTitle.LoadString(IDS_PROGRS_TITLE_SWITCH); - SetWindowText(sWindowTitle); // needs to be updated, see TSVN rev. 21375 - SetBackgroundImage(IDI_SWITCH_BKG); - LONG rev = 0; - if (st.GetStatus(m_targetPathList[0]) != (-2)) - { - if (st.status->entry != NULL) - { - rev = st.status->entry->revision; - } - } - - CString sCmdInfo; - sCmdInfo.Format(IDS_PROGRS_CMD_SWITCH, - m_targetPathList[0].GetWinPath(), (LPCTSTR)m_url.GetSVNPathString(), - (LPCTSTR)m_Revision.ToString()); - ReportCmd(sCmdInfo); - - bool depthIsSticky = true; - if (m_depth == svn_depth_unknown) - depthIsSticky = false; - if (!Switch(m_targetPathList[0], m_url, m_Revision, m_Revision, m_depth, depthIsSticky, m_options & ProgOptIgnoreExternals)) - { - ReportSVNError(); - return false; - } - m_UpdateStartRevMap[m_targetPathList[0].GetSVNApiPath(pool)] = rev; - if ((m_RevisionEnd >= 0)&&(rev >= 0) - &&((LONG)m_RevisionEnd > (LONG)rev)) - { - GetDlgItem(IDC_LOGBUTTON)->ShowWindow(SW_SHOW); - } -#endif - return true; -} -bool CGitProgressDlg::CmdClone(CString& sWindowTitle, bool& /*localoperation*/) -{ - if (!g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE)) - { - // should never run to here - ASSERT(FALSE); - return false; - } - this->m_TotalBytesTransferred = 0; - - sWindowTitle.LoadString(IDS_PROGRS_TITLE_CLONE); - CAppUtils::SetWindowTitle(m_hWnd, m_url.GetGitPathString(), sWindowTitle); - SetBackgroundImage(IDI_SWITCH_BKG); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROG_CLONE))); - - if (m_url.IsEmpty() || m_targetPathList.GetCount() == 0) - return false; - - CStringA url = CUnicodeUtils::GetMulti(m_url.GetGitPathString(), CP_UTF8); - CStringA path = CUnicodeUtils::GetMulti(m_targetPathList[0].GetWinPathString(),CP_UTF8); - - git_repository *cloned_repo = NULL; - git_remote *origin = NULL; - git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT; - - int error = 0; - - git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT; - - clone_opts.checkout_opts = checkout_opts; - - clone_opts.checkout_opts.checkout_strategy = m_bNoCheckout? GIT_CHECKOUT_NONE : GIT_CHECKOUT_SAFE_CREATE; - clone_opts.checkout_opts.progress_cb = CheckoutCallback; - clone_opts.checkout_opts.progress_payload = this; - - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; - - callbacks.update_tips = RemoteUpdatetipsCallback; - callbacks.progress = RemoteProgressCallback; - callbacks.completion = RemoteCompletionCallback; - callbacks.payload = this; - - clone_opts.remote_callbacks = &callbacks; - - if (!m_RefSpec.IsEmpty()) - clone_opts.checkout_branch = CUnicodeUtils::GetMulti(m_RefSpec, CP_UTF8).GetBuffer(); - - clone_opts.fetch_progress_cb = FetchCallback; - clone_opts.fetch_progress_payload = this; - - clone_opts.cred_acquire_cb = CAppUtils::Git2GetUserPassword; - - clone_opts.bare = m_bBare; - - m_Animate.ShowWindow(SW_SHOW); - m_Animate.Play(0, INT_MAX, INT_MAX); - error = git_clone(&cloned_repo, url, path, &clone_opts); - m_Animate.Stop(); - m_Animate.ShowWindow(SW_HIDE); - - git_remote_free(origin); - if (error) - { - ReportGitError(); - return false; - } - else if (cloned_repo) - git_repository_free(cloned_repo); - return true; -} - -void CGitProgressDlg::OnBnClickedNoninteractive() -{ - LRESULT res = ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_GETCHECK, 0, 0); - m_AlwaysConflicted = (res == BST_CHECKED); - CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE); - nonint = m_AlwaysConflicted; -} - -CString CGitProgressDlg::GetPathFromColumnText(const CString& sColumnText) -{ - CString sPath = sColumnText; - if (sPath.Find(':')<0) - { - // the path is not absolute: add the common root of all paths to it - sPath = g_Git.m_CurrentDir + _T("\\") + sColumnText; - } - return sPath; -} - -bool CGitProgressDlg::CmdSendMail(CString& sWindowTitle, bool& /*localoperation*/) -{ - sWindowTitle.LoadString(IDS_PROGRS_TITLE_SENDMAIL); - CAppUtils::SetWindowTitle(m_hWnd, m_targetPathList.GetCommonRoot().GetUIPathString(), sWindowTitle); - //SetBackgroundImage(IDI_ADD_BKG); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_SENDMAIL))); - bool ret=true; - if(this->m_SendMailFlags&SENDMAIL_COMBINED) - { - CString error; - CTGitPath path; - Notify(path,git_wc_notify_sendmail_start); - CString err; - int retry=0; - while(retry <3) - { - if(!!CPatch::SendPatchesCombined(m_targetPathList,m_SendMailTO,m_SendMailCC,m_SendMailSubject,!!(this->m_SendMailFlags&SENDMAIL_ATTACHMENT),!!(this->m_SendMailFlags&SENDMAIL_MAPI),&err)) - { - Notify(path,git_wc_notify_sendmail_error,ret,&err); - ret = false; - } - else - { - break; - } - - ++retry; - if (retry < 3) - Notify(path,git_wc_notify_sendmail_retry,ret,&err); - Sleep(2000); - if(m_bCancelled) - { - CString str; - str.LoadString(IDS_SVN_USERCANCELLED); - Notify(path,git_wc_notify_sendmail_error,ret,&str); - return false; - } - } - if (ret) - Notify(path,git_wc_notify_sendmail_done,ret); - } - else - { - for (int i = 0; ret && i < m_targetPathList.GetCount(); ++i) - { - CPatch patch; - Notify(m_targetPathList[i],git_wc_notify_sendmail_start); - - int retry=0; - while(retry<3) - { - if(!!patch.Send((CString&)m_targetPathList[i].GetWinPathString(),this->m_SendMailTO, - this->m_SendMailCC,!!(this->m_SendMailFlags&SENDMAIL_ATTACHMENT),!!(this->m_SendMailFlags&SENDMAIL_MAPI))) - { - Notify(m_targetPathList[i],git_wc_notify_sendmail_error,ret,&patch.m_LastError); - ret = false; - - } - else - { - ret = true; - break; - } - ++retry; - if (retry < 3) - Notify(m_targetPathList[i],git_wc_notify_sendmail_retry,ret,&patch.m_LastError); - Sleep(2000); - if(m_bCancelled) - { - CString str; - str.LoadString(IDS_SVN_USERCANCELLED); - Notify(m_targetPathList[i],git_wc_notify_sendmail_error,ret,&str); - return false; - } - } - if (ret) - Notify(m_targetPathList[i],git_wc_notify_sendmail_done,ret); - } - } - return ret; -} - -LRESULT CGitProgressDlg::OnTaskbarBtnCreated(WPARAM /*wParam*/, LPARAM /*lParam*/) -{ - m_pTaskbarList.Release(); - m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList); - return 0; -} - -HBRUSH CGitProgressDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr; - if (pWnd->GetDlgCtrlID() == IDC_TITLE_ANIMATE) - { - pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); // add this - pDC->SetBkMode(TRANSPARENT); - return (HBRUSH)m_background_brush.GetSafeHandle(); - } - else - hbr = CResizableStandAloneDialog::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: Return a different brush if the default is not desired - return hbr; -} -LRESULT CGitProgressDlg::OnCtlColorStatic(WPARAM wParam, LPARAM lParam) -{ - HDC hDC = (HDC)wParam; - HWND hwndCtl = (HWND)lParam; - - if (::GetDlgCtrlID(hwndCtl) == IDC_TITLE_ANIMATE) - { - CDC *pDC = CDC::FromHandle(hDC); - pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); - pDC->SetBkMode(TRANSPARENT); - return (LRESULT)(HBRUSH)m_background_brush.GetSafeHandle(); - } - return FALSE; -} - -bool CGitProgressDlg::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) -{ - if (!g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE)) - { - // should never run to here - ASSERT(0); - return false; - } - this->m_TotalBytesTransferred = 0; - - sWindowTitle.LoadString(IDS_PROGRS_TITLE_FETCH); - CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle); - SetBackgroundImage(IDI_UPDATE_BKG); - ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_TITLE_FETCH))); - - CStringA url = CUnicodeUtils::GetMulti(m_url.GetGitPathString(), CP_UTF8); - CStringA gitdir = CUnicodeUtils::GetMulti(CTGitPath(g_Git.m_CurrentDir).GetGitPathString(), CP_UTF8); - CStringA remotebranch = CUnicodeUtils::GetMulti(m_RefSpec, CP_UTF8); - - git_remote *remote = NULL; - git_repository *repo = NULL; - bool ret = true; - - do - { - if (git_repository_open(&repo, gitdir.GetBuffer())) - { - gitdir.ReleaseBuffer(); - ReportGitError(); - ret = false; - break; - } - - // first try with a named remote (e.g. "origin") - if (git_remote_load(&remote, repo, url) < 0) - { - // retry with repository located at a specific url - if (git_remote_create_inmemory(&remote, repo, NULL, url) < 0) - { - ReportGitError(); - ret = false; - break; - } - } - - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; - - callbacks.update_tips = RemoteUpdatetipsCallback; - callbacks.progress = RemoteProgressCallback; - callbacks.completion = RemoteCompletionCallback; - callbacks.payload = this; - - git_remote_set_callbacks(remote, &callbacks); - git_remote_set_cred_acquire_cb(remote, CAppUtils::Git2GetUserPassword, NULL); - git_remote_set_autotag(remote, (git_remote_autotag_option_t)m_AutoTag); - - if (!remotebranch.IsEmpty() && git_remote_set_fetchspec(remote, remotebranch)) - { - ReportGitError(); - ret = false; - break; - } - - m_Animate.ShowWindow(SW_SHOW); - m_Animate.Play(0, INT_MAX, INT_MAX); - - // Connect to the remote end specifying that we want to fetch - // information from it. - if (git_remote_connect(remote, GIT_DIRECTION_FETCH) < 0) { - ReportGitError(); - ret = false; - break; - } - - // Download the packfile and index it. This function updates the - // amount of received data and the indexer stats which lets you - // inform the user about progress. - if (git_remote_download(remote, FetchCallback, this) < 0) { - ReportGitError(); - ret = false; - break; - } - - m_Animate.ShowWindow(SW_HIDE); - // Update the references in the remote's namespace to point to the - // right commits. This may be needed even if there was no packfile - // to download, which can happen e.g. when the branches have been - // changed but all the neede objects are available locally. - if (git_remote_update_tips(remote) < 0) - { - ReportGitError(); - ret = false; - break; - } - - git_remote_disconnect(remote); - - } while(0); - - git_remote_free(remote); - git_repository_free(repo); - m_Animate.ShowWindow(SW_HIDE); - return ret; -} +// TortoiseGit - a Windows shell extension for easy version control + +// Copyright (C) 2008-2013 - TortoiseGit +// Copyright (C) 2003-2008 - TortoiseSVN + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#include "stdafx.h" +#include "TortoiseProc.h" +#include "messagebox.h" +#include "GITProgressDlg.h" +#include "LogDlg.h" +#include "TGitPath.h" +#include "registry.h" +#include "GitStatus.h" +#include "AppUtils.h" +#include "PathUtils.h" +#include "StringUtils.h" +#include "TempFile.h" +#include "UnicodeUtils.h" +#include "SoundUtils.h" +#include "GitDiff.h" +#include "Hooks.h" +#include "DropFiles.h" +//#include "GitLogHelper.h" +#include "RegHistory.h" +//#include "ConflictResolveDlg.h" +#include "LogFile.h" +#include "ShellUpdater.h" +#include "IconMenu.h" +#include "BugTraqAssociations.h" +#include "patch.h" +#include "MassiveGitTask.h" +#include "SmartHandle.h" + + +IMPLEMENT_DYNAMIC(CGitProgressDlg, CResizableStandAloneDialog) +CGitProgressDlg::CGitProgressDlg(CWnd* pParent /*=NULL*/) + : CResizableStandAloneDialog(CGitProgressDlg::IDD, pParent) + +#if 0 + , m_Revision(_T("HEAD")) + //, m_RevisionEnd(0) + , m_bLockWarning(false) + , m_bLockExists(false) + , m_bThreadRunning(FALSE) + , m_nConflicts(0) + , m_bMergesAddsDeletesOccurred(FALSE) + , m_dwCloseOnEnd((DWORD)-1) + , m_bFinishedItemAdded(false) + , m_bLastVisible(false) +// , m_depth(svn_depth_unknown) + , m_itemCount(-1) + , m_itemCountTotal(-1) + , m_AlwaysConflicted(false) + , m_BugTraqProvider(NULL) + , sDryRun(MAKEINTRESOURCE(IDS_PROGRS_DRYRUN)) + , sRecordOnly(MAKEINTRESOURCE(IDS_MERGE_RECORDONLY)) +#endif +{ +} + +CGitProgressDlg::~CGitProgressDlg() +{ +} + +void CGitProgressDlg::DoDataExchange(CDataExchange* pDX) +{ + CResizableStandAloneDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_SVNPROGRESS, m_ProgList); + DDX_Control(pDX, IDC_TITLE_ANIMATE, m_Animate); +} + +BEGIN_MESSAGE_MAP(CGitProgressDlg, CResizableStandAloneDialog) + ON_BN_CLICKED(IDC_LOGBUTTON, OnBnClickedLogbutton) + ON_WM_CLOSE() + ON_WM_SETCURSOR() + ON_EN_SETFOCUS(IDC_INFOTEXT, &CGitProgressDlg::OnEnSetfocusInfotext) + ON_BN_CLICKED(IDC_NONINTERACTIVE, &CGitProgressDlg::OnBnClickedNoninteractive) + ON_WM_CTLCOLOR() +END_MESSAGE_MAP() + + + + +BOOL CGitProgressDlg::OnInitDialog() +{ + __super::OnInitDialog(); + + + UpdateData(FALSE); + + AddAnchor(IDC_SVNPROGRESS, TOP_LEFT, BOTTOM_RIGHT); + AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, BOTTOM_RIGHT); + AddAnchor(IDC_PROGRESSLABEL, BOTTOM_LEFT, BOTTOM_CENTER); + AddAnchor(IDC_PROGRESSBAR, BOTTOM_CENTER, BOTTOM_RIGHT); + AddAnchor(IDC_INFOTEXT, BOTTOM_LEFT, BOTTOM_RIGHT); + AddAnchor(IDC_NONINTERACTIVE, BOTTOM_LEFT, BOTTOM_RIGHT); + AddAnchor(IDCANCEL, BOTTOM_RIGHT); + AddAnchor(IDOK, BOTTOM_RIGHT); + AddAnchor(IDC_LOGBUTTON, BOTTOM_RIGHT); + //SetPromptParentWindow(this->m_hWnd); + + m_Animate.Open(IDR_DOWNLOAD); + m_ProgList.m_pAnimate = &m_Animate; + + if (hWndExplorer) + CenterWindow(CWnd::FromHandle(hWndExplorer)); + EnableSaveRestore(_T("GITProgressDlg")); + + m_background_brush.CreateSolidBrush(GetSysColor(COLOR_WINDOW)); + return TRUE; +} + + + +void CGitProgressDlg::OnBnClickedLogbutton() +{ + switch(m_ProgList.m_Command) + { + case CGitProgressList::GitProgress_Add: + case CGitProgressList::GitProgress_Resolve: + { + CString cmd = _T(" /command:commit"); + cmd += _T(" /path:\"")+g_Git.m_CurrentDir+_T("\""); + + CAppUtils::RunTortoiseGitProc(cmd); + this->EndDialog(IDOK); + break; + } + } +#if 0 + if (m_targetPathList.GetCount() != 1) + return; + StringRevMap::iterator it = m_UpdateStartRevMap.begin(); + svn_revnum_t rev = -1; + if (it != m_UpdateStartRevMap.end()) + { + rev = it->second; + } + CLogDlg dlg; + dlg.SetParams(m_targetPathList[0], m_RevisionEnd, m_RevisionEnd, rev, 0, TRUE); + dlg.DoModal(); +#endif +} + + +void CGitProgressDlg::OnClose() +{ + DialogEnableWindow(IDCANCEL, TRUE); + __super::OnClose(); +} + +void CGitProgressDlg::OnOK() +{ + if ((m_ProgList.IsCancelled())&&(!m_ProgList.IsRunning())) + { + // I have made this wait a sensible amount of time (10 seconds) for the thread to finish + // You must be careful in the thread that after posting the WM_COMMAND/IDOK message, you + // don't do any more operations on the window which might require message passing + // If you try to send windows messages once we're waiting here, then the thread can't finished + // because the Window's message loop is blocked at this wait + WaitForSingleObject(m_ProgList.m_pThread->m_hThread, 10000); + __super::OnOK(); + } + m_ProgList.Cancel(); +} + +void CGitProgressDlg::OnCancel() +{ + if ((m_ProgList.IsCancelled())&&(!m_ProgList.IsRunning())) + __super::OnCancel(); + m_ProgList.Cancel(); +} + + +BOOL CGitProgressDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) +{ + if (!GetDlgItem(IDOK)->IsWindowEnabled()) + { + // only show the wait cursor over the list control + if ((pWnd)&&(pWnd == GetDlgItem(IDC_SVNPROGRESS))) + { + HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)); + SetCursor(hCur); + return TRUE; + } + } + HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); + SetCursor(hCur); + return CResizableStandAloneDialog::OnSetCursor(pWnd, nHitTest, message); +} + +BOOL CGitProgressDlg::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN) + { + if (pMsg->wParam == VK_ESCAPE) + { + // pressing the ESC key should close the dialog. But since we disabled the escape + // key (so the user doesn't get the idea that he could simply undo an e.g. update) + // this won't work. + // So if the user presses the ESC key, change it to VK_RETURN so the dialog gets + // the impression that the OK button was pressed. + if ((!m_ProgList.IsRunning())&&(!GetDlgItem(IDCANCEL)->IsWindowEnabled()) + &&(GetDlgItem(IDOK)->IsWindowEnabled())&&(GetDlgItem(IDOK)->IsWindowVisible())) + { + // since we convert ESC to RETURN, make sure the OK button has the focus. + GetDlgItem(IDOK)->SetFocus(); + pMsg->wParam = VK_RETURN; + } + } + } + return __super::PreTranslateMessage(pMsg); +} + + + +void CGitProgressDlg::OnEnSetfocusInfotext() +{ + CString sTemp; + GetDlgItemText(IDC_INFOTEXT, sTemp); + if (sTemp.IsEmpty()) + GetDlgItem(IDC_INFOTEXT)->HideCaret(); +} + + +void CGitProgressDlg::OnBnClickedNoninteractive() +{ + LRESULT res = ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_GETCHECK, 0, 0); + m_ProgList.m_AlwaysConflicted = (res == BST_CHECKED); + CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE); + nonint = m_ProgList.m_AlwaysConflicted; +} + +LRESULT CGitProgressDlg::OnCtlColorStatic(WPARAM wParam, LPARAM lParam) +{ + HDC hDC = (HDC)wParam; + HWND hwndCtl = (HWND)lParam; + + if (::GetDlgCtrlID(hwndCtl) == IDC_TITLE_ANIMATE) + { + CDC *pDC = CDC::FromHandle(hDC); + pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); + pDC->SetBkMode(TRANSPARENT); + return (LRESULT)(HBRUSH)m_background_brush.GetSafeHandle(); + } + return FALSE; +} + +HBRUSH CGitProgressDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + HBRUSH hbr; + if (pWnd->GetDlgCtrlID() == IDC_TITLE_ANIMATE) + { + pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); // add this + pDC->SetBkMode(TRANSPARENT); + return (HBRUSH)m_background_brush.GetSafeHandle(); + } + else + hbr = CResizableStandAloneDialog::OnCtlColor(pDC, pWnd, nCtlColor); + + // TODO: Return a different brush if the default is not desired + return hbr; +} \ No newline at end of file diff --git a/src/TortoiseProc/GitProgressDlg.h b/src/TortoiseProc/GitProgressDlg.h dissimilarity index 77% index c042bbfe3..5f0672cb8 100644 --- a/src/TortoiseProc/GitProgressDlg.h +++ b/src/TortoiseProc/GitProgressDlg.h @@ -1,411 +1,116 @@ -// TortoiseGit - a Windows shell extension for easy version control - -// Copyright (C) 2008-2013 - TortoiseGit -// Copyright (C) 2003-2008 - TortoiseSVN - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -#pragma once - -#include "StandAloneDlg.h" -#include "TGitPath.h" -#include "ProjectProperties.h" -#include "Git.h" -#include "GitStatus.h" -#include "Colors.h" -//#include "..\IBugTraqProvider\IBugTraqProvider_h.h" -#include "afxwin.h" -#include "Win7.h" -#include "UnicodeUtils.h" - -typedef int (__cdecl *GENERICCOMPAREFN)(const void * elem1, const void * elem2); -struct git_transfer_progress; - -/** - * \ingroup TortoiseProc - * Options which can be used to configure the way the dialog box works - */ -typedef enum -{ - ProgOptNone = 0, - ProgOptRecursive = 0x01, - ProgOptNonRecursive = 0x00, - /// Don't actually do the merge - just practice it - ProgOptDryRun = 0x04, - ProgOptIgnoreExternals = 0x08, - ProgOptKeeplocks = 0x10, - /// for locking this means steal the lock, for unlocking it means breaking the lock - ProgOptLockForce = 0x20, - ProgOptSwitchAfterCopy = 0x40, - ProgOptIncludeIgnored = 0x80, - ProgOptIgnoreAncestry = 0x100, - ProgOptEolDefault = 0x200, - ProgOptEolCRLF = 0x400, - ProgOptEolLF = 0x800, - ProgOptEolCR = 0x1000, - ProgOptSkipConflictCheck = 0x2000, - ProgOptRecordOnly = 0x4000 -} ProgressOptions; - -typedef enum -{ - CLOSE_MANUAL = 0, - CLOSE_NOERRORS, - CLOSE_NOCONFLICTS, - CLOSE_NOMERGES, - CLOSE_LOCAL -} ProgressCloseOptions; - -#define WM_SHOWCONFLICTRESOLVER (WM_APP + 100) - -typedef enum -{ - git_wc_notify_add, - git_wc_notify_sendmail_start, - git_wc_notify_sendmail_error, - git_wc_notify_sendmail_retry, - git_wc_notify_sendmail_done, - git_wc_notify_resolved, - git_wc_notify_revert, - git_wc_notify_fetch, - git_wc_notify_checkout, - git_wc_notify_update_ref, - -}git_wc_notify_action_t; -typedef enum -{ - SENDMAIL_ATTACHMENT =0x1, - SENDMAIL_COMBINED =0x2, - SENDMAIL_MAPI =0x4 -}; -/** - * \ingroup TortoiseProc - * Handles different Subversion commands and shows the notify messages - * in a listbox. Since several Subversion commands have similar notify - * messages they are grouped together in this single class. - */ -class CGitProgressDlg : public CResizableStandAloneDialog -{ -public: - typedef enum - { - GitProgress_Add, - GitProgress_Checkout, - GitProgress_Copy, - GitProgress_Export, - GitProgress_Rename, - GitProgress_Resolve, - GitProgress_Revert, - GitProgress_Switch, - GitProgress_SendMail, - GitProgress_Clone, - GitProgress_Fetch, - } Command; - - - DECLARE_DYNAMIC(CGitProgressDlg) - -public: - - CGitProgressDlg(CWnd* pParent = NULL); - virtual ~CGitProgressDlg(); - - - void SetCommand(Command cmd) {m_Command = cmd;} - void SetAutoClose(DWORD ac) {m_dwCloseOnEnd = ac;} - void SetOptions(DWORD opts) {m_options = opts;} - void SetPathList(const CTGitPathList& pathList) {m_targetPathList = pathList;} - void SetUrl(const CString& url) {m_url.SetFromUnknown(url);} - void SetSecondUrl(const CString& url) {m_url2.SetFromUnknown(url);} - void SetCommitMessage(const CString& msg) {m_sMessage = msg;} - void SetIsBare(bool b) { m_bBare = b; } - void SetNoCheckout(bool b){ m_bNoCheckout = b; } - void SetRefSpec(CString spec){ m_RefSpec = spec; } - void SetAutoTag(int tag){ m_AutoTag = tag; } - -// void SetRevision(const GitRev& rev) {m_Revision = rev;} -// void SetRevisionEnd(const GitRev& rev) {m_RevisionEnd = rev;} - - void SetDiffOptions(const CString& opts) {m_diffoptions = opts;} - void SetSendMailOption(CString &TO, CString &CC,CString &Subject,DWORD flags){m_SendMailTO=TO;m_SendMailSubject=Subject; m_SendMailCC=CC;this->m_SendMailFlags = flags;} - void SetDepth(git_depth_t depth = git_depth_unknown) {m_depth = depth;} - void SetPegRevision(GitRev pegrev = GitRev()) {m_pegRev = pegrev;} - void SetProjectProperties(ProjectProperties props) {m_ProjectProperties = props;} - void SetChangeList(const CString& changelist, bool keepchangelist) {m_changelist = changelist; m_keepchangelist = keepchangelist;} - void SetSelectedList(const CTGitPathList& selPaths); -// void SetRevisionRanges(const GitRevRangeArray& revArray) {m_revisionArray = revArray;} -// void SetBugTraqProvider(const CComPtr pBugtraqProvider) { m_BugTraqProvider = pBugtraqProvider;} - /** - * If the number of items for which the operation is done on is known - * beforehand, that number can be set here. It is then used to show a more - * accurate progress bar during the operation. - */ - void SetItemCount(long count) {if(count) m_itemCountTotal = count;} - - bool SetBackgroundImage(UINT nID); - - bool DidErrorsOccur() {return m_bErrorsOccurred;} - - enum { IDD = IDD_SVNPROGRESS }; - -private: - class NotificationData - { - public: - NotificationData() - : color(::GetSysColor(COLOR_WINDOWTEXT)) - , action((git_wc_notify_action_t)-1) - , bConflictedActionItem(false) - , bAuxItem(false) - {}; - git_wc_notify_action_t action; -#if 0 - action((git_wc_notify_action_t)-1), - kind(git_node_none), - content_state(git_wc_notify_state_inapplicable), - prop_state(git_wc_notify_state_inapplicable), - rev(0), - - bConflictedActionItem(false), - bAuxItem(false) - //, -// lock_state(git_wc_notify_lock_state_unchanged) - { -// merge_range.end = 0; -// merge_range.start = 0; - } -#endif - public: - // The text we put into the first column (the Git action for normal items, just text for aux items) - CString sActionColumnText; - CTGitPath path; - CTGitPath basepath; -// CString changelistname; - -// git_node_kind_t kind; -// CString mime_type; -// git_wc_notify_state_t content_state; -// git_wc_notify_state_t prop_state; -// git_wc_notify_lock_state_t lock_state; -// git_merge_range_t merge_range; - git_revnum_t rev; - COLORREF color; -// CString owner; ///< lock owner - bool bConflictedActionItem; // Is this item a conflict? - bool bAuxItem; // Set if this item is not a true 'Git action' - CString sPathColumnText; - CGitHash m_OldHash; - CGitHash m_NewHash; - - }; -protected: - - //Need update in the future implement the virtual methods from Git base class - virtual BOOL Notify(const CTGitPath& path, - git_wc_notify_action_t action, - int status = 0, - CString *strErr =NULL - /* - git_node_kind_t kind, const CString& mime_type, - git_wc_notify_state_t content_state, - git_wc_notify_state_t prop_state, LONG rev, - const git_lock_t * lock, git_wc_notify_lock_state_t lock_state, - const CString& changelistname, - git_merge_range_t * range, - git_error_t * err, apr_pool_t * pool*/ - ); - virtual BOOL Notify(const git_wc_notify_action_t action, const git_transfer_progress *stat); - virtual BOOL Notify(const git_wc_notify_action_t action, CString str, const git_oid *a, const git_oid *b); - -// virtual git_wc_conflict_choice_t ConflictResolveCallback(const git_wc_conflict_description_t *description, CString& mergedfile); - - static int FetchCallback(const git_transfer_progress *stats, void *payload) - { - return !((CGitProgressDlg*)payload) -> Notify(git_wc_notify_fetch, stats); - } - - static void CheckoutCallback(const char *path, size_t cur, size_t tot, void *payload) - { - CTGitPath tpath = CUnicodeUtils::GetUnicode(CStringA(path), CP_UTF8); - ((CGitProgressDlg*)payload) -> m_itemCountTotal = tot; - ((CGitProgressDlg*)payload) -> m_itemCount = cur; - ((CGitProgressDlg*)payload) -> Notify(tpath, git_wc_notify_checkout); - } - - static void RemoteProgressCallback(const char *str, int len, void *data) - { - CString progText; - progText = CUnicodeUtils::GetUnicode(CStringA(str, len)); - ((CGitProgressDlg*)data) -> SetDlgItemText(IDC_PROGRESSLABEL, progText); - } - static int RemoteCompletionCallback(git_remote_completion_type /*type*/, void * /*data*/) - { - return 0; - } - static int RemoteUpdatetipsCallback(const char *refname, const git_oid *a, const git_oid *b, void *data) - { - CString str; - str = CUnicodeUtils::GetUnicode(refname); - ((CGitProgressDlg*)data) -> Notify(git_wc_notify_update_ref, str, a, b); - return 0; - } - - virtual BOOL OnInitDialog(); - virtual BOOL Cancel(); - virtual void OnCancel(); - virtual BOOL PreTranslateMessage(MSG* pMsg); - virtual void DoDataExchange(CDataExchange* pDX); - - afx_msg void OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMDblclkSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnBnClickedLogbutton(); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedNoninteractive(); - afx_msg void OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); - afx_msg void OnClose(); - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg LRESULT OnGitProgress(WPARAM wParam, LPARAM lParam); - afx_msg void OnTimer(UINT_PTR nIDEvent); - afx_msg void OnEnSetfocusInfotext(); - afx_msg void OnLvnBegindragSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg LRESULT OnTaskbarBtnCreated(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnCtlColorStatic(WPARAM wParam, LPARAM lParam); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); - LRESULT OnShowConflictResolver(WPARAM, LPARAM); - - DECLARE_MESSAGE_MAP() - - void Sort(); - static bool SortCompare(const NotificationData* pElem1, const NotificationData* pElem2); - - static BOOL m_bAscending; - static int m_nSortedColumn; - CStringList m_ExtStack; - -private: - static UINT ProgressThreadEntry(LPVOID pVoid); - UINT ProgressThread(); - virtual void OnOK(); - void ReportGitError(); - void ReportError(const CString& sError); - void ReportWarning(const CString& sWarning); - void ReportNotification(const CString& sNotification); - void ReportCmd(const CString& sCmd); - void ReportString(CString sMessage, const CString& sMsgKind, COLORREF color = ::GetSysColor(COLOR_WINDOWTEXT)); - void AddItemToList(); - CString BuildInfoString(); - CString GetPathFromColumnText(const CString& sColumnText); - - /** - * Resizes the columns of the progress list so that the headings are visible. - */ - void ResizeColumns(); - - /// Predicate function to tell us if a notification data item is auxiliary or not - static bool NotificationDataIsAux(const NotificationData* pData); - - // the commands to execute - bool CmdAdd(CString& sWindowTitle, bool& localoperation); - bool CmdCheckout(CString& sWindowTitle, bool& localoperation); - bool CmdCopy(CString& sWindowTitle, bool& localoperation); - bool CmdExport(CString& sWindowTitle, bool& localoperation); - bool CmdRename(CString& sWindowTitle, bool& localoperation); - bool CmdResolve(CString& sWindowTitle, bool& localoperation); - bool CmdRevert(CString& sWindowTitle, bool& localoperation); - bool CmdSwitch(CString& sWindowTitle, bool& localoperation); - bool CmdSendMail(CString& sWindowTitle, bool& localoperation); - bool CmdClone(CString& sWindowTitle, bool& localoperation); - bool CmdFetch(CString& sWindowTitle, bool& localoperation); - -private: - typedef std::map StringRevMap; - typedef std::vector NotificationDataVect; - - - CString m_mergedfile; - NotificationDataVect m_arData; - CAnimateCtrl m_Animate; - CWinThread* m_pThread; - volatile LONG m_bThreadRunning; - - ProjectProperties m_ProjectProperties; - CListCtrl m_ProgList; - Command m_Command; - int m_options; // Use values from the ProgressOptions enum - git_depth_t m_depth; - CTGitPathList m_targetPathList; - CTGitPathList m_selectedPaths; - CTGitPath m_url; - CTGitPath m_url2; - CString m_sMessage; - CString m_diffoptions; - GitRev m_Revision; - GitRev m_RevisionEnd; - GitRev m_pegRev; -// GitRevRangeArray m_revisionArray; - CString m_changelist; - bool m_keepchangelist; - - DWORD m_dwCloseOnEnd; - - CTGitPath m_basePath; - StringRevMap m_UpdateStartRevMap; - StringRevMap m_FinishedRevMap; - - TCHAR m_columnbuf[MAX_PATH]; - - volatile BOOL m_bCancelled; - int m_nConflicts; - bool m_bErrorsOccurred; - bool m_bMergesAddsDeletesOccurred; - - int iFirstResized; - BOOL bSecondResized; - int nEnsureVisibleCount; - - CString m_sTotalBytesTransferred; - size_t m_TotalBytesTransferred; - - CColors m_Colors; - - bool m_bFinishedItemAdded; - bool m_bLastVisible; - - int m_itemCount; - int m_itemCountTotal; - - bool m_AlwaysConflicted; - - DWORD m_SendMailFlags; - CString m_SendMailTO; - CString m_SendMailCC; - CString m_SendMailSubject; - -/// CComPtr m_BugTraqProvider; - CComPtr m_pTaskbarList; - - // some strings different methods can use - CString sDryRun; - CString sRecordOnly; - - bool m_bBare; - bool m_bNoCheckout; - CString m_RefSpec; - CBrush m_background_brush; - int m_AutoTag; -}; +// TortoiseGit - a Windows shell extension for easy version control + +// Copyright (C) 2008-2013 - TortoiseGit +// Copyright (C) 2003-2008 - TortoiseSVN + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once + +#include "StandAloneDlg.h" +#include "TGitPath.h" +#include "ProjectProperties.h" +#include "Git.h" +#include "GitStatus.h" +#include "Colors.h" +//#include "..\IBugTraqProvider\IBugTraqProvider_h.h" +#include "afxwin.h" +#include "Win7.h" +#include "UnicodeUtils.h" +#include "GitProgressList.h" + +typedef int (__cdecl *GENERICCOMPAREFN)(const void * elem1, const void * elem2); + +/** + * \ingroup TortoiseProc + * Handles different Subversion commands and shows the notify messages + * in a listbox. Since several Subversion commands have similar notify + * messages they are grouped together in this single class. + */ +class CGitProgressDlg : public CResizableStandAloneDialog +{ +public: + + DECLARE_DYNAMIC(CGitProgressDlg) + +public: + + CGitProgressDlg(CWnd* pParent = NULL); + virtual ~CGitProgressDlg(); + + + void SetCommand(CGitProgressList::Command cmd) {m_ProgList.SetCommand(cmd);} + void SetAutoClose(DWORD ac) {m_dwCloseOnEnd = ac;} + void SetOptions(DWORD opts) {m_ProgList.SetOptions(opts);} + void SetPathList(const CTGitPathList& pathList) {m_ProgList.SetPathList(pathList);} + void SetUrl(const CString& url) {m_ProgList.SetUrl(url);} + void SetSecondUrl(const CString& url) {m_ProgList.SetSecondUrl(url);} + void SetCommitMessage(const CString& msg) {m_ProgList.SetCommitMessage(msg);} + void SetIsBare(bool b) { m_ProgList.SetIsBare(b); } + void SetNoCheckout(bool b){ m_ProgList.SetNoCheckout(b); } + void SetRefSpec(CString spec){ m_ProgList.SetRefSpec(spec); } + void SetAutoTag(int tag){ m_ProgList.SetAutoTag(tag); } + +// void SetRevision(const GitRev& rev) {m_Revision = rev;} +// void SetRevisionEnd(const GitRev& rev) {m_RevisionEnd = rev;} + + void SetDiffOptions(const CString& opts) {m_ProgList.SetDiffOptions(opts);} + void SetSendMailOption(CString &TO, CString &CC,CString &Subject,DWORD flags){m_ProgList.SetSendMailOption(TO, CC, Subject, flags);} + void SetDepth(git_depth_t depth = git_depth_unknown) {m_ProgList.SetDepth(depth);} + void SetPegRevision(GitRev pegrev = GitRev()) {m_ProgList.SetPegRevision(pegrev);} + void SetProjectProperties(ProjectProperties props) {m_ProgList.SetProjectProperties(props);} + void SetChangeList(const CString& changelist, bool keepchangelist) {m_ProgList.SetChangeList(changelist, keepchangelist);} + void SetSelectedList(const CTGitPathList& selPaths) {m_ProgList.SetSelectedList(selPaths);}; +// void SetRevisionRanges(const GitRevRangeArray& revArray) {m_revisionArray = revArray;} +// void SetBugTraqProvider(const CComPtr pBugtraqProvider) { m_BugTraqProvider = pBugtraqProvider;} + /** + * If the number of items for which the operation is done on is known + * beforehand, that number can be set here. It is then used to show a more + * accurate progress bar during the operation. + */ + void SetItemCount(long count) {if(count) m_ProgList.SetItemCount(count);} + + bool DidErrorsOccur() {return m_ProgList.m_bErrorsOccurred;} + + enum { IDD = IDD_SVNPROGRESS }; + + +protected: + + virtual BOOL OnInitDialog(); + virtual void OnCancel(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual void DoDataExchange(CDataExchange* pDX); + + afx_msg void OnBnClickedLogbutton(); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedNoninteractive(); + afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); + afx_msg void OnClose(); + afx_msg void OnEnSetfocusInfotext(); + afx_msg LRESULT OnCtlColorStatic(WPARAM wParam, LPARAM lParam); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + + DECLARE_MESSAGE_MAP() + +private: + virtual void OnOK(); + + CAnimateCtrl m_Animate; + CGitProgressList m_ProgList; + CBrush m_background_brush; + DWORD m_dwCloseOnEnd; + +}; diff --git a/src/TortoiseProc/GitProgressDlg.cpp b/src/TortoiseProc/GitProgressList.cpp similarity index 80% copy from src/TortoiseProc/GitProgressDlg.cpp copy to src/TortoiseProc/GitProgressList.cpp index 77a1d3a2b..06ea26b05 100644 --- a/src/TortoiseProc/GitProgressDlg.cpp +++ b/src/TortoiseProc/GitProgressList.cpp @@ -16,8 +16,9 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// + #include "stdafx.h" +#include "GitProgressList.h" #include "TortoiseProc.h" #include "messagebox.h" #include "GITProgressDlg.h" @@ -47,11 +48,12 @@ static UINT WM_GITPROGRESS = RegisterWindowMessage(_T("TORTOISEGIT_GITPROGRESS_MSG")); -BOOL CGitProgressDlg::m_bAscending = FALSE; -int CGitProgressDlg::m_nSortedColumn = -1; +BOOL CGitProgressList::m_bAscending = FALSE; +int CGitProgressList::m_nSortedColumn = -1; #define TRANSFERTIMER 100 #define VISIBLETIMER 101 +// CGitProgressList enum GITProgressDlgContextMenuCommands { @@ -68,9 +70,9 @@ enum GITProgressDlgContextMenuCommands ID_COPY }; -IMPLEMENT_DYNAMIC(CGitProgressDlg, CResizableStandAloneDialog) -CGitProgressDlg::CGitProgressDlg(CWnd* pParent /*=NULL*/) - : CResizableStandAloneDialog(CGitProgressDlg::IDD, pParent) +IMPLEMENT_DYNAMIC(CGitProgressList, CListCtrl) + +CGitProgressList::CGitProgressList():CListCtrl() , m_bCancelled(FALSE) , m_pThread(NULL) , m_bErrorsOccurred(false) @@ -78,29 +80,11 @@ CGitProgressDlg::CGitProgressDlg(CWnd* pParent /*=NULL*/) , m_bNoCheckout(false) , m_AutoTag(GIT_REMOTE_DOWNLOAD_TAGS_AUTO) , m_options(ProgOptNone) -#if 0 - , m_Revision(_T("HEAD")) - //, m_RevisionEnd(0) - , m_bLockWarning(false) - , m_bLockExists(false) - , m_bThreadRunning(FALSE) - , m_nConflicts(0) - , m_bMergesAddsDeletesOccurred(FALSE) - , m_dwCloseOnEnd((DWORD)-1) - , m_bFinishedItemAdded(false) - , m_bLastVisible(false) -// , m_depth(svn_depth_unknown) - , m_itemCount(-1) - , m_itemCountTotal(-1) - , m_AlwaysConflicted(false) - , m_BugTraqProvider(NULL) - , sDryRun(MAKEINTRESOURCE(IDS_PROGRS_DRYRUN)) - , sRecordOnly(MAKEINTRESOURCE(IDS_MERGE_RECORDONLY)) -#endif { + } -CGitProgressDlg::~CGitProgressDlg() +CGitProgressList::~CGitProgressList() { for (size_t i = 0; i < m_arData.size(); ++i) { @@ -112,39 +96,34 @@ CGitProgressDlg::~CGitProgressDlg() } } -void CGitProgressDlg::DoDataExchange(CDataExchange* pDX) -{ - CResizableStandAloneDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_SVNPROGRESS, m_ProgList); - DDX_Control(pDX, IDC_TITLE_ANIMATE, m_Animate); -} -BEGIN_MESSAGE_MAP(CGitProgressDlg, CResizableStandAloneDialog) - ON_BN_CLICKED(IDC_LOGBUTTON, OnBnClickedLogbutton) - ON_NOTIFY(NM_CUSTOMDRAW, IDC_SVNPROGRESS, OnNMCustomdrawSvnprogress) - ON_WM_CLOSE() - ON_NOTIFY(NM_DBLCLK, IDC_SVNPROGRESS, OnNMDblclkSvnprogress) - ON_NOTIFY(HDN_ITEMCLICK, 0, OnHdnItemclickSvnprogress) - ON_WM_SETCURSOR() - ON_WM_CONTEXTMENU() +BEGIN_MESSAGE_MAP(CGitProgressList, CListCtrl) + ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawSvnprogress) + ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclkSvnprogress) + ON_NOTIFY_REFLECT(HDN_ITEMCLICK, OnHdnItemclickSvnprogress) ON_REGISTERED_MESSAGE(WM_GITPROGRESS, OnGitProgress) - ON_WM_TIMER() - ON_EN_SETFOCUS(IDC_INFOTEXT, &CGitProgressDlg::OnEnSetfocusInfotext) - ON_NOTIFY(LVN_BEGINDRAG, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnBegindragSvnprogress) - ON_WM_SIZE() - ON_NOTIFY(LVN_GETDISPINFO, IDC_SVNPROGRESS, &CGitProgressDlg::OnLvnGetdispinfoSvnprogress) - ON_BN_CLICKED(IDC_NONINTERACTIVE, &CGitProgressDlg::OnBnClickedNoninteractive) + ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnLvnBegindragSvnprogress) + ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfoSvnprogress) ON_MESSAGE(WM_SHOWCONFLICTRESOLVER, OnShowConflictResolver) ON_REGISTERED_MESSAGE(WM_TASKBARBTNCREATED, OnTaskbarBtnCreated) - ON_WM_CTLCOLOR() + ON_WM_SIZE() + ON_WM_TIMER() + ON_WM_CONTEXTMENU() + ON_WM_CREATE() + ON_WM_CLOSE() END_MESSAGE_MAP() -BOOL CGitProgressDlg::Cancel() +BOOL CGitProgressList::Cancel() { return m_bCancelled; } -LRESULT CGitProgressDlg::OnShowConflictResolver(WPARAM /*wParam*/, LPARAM /*lParam*/) + + +// CGitProgressList message handlers + + +LRESULT CGitProgressList::OnShowConflictResolver(WPARAM /*wParam*/, LPARAM /*lParam*/) { #if 0 CConflictResolveDlg dlg(this); @@ -178,7 +157,7 @@ LRESULT CGitProgressDlg::OnShowConflictResolver(WPARAM /*wParam*/, LPARAM /*lPar return 0; } #if 0 -svn_wc_conflict_choice_t CGitProgressDlg::ConflictResolveCallback(const svn_wc_conflict_description_t *description, CString& mergedfile) +svn_wc_conflict_choice_t CGitProgressList::ConflictResolveCallback(const svn_wc_conflict_description_t *description, CString& mergedfile) { // we only bother the user when merging if (((m_Command == GitProgress_Merge)||(m_Command == GitProgress_MergeAll)||(m_Command == GitProgress_MergeReintegrate))&&(!m_AlwaysConflicted)&&(description)) @@ -194,11 +173,11 @@ svn_wc_conflict_choice_t CGitProgressDlg::ConflictResolveCallback(const svn_wc_c return svn_wc_conflict_choose_postpone; } #endif -void CGitProgressDlg::AddItemToList() +void CGitProgressList::AddItemToList() { - int totalcount = m_ProgList.GetItemCount(); + int totalcount = GetItemCount(); - m_ProgList.SetItemCountEx(totalcount+1, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL); + SetItemCountEx(totalcount+1, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL); // make columns width fit if (iFirstResized < 30) { @@ -212,8 +191,8 @@ void CGitProgressDlg::AddItemToList() // Make sure the item is *entirely* visible even if the horizontal // scroll bar is visible. - int count = m_ProgList.GetCountPerPage(); - if (totalcount <= (m_ProgList.GetTopIndex() + count + nEnsureVisibleCount + 2)) + int count = GetCountPerPage(); + if (totalcount <= (GetTopIndex() + count + nEnsureVisibleCount + 2)) { ++nEnsureVisibleCount; m_bLastVisible = true; @@ -227,7 +206,7 @@ void CGitProgressDlg::AddItemToList() } -BOOL CGitProgressDlg::Notify(const CTGitPath& path, git_wc_notify_action_t action, +BOOL CGitProgressList::Notify(const CTGitPath& path, git_wc_notify_action_t action, int /*status*/ , CString *strErr /* @@ -248,7 +227,8 @@ BOOL CGitProgressDlg::Notify(const CTGitPath& path, git_wc_notify_action_t actio data->sPathColumnText=path.GetGitPathString(); data->bAuxItem = false; - this->m_Animate.ShowWindow(SW_HIDE); + if (this->m_pAnimate) + this->m_pAnimate->ShowWindow(SW_HIDE); #if 0 data->kind = kind; @@ -567,7 +547,7 @@ BOOL CGitProgressDlg::Notify(const CTGitPath& path, git_wc_notify_action_t actio } -CString CGitProgressDlg::BuildInfoString() +CString CGitProgressList::BuildInfoString() { CString infotext; if(this->m_Command == GitProgress_Resolve) @@ -714,28 +694,28 @@ CString CGitProgressDlg::BuildInfoString() return infotext; } -void CGitProgressDlg::SetSelectedList(const CTGitPathList& selPaths) +void CGitProgressList::SetSelectedList(const CTGitPathList& selPaths) { m_selectedPaths = selPaths; } -void CGitProgressDlg::ResizeColumns() +void CGitProgressList::ResizeColumns() { - m_ProgList.SetRedraw(FALSE); + SetRedraw(FALSE); TCHAR textbuf[MAX_PATH]; - int maxcol = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1; + int maxcol = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1; for (int col = 0; col <= maxcol; ++col) { // find the longest width of all items - int count = m_ProgList.GetItemCount(); + int count = GetItemCount(); HDITEM hdi = {0}; hdi.mask = HDI_TEXT; hdi.pszText = textbuf; hdi.cchTextMax = sizeof(textbuf); - ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItem(col, &hdi); - int cx = m_ProgList.GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin + ((CHeaderCtrl*)(GetDlgItem(0)))->GetItem(col, &hdi); + int cx = GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin for (int index = 0; indexsActionColumnText) + 12; + linewidth = GetStringWidth(m_arData[index]->sActionColumnText) + 12; break; case 1: - linewidth = m_ProgList.GetStringWidth(m_arData[index]->sPathColumnText) + 12; + linewidth = GetStringWidth(m_arData[index]->sPathColumnText) + 12; break; } if (cx < linewidth) cx = linewidth; } - m_ProgList.SetColumnWidth(col, cx); + SetColumnWidth(col, cx); } - m_ProgList.SetRedraw(TRUE); + SetRedraw(TRUE); } -BOOL CGitProgressDlg::OnInitDialog() +bool CGitProgressList::SetBackgroundImage(UINT nID) { - __super::OnInitDialog(); - - // Let the TaskbarButtonCreated message through the UIPI filter. If we don't - // do this, Explorer would be unable to send that message to our window if we - // were running elevated. It's OK to make the call all the time, since if we're - // not elevated, this is a no-op. - CHANGEFILTERSTRUCT cfs = { sizeof(CHANGEFILTERSTRUCT) }; - typedef BOOL STDAPICALLTYPE ChangeWindowMessageFilterExDFN(HWND hWnd, UINT message, DWORD action, PCHANGEFILTERSTRUCT pChangeFilterStruct); - CAutoLibrary hUser = AtlLoadSystemLibraryUsingFullPath(_T("user32.dll")); - if (hUser) - { - ChangeWindowMessageFilterExDFN *pfnChangeWindowMessageFilterEx = (ChangeWindowMessageFilterExDFN*)GetProcAddress(hUser, "ChangeWindowMessageFilterEx"); - if (pfnChangeWindowMessageFilterEx) - { - pfnChangeWindowMessageFilterEx(m_hWnd, WM_TASKBARBTNCREATED, MSGFLT_ALLOW, &cfs); - } - } - m_pTaskbarList.Release(); - if (FAILED(m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList))) - m_pTaskbarList = nullptr; - - m_ProgList.SetExtendedStyle (LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); - - m_ProgList.DeleteAllItems(); - int c = ((CHeaderCtrl*)(m_ProgList.GetDlgItem(0)))->GetItemCount()-1; - while (c>=0) - m_ProgList.DeleteColumn(c--); - CString temp; - temp.LoadString(IDS_PROGRS_ACTION); - m_ProgList.InsertColumn(0, temp); - temp.LoadString(IDS_PROGRS_PATH); - m_ProgList.InsertColumn(1, temp); - - m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); - if (m_pThread==NULL) - { - ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED))); - } - else - { - m_pThread->m_bAutoDelete = FALSE; - m_pThread->ResumeThread(); - } - - UpdateData(FALSE); - - // Call this early so that the column headings aren't hidden before any - // text gets added. - ResizeColumns(); - - SetTimer(VISIBLETIMER, 300, NULL); - - AddAnchor(IDC_SVNPROGRESS, TOP_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_TITLE_ANIMATE, TOP_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_PROGRESSLABEL, BOTTOM_LEFT, BOTTOM_CENTER); - AddAnchor(IDC_PROGRESSBAR, BOTTOM_CENTER, BOTTOM_RIGHT); - AddAnchor(IDC_INFOTEXT, BOTTOM_LEFT, BOTTOM_RIGHT); - AddAnchor(IDC_NONINTERACTIVE, BOTTOM_LEFT, BOTTOM_RIGHT); - AddAnchor(IDCANCEL, BOTTOM_RIGHT); - AddAnchor(IDOK, BOTTOM_RIGHT); - AddAnchor(IDC_LOGBUTTON, BOTTOM_RIGHT); - //SetPromptParentWindow(this->m_hWnd); - - m_Animate.Open(IDR_DOWNLOAD); - - if (hWndExplorer) - CenterWindow(CWnd::FromHandle(hWndExplorer)); - EnableSaveRestore(_T("GITProgressDlg")); - - m_background_brush.CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - return TRUE; -} - -bool CGitProgressDlg::SetBackgroundImage(UINT nID) -{ - return CAppUtils::SetListCtrlBackgroundImage(m_ProgList.GetSafeHwnd(), nID); + return CAppUtils::SetListCtrlBackgroundImage(GetSafeHwnd(), nID); } -void CGitProgressDlg::ReportGitError() +void CGitProgressList::ReportGitError() { ReportError(CGit::GetLibGit2LastErr()); } -void CGitProgressDlg::ReportError(const CString& sError) +void CGitProgressList::ReportError(const CString& sError) { CSoundUtils::PlayTGitError(); ReportString(sError, CString(MAKEINTRESOURCE(IDS_ERR_ERROR)), m_Colors.GetColor(CColors::Conflict)); m_bErrorsOccurred = true; } -void CGitProgressDlg::ReportWarning(const CString& sWarning) +void CGitProgressList::ReportWarning(const CString& sWarning) { CSoundUtils::PlayTGitWarning(); ReportString(sWarning, CString(MAKEINTRESOURCE(IDS_WARN_WARNING)), m_Colors.GetColor(CColors::Conflict)); } -void CGitProgressDlg::ReportNotification(const CString& sNotification) +void CGitProgressList::ReportNotification(const CString& sNotification) { CSoundUtils::PlayTGitNotification(); ReportString(sNotification, CString(MAKEINTRESOURCE(IDS_WARN_NOTE))); } -void CGitProgressDlg::ReportCmd(const CString& sCmd) +void CGitProgressList::ReportCmd(const CString& sCmd) { ReportString(sCmd, CString(MAKEINTRESOURCE(IDS_PROGRS_CMDINFO)), m_Colors.GetColor(CColors::Cmd)); } -void CGitProgressDlg::ReportString(CString sMessage, const CString& sMsgKind, COLORREF color) +void CGitProgressList::ReportString(CString sMessage, const CString& sMsgKind, COLORREF color) { // instead of showing a dialog box with the error message or notification, // just insert the error text into the list control. @@ -899,12 +804,12 @@ void CGitProgressDlg::ReportString(CString sMessage, const CString& sMsgKind, CO } } -UINT CGitProgressDlg::ProgressThreadEntry(LPVOID pVoid) +UINT CGitProgressList::ProgressThreadEntry(LPVOID pVoid) { - return ((CGitProgressDlg*)pVoid)->ProgressThread(); + return ((CGitProgressList*)pVoid)->ProgressThread(); } -UINT CGitProgressDlg::ProgressThread() +UINT CGitProgressList::ProgressThread() { // The SetParams function should have loaded something for us @@ -914,8 +819,10 @@ UINT CGitProgressDlg::ProgressThread() bool bSuccess = false; m_AlwaysConflicted = false; +#if 0 //need DialogEnableWindow(IDOK, FALSE); DialogEnableWindow(IDCANCEL, TRUE); +#endif // SetAndClearProgressInfo(m_hWnd); m_itemCount = m_itemCountTotal; @@ -982,8 +889,10 @@ UINT CGitProgressDlg::ProgressThread() m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS); } +#if 0//need DialogEnableWindow(IDCANCEL, FALSE); DialogEnableWindow(IDOK, TRUE); +#endif CString info = BuildInfoString(); if (!bSuccess) @@ -1021,9 +930,9 @@ UINT CGitProgressDlg::ProgressThread() AddItemToList(); } - int count = m_ProgList.GetItemCount(); + int count = GetItemCount(); if ((count > 0)&&(m_bLastVisible)) - m_ProgList.EnsureVisible(count-1, FALSE); + EnsureVisible(count-1, FALSE); CLogFile logfile; if (logfile.Open()) @@ -1042,7 +951,9 @@ UINT CGitProgressDlg::ProgressThread() m_bCancelled = TRUE; InterlockedExchange(&m_bThreadRunning, FALSE); +#if 0 //need RefreshCursor(); +#endif #if 0 DWORD dwAutoClose = CRegStdDWORD(_T("Software\\TortoiseGit\\AutoClose"), CLOSE_MANUAL); @@ -1067,76 +978,7 @@ UINT CGitProgressDlg::ProgressThread() return 0; } -void CGitProgressDlg::OnBnClickedLogbutton() -{ - switch(this->m_Command) - { - case GitProgress_Add: - case GitProgress_Resolve: - { - CString cmd = _T(" /command:commit"); - cmd += _T(" /path:\"")+g_Git.m_CurrentDir+_T("\""); - - CAppUtils::RunTortoiseGitProc(cmd); - this->EndDialog(IDOK); - break; - } - } -#if 0 - if (m_targetPathList.GetCount() != 1) - return; - StringRevMap::iterator it = m_UpdateStartRevMap.begin(); - svn_revnum_t rev = -1; - if (it != m_UpdateStartRevMap.end()) - { - rev = it->second; - } - CLogDlg dlg; - dlg.SetParams(m_targetPathList[0], m_RevisionEnd, m_RevisionEnd, rev, 0, TRUE); - dlg.DoModal(); -#endif -} - - -void CGitProgressDlg::OnClose() -{ - if (m_bCancelled) - { - TerminateThread(m_pThread->m_hThread, (DWORD)-1); - InterlockedExchange(&m_bThreadRunning, FALSE); - } - else - { - m_bCancelled = TRUE; - return; - } - DialogEnableWindow(IDCANCEL, TRUE); - __super::OnClose(); -} - -void CGitProgressDlg::OnOK() -{ - if ((m_bCancelled)&&(!m_bThreadRunning)) - { - // I have made this wait a sensible amount of time (10 seconds) for the thread to finish - // You must be careful in the thread that after posting the WM_COMMAND/IDOK message, you - // don't do any more operations on the window which might require message passing - // If you try to send windows messages once we're waiting here, then the thread can't finished - // because the Window's message loop is blocked at this wait - WaitForSingleObject(m_pThread->m_hThread, 10000); - __super::OnOK(); - } - m_bCancelled = TRUE; -} - -void CGitProgressDlg::OnCancel() -{ - if ((m_bCancelled)&&(!m_bThreadRunning)) - __super::OnCancel(); - m_bCancelled = TRUE; -} - -void CGitProgressDlg::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) +void CGitProgressList::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) { NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); @@ -1156,12 +998,12 @@ void CGitProgressDlg::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResul lstrcpyn(m_columnbuf, data->sPathColumnText, pDispInfo->item.cchTextMax); if (!data->bAuxItem) { - int cWidth = m_ProgList.GetColumnWidth(1); + int cWidth = GetColumnWidth(1); cWidth = max(12, cWidth-12); - CDC * pDC = m_ProgList.GetDC(); + CDC * pDC = GetDC(); if (pDC != NULL) { - CFont * pFont = pDC->SelectObject(m_ProgList.GetFont()); + CFont * pFont = pDC->SelectObject(GetFont()); PathCompactPath(pDC->GetSafeHdc(), m_columnbuf, cWidth); pDC->SelectObject(pFont); ReleaseDC(pDC); @@ -1178,7 +1020,7 @@ void CGitProgressDlg::OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResul *pResult = 0; } -void CGitProgressDlg::OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) +void CGitProgressList::OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) { NMLVCUSTOMDRAW* pLVCD = reinterpret_cast( pNMHDR ); @@ -1216,7 +1058,7 @@ void CGitProgressDlg::OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) } } -void CGitProgressDlg::OnNMDblclkSvnprogress(NMHDR * /*pNMHDR*/, LRESULT * /*pResult*/) +void CGitProgressList::OnNMDblclkSvnprogress(NMHDR * /*pNMHDR*/, LRESULT * /*pResult*/) { #if 0 LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); @@ -1260,7 +1102,7 @@ void CGitProgressDlg::OnNMDblclkSvnprogress(NMHDR * /*pNMHDR*/, LRESULT * /*pRes #endif } -void CGitProgressDlg::OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) +void CGitProgressList::OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) { LPNMHEADER phdr = reinterpret_cast(pNMHDR); if (m_bThreadRunning) @@ -1273,20 +1115,20 @@ void CGitProgressDlg::OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult) Sort(); CString temp; - m_ProgList.SetRedraw(FALSE); - m_ProgList.DeleteAllItems(); - m_ProgList.SetItemCountEx (static_cast(m_arData.size())); + SetRedraw(FALSE); + DeleteAllItems(); + SetItemCountEx (static_cast(m_arData.size())); - m_ProgList.SetRedraw(TRUE); + SetRedraw(TRUE); *pResult = 0; } -bool CGitProgressDlg::NotificationDataIsAux(const NotificationData* pData) +bool CGitProgressList::NotificationDataIsAux(const NotificationData* pData) { return pData->bAuxItem; } -BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t action, CString str, const git_oid *a, const git_oid *b) +BOOL CGitProgressList::Notify(const git_wc_notify_action_t action, CString str, const git_oid *a, const git_oid *b) { NotificationData * data = new NotificationData(); data->action = action; @@ -1306,11 +1148,13 @@ BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t action, CString str, c m_arData.push_back(data); AddItemToList(); - m_Animate.Stop(); - m_Animate.ShowWindow(SW_HIDE); + if (m_pAnimate) + m_pAnimate->Stop(); + if (m_pAnimate) + m_pAnimate->ShowWindow(SW_HIDE); return TRUE; } -BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t /*action*/, const git_transfer_progress *stat) +BOOL CGitProgressList::Notify(const git_wc_notify_action_t /*action*/, const git_transfer_progress *stat) { static unsigned int start = 0; unsigned int dt = GetCurrentTime() - start; @@ -1376,7 +1220,7 @@ BOOL CGitProgressDlg::Notify(const git_wc_notify_action_t /*action*/, const git_ return TRUE; } -LRESULT CGitProgressDlg::OnGitProgress(WPARAM /*wParam*/, LPARAM /*lParam*/) +LRESULT CGitProgressList::OnGitProgress(WPARAM /*wParam*/, LPARAM /*lParam*/) { #if 0 SVNProgress * pProgressData = (SVNProgress *)lParam; @@ -1419,7 +1263,7 @@ LRESULT CGitProgressDlg::OnGitProgress(WPARAM /*wParam*/, LPARAM /*lParam*/) return 0; } -void CGitProgressDlg::OnTimer(UINT_PTR nIDEvent) +void CGitProgressList::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == TRANSFERTIMER) { @@ -1433,12 +1277,12 @@ void CGitProgressDlg::OnTimer(UINT_PTR nIDEvent) if (nIDEvent == VISIBLETIMER) { if (nEnsureVisibleCount) - m_ProgList.EnsureVisible(m_ProgList.GetItemCount()-1, false); + EnsureVisible(GetItemCount()-1, false); nEnsureVisibleCount = 0; } } -void CGitProgressDlg::Sort() +void CGitProgressList::Sort() { if(m_arData.size() < 2) { @@ -1453,20 +1297,20 @@ void CGitProgressDlg::Sort() for(;;) { // Search to the start of the non-aux entry in the next block - actionBlockBegin = std::find_if(actionBlockEnd, m_arData.end(), std::not1(std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux))); + actionBlockBegin = std::find_if(actionBlockEnd, m_arData.end(), std::not1(std::ptr_fun(&CGitProgressList::NotificationDataIsAux))); if(actionBlockBegin == m_arData.end()) { // There are no more actions break; } // Now search to find the end of the block - actionBlockEnd = std::find_if(actionBlockBegin+1, m_arData.end(), std::ptr_fun(&CGitProgressDlg::NotificationDataIsAux)); + actionBlockEnd = std::find_if(actionBlockBegin+1, m_arData.end(), std::ptr_fun(&CGitProgressList::NotificationDataIsAux)); // Now sort the block - std::sort(actionBlockBegin, actionBlockEnd, &CGitProgressDlg::SortCompare); + std::sort(actionBlockBegin, actionBlockEnd, &CGitProgressList::SortCompare); } } -bool CGitProgressDlg::SortCompare(const NotificationData * pData1, const NotificationData * pData2) +bool CGitProgressList::SortCompare(const NotificationData * pData1, const NotificationData * pData2) { int result = 0; switch (m_nSortedColumn) @@ -1492,100 +1336,20 @@ bool CGitProgressDlg::SortCompare(const NotificationData * pData1, const Notific return result < 0; } -BOOL CGitProgressDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) -{ - if (!GetDlgItem(IDOK)->IsWindowEnabled()) - { - // only show the wait cursor over the list control - if ((pWnd)&&(pWnd == GetDlgItem(IDC_SVNPROGRESS))) - { - HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)); - SetCursor(hCur); - return TRUE; - } - } - HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); - SetCursor(hCur); - return CResizableStandAloneDialog::OnSetCursor(pWnd, nHitTest, message); -} - -BOOL CGitProgressDlg::PreTranslateMessage(MSG* pMsg) -{ - if (pMsg->message == WM_KEYDOWN) - { - if (pMsg->wParam == VK_ESCAPE) - { - // pressing the ESC key should close the dialog. But since we disabled the escape - // key (so the user doesn't get the idea that he could simply undo an e.g. update) - // this won't work. - // So if the user presses the ESC key, change it to VK_RETURN so the dialog gets - // the impression that the OK button was pressed. - if ((!m_bThreadRunning)&&(!GetDlgItem(IDCANCEL)->IsWindowEnabled()) - &&(GetDlgItem(IDOK)->IsWindowEnabled())&&(GetDlgItem(IDOK)->IsWindowVisible())) - { - // since we convert ESC to RETURN, make sure the OK button has the focus. - GetDlgItem(IDOK)->SetFocus(); - pMsg->wParam = VK_RETURN; - } - } - if (pMsg->wParam == 'A') - { - if (GetKeyState(VK_CONTROL)&0x8000) - { - // Ctrl-A -> select all - m_ProgList.SetSelectionMark(0); - for (int i=0; iwParam == 'C')||(pMsg->wParam == VK_INSERT)) - { - int selIndex = m_ProgList.GetSelectionMark(); - if (selIndex >= 0) - { - if (GetKeyState(VK_CONTROL)&0x8000) - { - //Ctrl-C -> copy to clipboard - CString sClipdata; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - if (pos != NULL) - { - while (pos) - { - int nItem = m_ProgList.GetNextSelectedItem(pos); - CString sAction = m_ProgList.GetItemText(nItem, 0); - CString sPath = m_ProgList.GetItemText(nItem, 1); - CString sMime = m_ProgList.GetItemText(nItem, 2); - CString sLogCopyText; - sLogCopyText.Format(_T("%s: %s %s\r\n"), - (LPCTSTR)sAction, (LPCTSTR)sPath, (LPCTSTR)sMime); - sClipdata += sLogCopyText; - } - CStringUtils::WriteAsciiStringToClipboard(sClipdata); - } - } - } - } - } // if (pMsg->message == WM_KEYDOWN) - return __super::PreTranslateMessage(pMsg); -} - -void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) +void CGitProgressList::OnContextMenu(CWnd* pWnd, CPoint point) { if (m_options & ProgOptDryRun) return; // don't do anything in a dry-run. - if (pWnd == &m_ProgList) + if (pWnd == this) { - int selIndex = m_ProgList.GetSelectionMark(); + int selIndex = GetSelectionMark(); if ((point.x == -1) && (point.y == -1)) { // Menu was invoked from the keyboard rather than by right-clicking CRect rect; - m_ProgList.GetItemRect(selIndex, &rect, LVIR_LABEL); - m_ProgList.ClientToScreen(&rect); + GetItemRect(selIndex, &rect, LVIR_LABEL); + ClientToScreen(&rect); point = rect.CenterPoint(); } @@ -1602,7 +1366,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) /* if (data->action == svn_wc_notify_update_update || data->action == svn_wc_notify_resolved) { - if (m_ProgList.GetSelectedCount() == 1) + if (GetSelectedCount() == 1) { popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF); bAdded = true; @@ -1611,7 +1375,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) if (data->bConflictedActionItem) { - if (m_ProgList.GetSelectedCount() == 1) + if (GetSelectedCount() == 1) { popup.AppendMenuIcon(ID_EDITCONFLICT, IDS_MENUCONFLICT,IDI_CONFLICT); popup.SetDefaultItem(ID_EDITCONFLICT, FALSE); @@ -1623,7 +1387,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) else if ((data->content_state == svn_wc_notify_state_merged)||(GitProgress_Merge == m_Command)||(data->action == svn_wc_notify_resolved)) popup.SetDefaultItem(ID_COMPARE, FALSE); */ - if (m_ProgList.GetSelectedCount() == 1) + if (GetSelectedCount() == 1) { if ((data->action == git_wc_notify_add)|| (data->action == git_wc_notify_revert)|| @@ -1639,7 +1403,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) } } } // if ((data)&&(!data->path.IsDirectory())) - if (m_ProgList.GetSelectedCount() == 1) + if (GetSelectedCount() == 1) { if (data) { @@ -1655,7 +1419,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) } } } - if (m_ProgList.GetSelectedCount() > 0) + if (GetSelectedCount() > 0) { if (bAdded) popup.AppendMenu(MF_SEPARATOR, NULL); @@ -1665,7 +1429,9 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) if (bAdded) { int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); +#if 0//need DialogEnableWindow(IDOK, FALSE); +#endif //this->SetPromptApp(&theApp); theApp.DoWaitCursor(1); bool bOpenWith = false; @@ -1674,10 +1440,10 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) case ID_COPY: { CString sLines; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); + POSITION pos = GetFirstSelectedItemPosition(); while (pos) { - int nItem = m_ProgList.GetNextSelectedItem(pos); + int nItem = GetNextSelectedItem(pos); NotificationData * data = m_arData[nItem]; if (data) { @@ -1793,11 +1559,11 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) break; } SVN svn; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); + POSITION pos = GetFirstSelectedItemPosition(); CString sResolvedPaths; while (pos) { - int nItem = m_ProgList.GetNextSelectedItem(pos); + int nItem = GetNextSelectedItem(pos); NotificationData * data = m_arData[nItem]; if (data) { @@ -1821,8 +1587,8 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) { // When the last conflict is resolved we remove // the warning which we assume is in the last line. - int nIndex = m_ProgList.GetItemCount()-1; - VERIFY(m_ProgList.DeleteItem(nIndex)); + int nIndex = GetItemCount()-1; + VERIFY(DeleteItem(nIndex)); delete m_arData[nIndex]; m_arData.pop_back(); @@ -1832,7 +1598,7 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) } } } - m_ProgList.Invalidate(); + Invalidate(); CString info = BuildInfoString(); SetDlgItemText(IDC_INFOTEXT, info); @@ -1878,7 +1644,9 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) } } } +#if 0 //need DialogEnableWindow(IDOK, TRUE); +#endif theApp.DoWaitCursor(-1); } // if (bAdded) } @@ -1886,27 +1654,19 @@ void CGitProgressDlg::OnContextMenu(CWnd* pWnd, CPoint point) } } -void CGitProgressDlg::OnEnSetfocusInfotext() -{ - CString sTemp; - GetDlgItemText(IDC_INFOTEXT, sTemp); - if (sTemp.IsEmpty()) - GetDlgItem(IDC_INFOTEXT)->HideCaret(); -} - -void CGitProgressDlg::OnLvnBegindragSvnprogress(NMHDR* , LRESULT *pResult) +void CGitProgressList::OnLvnBegindragSvnprogress(NMHDR* , LRESULT *pResult) { //LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); #if 0 - int selIndex = m_ProgList.GetSelectionMark(); + int selIndex = GetSelectionMark(); if (selIndex < 0) return; CDropFiles dropFiles; // class for creating DROPFILES struct int index; - POSITION pos = m_ProgList.GetFirstSelectedItemPosition(); - while ( (index = m_ProgList.GetNextSelectedItem(pos)) >= 0 ) + POSITION pos = GetFirstSelectedItemPosition(); + while ( (index = GetNextSelectedItem(pos)) >= 0 ) { NotificationData * data = m_arData[index]; @@ -1926,24 +1686,24 @@ void CGitProgressDlg::OnLvnBegindragSvnprogress(NMHDR* , LRESULT *pResult) *pResult = 0; } -void CGitProgressDlg::OnSize(UINT nType, int cx, int cy) +void CGitProgressList::OnSize(UINT nType, int cx, int cy) { - CResizableStandAloneDialog::OnSize(nType, cx, cy); + CListCtrl::OnSize(nType, cx, cy); if ((nType == SIZE_RESTORED)&&(m_bLastVisible)) { - if(!m_ProgList.m_hWnd) + if(!m_hWnd) return; - int count = m_ProgList.GetItemCount(); + int count = GetItemCount(); if (count > 0) - m_ProgList.EnsureVisible(count-1, false); + EnsureVisible(count-1, false); } } ////////////////////////////////////////////////////////////////////////// /// commands ////////////////////////////////////////////////////////////////////////// -bool CGitProgressDlg::CmdAdd(CString& sWindowTitle, bool& localoperation) +bool CGitProgressList::CmdAdd(CString& sWindowTitle, bool& localoperation) { localoperation = true; sWindowTitle.LoadString(IDS_PROGRS_TITLE_ADD); @@ -2063,7 +1823,7 @@ bool CGitProgressDlg::CmdAdd(CString& sWindowTitle, bool& localoperation) else { CMassiveGitTask mgt(L"add -f"); - mgt.ExecuteWithNotify(&m_targetPathList, m_bCancelled, git_wc_notify_add, this, &CGitProgressDlg::Notify); + mgt.ExecuteWithNotify(&m_targetPathList, m_bCancelled, git_wc_notify_add, this, &CGitProgressList::Notify); } CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList); @@ -2073,7 +1833,7 @@ bool CGitProgressDlg::CmdAdd(CString& sWindowTitle, bool& localoperation) return true; } -bool CGitProgressDlg::CmdCopy(CString& /*sWindowTitle*/, bool& /*localoperation*/) +bool CGitProgressList::CmdCopy(CString& /*sWindowTitle*/, bool& /*localoperation*/) { #if 0 ASSERT(m_targetPathList.GetCount() == 1); @@ -2119,7 +1879,7 @@ bool CGitProgressDlg::CmdCopy(CString& /*sWindowTitle*/, bool& /*localoperation* return true; } -bool CGitProgressDlg::CmdExport(CString& /*sWindowTitle*/, bool& /*localoperation*/) +bool CGitProgressList::CmdExport(CString& /*sWindowTitle*/, bool& /*localoperation*/) { #if 0 ASSERT(m_targetPathList.GetCount() == 1); @@ -2144,7 +1904,7 @@ bool CGitProgressDlg::CmdExport(CString& /*sWindowTitle*/, bool& /*localoperatio return true; } -bool CGitProgressDlg::CmdRename(CString& /*sWindowTitle*/, bool& /*localoperation*/) +bool CGitProgressList::CmdRename(CString& /*sWindowTitle*/, bool& /*localoperation*/) { #if 0 ASSERT(m_targetPathList.GetCount() == 1); @@ -2163,7 +1923,7 @@ bool CGitProgressDlg::CmdRename(CString& /*sWindowTitle*/, bool& /*localoperatio return true; } -bool CGitProgressDlg::CmdResolve(CString& sWindowTitle, bool& localoperation) +bool CGitProgressList::CmdResolve(CString& sWindowTitle, bool& localoperation) { localoperation = true; @@ -2246,7 +2006,7 @@ bool CGitProgressDlg::CmdResolve(CString& sWindowTitle, bool& localoperation) return true; } -bool CGitProgressDlg::CmdRevert(CString& sWindowTitle, bool& localoperation) +bool CGitProgressList::CmdRevert(CString& sWindowTitle, bool& localoperation) { localoperation = true; @@ -2286,7 +2046,7 @@ bool CGitProgressDlg::CmdRevert(CString& sWindowTitle, bool& localoperation) return true; } -bool CGitProgressDlg::CmdSwitch(CString& /*sWindowTitle*/, bool& /*localoperation*/) +bool CGitProgressList::CmdSwitch(CString& /*sWindowTitle*/, bool& /*localoperation*/) { #if 0 ASSERT(m_targetPathList.GetCount() == 1); @@ -2326,7 +2086,7 @@ bool CGitProgressDlg::CmdSwitch(CString& /*sWindowTitle*/, bool& /*localoperatio #endif return true; } -bool CGitProgressDlg::CmdClone(CString& sWindowTitle, bool& /*localoperation*/) +bool CGitProgressList::CmdClone(CString& sWindowTitle, bool& /*localoperation*/) { if (!g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE)) { @@ -2380,11 +2140,18 @@ bool CGitProgressDlg::CmdClone(CString& sWindowTitle, bool& /*localoperation*/) clone_opts.bare = m_bBare; - m_Animate.ShowWindow(SW_SHOW); - m_Animate.Play(0, INT_MAX, INT_MAX); + if(m_pAnimate) + { + m_pAnimate->ShowWindow(SW_SHOW); + m_pAnimate->Play(0, INT_MAX, INT_MAX); + } error = git_clone(&cloned_repo, url, path, &clone_opts); - m_Animate.Stop(); - m_Animate.ShowWindow(SW_HIDE); + + if (m_pAnimate) + { + m_pAnimate->Stop(); + m_pAnimate->ShowWindow(SW_HIDE); + } git_remote_free(origin); if (error) @@ -2396,27 +2163,7 @@ bool CGitProgressDlg::CmdClone(CString& sWindowTitle, bool& /*localoperation*/) git_repository_free(cloned_repo); return true; } - -void CGitProgressDlg::OnBnClickedNoninteractive() -{ - LRESULT res = ::SendMessage(GetDlgItem(IDC_NONINTERACTIVE)->GetSafeHwnd(), BM_GETCHECK, 0, 0); - m_AlwaysConflicted = (res == BST_CHECKED); - CRegDWORD nonint = CRegDWORD(_T("Software\\TortoiseGit\\MergeNonInteractive"), FALSE); - nonint = m_AlwaysConflicted; -} - -CString CGitProgressDlg::GetPathFromColumnText(const CString& sColumnText) -{ - CString sPath = sColumnText; - if (sPath.Find(':')<0) - { - // the path is not absolute: add the common root of all paths to it - sPath = g_Git.m_CurrentDir + _T("\\") + sColumnText; - } - return sPath; -} - -bool CGitProgressDlg::CmdSendMail(CString& sWindowTitle, bool& /*localoperation*/) +bool CGitProgressList::CmdSendMail(CString& sWindowTitle, bool& /*localoperation*/) { sWindowTitle.LoadString(IDS_PROGRS_TITLE_SENDMAIL); CAppUtils::SetWindowTitle(m_hWnd, m_targetPathList.GetCommonRoot().GetUIPathString(), sWindowTitle); @@ -2498,44 +2245,14 @@ bool CGitProgressDlg::CmdSendMail(CString& sWindowTitle, bool& /*localoperation* return ret; } -LRESULT CGitProgressDlg::OnTaskbarBtnCreated(WPARAM /*wParam*/, LPARAM /*lParam*/) +LRESULT CGitProgressList::OnTaskbarBtnCreated(WPARAM /*wParam*/, LPARAM /*lParam*/) { m_pTaskbarList.Release(); m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList); return 0; } -HBRUSH CGitProgressDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr; - if (pWnd->GetDlgCtrlID() == IDC_TITLE_ANIMATE) - { - pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); // add this - pDC->SetBkMode(TRANSPARENT); - return (HBRUSH)m_background_brush.GetSafeHandle(); - } - else - hbr = CResizableStandAloneDialog::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: Return a different brush if the default is not desired - return hbr; -} -LRESULT CGitProgressDlg::OnCtlColorStatic(WPARAM wParam, LPARAM lParam) -{ - HDC hDC = (HDC)wParam; - HWND hwndCtl = (HWND)lParam; - - if (::GetDlgCtrlID(hwndCtl) == IDC_TITLE_ANIMATE) - { - CDC *pDC = CDC::FromHandle(hDC); - pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); - pDC->SetBkMode(TRANSPARENT); - return (LRESULT)(HBRUSH)m_background_brush.GetSafeHandle(); - } - return FALSE; -} - -bool CGitProgressDlg::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) +bool CGitProgressList::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) { if (!g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE)) { @@ -2598,9 +2315,11 @@ bool CGitProgressDlg::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) break; } - m_Animate.ShowWindow(SW_SHOW); - m_Animate.Play(0, INT_MAX, INT_MAX); - + if (m_pAnimate) + { + m_pAnimate->ShowWindow(SW_SHOW); + m_pAnimate->Play(0, INT_MAX, INT_MAX); + } // Connect to the remote end specifying that we want to fetch // information from it. if (git_remote_connect(remote, GIT_DIRECTION_FETCH) < 0) { @@ -2618,7 +2337,10 @@ bool CGitProgressDlg::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) break; } - m_Animate.ShowWindow(SW_HIDE); + if (m_pAnimate) + { + m_pAnimate->ShowWindow(SW_HIDE); + } // Update the references in the remote's namespace to point to the // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been @@ -2636,6 +2358,143 @@ bool CGitProgressDlg::CmdFetch(CString& sWindowTitle, bool& /*localoperation*/) git_remote_free(remote); git_repository_free(repo); - m_Animate.ShowWindow(SW_HIDE); + if (m_pAnimate) + m_pAnimate->ShowWindow(SW_HIDE); return ret; } + + +int CGitProgressList::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CListCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + // Let the TaskbarButtonCreated message through the UIPI filter. If we don't + // do this, Explorer would be unable to send that message to our window if we + // were running elevated. It's OK to make the call all the time, since if we're + // not elevated, this is a no-op. + CHANGEFILTERSTRUCT cfs = { sizeof(CHANGEFILTERSTRUCT) }; + typedef BOOL STDAPICALLTYPE ChangeWindowMessageFilterExDFN(HWND hWnd, UINT message, DWORD action, PCHANGEFILTERSTRUCT pChangeFilterStruct); + CAutoLibrary hUser = AtlLoadSystemLibraryUsingFullPath(_T("user32.dll")); + if (hUser) + { + ChangeWindowMessageFilterExDFN *pfnChangeWindowMessageFilterEx = (ChangeWindowMessageFilterExDFN*)GetProcAddress(hUser, "ChangeWindowMessageFilterEx"); + if (pfnChangeWindowMessageFilterEx) + { + pfnChangeWindowMessageFilterEx(m_hWnd, WM_TASKBARBTNCREATED, MSGFLT_ALLOW, &cfs); + } + } + m_pTaskbarList.Release(); + if (FAILED(m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList))) + m_pTaskbarList = nullptr; + + SetExtendedStyle (LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); + + DeleteAllItems(); + int c = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1; + while (c>=0) + DeleteColumn(c--); + + CString temp; + temp.LoadString(IDS_PROGRS_ACTION); + InsertColumn(0, temp); + temp.LoadString(IDS_PROGRS_PATH); + InsertColumn(1, temp); + + m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); + if (m_pThread==NULL) + { + ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED))); + } + else + { + m_pThread->m_bAutoDelete = FALSE; + m_pThread->ResumeThread(); + } + + // Call this early so that the column headings aren't hidden before any + // text gets added. + ResizeColumns(); + + SetTimer(VISIBLETIMER, 300, NULL); + + return 0; +} + + +void CGitProgressList::OnClose() +{ + // TODO: Add your message handler code here and/or call default + if (m_bCancelled) + { + TerminateThread(m_pThread->m_hThread, (DWORD)-1); + InterlockedExchange(&m_bThreadRunning, FALSE); + } + else + { + m_bCancelled = TRUE; + return; + } + CListCtrl::OnClose(); +} + + +BOOL CGitProgressList::PreTranslateMessage(MSG* pMsg) +{ + // TODO: Add your specialized code here and/or call the base class + if (pMsg->message == WM_KEYDOWN) + { + if (pMsg->wParam == 'A') + { + if (GetKeyState(VK_CONTROL)&0x8000) + { + // Ctrl-A -> select all + SetSelectionMark(0); + for (int i=0; iwParam == 'C')||(pMsg->wParam == VK_INSERT)) + { + int selIndex = GetSelectionMark(); + if (selIndex >= 0) + { + if (GetKeyState(VK_CONTROL)&0x8000) + { + //Ctrl-C -> copy to clipboard + CString sClipdata; + POSITION pos = GetFirstSelectedItemPosition(); + if (pos != NULL) + { + while (pos) + { + int nItem = GetNextSelectedItem(pos); + CString sAction = GetItemText(nItem, 0); + CString sPath = GetItemText(nItem, 1); + CString sMime = GetItemText(nItem, 2); + CString sLogCopyText; + sLogCopyText.Format(_T("%s: %s %s\r\n"), + (LPCTSTR)sAction, (LPCTSTR)sPath, (LPCTSTR)sMime); + sClipdata += sLogCopyText; + } + CStringUtils::WriteAsciiStringToClipboard(sClipdata); + } + } + } + } + } // if (pMsg->message == WM_KEYDOWN) + return CListCtrl::PreTranslateMessage(pMsg); +} + +CString CGitProgressList::GetPathFromColumnText(const CString& sColumnText) +{ + CString sPath = sColumnText; + if (sPath.Find(':')<0) + { + // the path is not absolute: add the common root of all paths to it + sPath = g_Git.m_CurrentDir + _T("\\") + sColumnText; + } + return sPath; +} \ No newline at end of file diff --git a/src/TortoiseProc/GitProgressDlg.h b/src/TortoiseProc/GitProgressList.h similarity index 83% copy from src/TortoiseProc/GitProgressDlg.h copy to src/TortoiseProc/GitProgressList.h index c042bbfe3..f9933b9a6 100644 --- a/src/TortoiseProc/GitProgressDlg.h +++ b/src/TortoiseProc/GitProgressList.h @@ -16,10 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -#pragma once -#include "StandAloneDlg.h" +#pragma once #include "TGitPath.h" #include "ProjectProperties.h" #include "Git.h" @@ -29,10 +27,7 @@ #include "afxwin.h" #include "Win7.h" #include "UnicodeUtils.h" - -typedef int (__cdecl *GENERICCOMPAREFN)(const void * elem1, const void * elem2); -struct git_transfer_progress; - +#include "resource.h" /** * \ingroup TortoiseProc * Options which can be used to configure the way the dialog box works @@ -68,8 +63,6 @@ typedef enum CLOSE_LOCAL } ProgressCloseOptions; -#define WM_SHOWCONFLICTRESOLVER (WM_APP + 100) - typedef enum { git_wc_notify_add, @@ -84,20 +77,21 @@ typedef enum git_wc_notify_update_ref, }git_wc_notify_action_t; + typedef enum { SENDMAIL_ATTACHMENT =0x1, SENDMAIL_COMBINED =0x2, SENDMAIL_MAPI =0x4 }; -/** - * \ingroup TortoiseProc - * Handles different Subversion commands and shows the notify messages - * in a listbox. Since several Subversion commands have similar notify - * messages they are grouped together in this single class. - */ -class CGitProgressDlg : public CResizableStandAloneDialog +// CGitProgressList +struct git_transfer_progress; +#define WM_SHOWCONFLICTRESOLVER (WM_APP + 100) + +class CGitProgressList : public CListCtrl { + DECLARE_DYNAMIC(CGitProgressList) + public: typedef enum { @@ -114,17 +108,10 @@ public: GitProgress_Fetch, } Command; + CGitProgressList(); + virtual ~CGitProgressList(); - DECLARE_DYNAMIC(CGitProgressDlg) - -public: - - CGitProgressDlg(CWnd* pParent = NULL); - virtual ~CGitProgressDlg(); - - - void SetCommand(Command cmd) {m_Command = cmd;} - void SetAutoClose(DWORD ac) {m_dwCloseOnEnd = ac;} + void SetCommand(CGitProgressList::Command cmd) {m_Command = cmd;} void SetOptions(DWORD opts) {m_options = opts;} void SetPathList(const CTGitPathList& pathList) {m_targetPathList = pathList;} void SetUrl(const CString& url) {m_url.SetFromUnknown(url);} @@ -153,13 +140,17 @@ public: * accurate progress bar during the operation. */ void SetItemCount(long count) {if(count) m_itemCountTotal = count;} - bool SetBackgroundImage(UINT nID); - bool DidErrorsOccur() {return m_bErrorsOccurred;} - - enum { IDD = IDD_SVNPROGRESS }; - + bool m_bErrorsOccurred; + CWnd *m_pTextCtrl; + CAnimateCtrl *m_pAnimate; + Command m_Command; + virtual BOOL Cancel(); + volatile BOOL IsCancelled() {return m_bCancelled;} + volatile LONG IsRunning() {return m_bThreadRunning;} + CWinThread* m_pThread; + bool m_AlwaysConflicted; private: class NotificationData { @@ -211,6 +202,7 @@ private: }; protected: + DECLARE_MESSAGE_MAP() //Need update in the future implement the virtual methods from Git base class virtual BOOL Notify(const CTGitPath& path, @@ -233,22 +225,22 @@ protected: static int FetchCallback(const git_transfer_progress *stats, void *payload) { - return !((CGitProgressDlg*)payload) -> Notify(git_wc_notify_fetch, stats); + return !((CGitProgressList*)payload) -> Notify(git_wc_notify_fetch, stats); } static void CheckoutCallback(const char *path, size_t cur, size_t tot, void *payload) { CTGitPath tpath = CUnicodeUtils::GetUnicode(CStringA(path), CP_UTF8); - ((CGitProgressDlg*)payload) -> m_itemCountTotal = tot; - ((CGitProgressDlg*)payload) -> m_itemCount = cur; - ((CGitProgressDlg*)payload) -> Notify(tpath, git_wc_notify_checkout); + ((CGitProgressList*)payload) -> m_itemCountTotal = tot; + ((CGitProgressList*)payload) -> m_itemCount = cur; + ((CGitProgressList*)payload) -> Notify(tpath, git_wc_notify_checkout); } static void RemoteProgressCallback(const char *str, int len, void *data) { CString progText; progText = CUnicodeUtils::GetUnicode(CStringA(str, len)); - ((CGitProgressDlg*)data) -> SetDlgItemText(IDC_PROGRESSLABEL, progText); + ((CGitProgressList*)data) -> SetDlgItemText(IDC_PROGRESSLABEL, progText); } static int RemoteCompletionCallback(git_remote_completion_type /*type*/, void * /*data*/) { @@ -258,37 +250,21 @@ protected: { CString str; str = CUnicodeUtils::GetUnicode(refname); - ((CGitProgressDlg*)data) -> Notify(git_wc_notify_update_ref, str, a, b); + ((CGitProgressList*)data) -> Notify(git_wc_notify_update_ref, str, a, b); return 0; } - virtual BOOL OnInitDialog(); - virtual BOOL Cancel(); - virtual void OnCancel(); - virtual BOOL PreTranslateMessage(MSG* pMsg); - virtual void DoDataExchange(CDataExchange* pDX); - afx_msg void OnNMCustomdrawSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnLvnGetdispinfoSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnNMDblclkSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnBnClickedLogbutton(); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedNoninteractive(); afx_msg void OnHdnItemclickSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); - afx_msg void OnClose(); afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); afx_msg LRESULT OnGitProgress(WPARAM wParam, LPARAM lParam); afx_msg void OnTimer(UINT_PTR nIDEvent); - afx_msg void OnEnSetfocusInfotext(); - afx_msg void OnLvnBegindragSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg LRESULT OnTaskbarBtnCreated(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnCtlColorStatic(WPARAM wParam, LPARAM lParam); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); LRESULT OnShowConflictResolver(WPARAM, LPARAM); - - DECLARE_MESSAGE_MAP() + afx_msg void OnLvnBegindragSvnprogress(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg LRESULT OnTaskbarBtnCreated(WPARAM wParam, LPARAM lParam); void Sort(); static bool SortCompare(const NotificationData* pElem1, const NotificationData* pElem2); @@ -300,7 +276,7 @@ protected: private: static UINT ProgressThreadEntry(LPVOID pVoid); UINT ProgressThread(); - virtual void OnOK(); + void ReportGitError(); void ReportError(const CString& sError); void ReportWarning(const CString& sWarning); @@ -311,7 +287,7 @@ private: CString BuildInfoString(); CString GetPathFromColumnText(const CString& sColumnText); - /** + /** * Resizes the columns of the progress list so that the headings are visible. */ void ResizeColumns(); @@ -336,16 +312,13 @@ private: typedef std::map StringRevMap; typedef std::vector NotificationDataVect; - CString m_mergedfile; NotificationDataVect m_arData; - CAnimateCtrl m_Animate; - CWinThread* m_pThread; + volatile LONG m_bThreadRunning; ProjectProperties m_ProjectProperties; - CListCtrl m_ProgList; - Command m_Command; + int m_options; // Use values from the ProgressOptions enum git_depth_t m_depth; CTGitPathList m_targetPathList; @@ -361,9 +334,7 @@ private: CString m_changelist; bool m_keepchangelist; - DWORD m_dwCloseOnEnd; - - CTGitPath m_basePath; + CTGitPath m_basePath; StringRevMap m_UpdateStartRevMap; StringRevMap m_FinishedRevMap; @@ -371,7 +342,6 @@ private: volatile BOOL m_bCancelled; int m_nConflicts; - bool m_bErrorsOccurred; bool m_bMergesAddsDeletesOccurred; int iFirstResized; @@ -389,8 +359,6 @@ private: int m_itemCount; int m_itemCountTotal; - bool m_AlwaysConflicted; - DWORD m_SendMailFlags; CString m_SendMailTO; CString m_SendMailCC; @@ -406,6 +374,11 @@ private: bool m_bBare; bool m_bNoCheckout; CString m_RefSpec; - CBrush m_background_brush; int m_AutoTag; +public: + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnClose(); + virtual BOOL PreTranslateMessage(MSG* pMsg); }; + + diff --git a/src/TortoiseProc/MassiveGitTask.cpp b/src/TortoiseProc/MassiveGitTask.cpp index 38ffab4ef..cf7dfcca7 100644 --- a/src/TortoiseProc/MassiveGitTask.cpp +++ b/src/TortoiseProc/MassiveGitTask.cpp @@ -55,7 +55,7 @@ void CMassiveGitTask::AddFile(CTGitPath filename) m_itemList.push_back(filename.GetGitPathString()); } -bool CMassiveGitTask::ExecuteWithNotify(CTGitPathList *pathList, volatile BOOL &cancel, git_wc_notify_action_t action, CGitProgressDlg * instance, NOTIFY_CALLBACK notifyMethod) +bool CMassiveGitTask::ExecuteWithNotify(CTGitPathList *pathList, volatile BOOL &cancel, git_wc_notify_action_t action, CGitProgressList * instance, NOTIFY_CALLBACK notifyMethod) { assert(m_bUnused); m_bUnused = false; diff --git a/src/TortoiseProc/MassiveGitTask.h b/src/TortoiseProc/MassiveGitTask.h index e31d885f6..b3e4945b8 100644 --- a/src/TortoiseProc/MassiveGitTask.h +++ b/src/TortoiseProc/MassiveGitTask.h @@ -19,12 +19,12 @@ // #pragma once -#include "GitProgressDlg.h" +#include "GitProgressList.h" #include "TGitPath.h" #define MAX_COMMANDLINE_LENGTH 30000 -typedef BOOL (CGitProgressDlg::*NOTIFY_CALLBACK)(const CTGitPath& path, git_wc_notify_action_t action, int status, CString *strErr); +typedef BOOL (CGitProgressList::*NOTIFY_CALLBACK)(const CTGitPath& path, git_wc_notify_action_t action, int status, CString *strErr); class CMassiveGitTask { @@ -34,7 +34,7 @@ public: void AddFile(CString filename); void AddFile(CTGitPath filename); - bool ExecuteWithNotify(CTGitPathList *pathList, volatile BOOL &cancel, git_wc_notify_action_t action, CGitProgressDlg * instance, NOTIFY_CALLBACK m_NotifyCallbackMethod); + bool ExecuteWithNotify(CTGitPathList *pathList, volatile BOOL &cancel, git_wc_notify_action_t action, CGitProgressList * instance, NOTIFY_CALLBACK m_NotifyCallbackMethod); bool Execute(BOOL &cancel); private: @@ -46,7 +46,7 @@ private: CString m_sParams; CTGitPathList m_pathList; STRING_VECTOR m_itemList; - CGitProgressDlg * m_NotifyCallbackInstance; + CGitProgressList * m_NotifyCallbackInstance; NOTIFY_CALLBACK m_NotifyCallbackMethod; git_wc_notify_action_t m_NotifyCallbackAction; }; diff --git a/src/TortoiseProc/TortoiseProc.vcxproj b/src/TortoiseProc/TortoiseProc.vcxproj index b988e3e5d..10b223b27 100644 --- a/src/TortoiseProc/TortoiseProc.vcxproj +++ b/src/TortoiseProc/TortoiseProc.vcxproj @@ -144,6 +144,7 @@ + @@ -308,6 +309,7 @@ + diff --git a/src/TortoiseProc/TortoiseProc.vcxproj.filters b/src/TortoiseProc/TortoiseProc.vcxproj.filters index 488f3b720..37b8b4642 100644 --- a/src/TortoiseProc/TortoiseProc.vcxproj.filters +++ b/src/TortoiseProc/TortoiseProc.vcxproj.filters @@ -635,6 +635,9 @@ Utils + + Utility Dialogs + @@ -1102,6 +1105,9 @@ Utils + + Utility Dialogs + -- 2.11.4.GIT