1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2014, 2016 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "BrowseRefsDlg.h"
23 #include "MessageBox.h"
25 #include "StringUtils.h"
27 static UINT WM_GUIUPDATES
= RegisterWindowMessage(_T("TORTOISEGIT_CHOOSEVERSION_GUIUPDATES"));
32 CString m_initialRefName
;
36 CWinThread
* m_pLoadingThread
;
37 static UINT
LoadingThreadEntry(LPVOID pVoid
)
39 return reinterpret_cast<CChooseVersion
*>(pVoid
)->LoadingThread();
41 volatile LONG m_bLoadingThreadRunning
;
44 CHistoryCombo m_ChooseVersioinBranch
;
45 CHistoryCombo m_ChooseVersioinTags
;
46 CHistoryCombo m_ChooseVersioinVersion
;
47 CButton m_RadioBranch
;
49 CString m_pendingRefName
;
52 //Notification when version changed. Can be implemented in derived classes.
53 virtual void OnVersionChanged(){}
55 afx_msg
void OnBnClickedChooseRadio()
57 this->m_ChooseVersioinTags
.EnableWindow(FALSE
);
58 this->m_ChooseVersioinBranch
.EnableWindow(FALSE
);
59 this->m_ChooseVersioinVersion
.EnableWindow(FALSE
);
60 m_pWin
->GetDlgItem(IDC_BUTTON_BROWSE_REF
)->EnableWindow(FALSE
);
61 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(FALSE
);
63 int radio
=m_pWin
->GetCheckedRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
);
68 case IDC_RADIO_BRANCH
:
69 this->m_ChooseVersioinBranch
.EnableWindow(TRUE
);
70 m_pWin
->GetDlgItem(IDC_BUTTON_BROWSE_REF
)->EnableWindow(TRUE
);
74 this->m_ChooseVersioinTags
.EnableWindow(TRUE
);
76 case IDC_RADIO_VERSION
:
77 this->m_ChooseVersioinVersion
.EnableWindow(TRUE
);
78 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(TRUE
);
81 // enable version browse button if Version is selected
82 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(radio
== IDC_RADIO_VERSION
);
86 void OnBnClickedChooseVersion()
88 // use the git log to allow selection of a version
91 m_ChooseVersioinVersion
.GetWindowText(revision
);
92 dlg
.SetParams(CTGitPath(), CTGitPath(), revision
, revision
, 0);
93 // tell the dialog to use mode for selecting revisions
95 dlg
.ShowWorkingTreeChanges(false);
96 // only one revision must be selected however
97 dlg
.SingleSelection(true);
98 if ( dlg
.DoModal() == IDOK
)
100 m_ChooseVersioinVersion
.SetWindowText(dlg
.GetSelectedHash().at(0).ToString());
105 void UpdateRevsionName()
107 int radio
=m_pWin
->GetCheckedRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
);
111 this->m_VersionName
=_T("HEAD");
113 case IDC_RADIO_BRANCH
:
114 this->m_VersionName
=m_ChooseVersioinBranch
.GetString();
115 if (!m_VersionName
.IsEmpty() && !g_Git
.IsBranchTagNameUnique(this->m_VersionName
))
116 this->m_VersionName
= L
"refs/heads/" + this->m_VersionName
;
119 this->m_VersionName
= m_ChooseVersioinTags
.GetString();
120 if (!m_VersionName
.IsEmpty() && !g_Git
.IsBranchTagNameUnique(this->m_VersionName
))
121 this->m_VersionName
= L
"refs/tags/" + m_ChooseVersioinTags
.GetString();
123 case IDC_RADIO_VERSION
:
124 this->m_VersionName
=m_ChooseVersioinVersion
.GetString();
128 void SetDefaultChoose(int id
)
130 m_pWin
->CheckRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
,id
);
131 OnBnClickedChooseRadio();
134 void OnBnClickedButtonBrowseRef()
138 CString resultRef
= CBrowseRefsDlg::PickRef(false, m_VersionName
, gPickRef_All
);
139 if(resultRef
.IsEmpty())
141 m_pendingRefName
= m_VersionName
;
142 m_bNotFullName
= true;
143 InitChooseVersion(false, true);
146 m_pendingRefName
= resultRef
;
147 m_bNotFullName
= false;
148 InitChooseVersion(false, true);
151 void SelectRef(CString refName
, bool bRefNameIsPossiblyNotFullName
= true)
153 if(bRefNameIsPossiblyNotFullName
)
155 //Make sure refName is a full ref name first
156 CString fullRefName
= g_Git
.GetFullRefName(refName
);
157 if(!fullRefName
.IsEmpty())
158 refName
= fullRefName
;
161 if (CStringUtils::StartsWith(refName
, L
"refs/"))
162 refName
= refName
.Mid(5);
163 if (CStringUtils::StartsWith(refName
, L
"heads/"))
165 refName
= refName
.Mid(6);
166 SetDefaultChoose(IDC_RADIO_BRANCH
);
167 m_ChooseVersioinBranch
.SetCurSel(
168 m_ChooseVersioinBranch
.FindStringExact(-1, refName
));
170 else if (CStringUtils::StartsWith(refName
, L
"remotes/"))
172 SetDefaultChoose(IDC_RADIO_BRANCH
);
173 m_ChooseVersioinBranch
.SetCurSel(
174 m_ChooseVersioinBranch
.FindStringExact(-1, refName
));
176 else if (CStringUtils::StartsWith(refName
, L
"tags/"))
178 refName
= refName
.Mid(5);
179 refName
.Replace(_T("^{}"), _T(""));
180 SetDefaultChoose(IDC_RADIO_TAGS
);
181 m_ChooseVersioinTags
.SetCurSel(
182 m_ChooseVersioinTags
.FindStringExact(-1, refName
));
186 SetDefaultChoose(IDC_RADIO_VERSION
);
187 m_ChooseVersioinVersion
.AddString(refName
);
197 g_Git
.GetBranchList(list
, ¤t
, CRegDWORD(L
"Software\\TortoiseGit\\BranchesIncludeFetchHead", TRUE
) ? CGit::BRANCH_ALL_F
: CGit::BRANCH_ALL
);
198 m_ChooseVersioinBranch
.SetList(list
);
199 m_ChooseVersioinBranch
.SetCurSel(current
);
202 g_Git
.GetTagList(list
);
203 m_ChooseVersioinTags
.SetList(list
);
204 m_ChooseVersioinTags
.SetCurSel(0);
206 m_pWin
->SendMessage(WM_GUIUPDATES
);
208 InterlockedExchange(&m_bLoadingThreadRunning
, FALSE
);
213 m_RadioBranch
.EnableWindow(TRUE
);
214 m_RadioTag
.EnableWindow(TRUE
);
216 if (m_pendingRefName
.IsEmpty())
219 SelectRef(m_pendingRefName
, m_bNotFullName
);
221 if (m_bIsFirstTimeToSetFocus
&& m_pWin
->GetDlgItem(IDC_COMBOBOXEX_BRANCH
)->IsWindowEnabled())
222 m_pWin
->GetDlgItem(IDC_COMBOBOXEX_BRANCH
)->SetFocus();
223 m_bIsFirstTimeToSetFocus
= false;
224 m_pWin
->GetDlgItem(IDOK
)->EnableWindow(TRUE
);
226 void InitChooseVersion(bool setFocusToBranchComboBox
= false, bool bReInit
= false)
228 m_ChooseVersioinBranch
.SetMaxHistoryItems(0x7FFFFFFF);
229 m_ChooseVersioinTags
.SetMaxHistoryItems(0x7FFFFFFF);
232 m_RadioBranch
.EnableWindow(FALSE
);
233 m_RadioTag
.EnableWindow(FALSE
);
235 m_bIsFirstTimeToSetFocus
= setFocusToBranchComboBox
;
238 m_pendingRefName
= m_initialRefName
;
239 m_bNotFullName
= true;
242 m_pWin
->GetDlgItem(IDOK
)->EnableWindow(FALSE
);
244 InterlockedExchange(&m_bLoadingThreadRunning
, TRUE
);
246 if ((m_pLoadingThread
= AfxBeginThread(LoadingThreadEntry
, this)) == nullptr)
248 InterlockedExchange(&m_bLoadingThreadRunning
, FALSE
);
249 CMessageBox::Show(nullptr, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
252 void WaitForFinishLoading()
254 if(m_bLoadingThreadRunning
&& m_pLoadingThread
)
256 DWORD ret
=::WaitForSingleObject(m_pLoadingThread
->m_hThread
,20000);
257 if(ret
== WAIT_TIMEOUT
)
258 ::TerminateThread(m_pLoadingThread
,0);
262 CString m_VersionName
;
264 bool m_bIsFirstTimeToSetFocus
;
265 CChooseVersion(CWnd
*win
)
267 , m_bIsFirstTimeToSetFocus(false)
268 , m_pLoadingThread(nullptr)
269 , m_bLoadingThreadRunning(FALSE
)
270 , m_bNotFullName(true)
276 #define CHOOSE_VERSION_DDX \
277 DDX_Control(pDX, IDC_COMBOBOXEX_BRANCH, m_ChooseVersioinBranch); \
278 DDX_Control(pDX, IDC_COMBOBOXEX_TAGS, m_ChooseVersioinTags); \
279 DDX_Control(pDX, IDC_COMBOBOXEX_VERSION, m_ChooseVersioinVersion); \
280 DDX_Control(pDX, IDC_RADIO_BRANCH, m_RadioBranch);\
281 DDX_Control(pDX, IDC_RADIO_TAGS, m_RadioTag);
283 #define CHOOSE_VERSION_EVENT\
284 ON_REGISTERED_MESSAGE(WM_GUIUPDATES, OnUpdateGUIHost)\
285 ON_BN_CLICKED(IDC_RADIO_HEAD, OnBnClickedChooseRadioHost)\
286 ON_BN_CLICKED(IDC_RADIO_BRANCH, OnBnClickedChooseRadioHost)\
287 ON_BN_CLICKED(IDC_RADIO_TAGS, OnBnClickedChooseRadioHost)\
288 ON_BN_CLICKED(IDC_BUTTON_SHOW, OnBnClickedShow)\
289 ON_BN_CLICKED(IDC_RADIO_VERSION, OnBnClickedChooseRadioHost)\
290 ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF, OnBnClickedButtonBrowseRefHost)
292 #define CHOOSE_VERSION_ADDANCHOR \
294 AddAnchor(IDC_COMBOBOXEX_BRANCH, TOP_LEFT, TOP_RIGHT); \
295 AddAnchor(IDC_COMBOBOXEX_TAGS, TOP_LEFT, TOP_RIGHT); \
296 AddAnchor(IDC_COMBOBOXEX_VERSION, TOP_LEFT, TOP_RIGHT); \
297 AddAnchor(IDC_GROUP_BASEON, TOP_LEFT, TOP_RIGHT); \
298 AddAnchor(IDC_BUTTON_SHOW,TOP_RIGHT); \
299 AddAnchor(IDC_BUTTON_BROWSE_REF,TOP_RIGHT); \
302 #define CHOOSE_EVENT_RADIO() \
303 LRESULT OnUpdateGUIHost(WPARAM, LPARAM) { UpdateGUI(); return 0; } \
304 afx_msg void OnBnClickedChooseRadioHost(){OnBnClickedChooseRadio();}\
305 afx_msg void OnBnClickedShow(){OnBnClickedChooseVersion();}\
306 afx_msg void OnBnClickedButtonBrowseRefHost(){OnBnClickedButtonBrowseRef();}