Use CAutoGeneralHandle
[TortoiseGit.git] / src / TortoiseProc / ChangedDlg.cpp
blobb1ed3ba1298da4ef6943a337e9b6583bce3bf417
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2012 - 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 "PathUtils.h"
27 #include ".\changeddlg.h"
28 #include "IconMenu.h"
29 #include "RefLogDlg.h"
31 #include "GitStatusListCtrl.h"
33 IMPLEMENT_DYNAMIC(CChangedDlg, CResizableStandAloneDialog)
34 CChangedDlg::CChangedDlg(CWnd* pParent /*=NULL*/)
35 : CResizableStandAloneDialog(CChangedDlg::IDD, pParent)
36 , m_bShowUnversioned(FALSE)
37 , m_iShowUnmodified(0)
38 , m_bBlock(FALSE)
39 , m_bCanceled(false)
40 , m_bShowIgnored(FALSE)
41 , m_bShowExternals(TRUE)
42 , m_bShowUserProps(FALSE)
44 m_bRemote = FALSE;
47 CChangedDlg::~CChangedDlg()
51 void CChangedDlg::DoDataExchange(CDataExchange* pDX)
53 CResizableStandAloneDialog::DoDataExchange(pDX);
54 DDX_Control(pDX, IDC_CHANGEDLIST, m_FileListCtrl);
55 DDX_Control(pDX, IDC_BUTTON_STASH, m_ctrlStash);
56 DDX_Check(pDX, IDC_SHOWUNVERSIONED, m_bShowUnversioned);
57 DDX_Check(pDX, IDC_SHOWUNMODIFIED, m_iShowUnmodified);
58 DDX_Check(pDX, IDC_SHOWIGNORED, m_bShowIgnored);
59 // DDX_Check(pDX, IDC_SHOWEXTERNALS, m_bShowExternals);
60 // DDX_Check(pDX, IDC_SHOWUSERPROPS, m_bShowUserProps);
64 BEGIN_MESSAGE_MAP(CChangedDlg, CResizableStandAloneDialog)
65 ON_BN_CLICKED(IDC_SHOWUNVERSIONED, OnBnClickedShowunversioned)
66 ON_BN_CLICKED(IDC_SHOWUNMODIFIED, OnBnClickedShowUnmodified)
67 // ON_BN_CLICKED(IDC_SHOWUSERPROPS, OnBnClickedShowUserProps)
68 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_NEEDSREFRESH, OnSVNStatusListCtrlNeedsRefresh)
69 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_ITEMCOUNTCHANGED, OnSVNStatusListCtrlItemCountChanged)
70 ON_BN_CLICKED(IDC_SHOWIGNORED, &CChangedDlg::OnBnClickedShowignored)
71 ON_BN_CLICKED(IDC_REFRESH, &CChangedDlg::OnBnClickedRefresh)
72 // ON_BN_CLICKED(IDC_SHOWEXTERNALS, &CChangedDlg::OnBnClickedShowexternals)
73 ON_BN_CLICKED(IDC_COMMIT, &CChangedDlg::OnBnClickedCommit)
74 ON_BN_CLICKED(IDC_BUTTON_STASH, &CChangedDlg::OnBnClickedStash)
75 ON_BN_CLICKED(IDC_BUTTON_UNIFIEDDIFF, &CChangedDlg::OnBnClickedButtonUnifieddiff)
76 END_MESSAGE_MAP()
78 BOOL CChangedDlg::OnInitDialog()
80 CResizableStandAloneDialog::OnInitDialog();
82 GetWindowText(m_sTitle);
84 m_tooltips.Create(this);
86 m_regAddBeforeCommit = CRegDWORD(_T("Software\\TortoiseGit\\AddBeforeCommit"), TRUE);
87 m_bShowUnversioned = m_regAddBeforeCommit;
88 UpdateData(FALSE);
90 m_FileListCtrl.Init(GITSLC_COLEXT | GITSLC_COLSTATUS | GITSLC_COLADD| GITSLC_COLDEL | GITSLC_COLMODIFICATIONDATE, _T("ChangedDlg"),
91 (GITSLC_POPALL ^ (GITSLC_POPSAVEAS|GITSLC_POPRESTORE)), false);
92 m_FileListCtrl.SetCancelBool(&m_bCanceled);
93 m_FileListCtrl.SetBackgroundImage(IDI_CFM_BKG);
94 m_FileListCtrl.SetEmptyString(IDS_REPOSTATUS_EMPTYFILELIST);
96 AdjustControlSize(IDC_SHOWUNVERSIONED);
97 AdjustControlSize(IDC_SHOWUNMODIFIED);
98 AdjustControlSize(IDC_SHOWIGNORED);
99 // AdjustControlSize(IDC_SHOWEXTERNALS);
100 // AdjustControlSize(IDC_SHOWUSERPROPS);
102 AddAnchor(IDC_CHANGEDLIST, TOP_LEFT, BOTTOM_RIGHT);
103 AddAnchor(IDC_SUMMARYTEXT, BOTTOM_LEFT, BOTTOM_RIGHT);
104 AddAnchor(IDC_SHOWUNVERSIONED, BOTTOM_LEFT);
105 AddAnchor(IDC_SHOWUNMODIFIED, BOTTOM_LEFT);
106 AddAnchor(IDC_SHOWIGNORED, BOTTOM_LEFT);
107 // AddAnchor(IDC_SHOWEXTERNALS, BOTTOM_LEFT);
108 // AddAnchor(IDC_SHOWUSERPROPS, BOTTOM_LEFT);
109 AddAnchor(IDC_INFOLABEL, BOTTOM_RIGHT);
110 AddAnchor(IDC_BUTTON_STASH, BOTTOM_RIGHT);
111 AddAnchor(IDC_BUTTON_UNIFIEDDIFF, BOTTOM_RIGHT);
112 AddAnchor(IDC_COMMIT, BOTTOM_RIGHT);
113 AddAnchor(IDC_REFRESH, BOTTOM_RIGHT);
114 AddAnchor(IDOK, BOTTOM_RIGHT);
115 // SetPromptParentWindow(m_hWnd);
116 if (hWndExplorer)
117 CenterWindow(CWnd::FromHandle(hWndExplorer));
118 EnableSaveRestore(_T("ChangedDlg"));
120 m_bRemote = !!(DWORD)CRegDWORD(_T("Software\\TortoiseGit\\CheckRepo"), FALSE);
122 // first start a thread to obtain the status without
123 // blocking the dialog
124 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
126 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
129 return TRUE;
132 UINT CChangedDlg::ChangedStatusThreadEntry(LPVOID pVoid)
134 return ((CChangedDlg*)pVoid)->ChangedStatusThread();
137 UINT CChangedDlg::ChangedStatusThread()
139 InterlockedExchange(&m_bBlock, TRUE);
141 g_Git.RefreshGitIndex();
143 m_bCanceled = false;
144 SetDlgItemText(IDOK, CString(MAKEINTRESOURCE(IDS_MSGBOX_CANCEL)));
145 DialogEnableWindow(IDC_REFRESH, FALSE);
146 DialogEnableWindow(IDC_SHOWUNVERSIONED, FALSE);
147 DialogEnableWindow(IDC_SHOWUNMODIFIED, FALSE);
148 DialogEnableWindow(IDC_SHOWIGNORED, FALSE);
149 DialogEnableWindow(IDC_SHOWUSERPROPS, FALSE);
150 CString temp;
151 m_FileListCtrl.Clear();
152 if (!m_FileListCtrl.GetStatus(&m_pathList, m_bRemote, m_bShowIgnored != FALSE, m_bShowUnversioned != FALSE,m_bShowUserProps != FALSE))
154 if (!m_FileListCtrl.GetLastErrorMessage().IsEmpty())
155 m_FileListCtrl.SetEmptyString(m_FileListCtrl.GetLastErrorMessage());
157 unsigned int dwShow = GITSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALS | GITSLC_SHOWLOCKS | GITSLC_SHOWSWITCHED | GITSLC_SHOWINCHANGELIST;
158 dwShow |= m_bShowUnversioned ? GITSLC_SHOWUNVERSIONED : 0;
159 dwShow |= m_iShowUnmodified ? GITSLC_SHOWNORMAL : 0;
160 dwShow |= m_bShowIgnored ? GITSLC_SHOWIGNORED : 0;
161 dwShow |= m_bShowExternals ? GITSLC_SHOWEXTERNAL | GITSLC_SHOWINEXTERNALS | GITSLC_SHOWEXTERNALFROMDIFFERENTREPO : 0;
162 m_FileListCtrl.Show(dwShow);
163 UpdateStatistics();
165 bool bIsDirectory = false;
167 CTGitPath commonDir = m_FileListCtrl.GetCommonDirectory(false);
168 if (m_pathList.GetCount() == 1)
170 if (m_pathList[0].IsEmpty())
171 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, m_sTitle);
172 else
173 CAppUtils::SetWindowTitle(m_hWnd, (g_Git.m_CurrentDir + _T("\\") + m_pathList[0].GetWinPathString()).TrimRight('\\'), m_sTitle);
174 bIsDirectory = m_pathList[0].IsDirectory() || m_pathList[0].IsEmpty(); // if it is empty it is g_Git.m_CurrentDir which is a directory
176 else
177 CAppUtils::SetWindowTitle(m_hWnd, commonDir.GetWinPathString(), m_sTitle);
179 SetDlgItemText(IDOK, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)));
180 DialogEnableWindow(IDC_REFRESH, TRUE);
181 DialogEnableWindow(IDC_SHOWUNVERSIONED, bIsDirectory);
182 //DialogEnableWindow(IDC_SHOWUNMODIFIED, bIsDirectory);
183 DialogEnableWindow(IDC_SHOWIGNORED, bIsDirectory);
184 DialogEnableWindow(IDC_SHOWUSERPROPS, TRUE);
185 InterlockedExchange(&m_bBlock, FALSE);
186 // revert the remote flag back to the default
187 m_bRemote = !!(DWORD)CRegDWORD(_T("Software\\TortoiseGit\\CheckRepo"), FALSE);
188 RefreshCursor();
189 return 0;
192 void CChangedDlg::OnOK()
194 if (m_bBlock)
196 m_bCanceled = true;
197 return;
199 __super::OnOK();
202 void CChangedDlg::OnCancel()
204 if (m_bBlock)
206 m_bCanceled = true;
207 return;
209 __super::OnCancel();
212 DWORD CChangedDlg::UpdateShowFlags()
214 DWORD dwShow = m_FileListCtrl.GetShowFlags();
215 if (m_bShowUnversioned)
216 dwShow |= GITSLC_SHOWUNVERSIONED;
217 else
218 dwShow &= ~GITSLC_SHOWUNVERSIONED;
219 if (m_iShowUnmodified)
220 dwShow |= GITSLC_SHOWNORMAL;
221 else
222 dwShow &= ~GITSLC_SHOWNORMAL;
223 if (m_bShowIgnored)
224 dwShow |= GITSLC_SHOWIGNORED;
225 else
226 dwShow &= ~GITSLC_SHOWIGNORED;
227 if (m_bShowExternals)
228 dwShow |= GITSLC_SHOWEXTERNAL | GITSLC_SHOWINEXTERNALS | GITSLC_SHOWEXTERNALFROMDIFFERENTREPO;
229 else
230 dwShow &= ~(GITSLC_SHOWEXTERNAL | GITSLC_SHOWINEXTERNALS | GITSLC_SHOWEXTERNALFROMDIFFERENTREPO);
232 return dwShow;
235 void CChangedDlg::OnBnClickedShowunversioned()
237 UpdateData();
238 m_regAddBeforeCommit = m_bShowUnversioned;
239 if(m_FileListCtrl.m_FileLoaded & CGitStatusListCtrl::FILELIST_UNVER)
241 m_FileListCtrl.Show(UpdateShowFlags());
243 else
245 if(m_bShowUnversioned)
247 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
249 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
253 UpdateStatistics();
256 void CChangedDlg::OnBnClickedShowUnmodified()
258 UpdateData();
259 m_FileListCtrl.Show(UpdateShowFlags());
260 m_regAddBeforeCommit = m_bShowUnversioned;
261 UpdateStatistics();
264 void CChangedDlg::OnBnClickedShowignored()
266 UpdateData();
267 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
269 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
273 void CChangedDlg::OnBnClickedShowexternals()
275 UpdateData();
276 m_FileListCtrl.Show(UpdateShowFlags());
277 UpdateStatistics();
280 void CChangedDlg::OnBnClickedShowUserProps()
282 UpdateData();
283 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
285 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
289 LRESULT CChangedDlg::OnSVNStatusListCtrlNeedsRefresh(WPARAM, LPARAM)
291 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
293 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
295 return 0;
298 LRESULT CChangedDlg::OnSVNStatusListCtrlItemCountChanged(WPARAM, LPARAM)
300 UpdateStatistics();
301 return 0;
304 BOOL CChangedDlg::PreTranslateMessage(MSG* pMsg)
306 m_tooltips.RelayEvent(pMsg);
307 if (pMsg->message == WM_KEYDOWN)
309 switch (pMsg->wParam)
311 case VK_F5:
313 if (m_bBlock)
314 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
315 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
317 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
320 break;
324 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
327 void CChangedDlg::OnBnClickedRefresh()
329 if (!m_bBlock)
331 if (AfxBeginThread(ChangedStatusThreadEntry, this)==NULL)
333 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
338 void CChangedDlg::UpdateStatistics()
340 CString temp;
341 #if 0
342 LONG lMin, lMax;
344 m_FileListCtrl.GetMinMaxRevisions(lMin, lMax, true, false);
345 if (LONG(m_FileListCtrl.m_HeadRev) >= 0)
347 temp.Format(IDS_REPOSTATUS_HEADREV, lMin, lMax, LONG(m_FileListCtrl.m_HeadRev));
348 SetDlgItemText(IDC_SUMMARYTEXT, temp);
350 else
352 temp.Format(IDS_REPOSTATUS_WCINFO, lMin, lMax);
353 SetDlgItemText(IDC_SUMMARYTEXT, temp);
355 #endif
356 temp = m_FileListCtrl.GetStatisticsString();
357 temp.Replace(_T(" = "), _T("="));
358 temp.Replace(_T("\n"), _T(", "));
359 SetDlgItemText(IDC_INFOLABEL, temp);
363 void CChangedDlg::OnBnClickedCommit()
365 CString cmd = _T("/command:commit /path:\"");
366 bool bSingleFile = ((m_pathList.GetCount()==1)&&(!m_pathList[0].IsEmpty())&&(!m_pathList[0].IsDirectory()));
367 if (bSingleFile)
368 cmd += m_pathList[0].GetWinPathString();
369 else
370 cmd += g_Git.m_CurrentDir + _T("\\") + m_pathList.GetCommonRoot().GetDirectory().GetWinPath();
371 cmd += _T("\"");
372 CAppUtils::RunTortoiseProc(cmd);
375 void CChangedDlg::OnBnClickedStash()
377 CIconMenu popup;
379 if (popup.CreatePopupMenu())
381 popup.AppendMenuIcon(ID_STASH_SAVE, IDS_MENUSTASHSAVE, IDI_COMMIT);
383 CTGitPath root = g_Git.m_CurrentDir;
384 if (root.HasStashDir())
386 popup.AppendMenuIcon(ID_STASH_POP, IDS_MENUSTASHPOP, IDI_RELOCATE);
387 popup.AppendMenuIcon(ID_STASH_APPLY, IDS_MENUSTASHAPPLY, IDI_RELOCATE);
388 popup.AppendMenuIcon(ID_STASH_LIST, IDS_MENUSTASHLIST, IDI_LOG);
391 POINT cursorPos;
392 GetCursorPos(&cursorPos);
393 int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, cursorPos.x, cursorPos.y, this, 0);
395 switch (cmd & 0xFFFF)
397 case ID_STASH_SAVE:
398 CAppUtils::StashSave();
399 break;
400 case ID_STASH_POP:
401 CAppUtils::StashPop(false);
402 return;
403 case ID_STASH_APPLY:
404 CAppUtils::StashApply(_T(""), false);
405 break;
406 case ID_STASH_LIST:
408 CRefLogDlg dlg;
409 dlg.m_CurrentBranch = _T("refs/stash");
410 dlg.DoModal();
412 break;
413 default:
414 return;
416 OnBnClickedRefresh();
420 void CChangedDlg::OnBnClickedButtonUnifieddiff()
422 CTGitPath commonDirectory = m_pathList.GetCommonRoot().GetDirectory();
423 bool bSingleFile = ((m_pathList.GetCount()==1)&&(!m_pathList[0].IsEmpty())&&(!m_pathList[0].IsDirectory()));
424 if (bSingleFile)
425 commonDirectory = m_pathList[0];
426 CAppUtils::StartShowUnifiedDiff(m_hWnd, commonDirectory, GitRev::GetHead(), commonDirectory, GitRev::GetWorkingCopy());