OSDN Git Service

Show Tag branch at loglist
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / RepositoryBar.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "stdafx.h"\r
20 #include "TortoiseProc.h"\r
21 #include "RepositoryBar.h"\r
22 #include "RevisionDlg.h"\r
23 #include "SVNInfo.h"\r
24 #include "SVN.h"\r
25 #include "WaitCursorEx.h"\r
26 \r
27 #define IDC_URL_COMBO     10000\r
28 #define IDC_REVISION_BTN  10001\r
29 #define IDC_UP_BTN        10002\r
30 \r
31 IMPLEMENT_DYNAMIC(CRepositoryBar, CReBarCtrl)\r
32 \r
33 #pragma warning(push)\r
34 #pragma warning(disable: 4355)  // 'this' used in base member initializer list\r
35 \r
36 CRepositoryBar::CRepositoryBar() : m_cbxUrl(this)\r
37         , m_pRepo(NULL)\r
38 {\r
39         m_UpIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_UP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);\r
40 }\r
41 \r
42 #pragma warning(pop)\r
43 \r
44 CRepositoryBar::~CRepositoryBar()\r
45 {\r
46         if (m_UpIcon)\r
47                 DestroyIcon(m_UpIcon);\r
48 }\r
49 \r
50 BEGIN_MESSAGE_MAP(CRepositoryBar, CReBarCtrl)\r
51         ON_CBN_SELCHANGE(IDC_URL_COMBO, OnCbnSelChange)\r
52         ON_BN_CLICKED(IDC_REVISION_BTN, OnBnClicked)\r
53         ON_BN_CLICKED(IDC_UP_BTN, OnGoUp)\r
54         ON_WM_DESTROY()\r
55 END_MESSAGE_MAP()\r
56 \r
57 bool CRepositoryBar::Create(CWnd* parent, UINT id, bool in_dialog)\r
58 {\r
59         CRect rect;\r
60         ASSERT(parent != 0);\r
61         parent->GetWindowRect(&rect);\r
62 \r
63         DWORD style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN\r
64                                 | CCS_TOP | RBS_AUTOSIZE | RBS_VARHEIGHT;\r
65 \r
66         DWORD style_ex = WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT;\r
67 \r
68         if (in_dialog)\r
69         {\r
70                 style |= CCS_NODIVIDER;\r
71         }\r
72         else\r
73         {\r
74                 style |= RBS_BANDBORDERS; \r
75         }\r
76 \r
77         if (CReBarCtrl::CreateEx(style_ex, style, CRect(0,0,200,100), parent, id))\r
78         {\r
79                 CFont *font = parent->GetFont();\r
80                 CString temp;\r
81 \r
82                 REBARINFO rbi;\r
83                 SecureZeroMemory(&rbi, sizeof rbi);\r
84                 rbi.cbSize = sizeof rbi;\r
85                 rbi.fMask  = 0;\r
86                 rbi.himl   = (HIMAGELIST)0;\r
87 \r
88                 if (!this->SetBarInfo(&rbi))\r
89                         return false;\r
90 \r
91                 REBARBANDINFO rbbi;\r
92                 SecureZeroMemory(&rbbi, sizeof rbbi);\r
93                 rbbi.cbSize = sizeof rbbi;\r
94                 rbbi.fMask  = RBBIM_TEXT | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;\r
95                 rbbi.fStyle = RBBS_NOGRIPPER | RBBS_FIXEDBMP;\r
96 \r
97                 if (in_dialog)\r
98                         rbbi.fMask |= RBBIM_COLORS;\r
99                 else\r
100                         rbbi.fMask |= RBBS_CHILDEDGE;\r
101 \r
102                 // Create the "URL" combo box control to be added\r
103                 rect = CRect(0, 0, 100, 400);\r
104                 m_cbxUrl.Create(WS_CHILD | WS_TABSTOP | CBS_DROPDOWN, rect, this, IDC_URL_COMBO);\r
105                 m_cbxUrl.SetURLHistory(true);\r
106                 m_cbxUrl.SetFont(font);\r
107                 m_cbxUrl.LoadHistory(_T("Software\\TortoiseSVN\\History\\repoURLS"), _T("url"));\r
108                 temp.LoadString(IDS_REPO_BROWSEURL);\r
109                 rbbi.lpText     = const_cast<LPTSTR>((LPCTSTR)temp);\r
110                 rbbi.hwndChild  = m_cbxUrl.m_hWnd;\r
111                 rbbi.clrFore    = ::GetSysColor(COLOR_WINDOWTEXT);\r
112                 rbbi.clrBack    = ::GetSysColor(COLOR_BTNFACE);\r
113                 rbbi.cx         = rect.right - rect.left;\r
114                 rbbi.cxMinChild = rect.right - rect.left;\r
115                 rbbi.cyMinChild = m_cbxUrl.GetItemHeight(-1) + 10;\r
116                 if (!InsertBand(0, &rbbi))\r
117                         return false;\r
118 \r
119                 // Reposition the combobox for correct redrawing\r
120                 m_cbxUrl.GetWindowRect(rect);\r
121                 m_cbxUrl.MoveWindow(rect.left, rect.top, rect.Width(), 300);\r
122 \r
123                 // Create the "Up" button control to be added\r
124                 rect = CRect(0, 0, 24, m_cbxUrl.GetItemHeight(-1) + 8);\r
125                 m_btnUp.Create(_T("UP"), WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON | BS_ICON, rect, this, IDC_UP_BTN);\r
126                 m_btnUp.SetIcon(m_UpIcon);\r
127                 m_btnUp.SetWindowText(_T(""));\r
128                 rbbi.lpText     = _T("");\r
129                 rbbi.hwndChild  = m_btnUp.m_hWnd;\r
130                 rbbi.clrFore    = ::GetSysColor(COLOR_WINDOWTEXT);\r
131                 rbbi.clrBack    = ::GetSysColor(COLOR_BTNFACE);\r
132                 rbbi.cx         = rect.right - rect.left;\r
133                 rbbi.cxMinChild = rect.right - rect.left;\r
134                 rbbi.cyMinChild = rect.bottom - rect.top;\r
135                 if (!InsertBand(1, &rbbi))\r
136                         return false;\r
137 \r
138                 // Create the "Revision" button control to be added\r
139                 rect = CRect(0, 0, 60, m_cbxUrl.GetItemHeight(-1) + 8);\r
140                 m_btnRevision.Create(_T("HEAD"), WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON, rect, this, IDC_REVISION_BTN);\r
141                 m_btnRevision.SetFont(font);\r
142                 temp.LoadString(IDS_REPO_BROWSEREV);\r
143                 rbbi.lpText     = const_cast<LPTSTR>((LPCTSTR)temp);\r
144                 rbbi.hwndChild  = m_btnRevision.m_hWnd;\r
145                 rbbi.clrFore    = ::GetSysColor(COLOR_WINDOWTEXT);\r
146                 rbbi.clrBack    = ::GetSysColor(COLOR_BTNFACE);\r
147                 rbbi.cx         = rect.right - rect.left;\r
148                 rbbi.cxMinChild = rect.right - rect.left;\r
149                 rbbi.cyMinChild = rect.bottom - rect.top;\r
150                 if (!InsertBand(2, &rbbi))\r
151                         return false;\r
152 \r
153                 MaximizeBand(0);\r
154 \r
155                 m_tooltips.Create(this);\r
156                 m_tooltips.AddTool(&m_btnUp, IDS_REPOBROWSE_TT_UPFOLDER);\r
157 \r
158                 return true;\r
159         }\r
160 \r
161         return false;\r
162 }\r
163 \r
164 void CRepositoryBar::ShowUrl(const CString& url, SVNRev rev)\r
165 {\r
166         if (url.Find('?')>=0)\r
167         {\r
168                 m_url = url.Left(url.Find('?'));\r
169                 m_rev = SVNRev(url.Mid(url.Find('?')+1));\r
170         }\r
171         else\r
172         {\r
173                 m_url = url;\r
174                 m_rev = rev;\r
175         }\r
176         m_cbxUrl.SetWindowText(m_url);\r
177         m_btnUp.EnableWindow(m_url.CompareNoCase(m_pRepo->GetRepoRoot()));\r
178         m_btnRevision.SetWindowText(m_rev.ToString());\r
179         if (m_headRev.IsValid())\r
180         {\r
181                 CString sTTText;\r
182                 sTTText.Format(IDS_REPOBROWSE_TT_HEADREV, (LPCTSTR)m_headRev.ToString());\r
183                 m_tooltips.AddTool(&m_btnRevision, sTTText);\r
184         }\r
185         else\r
186                 m_tooltips.DelTool(&m_btnRevision);\r
187 }\r
188 \r
189 void CRepositoryBar::GotoUrl(const CString& url, SVNRev rev, bool bAlreadyChecked /* = false */)\r
190 {\r
191         CString new_url = url;\r
192         SVNRev new_rev = rev;\r
193         CWaitCursorEx wait;\r
194 \r
195         new_url.TrimRight('/');\r
196         if (new_url.IsEmpty())\r
197         {\r
198                 new_url = GetCurrentUrl();\r
199                 new_rev = GetCurrentRev();\r
200                 new_url.TrimRight('/');\r
201         }\r
202         if (new_url.Find('?')>=0)\r
203         {\r
204                 new_rev = SVNRev(new_url.Mid(new_url.Find('?')+1));\r
205                 new_url = new_url.Left(new_url.Find('?'));\r
206         }\r
207 \r
208         if (m_pRepo)\r
209         {\r
210                 SVNRev rev = new_rev;\r
211                 m_headRev = SVNRev();\r
212                 m_pRepo->ChangeToUrl(new_url, rev, bAlreadyChecked);\r
213                 if (new_rev.IsHead() && !rev.IsHead())\r
214                         m_headRev = rev;\r
215                 if (!m_headRev.IsValid())\r
216                 {\r
217                         SVN svn;\r
218                         m_headRev = svn.GetHEADRevision(CTSVNPath(new_url));\r
219                 }\r
220         }\r
221         ShowUrl(new_url, new_rev);\r
222 }\r
223 \r
224 void CRepositoryBar::SetRevision(SVNRev rev)\r
225 {\r
226         m_btnRevision.SetWindowText(rev.ToString());\r
227         if (m_headRev.IsValid())\r
228         {\r
229                 CString sTTText;\r
230                 sTTText.Format(IDS_REPOBROWSE_TT_HEADREV, (LPCTSTR)m_headRev.ToString());\r
231                 m_tooltips.AddTool(&m_btnRevision, sTTText);\r
232         }\r
233         else\r
234                 m_tooltips.DelTool(&m_btnRevision);\r
235 }\r
236 \r
237 CString CRepositoryBar::GetCurrentUrl() const\r
238 {\r
239         if (m_cbxUrl.m_hWnd != 0)\r
240         {\r
241                 CString path, revision;\r
242                 m_cbxUrl.GetWindowText(path);\r
243                 m_btnRevision.GetWindowText(revision);\r
244                 return path;\r
245         }\r
246         else\r
247         {\r
248                 return m_url;\r
249         }\r
250 }\r
251 \r
252 SVNRev CRepositoryBar::GetCurrentRev() const\r
253 {\r
254         if (m_cbxUrl.m_hWnd != 0)\r
255         {\r
256                 CString path, revision;\r
257                 m_cbxUrl.GetWindowText(path);\r
258                 m_btnRevision.GetWindowText(revision);\r
259                 return SVNRev(revision);\r
260         }\r
261         else\r
262         {\r
263                 return m_rev;\r
264         }\r
265 }\r
266 \r
267 void CRepositoryBar::SaveHistory()\r
268 {\r
269         m_cbxUrl.SaveHistory();\r
270 }\r
271 \r
272 bool CRepositoryBar::CRepositoryCombo::OnReturnKeyPressed()\r
273 {\r
274         if (m_bar != 0)\r
275                 m_bar->GotoUrl();\r
276         if (GetDroppedState())\r
277                 ShowDropDown(FALSE);\r
278         return true;\r
279 }\r
280 \r
281 \r
282 void CRepositoryBar::OnCbnSelChange()\r
283 {\r
284         int idx = m_cbxUrl.GetCurSel();\r
285         if (idx >= 0)\r
286         {\r
287                 CString path, revision;\r
288                 m_cbxUrl.GetLBText(idx, path);\r
289                 m_btnRevision.GetWindowText(revision);\r
290                 m_url = path;\r
291                 m_rev = revision;\r
292                 GotoUrl(m_url, m_rev);\r
293         }\r
294 }\r
295 \r
296 void CRepositoryBar::OnBnClicked()\r
297 {\r
298         CString revision;\r
299 \r
300         m_tooltips.Pop();\r
301         m_btnRevision.GetWindowText(revision);\r
302 \r
303         CRevisionDlg dlg(this);\r
304         dlg.AllowWCRevs(false);\r
305         *((SVNRev*)&dlg) = SVNRev(revision);\r
306 \r
307         if (dlg.DoModal() == IDOK)\r
308         {\r
309                 revision = dlg.GetEnteredRevisionString();\r
310                 m_rev = SVNRev(revision);\r
311                 m_btnRevision.SetWindowText(SVNRev(revision).ToString());\r
312                 GotoUrl();\r
313         }\r
314 }\r
315 \r
316 void CRepositoryBar::OnGoUp()\r
317 {\r
318         CString sCurrentUrl = GetCurrentUrl();\r
319         CString sNewUrl = sCurrentUrl.Left(sCurrentUrl.ReverseFind('/'));\r
320         if (sNewUrl.GetLength() >= m_pRepo->GetRepoRoot().GetLength())\r
321                 GotoUrl(sNewUrl, GetCurrentRev(), true);\r
322 }\r
323 \r
324 void CRepositoryBar::SetFocusToURL()\r
325 {\r
326         m_cbxUrl.GetEditCtrl()->SetFocus();\r
327 }\r
328 \r
329 void CRepositoryBar::OnDestroy()\r
330 {\r
331         int idx = m_cbxUrl.GetCurSel();\r
332         if (idx >= 0)\r
333         {\r
334                 CString path, revision;\r
335                 m_cbxUrl.GetLBText(idx, path);\r
336                 m_btnRevision.GetWindowText(revision);\r
337                 m_url = path;\r
338                 m_rev = revision;\r
339         }\r
340         CReBarCtrl::OnDestroy();\r
341 }\r
342 \r
343 \r
344 BOOL CRepositoryBar::PreTranslateMessage(MSG* pMsg)\r
345 {\r
346         m_tooltips.RelayEvent(pMsg);\r
347         return CReBarCtrl::PreTranslateMessage(pMsg);\r
348 }\r
349 \r
350 ////////////////////////////////////////////////////////////////////////////////\r
351 \r
352 CRepositoryBarCnr::CRepositoryBarCnr(CRepositoryBar *repository_bar) :\r
353         m_pbarRepository(repository_bar)\r
354 {\r
355 }\r
356 \r
357 CRepositoryBarCnr::~CRepositoryBarCnr()\r
358 {\r
359 }\r
360 \r
361 BEGIN_MESSAGE_MAP(CRepositoryBarCnr, CStatic)\r
362         ON_WM_ERASEBKGND()\r
363         ON_WM_SIZE()\r
364         ON_WM_GETDLGCODE()\r
365         ON_WM_KEYDOWN()\r
366 END_MESSAGE_MAP()\r
367 \r
368 IMPLEMENT_DYNAMIC(CRepositoryBarCnr, CStatic)\r
369 \r
370 BOOL CRepositoryBarCnr::OnEraseBkgnd(CDC* /* pDC */)\r
371 {\r
372         return TRUE;\r
373 }\r
374 \r
375 void CRepositoryBarCnr::OnSize(UINT /* nType */, int cx, int cy)\r
376 {\r
377         m_pbarRepository->MoveWindow(0, 0, cx, cy);\r
378 }\r
379 \r
380 void CRepositoryBarCnr::DrawItem(LPDRAWITEMSTRUCT)\r
381 {\r
382 }\r
383 \r
384 UINT CRepositoryBarCnr::OnGetDlgCode()\r
385 {\r
386         return CStatic::OnGetDlgCode() | DLGC_WANTTAB;\r
387 }\r
388 \r
389 void CRepositoryBarCnr::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)\r
390 {\r
391         if (nChar == VK_TAB)\r
392         {\r
393                 CWnd *child = m_pbarRepository->GetWindow(GW_CHILD);\r
394                 if (child != 0)\r
395                 {\r
396                         child = child->GetWindow(GW_HWNDLAST);\r
397                         if (child != 0)\r
398                                 child->SetFocus();\r
399                 }\r
400         }\r
401 \r
402         CStatic::OnKeyDown(nChar, nRepCnt, nFlags);\r
403 }\r
404 \r