1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2009 - TortoiseSVN
\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
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
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
20 #include "TortoiseProc.h"
\r
21 #include "Revisiongraphdlg.h"
\r
22 #include "MessageBox.h"
\r
24 #include "AppUtils.h"
\r
25 #include "StringUtils.h"
\r
26 #include "TempFile.h"
\r
27 #include "UnicodeUtils.h"
\r
28 #include "TSVNPath.h"
\r
29 #include "SVNInfo.h"
\r
30 #include "SVNDiff.h"
\r
31 #include "RevGraphFilterDlg.h"
\r
32 #include ".\revisiongraphdlg.h"
\r
33 #include "RepositoryInfo.h"
\r
34 #include "RevisionInRange.h"
\r
35 #include "RemovePathsBySubString.h"
\r
38 #define new DEBUG_NEW
\r
40 static char THIS_FILE[] = __FILE__;
\r
43 using namespace Gdiplus;
\r
45 IMPLEMENT_DYNAMIC(CRevisionGraphDlg, CResizableStandAloneDialog)
\r
46 CRevisionGraphDlg::CRevisionGraphDlg(CWnd* pParent /*=NULL*/)
\r
47 : CResizableStandAloneDialog(CRevisionGraphDlg::IDD, pParent)
\r
49 , m_bFetchLogs(true)
\r
50 , m_fZoomFactor(0.5)
\r
52 // GDI+ initialization
\r
54 GdiplusStartupInput input;
\r
55 GdiplusStartup (&m_gdiPlusToken, &input, NULL);
\r
57 // restore option state
\r
59 DWORD dwOpts = CRegStdDWORD(_T("Software\\TortoiseSVN\\RevisionGraphOptions"), 0x1ff199);
\r
60 m_Graph.m_state.GetOptions()->SetRegistryFlags (dwOpts, 0x7fbf);
\r
63 CRevisionGraphDlg::~CRevisionGraphDlg()
\r
65 // save option state
\r
67 CRegStdDWORD regOpts = CRegStdDWORD(_T("Software\\TortoiseSVN\\RevisionGraphOptions"), 1);
\r
68 regOpts = m_Graph.m_state.GetOptions()->GetRegistryFlags();
\r
72 GdiplusShutdown (m_gdiPlusToken);
\r
75 void CRevisionGraphDlg::DoDataExchange(CDataExchange* pDX)
\r
77 CResizableStandAloneDialog::DoDataExchange(pDX);
\r
81 BEGIN_MESSAGE_MAP(CRevisionGraphDlg, CResizableStandAloneDialog)
\r
84 ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
\r
85 ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
\r
86 ON_COMMAND(ID_VIEW_ZOOM100, OnViewZoom100)
\r
87 ON_COMMAND(ID_VIEW_ZOOMHEIGHT, OnViewZoomHeight)
\r
88 ON_COMMAND(ID_VIEW_ZOOMWIDTH, OnViewZoomWidth)
\r
89 ON_COMMAND(ID_VIEW_ZOOMALL, OnViewZoomAll)
\r
90 ON_COMMAND(ID_MENUEXIT, OnMenuexit)
\r
91 ON_COMMAND(ID_MENUHELP, OnMenuhelp)
\r
92 ON_COMMAND(ID_VIEW_COMPAREHEADREVISIONS, OnViewCompareheadrevisions)
\r
93 ON_COMMAND(ID_VIEW_COMPAREREVISIONS, OnViewComparerevisions)
\r
94 ON_COMMAND(ID_VIEW_UNIFIEDDIFF, OnViewUnifieddiff)
\r
95 ON_COMMAND(ID_VIEW_UNIFIEDDIFFOFHEADREVISIONS, OnViewUnifieddiffofheadrevisions)
\r
96 ON_COMMAND(ID_FILE_SAVEGRAPHAS, OnFileSavegraphas)
\r
97 ON_COMMAND_EX(ID_VIEW_SHOWALLREVISIONS, OnToggleOption)
\r
98 ON_COMMAND_EX(ID_VIEW_GROUPBRANCHES, OnToggleOption)
\r
99 ON_COMMAND_EX(ID_VIEW_TOPDOWN, OnToggleOption)
\r
100 ON_COMMAND_EX(ID_VIEW_TOPALIGNTREES, OnToggleOption)
\r
101 ON_COMMAND_EX(ID_VIEW_SHOWHEAD, OnToggleOption)
\r
102 ON_COMMAND_EX(ID_VIEW_EXACTCOPYSOURCE, OnToggleOption)
\r
103 ON_COMMAND_EX(ID_VIEW_FOLDTAGS, OnToggleOption)
\r
104 ON_COMMAND_EX(ID_VIEW_REDUCECROSSLINES, OnToggleOption)
\r
105 ON_COMMAND_EX(ID_VIEW_REMOVEDELETEDONES, OnToggleOption)
\r
106 ON_COMMAND_EX(ID_VIEW_SHOWWCREV, OnToggleReloadOption)
\r
107 ON_COMMAND_EX(ID_VIEW_REMOVEUNCHANGEDBRANCHES, OnToggleOption)
\r
108 ON_COMMAND_EX(ID_VIEW_SHOWWCMODIFICATION, OnToggleReloadOption)
\r
109 ON_COMMAND_EX(ID_VIEW_SHOWDIFFPATHS, OnToggleOption)
\r
110 ON_COMMAND_EX(ID_VIEW_SHOWTREESTRIPES, OnToggleRedrawOption)
\r
111 ON_CBN_SELCHANGE(ID_REVGRAPH_ZOOMCOMBO, OnChangeZoom)
\r
112 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
\r
113 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
\r
114 ON_COMMAND(ID_VIEW_FILTER, OnViewFilter)
\r
115 ON_COMMAND(ID_VIEW_SHOWOVERVIEW, OnViewShowoverview)
\r
118 BOOL CRevisionGraphDlg::InitializeToolbar()
\r
120 // set up the toolbar
\r
121 // add the tool bar to the dialog
\r
122 m_ToolBar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT | CBRS_SIZE_DYNAMIC);
\r
123 m_ToolBar.LoadToolBar(IDR_REVGRAPHBAR);
\r
124 m_ToolBar.ShowWindow(SW_SHOW);
\r
125 m_ToolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY);
\r
127 // toolbars aren't true-color without some tweaking:
\r
129 CImageList cImageList;
\r
133 cBitmap.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_REVGRAPHBAR),
\r
134 IMAGE_BITMAP, 0, 0,
\r
135 LR_DEFAULTSIZE|LR_CREATEDIBSECTION));
\r
136 cBitmap.GetBitmap(&bmBitmap);
\r
138 CSize cSize(bmBitmap.bmWidth, bmBitmap.bmHeight);
\r
139 int nNbBtn = cSize.cx/20;
\r
140 RGBTRIPLE * rgb = (RGBTRIPLE*)(bmBitmap.bmBits);
\r
141 COLORREF rgbMask = RGB(rgb[0].rgbtRed, rgb[0].rgbtGreen, rgb[0].rgbtBlue);
\r
143 cImageList.Create(20, cSize.cy, ILC_COLOR32|ILC_MASK, nNbBtn, 0);
\r
144 cImageList.Add(&cBitmap, rgbMask);
\r
145 m_ToolBar.SendMessage(TB_SETIMAGELIST, 0, (LPARAM)cImageList.m_hImageList);
\r
146 cImageList.Detach();
\r
149 RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
\r
151 #define SNAP_WIDTH 60 //the width of the combo box
\r
152 // set up the ComboBox control as a snap mode select box
\r
153 // First get the index of the placeholders position in the toolbar
\r
154 int zoomComboIndex = 0;
\r
155 while (m_ToolBar.GetItemID(zoomComboIndex) != ID_REVGRAPH_ZOOMCOMBO) zoomComboIndex++;
\r
157 // next convert that button to a separator and get its position
\r
158 m_ToolBar.SetButtonInfo(zoomComboIndex, ID_REVGRAPH_ZOOMCOMBO, TBBS_SEPARATOR,
\r
161 m_ToolBar.GetItemRect(zoomComboIndex, &rect);
\r
163 // expand the rectangle to allow the combo box room to drop down
\r
165 rect.bottom += 200;
\r
167 // then create the combo box and show it
\r
168 if (!m_ToolBar.m_ZoomCombo.CreateEx(WS_EX_RIGHT, WS_CHILD|WS_VISIBLE|CBS_AUTOHSCROLL|CBS_DROPDOWN,
\r
169 rect, &m_ToolBar, ID_REVGRAPH_ZOOMCOMBO))
\r
171 TRACE0("Failed to create combo-box\n");
\r
174 m_ToolBar.m_ZoomCombo.ShowWindow(SW_SHOW);
\r
176 // fill the combo box
\r
178 TCHAR* texts[] = { _T("5%")
\r
188 COMBOBOXEXITEM cbei;
\r
189 SecureZeroMemory(&cbei, sizeof cbei);
\r
190 cbei.mask = CBEIF_TEXT;
\r
192 for (TCHAR** text = texts; *text != NULL; ++text)
\r
194 cbei.pszText = *text;
\r
195 m_ToolBar.m_ZoomCombo.InsertItem(&cbei);
\r
198 m_ToolBar.m_ZoomCombo.SetCurSel(1);
\r
200 UpdateOptionAvailability();
\r
205 BOOL CRevisionGraphDlg::OnInitDialog()
\r
207 CResizableStandAloneDialog::OnInitDialog();
\r
211 // set up the status bar
\r
212 m_StatusBar.Create(WS_CHILD|WS_VISIBLE|SBT_OWNERDRAW,
\r
213 CRect(0,0,0,0), this, 1);
\r
214 int strPartDim[2]= {120, -1};
\r
215 m_StatusBar.SetParts(2, strPartDim);
\r
217 if (InitializeToolbar() != TRUE)
\r
220 CSyncPointer<CAllRevisionGraphOptions>
\r
221 options (m_Graph.m_state.GetOptions());
\r
223 for (size_t i = 0; i < options->count(); ++i)
\r
224 if ((*options)[i]->CommandID() != 0)
\r
225 SetOption ((*options)[i]->CommandID());
\r
227 CMenu * pMenu = GetMenu();
\r
230 CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseSVN\\ShowRevGraphOverview"), FALSE);
\r
231 m_Graph.SetShowOverview ((DWORD)reg != FALSE);
\r
232 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | (DWORD(reg) ? MF_CHECKED : 0));
\r
233 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW);
\r
234 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate | (DWORD(reg) ? TBSTATE_CHECKED : 0));
\r
237 m_hAccel = LoadAccelerators(AfxGetResourceHandle(),MAKEINTRESOURCE(IDR_ACC_REVISIONGRAPH));
\r
239 CRect graphrect = GetGraphRect();
\r
240 m_Graph.Init(this, &graphrect);
\r
241 m_Graph.SetOwner(this);
\r
242 m_Graph.UpdateWindow();
\r
245 EnableSaveRestore(_T("RevisionGraphDlg"));
\r
247 assert (m_Graph.m_bThreadRunning == TRUE);
\r
248 if (AfxBeginThread(WorkerThread, this)== NULL)
\r
250 InterlockedExchange (&m_Graph.m_bThreadRunning, FALSE);
\r
251 CMessageBox::Show(this->m_hWnd, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
\r
254 CenterWindow(CWnd::FromHandle(hWndExplorer));
\r
255 return TRUE; // return TRUE unless you set the focus to a control
\r
258 UINT CRevisionGraphDlg::WorkerThread(LPVOID pVoid)
\r
260 CRevisionGraphDlg* pDlg;
\r
261 pDlg = (CRevisionGraphDlg*)pVoid;
\r
262 assert (pDlg->m_Graph.m_bThreadRunning == TRUE);
\r
263 CoInitialize(NULL);
\r
265 if (pDlg->m_bFetchLogs)
\r
267 pDlg->m_Graph.m_pProgress = new CProgressDlg();
\r
268 pDlg->m_Graph.m_pProgress->SetTitle(IDS_REVGRAPH_PROGTITLE);
\r
269 pDlg->m_Graph.m_pProgress->SetCancelMsg(IDS_REVGRAPH_PROGCANCEL);
\r
270 pDlg->m_Graph.m_pProgress->SetTime();
\r
271 pDlg->m_Graph.m_pProgress->SetProgress(0, 100);
\r
273 svn_revnum_t pegRev = pDlg->m_Graph.m_pegRev.IsNumber()
\r
274 ? (svn_revnum_t)pDlg->m_Graph.m_pegRev
\r
275 : (svn_revnum_t)-1;
\r
277 if (!pDlg->m_Graph.FetchRevisionData (pDlg->m_Graph.m_sPath, pegRev))
\r
278 CMessageBox::Show ( pDlg->m_hWnd
\r
279 , pDlg->m_Graph.m_state.GetLastErrorMessage()
\r
280 , _T("TortoiseSVN")
\r
283 pDlg->m_Graph.m_pProgress->Stop();
\r
284 delete pDlg->m_Graph.m_pProgress;
\r
285 pDlg->m_Graph.m_pProgress = NULL;
\r
287 pDlg->m_bFetchLogs = false; // we've got the logs, no need to fetch them a second time
\r
290 // standard plus user settings
\r
292 if (pDlg->m_Graph.AnalyzeRevisionData())
\r
294 pDlg->UpdateStatusBar();
\r
295 pDlg->UpdateOptionAvailability();
\r
299 InterlockedExchange(&pDlg->m_Graph.m_bThreadRunning, FALSE);
\r
301 pDlg->m_Graph.SendMessage (CRevisionGraphWnd::WM_WORKERTHREADDONE, 0, 0);
\r
305 void CRevisionGraphDlg::OnSize(UINT nType, int cx, int cy)
\r
307 __super::OnSize(nType, cx, cy);
\r
309 GetClientRect(&rect);
\r
310 if (IsWindow(m_ToolBar))
\r
312 RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
\r
314 if (IsWindow(m_StatusBar))
\r
316 CRect statusbarrect;
\r
317 m_StatusBar.GetClientRect(&statusbarrect);
\r
318 statusbarrect.top = rect.bottom - statusbarrect.top + statusbarrect.bottom;
\r
319 m_StatusBar.MoveWindow(&statusbarrect);
\r
321 if (IsWindow(m_Graph))
\r
323 m_Graph.MoveWindow (GetGraphRect());
\r
327 BOOL CRevisionGraphDlg::PreTranslateMessage(MSG* pMsg)
\r
329 #define SCROLL_STEP 20
\r
330 if (pMsg->message == WM_KEYDOWN)
\r
333 switch (pMsg->wParam)
\r
336 pos = m_Graph.GetScrollPos(SB_VERT);
\r
337 m_Graph.SetScrollPos(SB_VERT, pos - SCROLL_STEP);
\r
338 m_Graph.Invalidate();
\r
341 pos = m_Graph.GetScrollPos(SB_VERT);
\r
342 m_Graph.SetScrollPos(SB_VERT, pos + SCROLL_STEP);
\r
343 m_Graph.Invalidate();
\r
346 pos = m_Graph.GetScrollPos(SB_HORZ);
\r
347 m_Graph.SetScrollPos(SB_HORZ, pos - SCROLL_STEP);
\r
348 m_Graph.Invalidate();
\r
351 pos = m_Graph.GetScrollPos(SB_HORZ);
\r
352 m_Graph.SetScrollPos(SB_HORZ, pos + SCROLL_STEP);
\r
353 m_Graph.Invalidate();
\r
356 pos = m_Graph.GetScrollPos(SB_VERT);
\r
357 m_Graph.SetScrollPos(SB_VERT, pos - GetGraphRect().Height() / 2);
\r
358 m_Graph.Invalidate();
\r
361 pos = m_Graph.GetScrollPos(SB_VERT);
\r
362 m_Graph.SetScrollPos(SB_VERT, pos + GetGraphRect().Height() / 2);
\r
363 m_Graph.Invalidate();
\r
366 UpdateFullHistory();
\r
370 if ((m_hAccel)&&(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST))
\r
372 if (pMsg->wParam == VK_ESCAPE)
\r
373 if (m_Graph.CancelMouseZoom())
\r
375 return TranslateAccelerator(m_hWnd,m_hAccel,pMsg);
\r
377 return __super::PreTranslateMessage(pMsg);
\r
380 void CRevisionGraphDlg::DoZoom (float zoom)
\r
382 m_fZoomFactor = zoom;
\r
383 m_Graph.DoZoom (zoom);
\r
387 void CRevisionGraphDlg::OnViewZoomin()
\r
389 DoZoom (min (2.0f, m_fZoomFactor / .9f));
\r
392 void CRevisionGraphDlg::OnViewZoomout()
\r
394 DoZoom (max (0.01f, m_fZoomFactor * .9f));
\r
397 void CRevisionGraphDlg::OnViewZoom100()
\r
402 void CRevisionGraphDlg::OnViewZoomHeight()
\r
404 CRect graphRect = m_Graph.GetGraphRect();
\r
405 CRect windowRect = m_Graph.GetWindowRect();
\r
407 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
\r
408 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
\r
409 if ((horzfact < vertfact) && (horzfact < 2.0f))
\r
410 vertfact = (windowRect.Height() - 20.0f)/(4.0f + graphRect.Height());
\r
412 DoZoom (min (2.0f, vertfact));
\r
415 void CRevisionGraphDlg::OnViewZoomWidth()
\r
417 // zoom the graph so that it is completely visible in the window
\r
418 CRect graphRect = m_Graph.GetGraphRect();
\r
419 CRect windowRect = m_Graph.GetWindowRect();
\r
421 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
\r
422 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
\r
423 if ((vertfact < horzfact) && (vertfact < 2.0f))
\r
424 horzfact = (windowRect.Width() - 20.0f)/(4.0f + graphRect.Width());
\r
426 DoZoom (min (2.0f, horzfact));
\r
429 void CRevisionGraphDlg::OnViewZoomAll()
\r
431 // zoom the graph so that it is completely visible in the window
\r
432 CRect graphRect = m_Graph.GetGraphRect();
\r
433 CRect windowRect = m_Graph.GetWindowRect();
\r
435 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
\r
436 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
\r
438 DoZoom (min (2.0f, min(horzfact, vertfact)));
\r
441 void CRevisionGraphDlg::OnMenuexit()
\r
443 if (!m_Graph.m_bThreadRunning)
\r
447 void CRevisionGraphDlg::OnMenuhelp()
\r
452 void CRevisionGraphDlg::OnViewCompareheadrevisions()
\r
454 m_Graph.CompareRevs(true);
\r
457 void CRevisionGraphDlg::OnViewComparerevisions()
\r
459 m_Graph.CompareRevs(false);
\r
462 void CRevisionGraphDlg::OnViewUnifieddiff()
\r
464 m_Graph.UnifiedDiffRevs(false);
\r
467 void CRevisionGraphDlg::OnViewUnifieddiffofheadrevisions()
\r
469 m_Graph.UnifiedDiffRevs(true);
\r
472 void CRevisionGraphDlg::UpdateFullHistory()
\r
474 m_Graph.SetDlgTitle (false);
\r
477 LogCache::CRepositoryInfo& cachedProperties
\r
478 = svn.GetLogCachePool()->GetRepositoryInfo();
\r
479 CString root = m_Graph.m_state.GetRepositoryRoot();
\r
480 CString uuid = m_Graph.m_state.GetRepositoryUUID();
\r
482 cachedProperties.ResetHeadRevision (uuid, root);
\r
484 m_bFetchLogs = true;
\r
485 StartWorkerThread();
\r
488 void CRevisionGraphDlg::SetOption (UINT controlID)
\r
490 CMenu * pMenu = GetMenu();
\r
494 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(controlID);
\r
497 if (m_Graph.m_state.GetOptions()->IsSelected (controlID))
\r
499 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_CHECKED);
\r
500 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate | TBSTATE_CHECKED);
\r
504 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_UNCHECKED);
\r
505 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate & (~TBSTATE_CHECKED));
\r
510 BOOL CRevisionGraphDlg::ToggleOption (UINT controlID)
\r
512 // check request for validity
\r
514 if (m_Graph.m_bThreadRunning)
\r
516 int state = m_ToolBar.GetToolBarCtrl().GetState(controlID);
\r
517 if (state & TBSTATE_CHECKED)
\r
518 state &= ~TBSTATE_CHECKED;
\r
520 state |= TBSTATE_CHECKED;
\r
521 m_ToolBar.GetToolBarCtrl().SetState (controlID, state);
\r
525 CMenu * pMenu = GetMenu();
\r
529 // actually toggle the option
\r
531 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(controlID);
\r
532 UINT state = pMenu->GetMenuState(controlID, MF_BYCOMMAND);
\r
533 if (state & MF_CHECKED)
\r
535 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_UNCHECKED);
\r
536 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate & (~TBSTATE_CHECKED));
\r
540 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_CHECKED);
\r
541 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate | TBSTATE_CHECKED);
\r
544 CSyncPointer<CAllRevisionGraphOptions>
\r
545 options (m_Graph.m_state.GetOptions());
\r
546 if (((state & MF_CHECKED) != 0) == options->IsSelected (controlID))
\r
547 options->ToggleSelection (controlID);
\r
552 BOOL CRevisionGraphDlg::OnToggleOption (UINT controlID)
\r
554 if (!ToggleOption (controlID))
\r
557 // re-process the data
\r
559 StartWorkerThread();
\r
564 BOOL CRevisionGraphDlg::OnToggleReloadOption (UINT controlID)
\r
566 if (!m_Graph.m_state.GetFetchedWCState())
\r
567 m_bFetchLogs = true;
\r
569 return OnToggleOption (controlID);
\r
572 BOOL CRevisionGraphDlg::OnToggleRedrawOption (UINT controlID)
\r
574 if (!ToggleOption (controlID))
\r
577 m_Graph.BuildPreview();
\r
583 void CRevisionGraphDlg::StartWorkerThread()
\r
585 if (InterlockedExchange(&m_Graph.m_bThreadRunning, TRUE) == TRUE)
\r
588 if (AfxBeginThread(WorkerThread, this)==NULL)
\r
590 CMessageBox::Show(this->m_hWnd, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
\r
591 InterlockedExchange(&m_Graph.m_bThreadRunning, FALSE);
\r
595 void CRevisionGraphDlg::OnCancel()
\r
597 if (!m_Graph.m_bThreadRunning)
\r
598 __super::OnCancel();
\r
601 void CRevisionGraphDlg::OnOK()
\r
606 void CRevisionGraphDlg::OnFileSavegraphas()
\r
609 int filterindex = 0;
\r
610 if (CAppUtils::FileOpenSave(tempfile, &filterindex, IDS_REVGRAPH_SAVEPIC, IDS_PICTUREFILEFILTER, false, m_hWnd))
\r
612 // if the user doesn't specify a file extension, default to
\r
613 // wmf and add that extension to the filename. But only if the
\r
614 // user chose the 'pictures' filter. The filename isn't changed
\r
615 // if the 'All files' filter was chosen.
\r
617 int dotPos = tempfile.ReverseFind('.');
\r
618 int slashPos = tempfile.ReverseFind('\\');
\r
619 if (dotPos > slashPos)
\r
620 extension = tempfile.Mid(dotPos);
\r
621 if ((filterindex == 1)&&(extension.IsEmpty()))
\r
623 extension = _T(".wmf");
\r
624 tempfile += extension;
\r
626 m_Graph.SaveGraphAs(tempfile);
\r
630 CRect CRevisionGraphDlg::GetGraphRect()
\r
633 GetClientRect(&rect);
\r
635 CRect statusbarrect;
\r
636 m_StatusBar.GetClientRect(&statusbarrect);
\r
637 rect.bottom -= statusbarrect.Height();
\r
640 m_ToolBar.GetClientRect(&toolbarrect);
\r
641 rect.top += toolbarrect.Height();
\r
646 void CRevisionGraphDlg::UpdateStatusBar()
\r
649 sFormat.Format(IDS_REVGRAPH_STATUSBARURL, (LPCTSTR)m_Graph.m_sPath);
\r
650 m_StatusBar.SetText(sFormat,1,0);
\r
651 sFormat.Format(IDS_REVGRAPH_STATUSBARNUMNODES, m_Graph.m_state.GetNodeCount());
\r
652 m_StatusBar.SetText(sFormat,0,0);
\r
655 void CRevisionGraphDlg::OnChangeZoom()
\r
657 if (!IsWindow(m_Graph.GetSafeHwnd()))
\r
661 CComboBoxEx* pCBox = (CComboBoxEx*)m_ToolBar.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO);
\r
662 pCBox->GetWindowText(strItem);
\r
663 if (strItem.IsEmpty())
\r
665 ATLTRACE(_T("OnChangeZoom to %s\n"), strItem);
\r
667 DoZoom ((float)(_tstof(strItem)/100.0));
\r
670 void CRevisionGraphDlg::UpdateZoomBox()
\r
674 CComboBoxEx* pCBox = (CComboBoxEx*)m_ToolBar.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO);
\r
675 pCBox->GetWindowText(strItem);
\r
676 strText.Format(_T("%.0f%%"), (m_fZoomFactor*100.0));
\r
677 if (strText.Compare(strItem) != 0)
\r
678 pCBox->SetWindowText(strText);
\r
681 BOOL CRevisionGraphDlg::OnToolTipNotify(UINT /*id*/, NMHDR *pNMHDR, LRESULT *pResult)
\r
683 // need to handle both ANSI and UNICODE versions of the message
\r
684 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
\r
685 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
\r
686 CString strTipText;
\r
688 UINT_PTR nID = pNMHDR->idFrom;
\r
690 if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
\r
691 pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
\r
693 // idFrom is actually the HWND of the tool
\r
694 nID = ::GetDlgCtrlID((HWND)nID);
\r
697 if (nID != 0) // will be zero on a separator
\r
699 strTipText.LoadString (static_cast<UINT>(nID));
\r
703 if (strTipText.IsEmpty())
\r
706 if (strTipText.GetLength() >= MAX_TT_LENGTH)
\r
707 strTipText = strTipText.Left(MAX_TT_LENGTH);
\r
709 if (pNMHDR->code == TTN_NEEDTEXTA)
\r
711 ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 600);
\r
712 pTTTA->lpszText = m_szTip;
\r
713 WideCharToMultiByte(CP_ACP, 0, strTipText, -1, m_szTip, strTipText.GetLength()+1, 0, 0);
\r
717 ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 600);
\r
718 lstrcpyn(m_wszTip, strTipText, strTipText.GetLength()+1);
\r
719 pTTTW->lpszText = m_wszTip;
\r
721 // bring the tooltip window above other pop up windows
\r
722 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
\r
723 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
\r
724 return TRUE; // message was handled
\r
727 void CRevisionGraphDlg::OnViewFilter()
\r
729 CSyncPointer<CAllRevisionGraphOptions>
\r
730 options (m_Graph.m_state.GetOptions());
\r
732 CRevisionInRange* revisionRange = options->GetOption<CRevisionInRange>();
\r
733 svn_revnum_t head = m_Graph.m_state.GetHeadRevision();
\r
734 svn_revnum_t lowerLimit = revisionRange->GetLowerLimit();
\r
735 svn_revnum_t upperLimit = revisionRange->GetUpperLimit();
\r
737 CRemovePathsBySubString* pathFilter = options->GetOption<CRemovePathsBySubString>();
\r
739 CRevGraphFilterDlg dlg;
\r
740 dlg.SetMaxRevision (head);
\r
741 dlg.SetFilterString (m_sFilter);
\r
742 dlg.SetRemoveSubTrees (pathFilter->GetRemoveSubTrees());
\r
743 dlg.SetRevisionRange ( min (head, lowerLimit == -1 ? 1 : lowerLimit)
\r
744 , min (head, upperLimit == -1 ? head : upperLimit));
\r
746 if (dlg.DoModal()==IDOK)
\r
748 // user pressed OK to dismiss the dialog, which means
\r
749 // we have to accept the new filter settings and apply them
\r
750 svn_revnum_t minrev, maxrev;
\r
751 dlg.GetRevisionRange(minrev, maxrev);
\r
752 m_sFilter = dlg.GetFilterString();
\r
754 revisionRange->SetLowerLimit (minrev);
\r
755 revisionRange->SetUpperLimit (maxrev == head ? revision_t (NO_REVISION) : maxrev);
\r
757 pathFilter->SetRemoveSubTrees (dlg.GetRemoveSubTrees());
\r
758 std::set<std::string>& filterPaths = pathFilter->GetFilterPaths();
\r
760 filterPaths.clear();
\r
762 CString path = m_sFilter.Tokenize (_T("*"), index);
\r
763 while (!path.IsEmpty())
\r
765 filterPaths.insert (CUnicodeUtils::StdGetUTF8 ((LPCTSTR)path));
\r
766 path = m_sFilter.Tokenize (_T("*"), index);
\r
769 // update menu & toolbar
\r
771 CMenu * pMenu = GetMenu();
\r
772 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_FILTER);
\r
773 if (revisionRange->IsActive() || pathFilter->IsActive())
\r
776 pMenu->CheckMenuItem(ID_VIEW_FILTER, MF_BYCOMMAND | MF_CHECKED);
\r
777 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_FILTER, tbstate | TBSTATE_CHECKED);
\r
782 pMenu->CheckMenuItem(ID_VIEW_FILTER, MF_BYCOMMAND | MF_UNCHECKED);
\r
783 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_FILTER, tbstate & (~TBSTATE_CHECKED));
\r
788 StartWorkerThread();
\r
792 void CRevisionGraphDlg::OnViewShowoverview()
\r
794 CMenu * pMenu = GetMenu();
\r
797 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW);
\r
798 UINT state = pMenu->GetMenuState(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND);
\r
799 if (state & MF_CHECKED)
\r
801 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | MF_UNCHECKED);
\r
802 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate & (~TBSTATE_CHECKED));
\r
803 m_Graph.SetShowOverview (false);
\r
807 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | MF_CHECKED);
\r
808 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate | TBSTATE_CHECKED);
\r
809 m_Graph.SetShowOverview (true);
\r
812 CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseSVN\\ShowRevGraphOverview"), FALSE);
\r
813 reg = m_Graph.GetShowOverview();
\r
814 m_Graph.Invalidate(FALSE);
\r
817 void CRevisionGraphDlg::UpdateOptionAvailability (UINT id, bool available)
\r
819 CMenu * pMenu = GetMenu();
\r
823 pMenu->EnableMenuItem (id, available ? MF_ENABLED : MF_GRAYED);
\r
825 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(id);
\r
826 int newTbstate = available
\r
827 ? tbstate | TBSTATE_ENABLED
\r
828 : tbstate & ~TBSTATE_ENABLED;
\r
830 if (tbstate != newTbstate)
\r
831 m_ToolBar.GetToolBarCtrl().SetState(id, newTbstate);
\r
834 void CRevisionGraphDlg::UpdateOptionAvailability()
\r
836 bool multipleTrees = m_Graph.m_state.GetTreeCount() > 1;
\r
837 bool isWCPath = !CTSVNPath (m_Graph.m_sPath).IsUrl();
\r
839 UpdateOptionAvailability (ID_VIEW_TOPALIGNTREES, multipleTrees);
\r
840 UpdateOptionAvailability (ID_VIEW_SHOWTREESTRIPES, multipleTrees);
\r
841 UpdateOptionAvailability (ID_VIEW_SHOWWCREV, isWCPath);
\r
842 UpdateOptionAvailability (ID_VIEW_SHOWWCMODIFICATION, isWCPath);
\r