Provide (experimental) clang-format file
[TortoiseGit.git] / src / TortoiseProc / ChooseVersion.h
blob1e4edc0c5cd9b3f4551c66f047ddbc7aa4e2f487
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2017 - 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.
19 #pragma once
20 #include "afxwin.h"
21 #include "LogDlg.h"
22 #include "BrowseRefsDlg.h"
23 #include "MessageBox.h"
24 #include "registry.h"
25 #include "StringUtils.h"
27 static UINT WM_GUIUPDATES = RegisterWindowMessage(L"TORTOISEGIT_CHOOSEVERSION_GUIUPDATES");
29 class CChooseVersion
31 public:
32 CString m_initialRefName;
34 private:
35 CWnd * m_pWin;
36 CWinThread* m_pLoadingThread;
37 static UINT LoadingThreadEntry(LPVOID pVoid)
39 return reinterpret_cast<CChooseVersion*>(pVoid)->LoadingThread();
41 volatile LONG m_bLoadingThreadRunning;
43 protected:
44 CHistoryCombo m_ChooseVersioinBranch;
45 CHistoryCombo m_ChooseVersioinTags;
46 CHistoryCombo m_ChooseVersioinVersion;
47 CButton m_RadioBranch;
48 CButton m_RadioTag;
49 CString m_pendingRefName;
50 bool m_bNotFullName;
51 bool m_bSkipCurrentBranch;
53 //Notification when version changed. Can be implemented in derived classes.
54 virtual void OnVersionChanged(){}
56 afx_msg void OnBnClickedChooseRadio()
58 this->m_ChooseVersioinTags.EnableWindow(FALSE);
59 this->m_ChooseVersioinBranch.EnableWindow(FALSE);
60 this->m_ChooseVersioinVersion.EnableWindow(FALSE);
61 m_pWin->GetDlgItem(IDC_BUTTON_BROWSE_REF)->EnableWindow(FALSE);
62 m_pWin->GetDlgItem(IDC_BUTTON_SHOW)->EnableWindow(FALSE);
63 m_bIsBranch = false;
64 int radio=m_pWin->GetCheckedRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION);
65 switch (radio)
67 case IDC_RADIO_HEAD:
68 break;
69 case IDC_RADIO_BRANCH:
70 this->m_ChooseVersioinBranch.EnableWindow(TRUE);
71 m_pWin->GetDlgItem(IDC_BUTTON_BROWSE_REF)->EnableWindow(TRUE);
72 m_bIsBranch = true;
73 break;
74 case IDC_RADIO_TAGS:
75 this->m_ChooseVersioinTags.EnableWindow(TRUE);
76 break;
77 case IDC_RADIO_VERSION:
78 this->m_ChooseVersioinVersion.EnableWindow(TRUE);
79 m_pWin->GetDlgItem(IDC_BUTTON_SHOW)->EnableWindow(TRUE);
80 break;
82 // enable version browse button if Version is selected
83 m_pWin->GetDlgItem(IDC_BUTTON_SHOW)->EnableWindow(radio == IDC_RADIO_VERSION);
84 OnVersionChanged();
87 void OnBnClickedChooseVersion()
89 // use the git log to allow selection of a version
90 CLogDlg dlg;
91 CString revision;
92 m_ChooseVersioinVersion.GetWindowText(revision);
93 dlg.SetParams(CTGitPath(), CTGitPath(), revision, revision, 0);
94 // tell the dialog to use mode for selecting revisions
95 dlg.SetSelect(true);
96 dlg.ShowWorkingTreeChanges(false);
97 // only one revision must be selected however
98 dlg.SingleSelection(true);
99 if (dlg.DoModal() == IDOK && !dlg.GetSelectedHash().empty())
101 m_ChooseVersioinVersion.SetWindowText(dlg.GetSelectedHash().at(0).ToString());
102 OnVersionChanged();
106 void UpdateRevsionName()
108 int radio=m_pWin->GetCheckedRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION);
109 switch (radio)
111 case IDC_RADIO_HEAD:
112 this->m_VersionName = L"HEAD";
113 break;
114 case IDC_RADIO_BRANCH:
115 this->m_VersionName=m_ChooseVersioinBranch.GetString();
116 if (!m_VersionName.IsEmpty() && !g_Git.IsBranchTagNameUnique(this->m_VersionName))
117 this->m_VersionName = L"refs/heads/" + this->m_VersionName;
118 break;
119 case IDC_RADIO_TAGS:
120 this->m_VersionName = m_ChooseVersioinTags.GetString();
121 if (!m_VersionName.IsEmpty() && !g_Git.IsBranchTagNameUnique(this->m_VersionName))
122 this->m_VersionName = L"refs/tags/" + m_ChooseVersioinTags.GetString();
123 break;
124 case IDC_RADIO_VERSION:
125 this->m_VersionName=m_ChooseVersioinVersion.GetString();
126 break;
129 void SetDefaultChoose(int id)
131 m_pWin->CheckRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION,id);
132 OnBnClickedChooseRadio();
135 void OnBnClickedButtonBrowseRef()
137 CString origRef;
138 UpdateRevsionName();
139 CString resultRef = CBrowseRefsDlg::PickRef(false, m_VersionName, gPickRef_All);
140 if(resultRef.IsEmpty())
142 m_pendingRefName = m_VersionName;
143 m_bNotFullName = true;
144 InitChooseVersion(false, true);
145 return;
147 m_pendingRefName = resultRef;
148 m_bNotFullName = false;
149 InitChooseVersion(false, true);
152 void SelectRef(CString refName, bool bRefNameIsPossiblyNotFullName = true)
154 if(bRefNameIsPossiblyNotFullName)
156 //Make sure refName is a full ref name first
157 CString fullRefName = g_Git.GetFullRefName(refName);
158 if(!fullRefName.IsEmpty())
159 refName = fullRefName;
162 if (CStringUtils::StartsWith(refName, L"refs/"))
163 refName = refName.Mid(5);
164 if (CStringUtils::StartsWith(refName, L"heads/"))
166 refName = refName.Mid(6);
167 SetDefaultChoose(IDC_RADIO_BRANCH);
168 m_ChooseVersioinBranch.SetCurSel(
169 m_ChooseVersioinBranch.FindStringExact(-1, refName));
171 else if (CStringUtils::StartsWith(refName, L"remotes/"))
173 SetDefaultChoose(IDC_RADIO_BRANCH);
174 m_ChooseVersioinBranch.SetCurSel(
175 m_ChooseVersioinBranch.FindStringExact(-1, refName));
177 else if (CStringUtils::StartsWith(refName, L"tags/"))
179 refName = refName.Mid(5);
180 refName.Replace(L"^{}", L"");
181 SetDefaultChoose(IDC_RADIO_TAGS);
182 m_ChooseVersioinTags.SetCurSel(
183 m_ChooseVersioinTags.FindStringExact(-1, refName));
185 else
187 SetDefaultChoose(IDC_RADIO_VERSION);
188 m_ChooseVersioinVersion.AddString(refName);
190 OnVersionChanged();
193 UINT LoadingThread()
195 STRING_VECTOR list;
197 int current = -1;
198 g_Git.GetBranchList(list, &current, CRegDWORD(L"Software\\TortoiseGit\\BranchesIncludeFetchHead", TRUE) ? CGit::BRANCH_ALL_F : CGit::BRANCH_ALL, m_bSkipCurrentBranch);
199 m_ChooseVersioinBranch.SetList(list);
200 m_ChooseVersioinBranch.SetCurSel(current);
202 list.clear();
203 g_Git.GetTagList(list);
204 m_ChooseVersioinTags.SetList(list);
205 m_ChooseVersioinTags.SetCurSel(0);
207 m_pWin->SendMessage(WM_GUIUPDATES);
209 InterlockedExchange(&m_bLoadingThreadRunning, FALSE);
210 return 0;
212 void UpdateGUI()
214 m_RadioBranch.EnableWindow(TRUE);
215 m_RadioTag.EnableWindow(TRUE);
217 if (m_pendingRefName.IsEmpty())
218 OnVersionChanged();
219 else
220 SelectRef(m_pendingRefName, m_bNotFullName);
222 if (m_bIsFirstTimeToSetFocus && m_pWin->GetDlgItem(IDC_COMBOBOXEX_BRANCH)->IsWindowEnabled())
223 m_pWin->GetDlgItem(IDC_COMBOBOXEX_BRANCH)->SetFocus();
224 m_bIsFirstTimeToSetFocus = false;
225 m_pWin->GetDlgItem(IDOK)->EnableWindow(TRUE);
227 void InitChooseVersion(bool setFocusToBranchComboBox = false, bool bReInit = false)
229 m_ChooseVersioinBranch.SetMaxHistoryItems(0x7FFFFFFF);
230 m_ChooseVersioinTags.SetMaxHistoryItems(0x7FFFFFFF);
232 m_bIsBranch = false;
233 m_RadioBranch.EnableWindow(FALSE);
234 m_RadioTag.EnableWindow(FALSE);
236 m_bIsFirstTimeToSetFocus = setFocusToBranchComboBox;
237 if (!bReInit)
239 m_pendingRefName = m_initialRefName;
240 m_bNotFullName = true;
243 m_pWin->GetDlgItem(IDOK)->EnableWindow(FALSE);
245 InterlockedExchange(&m_bLoadingThreadRunning, TRUE);
247 if ((m_pLoadingThread = AfxBeginThread(LoadingThreadEntry, this)) == nullptr)
249 InterlockedExchange(&m_bLoadingThreadRunning, FALSE);
250 CMessageBox::Show(nullptr, 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);
262 public:
263 CString m_VersionName;
264 bool m_bIsBranch;
265 bool m_bIsFirstTimeToSetFocus;
266 CChooseVersion(CWnd *win)
267 : m_bIsBranch(false)
268 , m_bIsFirstTimeToSetFocus(false)
269 , m_pLoadingThread(nullptr)
270 , m_bLoadingThreadRunning(FALSE)
271 , m_bNotFullName(true)
272 , m_bSkipCurrentBranch(false)
274 m_pWin=win;
278 #define CHOOSE_VERSION_DDX \
279 DDX_Control(pDX, IDC_COMBOBOXEX_BRANCH, m_ChooseVersioinBranch); \
280 DDX_Control(pDX, IDC_COMBOBOXEX_TAGS, m_ChooseVersioinTags); \
281 DDX_Control(pDX, IDC_COMBOBOXEX_VERSION, m_ChooseVersioinVersion); \
282 DDX_Control(pDX, IDC_RADIO_BRANCH, m_RadioBranch);\
283 DDX_Control(pDX, IDC_RADIO_TAGS, m_RadioTag);
285 #define CHOOSE_VERSION_EVENT\
286 ON_REGISTERED_MESSAGE(WM_GUIUPDATES, OnUpdateGUIHost)\
287 ON_BN_CLICKED(IDC_RADIO_HEAD, OnBnClickedChooseRadioHost)\
288 ON_BN_CLICKED(IDC_RADIO_BRANCH, OnBnClickedChooseRadioHost)\
289 ON_BN_CLICKED(IDC_RADIO_TAGS, OnBnClickedChooseRadioHost)\
290 ON_BN_CLICKED(IDC_BUTTON_SHOW, OnBnClickedShow)\
291 ON_BN_CLICKED(IDC_RADIO_VERSION, OnBnClickedChooseRadioHost)\
292 ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF, OnBnClickedButtonBrowseRefHost)
294 #define CHOOSE_VERSION_ADDANCHOR \
296 AddAnchor(IDC_COMBOBOXEX_BRANCH, TOP_LEFT, TOP_RIGHT); \
297 AddAnchor(IDC_COMBOBOXEX_TAGS, TOP_LEFT, TOP_RIGHT); \
298 AddAnchor(IDC_COMBOBOXEX_VERSION, TOP_LEFT, TOP_RIGHT); \
299 AddAnchor(IDC_GROUP_BASEON, TOP_LEFT, TOP_RIGHT); \
300 AddAnchor(IDC_BUTTON_SHOW,TOP_RIGHT); \
301 AddAnchor(IDC_BUTTON_BROWSE_REF,TOP_RIGHT); \
304 #define CHOOSE_EVENT_RADIO() \
305 LRESULT OnUpdateGUIHost(WPARAM, LPARAM) { UpdateGUI(); return 0; } \
306 afx_msg void OnBnClickedChooseRadioHost(){OnBnClickedChooseRadio();}\
307 afx_msg void OnBnClickedShow(){OnBnClickedChooseVersion();}\
308 afx_msg void OnBnClickedButtonBrowseRefHost(){OnBnClickedButtonBrowseRef();}