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.
21 #include "TortoiseProc.h"
22 #include "ChangedDlg.h"
23 #include "messagebox.h"
26 #include "PathUtils.h"
27 #include ".\changeddlg.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)
40 , m_bShowIgnored(FALSE
)
41 , m_bShowExternals(TRUE
)
46 CChangedDlg::~CChangedDlg()
50 void CChangedDlg::DoDataExchange(CDataExchange
* pDX
)
52 CResizableStandAloneDialog::DoDataExchange(pDX
);
53 DDX_Control(pDX
, IDC_CHANGEDLIST
, m_FileListCtrl
);
54 DDX_Control(pDX
, IDC_BUTTON_STASH
, m_ctrlStash
);
55 DDX_Check(pDX
, IDC_SHOWUNVERSIONED
, m_bShowUnversioned
);
56 DDX_Check(pDX
, IDC_SHOWUNMODIFIED
, m_iShowUnmodified
);
57 DDX_Check(pDX
, IDC_SHOWIGNORED
, m_bShowIgnored
);
58 // DDX_Check(pDX, IDC_SHOWEXTERNALS, m_bShowExternals);
62 BEGIN_MESSAGE_MAP(CChangedDlg
, CResizableStandAloneDialog
)
63 ON_BN_CLICKED(IDC_SHOWUNVERSIONED
, OnBnClickedShowunversioned
)
64 ON_BN_CLICKED(IDC_SHOWUNMODIFIED
, OnBnClickedShowUnmodified
)
65 // ON_BN_CLICKED(IDC_SHOWUSERPROPS, OnBnClickedShowUserProps)
66 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_NEEDSREFRESH
, OnSVNStatusListCtrlNeedsRefresh
)
67 ON_REGISTERED_MESSAGE(CGitStatusListCtrl::GITSLNM_ITEMCOUNTCHANGED
, OnSVNStatusListCtrlItemCountChanged
)
68 ON_BN_CLICKED(IDC_SHOWIGNORED
, &CChangedDlg::OnBnClickedShowignored
)
69 ON_BN_CLICKED(IDC_REFRESH
, &CChangedDlg::OnBnClickedRefresh
)
70 // ON_BN_CLICKED(IDC_SHOWEXTERNALS, &CChangedDlg::OnBnClickedShowexternals)
71 ON_BN_CLICKED(IDC_COMMIT
, &CChangedDlg::OnBnClickedCommit
)
72 ON_BN_CLICKED(IDC_BUTTON_STASH
, &CChangedDlg::OnBnClickedStash
)
73 ON_BN_CLICKED(IDC_BUTTON_UNIFIEDDIFF
, &CChangedDlg::OnBnClickedButtonUnifieddiff
)
76 BOOL
CChangedDlg::OnInitDialog()
78 CResizableStandAloneDialog::OnInitDialog();
80 GetWindowText(m_sTitle
);
82 m_tooltips
.Create(this);
84 m_regAddBeforeCommit
= CRegDWORD(_T("Software\\TortoiseGit\\AddBeforeCommit"), TRUE
);
85 m_bShowUnversioned
= m_regAddBeforeCommit
;
88 m_FileListCtrl
.Init(GITSLC_COLEXT
| GITSLC_COLSTATUS
| GITSLC_COLADD
| GITSLC_COLDEL
| GITSLC_COLMODIFICATIONDATE
, _T("ChangedDlg"),
89 (GITSLC_POPALL
^ (GITSLC_POPSAVEAS
|GITSLC_POPRESTORE
)), false);
90 m_FileListCtrl
.SetCancelBool(&m_bCanceled
);
91 m_FileListCtrl
.SetBackgroundImage(IDI_CFM_BKG
);
92 m_FileListCtrl
.SetEmptyString(IDS_REPOSTATUS_EMPTYFILELIST
);
94 AdjustControlSize(IDC_SHOWUNVERSIONED
);
95 AdjustControlSize(IDC_SHOWUNMODIFIED
);
96 AdjustControlSize(IDC_SHOWIGNORED
);
97 // AdjustControlSize(IDC_SHOWEXTERNALS);
98 // AdjustControlSize(IDC_SHOWUSERPROPS);
100 AddAnchor(IDC_CHANGEDLIST
, TOP_LEFT
, BOTTOM_RIGHT
);
101 AddAnchor(IDC_SUMMARYTEXT
, BOTTOM_LEFT
, BOTTOM_RIGHT
);
102 AddAnchor(IDC_SHOWUNVERSIONED
, BOTTOM_LEFT
);
103 AddAnchor(IDC_SHOWUNMODIFIED
, BOTTOM_LEFT
);
104 AddAnchor(IDC_SHOWIGNORED
, BOTTOM_LEFT
);
105 // AddAnchor(IDC_SHOWEXTERNALS, BOTTOM_LEFT);
106 // AddAnchor(IDC_SHOWUSERPROPS, BOTTOM_LEFT);
107 AddAnchor(IDC_INFOLABEL
, BOTTOM_RIGHT
);
108 AddAnchor(IDC_BUTTON_STASH
, BOTTOM_RIGHT
);
109 AddAnchor(IDC_BUTTON_UNIFIEDDIFF
, BOTTOM_RIGHT
);
110 AddAnchor(IDC_COMMIT
, BOTTOM_RIGHT
);
111 AddAnchor(IDC_REFRESH
, BOTTOM_RIGHT
);
112 AddAnchor(IDOK
, BOTTOM_RIGHT
);
113 // SetPromptParentWindow(m_hWnd);
115 CenterWindow(CWnd::FromHandle(hWndExplorer
));
116 EnableSaveRestore(_T("ChangedDlg"));
118 m_bRemote
= !!(DWORD
)CRegDWORD(_T("Software\\TortoiseGit\\CheckRepo"), FALSE
);
120 // first start a thread to obtain the status without
121 // blocking the dialog
122 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
124 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
130 UINT
CChangedDlg::ChangedStatusThreadEntry(LPVOID pVoid
)
132 return ((CChangedDlg
*)pVoid
)->ChangedStatusThread();
135 UINT
CChangedDlg::ChangedStatusThread()
137 InterlockedExchange(&m_bBlock
, TRUE
);
139 g_Git
.RefreshGitIndex();
142 SetDlgItemText(IDOK
, CString(MAKEINTRESOURCE(IDS_MSGBOX_CANCEL
)));
143 DialogEnableWindow(IDC_REFRESH
, FALSE
);
144 DialogEnableWindow(IDC_SHOWUNVERSIONED
, FALSE
);
145 DialogEnableWindow(IDC_SHOWUNMODIFIED
, FALSE
);
146 DialogEnableWindow(IDC_SHOWIGNORED
, FALSE
);
147 DialogEnableWindow(IDC_SHOWUSERPROPS
, FALSE
);
149 m_FileListCtrl
.Clear();
150 if (!m_FileListCtrl
.GetStatus(&m_pathList
, m_bRemote
, m_bShowIgnored
!= FALSE
, m_bShowUnversioned
!= FALSE
))
152 if (!m_FileListCtrl
.GetLastErrorMessage().IsEmpty())
153 m_FileListCtrl
.SetEmptyString(m_FileListCtrl
.GetLastErrorMessage());
155 unsigned int dwShow
= GITSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALS
| GITSLC_SHOWLOCKS
| GITSLC_SHOWSWITCHED
| GITSLC_SHOWINCHANGELIST
;
156 dwShow
|= m_bShowUnversioned
? GITSLC_SHOWUNVERSIONED
: 0;
157 dwShow
|= m_iShowUnmodified
? GITSLC_SHOWNORMAL
: 0;
158 dwShow
|= m_bShowIgnored
? GITSLC_SHOWIGNORED
: 0;
159 dwShow
|= m_bShowExternals
? GITSLC_SHOWEXTERNAL
| GITSLC_SHOWINEXTERNALS
| GITSLC_SHOWEXTERNALFROMDIFFERENTREPO
: 0;
160 m_FileListCtrl
.Show(dwShow
);
163 bool bIsDirectory
= false;
165 CTGitPath commonDir
= m_FileListCtrl
.GetCommonDirectory(false);
166 if (m_pathList
.GetCount() == 1)
168 if (m_pathList
[0].IsEmpty())
169 CAppUtils::SetWindowTitle(m_hWnd
, g_Git
.m_CurrentDir
, m_sTitle
);
171 CAppUtils::SetWindowTitle(m_hWnd
, (g_Git
.m_CurrentDir
+ _T("\\") + m_pathList
[0].GetWinPathString()).TrimRight('\\'), m_sTitle
);
172 bIsDirectory
= m_pathList
[0].IsDirectory() || m_pathList
[0].IsEmpty(); // if it is empty it is g_Git.m_CurrentDir which is a directory
175 CAppUtils::SetWindowTitle(m_hWnd
, commonDir
.GetWinPathString(), m_sTitle
);
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_SHOWUSERPROPS
, TRUE
);
183 InterlockedExchange(&m_bBlock
, FALSE
);
184 // revert the remote flag back to the default
185 m_bRemote
= !!(DWORD
)CRegDWORD(_T("Software\\TortoiseGit\\CheckRepo"), FALSE
);
190 void CChangedDlg::OnOK()
200 void CChangedDlg::OnCancel()
210 DWORD
CChangedDlg::UpdateShowFlags()
212 DWORD dwShow
= m_FileListCtrl
.GetShowFlags();
213 if (m_bShowUnversioned
)
214 dwShow
|= GITSLC_SHOWUNVERSIONED
;
216 dwShow
&= ~GITSLC_SHOWUNVERSIONED
;
217 if (m_iShowUnmodified
)
218 dwShow
|= GITSLC_SHOWNORMAL
;
220 dwShow
&= ~GITSLC_SHOWNORMAL
;
222 dwShow
|= GITSLC_SHOWIGNORED
;
224 dwShow
&= ~GITSLC_SHOWIGNORED
;
225 if (m_bShowExternals
)
226 dwShow
|= GITSLC_SHOWEXTERNAL
| GITSLC_SHOWINEXTERNALS
| GITSLC_SHOWEXTERNALFROMDIFFERENTREPO
;
228 dwShow
&= ~(GITSLC_SHOWEXTERNAL
| GITSLC_SHOWINEXTERNALS
| GITSLC_SHOWEXTERNALFROMDIFFERENTREPO
);
233 void CChangedDlg::OnBnClickedShowunversioned()
236 m_regAddBeforeCommit
= m_bShowUnversioned
;
237 if(m_FileListCtrl
.m_FileLoaded
& CGitStatusListCtrl::FILELIST_UNVER
)
239 m_FileListCtrl
.Show(UpdateShowFlags());
243 if(m_bShowUnversioned
)
245 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
247 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
254 void CChangedDlg::OnBnClickedShowUnmodified()
257 m_FileListCtrl
.Show(UpdateShowFlags());
258 m_regAddBeforeCommit
= m_bShowUnversioned
;
262 void CChangedDlg::OnBnClickedShowignored()
265 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
267 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
271 void CChangedDlg::OnBnClickedShowexternals()
274 m_FileListCtrl
.Show(UpdateShowFlags());
278 void CChangedDlg::OnBnClickedShowUserProps()
281 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
283 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
287 LRESULT
CChangedDlg::OnSVNStatusListCtrlNeedsRefresh(WPARAM
, LPARAM
)
289 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
291 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
296 LRESULT
CChangedDlg::OnSVNStatusListCtrlItemCountChanged(WPARAM
, LPARAM
)
302 BOOL
CChangedDlg::PreTranslateMessage(MSG
* pMsg
)
304 m_tooltips
.RelayEvent(pMsg
);
305 if (pMsg
->message
== WM_KEYDOWN
)
307 switch (pMsg
->wParam
)
312 return CResizableStandAloneDialog::PreTranslateMessage(pMsg
);
313 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
315 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
322 return CResizableStandAloneDialog::PreTranslateMessage(pMsg
);
325 void CChangedDlg::OnBnClickedRefresh()
329 if (AfxBeginThread(ChangedStatusThreadEntry
, this)==NULL
)
331 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
336 void CChangedDlg::UpdateStatistics()
342 m_FileListCtrl
.GetMinMaxRevisions(lMin
, lMax
, true, false);
343 if (LONG(m_FileListCtrl
.m_HeadRev
) >= 0)
345 temp
.Format(IDS_REPOSTATUS_HEADREV
, lMin
, lMax
, LONG(m_FileListCtrl
.m_HeadRev
));
346 SetDlgItemText(IDC_SUMMARYTEXT
, temp
);
350 temp
.Format(IDS_REPOSTATUS_WCINFO
, lMin
, lMax
);
351 SetDlgItemText(IDC_SUMMARYTEXT
, temp
);
354 temp
= m_FileListCtrl
.GetStatisticsString();
355 temp
.Replace(_T(" = "), _T("="));
356 temp
.Replace(_T("\n"), _T(", "));
357 SetDlgItemText(IDC_INFOLABEL
, temp
);
361 void CChangedDlg::OnBnClickedCommit()
363 CString cmd
= _T("/command:commit /path:\"");
364 bool bSingleFile
= ((m_pathList
.GetCount()==1)&&(!m_pathList
[0].IsEmpty())&&(!m_pathList
[0].IsDirectory()));
366 cmd
+= m_pathList
[0].GetWinPathString();
368 cmd
+= g_Git
.m_CurrentDir
+ _T("\\") + m_pathList
.GetCommonRoot().GetDirectory().GetWinPath();
370 CAppUtils::RunTortoiseProc(cmd
);
373 void CChangedDlg::OnBnClickedStash()
377 if (popup
.CreatePopupMenu())
379 popup
.AppendMenuIcon(ID_STASH_SAVE
, IDS_MENUSTASHSAVE
, IDI_COMMIT
);
381 CTGitPath root
= g_Git
.m_CurrentDir
;
382 if (root
.HasStashDir())
384 popup
.AppendMenuIcon(ID_STASH_POP
, IDS_MENUSTASHPOP
, IDI_RELOCATE
);
385 popup
.AppendMenuIcon(ID_STASH_APPLY
, IDS_MENUSTASHAPPLY
, IDI_RELOCATE
);
386 popup
.AppendMenuIcon(ID_STASH_LIST
, IDS_MENUSTASHLIST
, IDI_LOG
);
390 GetCursorPos(&cursorPos
);
391 int cmd
= popup
.TrackPopupMenu(TPM_RETURNCMD
| TPM_LEFTALIGN
| TPM_NONOTIFY
, cursorPos
.x
, cursorPos
.y
, this, 0);
393 switch (cmd
& 0xFFFF)
396 CAppUtils::StashSave();
399 CAppUtils::StashPop(false);
402 CAppUtils::StashApply(_T(""), false);
407 dlg
.m_CurrentBranch
= _T("refs/stash");
414 OnBnClickedRefresh();
418 void CChangedDlg::OnBnClickedButtonUnifieddiff()
420 CTGitPath commonDirectory
= m_pathList
.GetCommonRoot().GetDirectory();
421 bool bSingleFile
= ((m_pathList
.GetCount()==1)&&(!m_pathList
[0].IsEmpty())&&(!m_pathList
[0].IsDirectory()));
423 commonDirectory
= m_pathList
[0];
424 CAppUtils::StartShowUnifiedDiff(m_hWnd
, commonDirectory
, GitRev::GetHead(), commonDirectory
, GitRev::GetWorkingCopy());