1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013 - 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 static UINT WM_GUIUPDATES
= RegisterWindowMessage(_T("TORTOISEGIT_CHOOSEVERSION_GUIUPDATES"));
30 CString m_initialRefName
;
34 CWinThread
* m_pLoadingThread
;
35 static UINT
LoadingThreadEntry(LPVOID pVoid
)
37 return ((CChooseVersion
*)pVoid
)->LoadingThread();
39 volatile LONG m_bLoadingThreadRunning
;
42 CHistoryCombo m_ChooseVersioinBranch
;
43 CHistoryCombo m_ChooseVersioinTags
;
44 CHistoryCombo m_ChooseVersioinVersion
;
45 CButton m_RadioBranch
;
47 CString m_pendingRefName
;
51 //Notification when version changed. Can be implemented in derived classes.
52 virtual void OnVersionChanged(){}
54 afx_msg
void OnBnClickedChooseRadio()
56 this->m_ChooseVersioinTags
.EnableWindow(FALSE
);
57 this->m_ChooseVersioinBranch
.EnableWindow(FALSE
);
58 this->m_ChooseVersioinVersion
.EnableWindow(FALSE
);
59 m_pWin
->GetDlgItem(IDC_BUTTON_BROWSE_REF
)->EnableWindow(FALSE
);
60 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(FALSE
);
62 int radio
=m_pWin
->GetCheckedRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
);
67 case IDC_RADIO_BRANCH
:
68 this->m_ChooseVersioinBranch
.EnableWindow(TRUE
);
69 m_pWin
->GetDlgItem(IDC_BUTTON_BROWSE_REF
)->EnableWindow(TRUE
);
73 this->m_ChooseVersioinTags
.EnableWindow(TRUE
);
75 case IDC_RADIO_VERSION
:
76 this->m_ChooseVersioinVersion
.EnableWindow(TRUE
);
77 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(TRUE
);
80 // enable version browse button if Version is selected
81 m_pWin
->GetDlgItem(IDC_BUTTON_SHOW
)->EnableWindow(radio
== IDC_RADIO_VERSION
);
85 void OnBnClickedChooseVersion()
87 // use the git log to allow selection of a version
89 // tell the dialog to use mode for selecting revisions
91 // only one revision must be selected however
92 dlg
.SingleSelection(true);
93 if ( dlg
.DoModal() == IDOK
)
95 // get selected hash if any
96 CString selectedHash
= dlg
.GetSelectedHash();
97 // load into window, do this even if empty so that it is clear that nothing has been selected
98 m_ChooseVersioinVersion
.SetWindowText( selectedHash
);
103 void UpdateRevsionName()
105 int radio
=m_pWin
->GetCheckedRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
);
109 this->m_VersionName
=_T("HEAD");
111 case IDC_RADIO_BRANCH
:
112 this->m_VersionName
=m_ChooseVersioinBranch
.GetString();
113 if (!g_Git
.IsBranchTagNameUnique(this->m_VersionName
))
114 this->m_VersionName
= L
"refs/heads/" + this->m_VersionName
;
117 this->m_VersionName
= m_ChooseVersioinTags
.GetString();
118 if (!g_Git
.IsBranchTagNameUnique(this->m_VersionName
))
119 this->m_VersionName
= L
"refs/tags/" + m_ChooseVersioinTags
.GetString();
121 case IDC_RADIO_VERSION
:
122 this->m_VersionName
=m_ChooseVersioinVersion
.GetString();
126 void SetDefaultChoose(int id
)
128 m_pWin
->CheckRadioButton(IDC_RADIO_HEAD
,IDC_RADIO_VERSION
,id
);
129 OnBnClickedChooseRadio();
132 void OnBnClickedButtonBrowseRef()
136 CString resultRef
= CBrowseRefsDlg::PickRef(false, m_VersionName
, gPickRef_All
);
137 if(resultRef
.IsEmpty())
139 Init(false, true, false);
142 m_pendingRefName
= resultRef
;
143 m_bNotFullName
= false;
144 Init(false, true, true);
147 void SelectRef(CString refName
, bool bRefNameIsPossiblyNotFullName
= true)
149 if(bRefNameIsPossiblyNotFullName
)
151 //Make sure refName is a full ref name first
152 CString fullRefName
= g_Git
.GetFullRefName(refName
);
153 if(!fullRefName
.IsEmpty())
154 refName
= fullRefName
;
157 if(wcsncmp(refName
,L
"refs/",5)==0)
158 refName
= refName
.Mid(5);
159 if(wcsncmp(refName
,L
"heads/",6)==0)
161 refName
= refName
.Mid(6);
162 SetDefaultChoose(IDC_RADIO_BRANCH
);
163 m_ChooseVersioinBranch
.SetCurSel(
164 m_ChooseVersioinBranch
.FindStringExact(-1, refName
));
166 else if(wcsncmp(refName
,L
"remotes/",8)==0)
168 SetDefaultChoose(IDC_RADIO_BRANCH
);
169 m_ChooseVersioinBranch
.SetCurSel(
170 m_ChooseVersioinBranch
.FindStringExact(-1, refName
));
172 else if(wcsncmp(refName
,L
"tags/",5)==0)
174 refName
= refName
.Mid(5);
175 refName
.Replace(_T("^{}"), _T(""));
176 SetDefaultChoose(IDC_RADIO_TAGS
);
177 m_ChooseVersioinTags
.SetCurSel(
178 m_ChooseVersioinTags
.FindStringExact(-1, refName
));
182 SetDefaultChoose(IDC_RADIO_VERSION
);
183 m_ChooseVersioinVersion
.AddString(refName
);
193 g_Git
.GetBranchList(list
,¤t
,CGit::BRANCH_ALL_F
);
194 for (int i
= m_ChooseVersioinBranch
.GetCount(); i
>= 0; --i
)
195 m_ChooseVersioinBranch
.DeleteString(i
);
196 m_ChooseVersioinBranch
.AddString(list
, false);
197 m_ChooseVersioinBranch
.SetCurSel(current
);
200 g_Git
.GetTagList(list
);
201 for (int i
= m_ChooseVersioinTags
.GetCount(); i
>= 0; --i
)
202 m_ChooseVersioinTags
.DeleteString(i
);
203 m_ChooseVersioinTags
.AddString(list
, false);
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
);
218 if (m_pendingRefName
.IsEmpty())
221 SelectRef(m_pendingRefName
, m_bNotFullName
);
224 if (m_bIsFirstTimeToSetFocus
&& m_pWin
->GetDlgItem(IDC_COMBOBOXEX_BRANCH
)->IsWindowEnabled())
225 m_pWin
->GetDlgItem(IDC_COMBOBOXEX_BRANCH
)->SetFocus();
226 m_bIsFirstTimeToSetFocus
= false;
228 void Init(bool setFocusToBranchComboBox
= false, bool bReInit
= false, bool bSelectRef
= true)
230 m_ChooseVersioinBranch
.SetMaxHistoryItems(0x7FFFFFFF);
231 m_ChooseVersioinTags
.SetMaxHistoryItems(0x7FFFFFFF);
234 m_RadioBranch
.EnableWindow(FALSE
);
235 m_RadioTag
.EnableWindow(FALSE
);
237 m_bIsFirstTimeToSetFocus
= setFocusToBranchComboBox
;
238 m_bSelectRef
= bSelectRef
;
241 m_pendingRefName
= m_initialRefName
;
242 m_bNotFullName
= true;
245 InterlockedExchange(&m_bLoadingThreadRunning
, TRUE
);
247 if ( (m_pLoadingThread
=AfxBeginThread(LoadingThreadEntry
, this)) ==NULL
)
249 InterlockedExchange(&m_bLoadingThreadRunning
, FALSE
);
250 CMessageBox::Show(NULL
, IDS_ERR_THREADSTARTFAILED
, IDS_APPNAME
, MB_OK
| MB_ICONERROR
);
253 void WaitForFinishLoading()
255 if(m_bLoadingThreadRunning
&& m_pLoadingThread
)
257 DWORD ret
=::WaitForSingleObject(m_pLoadingThread
->m_hThread
,20000);
258 if(ret
== WAIT_TIMEOUT
)
259 ::TerminateThread(m_pLoadingThread
,0);
263 CString m_VersionName
;
265 bool m_bIsFirstTimeToSetFocus
;
266 CChooseVersion(CWnd
*win
)
273 #define CHOOSE_VERSION_DDX \
274 DDX_Control(pDX, IDC_COMBOBOXEX_BRANCH, m_ChooseVersioinBranch); \
275 DDX_Control(pDX, IDC_COMBOBOXEX_TAGS, m_ChooseVersioinTags); \
276 DDX_Control(pDX, IDC_COMBOBOXEX_VERSION, m_ChooseVersioinVersion); \
277 DDX_Control(pDX, IDC_RADIO_BRANCH, m_RadioBranch);\
278 DDX_Control(pDX, IDC_RADIO_TAGS, m_RadioTag);
280 #define CHOOSE_VERSION_EVENT\
281 ON_REGISTERED_MESSAGE(WM_GUIUPDATES, OnUpdateGUIHost)\
282 ON_BN_CLICKED(IDC_RADIO_HEAD, OnBnClickedChooseRadioHost)\
283 ON_BN_CLICKED(IDC_RADIO_BRANCH, OnBnClickedChooseRadioHost)\
284 ON_BN_CLICKED(IDC_RADIO_TAGS, OnBnClickedChooseRadioHost)\
285 ON_BN_CLICKED(IDC_BUTTON_SHOW, OnBnClickedShow)\
286 ON_BN_CLICKED(IDC_RADIO_VERSION, OnBnClickedChooseRadioHost)\
287 ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF, OnBnClickedButtonBrowseRefHost)
289 #define CHOOSE_VERSION_ADDANCHOR \
291 AddAnchor(IDC_COMBOBOXEX_BRANCH, TOP_LEFT, TOP_RIGHT); \
292 AddAnchor(IDC_COMBOBOXEX_TAGS, TOP_LEFT, TOP_RIGHT); \
293 AddAnchor(IDC_COMBOBOXEX_VERSION, TOP_LEFT, TOP_RIGHT); \
294 AddAnchor(IDC_GROUP_BASEON, TOP_LEFT, TOP_RIGHT); \
295 AddAnchor(IDC_BUTTON_SHOW,TOP_RIGHT); \
296 AddAnchor(IDC_BUTTON_BROWSE_REF,TOP_RIGHT); \
299 #define CHOOSE_EVENT_RADIO() \
300 LRESULT OnUpdateGUIHost(WPARAM, LPARAM) { UpdateGUI(); return 0; } \
301 afx_msg void OnBnClickedChooseRadioHost(){OnBnClickedChooseRadio();}\
302 afx_msg void OnBnClickedShow(){OnBnClickedChooseVersion();}\
303 afx_msg void OnBnClickedButtonBrowseRefHost(){OnBnClickedButtonBrowseRef();}