Fixed typos
[TortoiseGit.git] / src / TortoiseProc / ChangedDlg.cpp
blob4452b6d4698d895a1e42730caea24877a14982f4
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2018 - TortoiseGit
4 // Copyright (C) 2003-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "TortoiseProc.h"
22 #include "ChangedDlg.h"
23 #include "MessageBox.h"
24 #include "cursor.h"
25 #include "AppUtils.h"
26 #include "ChangedDlg.h"
27 #include "IconMenu.h"
28 #include "RefLogDlg.h"
30 IMPLEMENT_DYNAMIC(CChangedDlg, CResizableStandAloneDialog)
31 CChangedDlg::CChangedDlg(CWnd* pParent /*=nullptr*/)
32 : CResizableStandAloneDialog(CChangedDlg::IDD, pParent)
33 , m_bShowUnversioned(FALSE)
34 , m_iShowUnmodified(0)
35 , m_bBlock(FALSE)
36 , m_bCanceled(false)
37 , m_bShowIgnored(FALSE)
38 , m_bShowLocalChangesIgnored(FALSE)
39 , m_bWholeProject(FALSE)
40 , m_bRemote(FALSE)
44 CChangedDlg::~CChangedDlg()
48 void CChangedDlg::DoDataExchange(CDataExchange* pDX)
50 CResizableStandAloneDialog::DoDataExchange(pDX);
51 DDX_Control(pDX, IDC_CHANGEDLIST, m_FileListCtrl);
52 DDX_Control(pDX, IDC_BUTTON_STASH, m_ctrlStash);
53 DDX_Check(pDX, IDC_SHOWUNVERSIONED, m_bShowUnversioned);
54 DDX_Check(pDX, IDC_SHOWUNMODIFIED, m_iShowUnmodified);
55 DDX_Check(pDX, IDC_SHOWIGNORED, m_bShowIgnored);
56 DDX_Check(pDX, IDC_SHOWLOCALCHANGESIGNORED, m_bShowLocalChangesIgnored);
57 DDX_Check(pDX, IDC_WHOLE_PROJECT, m_bWholeProject);
61 BEGIN_MESSAGE_MAP(CChangedDlg, CResizableStandAloneDialog)
62 ON_BN_CLICKED(IDC_SHOWUNVERSIONED, OnBnClickedShowunversioned)
63 ON_BN_CLICKED(IDC_SHOWUNMODIFIED, OnBnClickedShowUnmodified)
64 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_NEEDSREFRESH, OnSVNStatusListCtrlNeedsRefresh)
65 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_ITEMCOUNTCHANGED, OnSVNStatusListCtrlItemCountChanged)
66 ON_BN_CLICKED(IDC_SHOWIGNORED, &CChangedDlg::OnBnClickedShowignored)
67 ON_BN_CLICKED(IDC_REFRESH, &CChangedDlg::OnBnClickedRefresh)
68 ON_BN_CLICKED(IDC_COMMIT, &CChangedDlg::OnBnClickedCommit)
69 ON_BN_CLICKED(IDC_BUTTON_STASH, &CChangedDlg::OnBnClickedStash)
70 ON_BN_CLICKED(IDC_BUTTON_UNIFIEDDIFF, &CChangedDlg::OnBnClickedButtonUnifieddiff)
71 ON_BN_CLICKED(IDC_SHOWLOCALCHANGESIGNORED, &CChangedDlg::OnBnClickedShowlocalchangesignored)
72 ON_BN_CLICKED(IDC_WHOLE_PROJECT, OnBnClickedWholeProject)
73 END_MESSAGE_MAP()
75 BOOL CChangedDlg::OnInitDialog()
77 CResizableStandAloneDialog::OnInitDialog();
79 m_regAddBeforeCommit = CRegDWORD(L"Software\\TortoiseGit\\AddBeforeCommit", TRUE);
80 m_bShowUnversioned = m_regAddBeforeCommit;
82 CString regPath(g_Git.m_CurrentDir);
83 regPath.Replace(L':', L'_');
84 m_regShowWholeProject = CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\ShowWholeProject\\" + regPath, FALSE);
85 m_bWholeProject = m_regShowWholeProject;
86 SetDlgTitle();
88 if (m_pathList.GetCount() == 1 && m_pathList[0].GetWinPathString().IsEmpty())
90 m_bWholeProject = BST_CHECKED;
91 DialogEnableWindow(IDC_WHOLE_PROJECT, FALSE);
94 UpdateData(FALSE);
96 m_FileListCtrl.Init(GITSLC_COLEXT | GITSLC_COLSTATUS | GITSLC_COLADD| GITSLC_COLDEL | GITSLC_COLMODIFICATIONDATE, L"ChangedDlg", (GITSLC_POPALL ^ (GITSLC_POPSAVEAS | GITSLC_POPRESTORE | GITSLC_POPPREPAREDIFF)), false);
97 m_FileListCtrl.SetCancelBool(&m_bCanceled);
98 m_FileListCtrl.SetBackgroundImage(IDI_CFM_BKG);
99 m_FileListCtrl.SetEmptyString(IDS_REPOSTATUS_EMPTYFILELIST);
101 AdjustControlSize(IDC_SHOWUNVERSIONED);
102 AdjustControlSize(IDC_SHOWUNMODIFIED);
103 AdjustControlSize(IDC_SHOWLOCALCHANGESIGNORED);
104 AdjustControlSize(IDC_SHOWIGNORED);
105 AdjustControlSize(IDC_WHOLE_PROJECT);
107 AddAnchor(IDC_CHANGEDLIST, TOP_LEFT, BOTTOM_RIGHT);
108 AddAnchor(IDC_SUMMARYTEXT, BOTTOM_LEFT, BOTTOM_RIGHT);
109 AddAnchor(IDC_SHOWUNVERSIONED, BOTTOM_LEFT);
110 AddAnchor(IDC_SHOWUNMODIFIED, BOTTOM_LEFT);
111 AddAnchor(IDC_SHOWLOCALCHANGESIGNORED, BOTTOM_LEFT);
112 AddAnchor(IDC_SHOWIGNORED, BOTTOM_LEFT);
113 AddAnchor(IDC_WHOLE_PROJECT, BOTTOM_LEFT);
114 AddAnchor(IDC_INFOLABEL, BOTTOM_RIGHT);
115 AddAnchor(IDC_BUTTON_STASH, BOTTOM_RIGHT);
116 AddAnchor(IDC_BUTTON_UNIFIEDDIFF, BOTTOM_RIGHT);
117 AddAnchor(IDC_COMMIT, BOTTOM_RIGHT);
118 AddAnchor(IDC_REFRESH, BOTTOM_RIGHT);
119 AddAnchor(IDOK, BOTTOM_RIGHT);
120 // SetPromptParentWindow(m_hWnd);
121 if (GetExplorerHWND())
122 CenterWindow(CWnd::FromHandle(GetExplorerHWND()));
123 EnableSaveRestore(L"ChangedDlg");
125 m_ctrlStash.m_bAlwaysShowArrow = true;
127 m_bRemote = !!(DWORD)CRegDWORD(L"Software\\TortoiseGit\\CheckRepo", FALSE);
129 // first start a thread to obtain the status without
130 // blocking the dialog
131 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
133 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
136 return TRUE;
139 UINT CChangedDlg::ChangedStatusThreadEntry(LPVOID pVoid)
141 return reinterpret_cast<CChangedDlg*>(pVoid)->ChangedStatusThread();
144 UINT CChangedDlg::ChangedStatusThread()
146 InterlockedExchange(&m_bBlock, TRUE);
148 g_Git.RefreshGitIndex();
150 m_bCanceled = false;
151 SetDlgItemText(IDOK, CString(MAKEINTRESOURCE(IDS_MSGBOX_CANCEL)));
152 DialogEnableWindow(IDC_REFRESH, FALSE);
153 DialogEnableWindow(IDC_SHOWUNVERSIONED, FALSE);
154 DialogEnableWindow(IDC_SHOWUNMODIFIED, FALSE);
155 DialogEnableWindow(IDC_SHOWIGNORED, FALSE);
156 DialogEnableWindow(IDC_SHOWLOCALCHANGESIGNORED, FALSE);
157 m_FileListCtrl.StoreScrollPos();
158 m_FileListCtrl.Clear();
159 if (!m_FileListCtrl.GetStatus(m_bWholeProject ? nullptr : &m_pathList, m_bRemote, m_bShowIgnored != FALSE, m_bShowUnversioned != FALSE, m_bShowLocalChangesIgnored != FALSE))
161 if (!m_FileListCtrl.GetLastErrorMessage().IsEmpty())
162 m_FileListCtrl.SetEmptyString(m_FileListCtrl.GetLastErrorMessage());
164 unsigned int dwShow = GITSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALS | GITSLC_SHOWSWITCHED | GITSLC_SHOWINCHANGELIST;
165 dwShow |= m_bShowUnversioned ? GITSLC_SHOWUNVERSIONED : 0;
166 dwShow |= m_iShowUnmodified ? GITSLC_SHOWNORMAL : 0;
167 dwShow |= m_bShowIgnored ? GITSLC_SHOWIGNORED : 0;
168 dwShow |= m_bShowLocalChangesIgnored ? GITSLC_SHOWASSUMEVALID | GITSLC_SHOWSKIPWORKTREE : 0;
169 m_FileListCtrl.Show(dwShow);
170 UpdateStatistics();
172 SetDlgTitle();
173 bool bIsDirectory = false;
174 if (m_pathList.GetCount() == 1)
175 bIsDirectory = m_pathList[0].IsDirectory() || m_pathList[0].IsEmpty(); // if it is empty it is g_Git.m_CurrentDir which is a directory
177 SetDlgItemText(IDOK, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)));
178 DialogEnableWindow(IDC_REFRESH, TRUE);
179 DialogEnableWindow(IDC_SHOWUNVERSIONED, bIsDirectory);
180 //DialogEnableWindow(IDC_SHOWUNMODIFIED, bIsDirectory);
181 DialogEnableWindow(IDC_SHOWIGNORED, bIsDirectory);
182 DialogEnableWindow(IDC_SHOWLOCALCHANGESIGNORED, TRUE);
183 InterlockedExchange(&m_bBlock, FALSE);
184 // revert the remote flag back to the default
185 m_bRemote = !!(DWORD)CRegDWORD(L"Software\\TortoiseGit\\CheckRepo", FALSE);
186 RefreshCursor();
187 return 0;
190 void CChangedDlg::OnOK()
192 if (m_bBlock)
194 m_bCanceled = true;
195 return;
197 __super::OnOK();
200 void CChangedDlg::OnCancel()
202 if (m_bBlock)
204 m_bCanceled = true;
205 return;
207 __super::OnCancel();
210 DWORD CChangedDlg::UpdateShowFlags()
212 DWORD dwShow = m_FileListCtrl.GetShowFlags();
213 if (m_bShowUnversioned)
214 dwShow |= GITSLC_SHOWUNVERSIONED;
215 else
216 dwShow &= ~GITSLC_SHOWUNVERSIONED;
217 if (m_iShowUnmodified)
218 dwShow |= GITSLC_SHOWNORMAL;
219 else
220 dwShow &= ~GITSLC_SHOWNORMAL;
221 if (m_bShowIgnored)
222 dwShow |= GITSLC_SHOWIGNORED;
223 else
224 dwShow &= ~GITSLC_SHOWIGNORED;
225 if (m_bShowLocalChangesIgnored)
226 dwShow |= GITSLC_SHOWASSUMEVALID|GITSLC_SHOWSKIPWORKTREE;
227 else
228 dwShow &= ~(GITSLC_SHOWASSUMEVALID|GITSLC_SHOWSKIPWORKTREE);
230 // old bShowExternals:
231 dwShow &= ~(GITSLC_SHOWEXTERNAL | GITSLC_SHOWINEXTERNALS | GITSLC_SHOWEXTERNALFROMDIFFERENTREPO);
233 return dwShow;
236 void CChangedDlg::SetDlgTitle()
238 if (m_sTitle.IsEmpty())
239 GetWindowText(m_sTitle);
241 if (m_bWholeProject)
242 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, m_sTitle);
243 else
245 if (m_pathList.GetCount() == 1)
246 CAppUtils::SetWindowTitle(m_hWnd, g_Git.CombinePath(m_pathList[0].GetUIPathString()), m_sTitle);
247 else
248 CAppUtils::SetWindowTitle(m_hWnd, g_Git.CombinePath(m_FileListCtrl.GetCommonDirectory(false)), m_sTitle);
252 void CChangedDlg::OnBnClickedShowunversioned()
254 UpdateData();
255 m_regAddBeforeCommit = m_bShowUnversioned;
256 if(m_FileListCtrl.m_FileLoaded & CGitStatusListCtrl::FILELIST_UNVER)
258 m_FileListCtrl.StoreScrollPos();
259 m_FileListCtrl.Show(UpdateShowFlags());
261 else
263 if(m_bShowUnversioned)
265 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
266 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
269 UpdateStatistics();
272 void CChangedDlg::OnBnClickedShowUnmodified()
274 UpdateData();
275 m_FileListCtrl.StoreScrollPos();
276 m_FileListCtrl.Show(UpdateShowFlags());
277 m_regAddBeforeCommit = m_bShowUnversioned;
278 UpdateStatistics();
281 void CChangedDlg::OnBnClickedShowignored()
283 UpdateData();
284 m_FileListCtrl.StoreScrollPos();
285 if (m_FileListCtrl.m_FileLoaded & CGitStatusListCtrl::FILELIST_IGNORE)
286 m_FileListCtrl.Show(UpdateShowFlags());
287 else if (m_bShowIgnored)
289 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
290 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
292 UpdateStatistics();
295 void CChangedDlg::OnBnClickedShowlocalchangesignored()
297 UpdateData();
298 m_FileListCtrl.StoreScrollPos();
299 if (m_FileListCtrl.m_FileLoaded & CGitStatusListCtrl::FILELIST_LOCALCHANGESIGNORED)
300 m_FileListCtrl.Show(UpdateShowFlags());
301 else if (m_bShowLocalChangesIgnored)
303 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
304 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
306 UpdateStatistics();
309 LRESULT CChangedDlg::OnSVNStatusListCtrlNeedsRefresh(WPARAM, LPARAM)
311 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
312 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
313 return 0;
316 LRESULT CChangedDlg::OnSVNStatusListCtrlItemCountChanged(WPARAM, LPARAM)
318 UpdateStatistics();
319 return 0;
322 BOOL CChangedDlg::PreTranslateMessage(MSG* pMsg)
324 if (pMsg->message == WM_KEYDOWN)
326 switch (pMsg->wParam)
328 case VK_F5:
330 if (m_bBlock)
331 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
332 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
334 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
337 break;
341 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
344 void CChangedDlg::OnBnClickedRefresh()
346 if (!m_bBlock)
348 if (!AfxBeginThread(ChangedStatusThreadEntry, this))
349 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
353 void CChangedDlg::UpdateStatistics()
355 CString temp;
356 #if 0
357 LONG lMin, lMax;
359 m_FileListCtrl.GetMinMaxRevisions(lMin, lMax, true, false);
360 if (LONG(m_FileListCtrl.m_HeadRev) >= 0)
362 temp.Format(IDS_REPOSTATUS_HEADREV, lMin, lMax, LONG(m_FileListCtrl.m_HeadRev));
363 SetDlgItemText(IDC_SUMMARYTEXT, temp);
365 else
367 temp.Format(IDS_REPOSTATUS_WCINFO, lMin, lMax);
368 SetDlgItemText(IDC_SUMMARYTEXT, temp);
370 #endif
371 temp = m_FileListCtrl.GetStatisticsString();
372 temp.Replace(L" = ", L"=");
373 temp.Replace(L"\n", L", ");
374 SetDlgItemText(IDC_INFOLABEL, temp);
377 void CChangedDlg::OnBnClickedCommit()
379 CTGitPathList pathList;
380 bool bSingleFile = (m_pathList.GetCount() >= 1 && !m_pathList[0].IsEmpty() && !m_pathList[0].IsDirectory());
381 if (bSingleFile)
382 pathList.AddPath(m_pathList[0]);
383 else
384 pathList.AddPath(m_pathList.GetCommonRoot().GetDirectory());
386 bool bSelectFilesForCommit = !!DWORD(CRegStdDWORD(L"Software\\TortoiseGit\\SelectFilesForCommit", TRUE));
388 CString logmsg;
389 CAppUtils::Commit(GetSafeHwnd(),
390 L"",
391 m_bWholeProject,
392 logmsg,
393 pathList,
394 bSelectFilesForCommit);
396 OnBnClickedRefresh();
399 void CChangedDlg::OnBnClickedStash()
401 CIconMenu popup;
403 if (popup.CreatePopupMenu())
405 popup.AppendMenuIcon(ID_STASH_SAVE, IDS_MENUSTASHSAVE, IDI_COMMIT);
407 CTGitPath root = g_Git.m_CurrentDir;
408 if (root.HasStashDir())
410 popup.AppendMenuIcon(ID_STASH_POP, IDS_MENUSTASHPOP, IDI_RELOCATE);
411 popup.AppendMenuIcon(ID_STASH_APPLY, IDS_MENUSTASHAPPLY, IDI_RELOCATE);
412 popup.AppendMenuIcon(ID_STASH_LIST, IDS_MENUSTASHLIST, IDI_LOG);
415 RECT rect;
416 GetDlgItem(IDC_BUTTON_STASH)->GetWindowRect(&rect);
417 TPMPARAMS params;
418 params.cbSize = sizeof(TPMPARAMS);
419 params.rcExclude = rect;
420 int cmd = popup.TrackPopupMenuEx(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY | TPM_VERTICAL, rect.left, rect.top, this, &params);
422 switch (cmd & 0xFFFF)
424 case ID_STASH_SAVE:
425 CAppUtils::StashSave(GetSafeHwnd());
426 break;
427 case ID_STASH_POP:
428 CAppUtils::StashPop(GetSafeHwnd(), 2);
429 break;
430 case ID_STASH_APPLY:
431 CAppUtils::StashApply(GetSafeHwnd(), L"", false);
432 break;
433 case ID_STASH_LIST:
435 CRefLogDlg dlg;
436 dlg.m_CurrentBranch = L"refs/stash";
437 dlg.DoModal();
439 break;
440 default:
441 return;
443 OnBnClickedRefresh();
447 void CChangedDlg::OnBnClickedButtonUnifieddiff()
449 CTGitPath commonDirectory;
450 if (!m_bWholeProject)
451 commonDirectory = m_pathList.GetCommonRoot().GetDirectory();
452 bool bSingleFile = ((m_pathList.GetCount()==1)&&(!m_pathList[0].IsEmpty())&&(!m_pathList[0].IsDirectory()));
453 if (bSingleFile)
454 commonDirectory = m_pathList[0];
455 CString sCmd;
456 sCmd.Format(L"/command:showcompare /unified /path:\"%s\" /revision1:HEAD /revision2:%s", (LPCTSTR)g_Git.CombinePath(commonDirectory), (LPCTSTR)GitRev::GetWorkingCopy());
457 if (!!(GetAsyncKeyState(VK_SHIFT) & 0x8000))
458 sCmd += L" /alternative";
459 CAppUtils::RunTortoiseGitProc(sCmd);
462 void CChangedDlg::OnBnClickedWholeProject()
464 UpdateData();
465 m_regShowWholeProject = m_bWholeProject;
466 OnBnClickedRefresh();