Merge branch 'restructure-tree'
[TortoiseGit.git] / src / TortoiseProc / RepositoryBar.cpp
blob9f4e397144d9958a865061ac0dd2d84cfab62579
1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
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 #include "stdafx.h"
20 #include "TortoiseProc.h"
21 #include "RepositoryBar.h"
22 #include "RevisionDlg.h"
23 #include "SVNInfo.h"
24 #include "SVN.h"
25 #include "WaitCursorEx.h"
27 #define IDC_URL_COMBO 10000
28 #define IDC_REVISION_BTN 10001
29 #define IDC_UP_BTN 10002
31 IMPLEMENT_DYNAMIC(CRepositoryBar, CReBarCtrl)
33 #pragma warning(push)
34 #pragma warning(disable: 4355) // 'this' used in base member initializer list
36 CRepositoryBar::CRepositoryBar() : m_cbxUrl(this)
37 , m_pRepo(NULL)
39 m_UpIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_UP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
42 #pragma warning(pop)
44 CRepositoryBar::~CRepositoryBar()
46 if (m_UpIcon)
47 DestroyIcon(m_UpIcon);
50 BEGIN_MESSAGE_MAP(CRepositoryBar, CReBarCtrl)
51 ON_CBN_SELCHANGE(IDC_URL_COMBO, OnCbnSelChange)
52 ON_BN_CLICKED(IDC_REVISION_BTN, OnBnClicked)
53 ON_BN_CLICKED(IDC_UP_BTN, OnGoUp)
54 ON_WM_DESTROY()
55 END_MESSAGE_MAP()
57 bool CRepositoryBar::Create(CWnd* parent, UINT id, bool in_dialog)
59 CRect rect;
60 ASSERT(parent != 0);
61 parent->GetWindowRect(&rect);
63 DWORD style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
64 | CCS_TOP | RBS_AUTOSIZE | RBS_VARHEIGHT;
66 DWORD style_ex = WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT;
68 if (in_dialog)
70 style |= CCS_NODIVIDER;
72 else
74 style |= RBS_BANDBORDERS;
77 if (CReBarCtrl::CreateEx(style_ex, style, CRect(0,0,200,100), parent, id))
79 CFont *font = parent->GetFont();
80 CString temp;
82 REBARINFO rbi;
83 SecureZeroMemory(&rbi, sizeof rbi);
84 rbi.cbSize = sizeof rbi;
85 rbi.fMask = 0;
86 rbi.himl = (HIMAGELIST)0;
88 if (!this->SetBarInfo(&rbi))
89 return false;
91 REBARBANDINFO rbbi;
92 SecureZeroMemory(&rbbi, sizeof rbbi);
93 rbbi.cbSize = sizeof rbbi;
94 rbbi.fMask = RBBIM_TEXT | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
95 rbbi.fStyle = RBBS_NOGRIPPER | RBBS_FIXEDBMP;
97 if (in_dialog)
98 rbbi.fMask |= RBBIM_COLORS;
99 else
100 rbbi.fMask |= RBBS_CHILDEDGE;
102 // Create the "URL" combo box control to be added
103 rect = CRect(0, 0, 100, 400);
104 m_cbxUrl.Create(WS_CHILD | WS_TABSTOP | CBS_DROPDOWN, rect, this, IDC_URL_COMBO);
105 m_cbxUrl.SetURLHistory(true);
106 m_cbxUrl.SetFont(font);
107 m_cbxUrl.LoadHistory(_T("Software\\TortoiseGit\\History\\repoURLS"), _T("url"));
108 temp.LoadString(IDS_REPO_BROWSEURL);
109 rbbi.lpText = const_cast<LPTSTR>((LPCTSTR)temp);
110 rbbi.hwndChild = m_cbxUrl.m_hWnd;
111 rbbi.clrFore = ::GetSysColor(COLOR_WINDOWTEXT);
112 rbbi.clrBack = ::GetSysColor(COLOR_BTNFACE);
113 rbbi.cx = rect.right - rect.left;
114 rbbi.cxMinChild = rect.right - rect.left;
115 rbbi.cyMinChild = m_cbxUrl.GetItemHeight(-1) + 10;
116 if (!InsertBand(0, &rbbi))
117 return false;
119 // Reposition the combobox for correct redrawing
120 m_cbxUrl.GetWindowRect(rect);
121 m_cbxUrl.MoveWindow(rect.left, rect.top, rect.Width(), 300);
123 // Create the "Up" button control to be added
124 rect = CRect(0, 0, 24, m_cbxUrl.GetItemHeight(-1) + 8);
125 m_btnUp.Create(_T("UP"), WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON | BS_ICON, rect, this, IDC_UP_BTN);
126 m_btnUp.SetIcon(m_UpIcon);
127 m_btnUp.SetWindowText(_T(""));
128 rbbi.lpText = _T("");
129 rbbi.hwndChild = m_btnUp.m_hWnd;
130 rbbi.clrFore = ::GetSysColor(COLOR_WINDOWTEXT);
131 rbbi.clrBack = ::GetSysColor(COLOR_BTNFACE);
132 rbbi.cx = rect.right - rect.left;
133 rbbi.cxMinChild = rect.right - rect.left;
134 rbbi.cyMinChild = rect.bottom - rect.top;
135 if (!InsertBand(1, &rbbi))
136 return false;
138 // Create the "Revision" button control to be added
139 rect = CRect(0, 0, 60, m_cbxUrl.GetItemHeight(-1) + 8);
140 m_btnRevision.Create(_T("HEAD"), WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON, rect, this, IDC_REVISION_BTN);
141 m_btnRevision.SetFont(font);
142 temp.LoadString(IDS_REPO_BROWSEREV);
143 rbbi.lpText = const_cast<LPTSTR>((LPCTSTR)temp);
144 rbbi.hwndChild = m_btnRevision.m_hWnd;
145 rbbi.clrFore = ::GetSysColor(COLOR_WINDOWTEXT);
146 rbbi.clrBack = ::GetSysColor(COLOR_BTNFACE);
147 rbbi.cx = rect.right - rect.left;
148 rbbi.cxMinChild = rect.right - rect.left;
149 rbbi.cyMinChild = rect.bottom - rect.top;
150 if (!InsertBand(2, &rbbi))
151 return false;
153 MaximizeBand(0);
155 m_tooltips.Create(this);
156 m_tooltips.AddTool(&m_btnUp, IDS_REPOBROWSE_TT_UPFOLDER);
158 return true;
161 return false;
164 void CRepositoryBar::ShowUrl(const CString& url, SVNRev rev)
166 if (url.Find('?')>=0)
168 m_url = url.Left(url.Find('?'));
169 m_rev = SVNRev(url.Mid(url.Find('?')+1));
171 else
173 m_url = url;
174 m_rev = rev;
176 m_cbxUrl.SetWindowText(m_url);
177 m_btnUp.EnableWindow(m_url.CompareNoCase(m_pRepo->GetRepoRoot()));
178 m_btnRevision.SetWindowText(m_rev.ToString());
179 if (m_headRev.IsValid())
181 CString sTTText;
182 sTTText.Format(IDS_REPOBROWSE_TT_HEADREV, (LPCTSTR)m_headRev.ToString());
183 m_tooltips.AddTool(&m_btnRevision, sTTText);
185 else
186 m_tooltips.DelTool(&m_btnRevision);
189 void CRepositoryBar::GotoUrl(const CString& url, SVNRev rev, bool bAlreadyChecked /* = false */)
191 CString new_url = url;
192 SVNRev new_rev = rev;
193 CWaitCursorEx wait;
195 new_url.TrimRight('/');
196 if (new_url.IsEmpty())
198 new_url = GetCurrentUrl();
199 new_rev = GetCurrentRev();
200 new_url.TrimRight('/');
202 if (new_url.Find('?')>=0)
204 new_rev = SVNRev(new_url.Mid(new_url.Find('?')+1));
205 new_url = new_url.Left(new_url.Find('?'));
208 if (m_pRepo)
210 SVNRev rev = new_rev;
211 m_headRev = SVNRev();
212 m_pRepo->ChangeToUrl(new_url, rev, bAlreadyChecked);
213 if (new_rev.IsHead() && !rev.IsHead())
214 m_headRev = rev;
215 if (!m_headRev.IsValid())
217 SVN svn;
218 m_headRev = svn.GetHEADRevision(CTSVNPath(new_url));
221 ShowUrl(new_url, new_rev);
224 void CRepositoryBar::SetRevision(SVNRev rev)
226 m_btnRevision.SetWindowText(rev.ToString());
227 if (m_headRev.IsValid())
229 CString sTTText;
230 sTTText.Format(IDS_REPOBROWSE_TT_HEADREV, (LPCTSTR)m_headRev.ToString());
231 m_tooltips.AddTool(&m_btnRevision, sTTText);
233 else
234 m_tooltips.DelTool(&m_btnRevision);
237 CString CRepositoryBar::GetCurrentUrl() const
239 if (m_cbxUrl.m_hWnd != 0)
241 CString path, revision;
242 m_cbxUrl.GetWindowText(path);
243 m_btnRevision.GetWindowText(revision);
244 return path;
246 else
248 return m_url;
252 SVNRev CRepositoryBar::GetCurrentRev() const
254 if (m_cbxUrl.m_hWnd != 0)
256 CString path, revision;
257 m_cbxUrl.GetWindowText(path);
258 m_btnRevision.GetWindowText(revision);
259 return SVNRev(revision);
261 else
263 return m_rev;
267 void CRepositoryBar::SaveHistory()
269 m_cbxUrl.SaveHistory();
272 bool CRepositoryBar::CRepositoryCombo::OnReturnKeyPressed()
274 if (m_bar != 0)
275 m_bar->GotoUrl();
276 if (GetDroppedState())
277 ShowDropDown(FALSE);
278 return true;
282 void CRepositoryBar::OnCbnSelChange()
284 int idx = m_cbxUrl.GetCurSel();
285 if (idx >= 0)
287 CString path, revision;
288 m_cbxUrl.GetLBText(idx, path);
289 m_btnRevision.GetWindowText(revision);
290 m_url = path;
291 m_rev = revision;
292 GotoUrl(m_url, m_rev);
296 void CRepositoryBar::OnBnClicked()
298 CString revision;
300 m_tooltips.Pop();
301 m_btnRevision.GetWindowText(revision);
303 CRevisionDlg dlg(this);
304 dlg.AllowWCRevs(false);
305 *((SVNRev*)&dlg) = SVNRev(revision);
307 if (dlg.DoModal() == IDOK)
309 revision = dlg.GetEnteredRevisionString();
310 m_rev = SVNRev(revision);
311 m_btnRevision.SetWindowText(SVNRev(revision).ToString());
312 GotoUrl();
316 void CRepositoryBar::OnGoUp()
318 CString sCurrentUrl = GetCurrentUrl();
319 CString sNewUrl = sCurrentUrl.Left(sCurrentUrl.ReverseFind('/'));
320 if (sNewUrl.GetLength() >= m_pRepo->GetRepoRoot().GetLength())
321 GotoUrl(sNewUrl, GetCurrentRev(), true);
324 void CRepositoryBar::SetFocusToURL()
326 m_cbxUrl.GetEditCtrl()->SetFocus();
329 void CRepositoryBar::OnDestroy()
331 int idx = m_cbxUrl.GetCurSel();
332 if (idx >= 0)
334 CString path, revision;
335 m_cbxUrl.GetLBText(idx, path);
336 m_btnRevision.GetWindowText(revision);
337 m_url = path;
338 m_rev = revision;
340 CReBarCtrl::OnDestroy();
344 BOOL CRepositoryBar::PreTranslateMessage(MSG* pMsg)
346 m_tooltips.RelayEvent(pMsg);
347 return CReBarCtrl::PreTranslateMessage(pMsg);
350 ////////////////////////////////////////////////////////////////////////////////
352 CRepositoryBarCnr::CRepositoryBarCnr(CRepositoryBar *repository_bar) :
353 m_pbarRepository(repository_bar)
357 CRepositoryBarCnr::~CRepositoryBarCnr()
361 BEGIN_MESSAGE_MAP(CRepositoryBarCnr, CStatic)
362 ON_WM_ERASEBKGND()
363 ON_WM_SIZE()
364 ON_WM_GETDLGCODE()
365 ON_WM_KEYDOWN()
366 END_MESSAGE_MAP()
368 IMPLEMENT_DYNAMIC(CRepositoryBarCnr, CStatic)
370 BOOL CRepositoryBarCnr::OnEraseBkgnd(CDC* /* pDC */)
372 return TRUE;
375 void CRepositoryBarCnr::OnSize(UINT /* nType */, int cx, int cy)
377 m_pbarRepository->MoveWindow(0, 0, cx, cy);
380 void CRepositoryBarCnr::DrawItem(LPDRAWITEMSTRUCT)
384 UINT CRepositoryBarCnr::OnGetDlgCode()
386 return CStatic::OnGetDlgCode() | DLGC_WANTTAB;
389 void CRepositoryBarCnr::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
391 if (nChar == VK_TAB)
393 CWnd *child = m_pbarRepository->GetWindow(GW_CHILD);
394 if (child != 0)
396 child = child->GetWindow(GW_HWNDLAST);
397 if (child != 0)
398 child->SetFocus();
402 CStatic::OnKeyDown(nChar, nRepCnt, nFlags);