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.
20 #include "TortoiseProc.h"
21 #include "RepositoryBar.h"
22 #include "RevisionDlg.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
)
34 #pragma warning(disable: 4355) // 'this' used in base member initializer list
36 CRepositoryBar::CRepositoryBar() : m_cbxUrl(this)
39 m_UpIcon
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_UP
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
44 CRepositoryBar::~CRepositoryBar()
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
)
57 bool CRepositoryBar::Create(CWnd
* parent
, UINT id
, bool in_dialog
)
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
;
70 style
|= CCS_NODIVIDER
;
74 style
|= RBS_BANDBORDERS
;
77 if (CReBarCtrl::CreateEx(style_ex
, style
, CRect(0,0,200,100), parent
, id
))
79 CFont
*font
= parent
->GetFont();
83 SecureZeroMemory(&rbi
, sizeof rbi
);
84 rbi
.cbSize
= sizeof rbi
;
86 rbi
.himl
= (HIMAGELIST
)0;
88 if (!this->SetBarInfo(&rbi
))
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
;
98 rbbi
.fMask
|= RBBIM_COLORS
;
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
))
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
))
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
))
155 m_tooltips
.Create(this);
156 m_tooltips
.AddTool(&m_btnUp
, IDS_REPOBROWSE_TT_UPFOLDER
);
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));
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())
182 sTTText
.Format(IDS_REPOBROWSE_TT_HEADREV
, (LPCTSTR
)m_headRev
.ToString());
183 m_tooltips
.AddTool(&m_btnRevision
, sTTText
);
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
;
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('?'));
210 SVNRev rev
= new_rev
;
211 m_headRev
= SVNRev();
212 m_pRepo
->ChangeToUrl(new_url
, rev
, bAlreadyChecked
);
213 if (new_rev
.IsHead() && !rev
.IsHead())
215 if (!m_headRev
.IsValid())
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())
230 sTTText
.Format(IDS_REPOBROWSE_TT_HEADREV
, (LPCTSTR
)m_headRev
.ToString());
231 m_tooltips
.AddTool(&m_btnRevision
, sTTText
);
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
);
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
);
267 void CRepositoryBar::SaveHistory()
269 m_cbxUrl
.SaveHistory();
272 bool CRepositoryBar::CRepositoryCombo::OnReturnKeyPressed()
276 if (GetDroppedState())
282 void CRepositoryBar::OnCbnSelChange()
284 int idx
= m_cbxUrl
.GetCurSel();
287 CString path
, revision
;
288 m_cbxUrl
.GetLBText(idx
, path
);
289 m_btnRevision
.GetWindowText(revision
);
292 GotoUrl(m_url
, m_rev
);
296 void CRepositoryBar::OnBnClicked()
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());
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();
334 CString path
, revision
;
335 m_cbxUrl
.GetLBText(idx
, path
);
336 m_btnRevision
.GetWindowText(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
)
368 IMPLEMENT_DYNAMIC(CRepositoryBarCnr
, CStatic
)
370 BOOL
CRepositoryBarCnr::OnEraseBkgnd(CDC
* /* pDC */)
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
)
393 CWnd
*child
= m_pbarRepository
->GetWindow(GW_CHILD
);
396 child
= child
->GetWindow(GW_HWNDLAST
);
402 CStatic::OnKeyDown(nChar
, nRepCnt
, nFlags
);