1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2012 - TortoiseSVN
4 // Copyright (C) 2012-2016 - TortoiseGit
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "TortoiseProc.h"
22 #include "RevisionGraphDlg.h"
25 #include "StringUtils.h"
27 #include "UnicodeUtils.h"
29 //#include "SVNInfo.h"
30 //#include "SVNDiff.h"
31 #include "RevGraphFilterDlg.h"
32 //#include "RepositoryInfo.h"
33 //#include "RevisionInRange.h"
34 //#include "RemovePathsBySubString.h"
39 static char THIS_FILE
[] = __FILE__
;
42 using namespace Gdiplus
;
44 IMPLEMENT_DYNAMIC(CRevisionGraphDlg
, CResizableStandAloneDialog
)
45 CRevisionGraphDlg::CRevisionGraphDlg(CWnd
* pParent
/*=nullptr*/)
46 : CResizableStandAloneDialog(CRevisionGraphDlg::IDD
, pParent
)
49 , m_fZoomFactor(DEFAULT_ZOOM
)
52 // GDI+ initialization
54 GdiplusStartupInput input
;
55 GdiplusStartup(&m_gdiPlusToken
, &input
, nullptr);
57 // restore option state
59 // DWORD dwOpts = CRegStdDWORD(L"Software\\TortoiseGit\\RevisionGraphOptions", 0x1ff199);
60 // m_Graph.m_state.GetOptions()->SetRegistryFlags (dwOpts, 0x407fbf);
66 CRevisionGraphDlg::~CRevisionGraphDlg()
70 CRegStdDWORD regOpts
= CRegStdDWORD(L
"Software\\TortoiseGit\\RevisionGraphOptions", 1);
71 // regOpts = m_Graph.m_state.GetOptions()->GetRegistryFlags();
75 GdiplusShutdown (m_gdiPlusToken
);
78 void CRevisionGraphDlg::DoDataExchange(CDataExchange
* pDX
)
80 CResizableStandAloneDialog::DoDataExchange(pDX
);
84 BEGIN_MESSAGE_MAP(CRevisionGraphDlg
, CResizableStandAloneDialog
)
88 ON_COMMAND(ID_VIEW_ZOOMIN
, OnViewZoomin
)
89 ON_COMMAND(ID_VIEW_ZOOMOUT
, OnViewZoomout
)
90 ON_COMMAND(ID_VIEW_ZOOM100
, OnViewZoom100
)
91 ON_COMMAND(ID_VIEW_ZOOMHEIGHT
, OnViewZoomHeight
)
92 ON_COMMAND(ID_VIEW_ZOOMWIDTH
, OnViewZoomWidth
)
93 ON_COMMAND(ID_VIEW_ZOOMALL
, OnViewZoomAll
)
94 ON_CBN_SELCHANGE(ID_REVGRAPH_ZOOMCOMBO
, OnChangeZoom
)
95 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW
, 0, 0xFFFF, OnToolTipNotify
)
96 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA
, 0, 0xFFFF, OnToolTipNotify
)
97 ON_COMMAND(ID_MENUEXIT
, OnMenuexit
)
98 ON_COMMAND(ID_MENUHELP
, OnMenuhelp
)
99 ON_COMMAND(ID_FILE_SAVEGRAPHAS
, OnFileSavegraphas
)
100 ON_COMMAND(ID_VIEW_SHOWOVERVIEW
, OnViewShowoverview
)
101 ON_COMMAND(ID_VIEW_FILTER
, OnViewFilter
)
102 ON_COMMAND(ID_VIEW_COMPAREHEADREVISIONS
, OnViewCompareheadrevisions
)
103 ON_COMMAND(ID_VIEW_COMPAREREVISIONS
, OnViewComparerevisions
)
104 ON_COMMAND(ID_VIEW_UNIFIEDDIFF
, OnViewUnifieddiff
)
105 ON_COMMAND(ID_VIEW_UNIFIEDDIFFOFHEADREVISIONS
, OnViewUnifieddiffofheadrevisions
)
108 ON_COMMAND_EX(ID_VIEW_SHOWALLREVISIONS
, OnToggleOption
)
109 ON_COMMAND_EX(ID_VIEW_GROUPBRANCHES
, OnToggleOption
)
110 ON_COMMAND_EX(ID_VIEW_TOPDOWN
, OnToggleOption
)
111 ON_COMMAND_EX(ID_VIEW_TOPALIGNTREES
, OnToggleOption
)
112 ON_COMMAND_EX(ID_VIEW_SHOWHEAD
, OnToggleOption
)
113 ON_COMMAND_EX(ID_VIEW_EXACTCOPYSOURCE
, OnToggleOption
)
114 ON_COMMAND_EX(ID_VIEW_FOLDTAGS
, OnToggleOption
)
115 ON_COMMAND_EX(ID_VIEW_REDUCECROSSLINES
, OnToggleOption
)
116 ON_COMMAND_EX(ID_VIEW_REMOVEDELETEDONES
, OnToggleOption
)
117 ON_COMMAND_EX(ID_VIEW_SHOWWCREV
, OnToggleReloadOption
)
118 ON_COMMAND_EX(ID_VIEW_REMOVEUNCHANGEDBRANCHES
, OnToggleOption
)
119 ON_COMMAND_EX(ID_VIEW_REMOVETAGS
, OnToggleOption
)
120 ON_COMMAND_EX(ID_VIEW_SHOWWCMODIFICATION
, OnToggleReloadOption
)
121 ON_COMMAND_EX(ID_VIEW_SHOWDIFFPATHS
, OnToggleOption
)
122 ON_COMMAND_EX(ID_VIEW_SHOWTREESTRIPES
, OnToggleRedrawOption
)
124 ON_WM_WINDOWPOSCHANGING()
128 BOOL
CRevisionGraphDlg::InitializeToolbar()
130 // set up the toolbar
131 // add the tool bar to the dialog
132 m_ToolBar
.CreateEx(this, TBSTYLE_FLAT
| TBSTYLE_WRAPABLE
| TBSTYLE_TRANSPARENT
| CBRS_SIZE_DYNAMIC
);
133 m_ToolBar
.LoadToolBar(IDR_REVGRAPHBAR
);
134 m_ToolBar
.ShowWindow(SW_SHOW
);
135 m_ToolBar
.SetBarStyle(CBRS_ALIGN_TOP
| CBRS_TOOLTIPS
| CBRS_FLYBY
);
137 // toolbars aren't true-color without some tweaking:
139 CImageList cImageList
;
143 cBitmap
.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_REVGRAPHBAR
),
145 LR_DEFAULTSIZE
|LR_CREATEDIBSECTION
));
146 cBitmap
.GetBitmap(&bmBitmap
);
148 CSize
cSize(bmBitmap
.bmWidth
, bmBitmap
.bmHeight
);
149 int nNbBtn
= cSize
.cx
/20;
150 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)(bmBitmap
.bmBits
);
151 COLORREF rgbMask
= RGB(rgb
[0].rgbtRed
, rgb
[0].rgbtGreen
, rgb
[0].rgbtBlue
);
153 cImageList
.Create(20, cSize
.cy
, ILC_COLOR32
|ILC_MASK
, nNbBtn
, 0);
154 cImageList
.Add(&cBitmap
, rgbMask
);
155 m_ToolBar
.SendMessage(TB_SETIMAGELIST
, 0, (LPARAM
)cImageList
.m_hImageList
);
159 RepositionBars(AFX_IDW_CONTROLBAR_FIRST
, AFX_IDW_CONTROLBAR_LAST
, 0);
162 #define SNAP_WIDTH 60 //the width of the combo box
163 // set up the ComboBox control as a snap mode select box
164 // First get the index of the placeholders position in the toolbar
165 int zoomComboIndex
= 0;
166 while (m_ToolBar
.GetItemID(zoomComboIndex
) != ID_REVGRAPH_ZOOMCOMBO
) ++zoomComboIndex
;
168 // next convert that button to a separator and get its position
169 m_ToolBar
.SetButtonInfo(zoomComboIndex
, ID_REVGRAPH_ZOOMCOMBO
, TBBS_SEPARATOR
,
172 m_ToolBar
.GetItemRect(zoomComboIndex
, &rect
);
174 // expand the rectangle to allow the combo box room to drop down
178 // then create the combo box and show it
179 if (!m_ToolBar
.m_ZoomCombo
.CreateEx(WS_EX_RIGHT
, WS_CHILD
|WS_VISIBLE
|CBS_AUTOHSCROLL
|CBS_DROPDOWN
,
180 rect
, &m_ToolBar
, ID_REVGRAPH_ZOOMCOMBO
))
182 CTraceToOutputDebugString::Instance()(__FUNCTION__
": Failed to create combo-box\n");
185 m_ToolBar
.m_ZoomCombo
.ShowWindow(SW_SHOW
);
187 // fill the combo box
189 TCHAR
* texts
[] = { L
"5%"
199 COMBOBOXEXITEM cbei
= { 0 };
200 cbei
.mask
= CBEIF_TEXT
;
202 for (TCHAR
** text
= texts
; *text
; ++text
)
204 cbei
.pszText
= *text
;
205 m_ToolBar
.m_ZoomCombo
.InsertItem(&cbei
);
208 m_ToolBar
.m_ZoomCombo
.SetCurSel(1);
210 UpdateOptionAvailability();
215 BOOL
CRevisionGraphDlg::OnInitDialog()
217 CResizableStandAloneDialog::OnInitDialog();
218 CAppUtils::MarkWindowAsUnpinnable(m_hWnd
);
222 CString sWindowTitle
;
223 GetWindowText(sWindowTitle
);
224 CAppUtils::SetWindowTitle(m_hWnd
, g_Git
.m_CurrentDir
, sWindowTitle
);
227 // set up the status bar
228 m_StatusBar
.Create(WS_CHILD
|WS_VISIBLE
|SBT_OWNERDRAW
,
229 CRect(0,0,0,0), this, 1);
230 int strPartDim
[2]= {120, -1};
231 m_StatusBar
.SetParts(2, strPartDim
);
233 if (InitializeToolbar() != TRUE
)
236 m_pTaskbarList
.Release();
237 if (FAILED(m_pTaskbarList
.CoCreateInstance(CLSID_TaskbarList
)))
238 m_pTaskbarList
= nullptr;
240 // CSyncPointer<CAllRevisionGraphOptions>
241 // options (m_Graph.m_state.GetOptions());
243 // for (size_t i = 0; i < options->count(); ++i)
244 // if ((*options)[i]->CommandID() != 0)
245 // SetOption ((*options)[i]->CommandID());
248 CMenu
* pMenu
= GetMenu();
251 CRegDWORD
reg(L
"Software\\TortoiseGit\\ShowRevGraphOverview", FALSE
);
252 m_Graph
.SetShowOverview ((DWORD
)reg
!= FALSE
);
253 pMenu
->CheckMenuItem(ID_VIEW_SHOWOVERVIEW
, MF_BYCOMMAND
| (DWORD(reg
) ? MF_CHECKED
: 0));
254 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW
);
255 m_ToolBar
.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW
, tbstate
| (DWORD(reg
) ? TBSTATE_CHECKED
: 0));
259 // m_hAccel = LoadAccelerators(AfxGetResourceHandle(),MAKEINTRESOURCE(IDR_ACC_REVISIONGRAPH));
262 CRect graphrect
= GetGraphRect();
263 m_Graph
.Init(this, &graphrect
);
264 m_Graph
.SetOwner(this);
265 m_Graph
.UpdateWindow();
266 DoZoom (DEFAULT_ZOOM
);
268 // begin background operation
271 EnableSaveRestore(L
"RevisionGraphDlg");
272 // if (GetExplorerHWND())
273 // CenterWindow(CWnd::FromHandle(GetExplorerHWND()));
275 return TRUE
; // return TRUE unless you set the focus to a control
278 bool CRevisionGraphDlg::UpdateData()
280 CoInitialize(nullptr);
282 if (!m_Graph
.FetchRevisionData (m_Graph
.m_sPath
, nullptr, m_pTaskbarList
, m_hWnd
))
284 // only show the error dialog if we're not in hidden mode
287 // TGitMessageBox( m_hWnd
288 // , // m_Graph.m_state.GetLastErrorMessage()
297 CProgressDlg progress
;
298 progress
.SetTitle(IDS_REVGRAPH_PROGTITLE
);
299 progress
.SetCancelMsg(IDS_REVGRAPH_PROGCANCEL
);
301 progress
.SetProgress(0, 100);
304 m_pTaskbarList
->SetProgressState(m_hWnd
, TBPF_NORMAL
);
305 m_pTaskbarList
->SetProgressValue(m_hWnd
, 0, 100);
308 svn_revnum_t pegRev
= m_Graph
.m_pegRev
.IsNumber()
309 ? (svn_revnum_t
)m_Graph
.m_pegRev
312 if (!m_Graph
.FetchRevisionData (m_Graph
.m_sPath
, pegRev
, &progress
, m_pTaskbarList
, m_hWnd
))
314 // only show the error dialog if we're not in hidden mode
317 TSVNMessageBox( m_hWnd
318 , m_Graph
.m_state
.GetLastErrorMessage()
327 m_pTaskbarList
->SetProgressState(m_hWnd
, TBPF_NOPROGRESS
);
330 m_bFetchLogs
= false; // we've got the logs, no need to fetch them a second time
333 // standard plus user settings
336 if (m_Graph
.AnalyzeRevisionData())
339 UpdateOptionAvailability();
344 m_Graph
.PostMessage (CRevisionGraphWnd::WM_WORKERTHREADDONE
, 0, 0);
349 void CRevisionGraphDlg::OnSize(UINT nType
, int cx
, int cy
)
351 __super::OnSize(nType
, cx
, cy
);
353 GetClientRect(&rect
);
354 if (IsWindow(m_ToolBar
))
356 RepositionBars(AFX_IDW_CONTROLBAR_FIRST
, AFX_IDW_CONTROLBAR_LAST
, 0);
358 if (IsWindow(m_StatusBar
))
361 m_StatusBar
.GetClientRect(&statusbarrect
);
362 statusbarrect
.top
= rect
.bottom
- statusbarrect
.top
+ statusbarrect
.bottom
;
363 m_StatusBar
.MoveWindow(&statusbarrect
);
365 if (IsWindow(m_Graph
))
367 m_Graph
.MoveWindow (GetGraphRect());
371 BOOL
CRevisionGraphDlg::PreTranslateMessage(MSG
* pMsg
)
373 #define SCROLL_STEP 20
374 if (pMsg
->message
== WM_KEYDOWN
)
377 switch (pMsg
->wParam
)
380 pos
= m_Graph
.GetScrollPos(SB_VERT
);
381 m_Graph
.SetScrollPos(SB_VERT
, pos
- SCROLL_STEP
);
382 m_Graph
.Invalidate();
385 pos
= m_Graph
.GetScrollPos(SB_VERT
);
386 m_Graph
.SetScrollPos(SB_VERT
, pos
+ SCROLL_STEP
);
387 m_Graph
.Invalidate();
390 pos
= m_Graph
.GetScrollPos(SB_HORZ
);
391 m_Graph
.SetScrollPos(SB_HORZ
, pos
- SCROLL_STEP
);
392 m_Graph
.Invalidate();
395 pos
= m_Graph
.GetScrollPos(SB_HORZ
);
396 m_Graph
.SetScrollPos(SB_HORZ
, pos
+ SCROLL_STEP
);
397 m_Graph
.Invalidate();
400 pos
= m_Graph
.GetScrollPos(SB_VERT
);
401 m_Graph
.SetScrollPos(SB_VERT
, pos
- GetGraphRect().Height() / 2);
402 m_Graph
.Invalidate();
405 pos
= m_Graph
.GetScrollPos(SB_VERT
);
406 m_Graph
.SetScrollPos(SB_VERT
, pos
+ GetGraphRect().Height() / 2);
407 m_Graph
.Invalidate();
414 if ((m_hAccel
)&&(pMsg
->message
>= WM_KEYFIRST
&& pMsg
->message
<= WM_KEYLAST
))
416 if (pMsg
->wParam
== VK_ESCAPE
)
417 if (m_Graph
.CancelMouseZoom())
419 return TranslateAccelerator(m_hWnd
,m_hAccel
,pMsg
);
421 return __super::PreTranslateMessage(pMsg
);
424 void CRevisionGraphDlg::DoZoom (float zoom
)
426 m_fZoomFactor
= zoom
;
427 m_Graph
.DoZoom (zoom
);
431 void CRevisionGraphDlg::OnViewZoomin()
433 DoZoom (min (MAX_ZOOM
, m_fZoomFactor
/ ZOOM_STEP
));
436 void CRevisionGraphDlg::OnViewZoomout()
438 DoZoom (max (MIN_ZOOM
, m_fZoomFactor
* ZOOM_STEP
));
441 void CRevisionGraphDlg::OnViewZoom100()
443 DoZoom (DEFAULT_ZOOM
);
446 void CRevisionGraphDlg::OnViewZoomHeight()
448 CRect graphRect
= m_Graph
.GetGraphRect();
449 CRect windowRect
= m_Graph
.GetWindowRect();
451 float horzfact
= (windowRect
.Width() - 4.0f
)/(4.0f
+ graphRect
.Width());
452 float vertfact
= (windowRect
.Height() - 4.0f
)/(4.0f
+ graphRect
.Height());
453 if ((horzfact
< vertfact
) && (horzfact
< MAX_ZOOM
))
454 vertfact
= (windowRect
.Height() - 20.0f
)/(4.0f
+ graphRect
.Height());
456 DoZoom (min (MAX_ZOOM
, vertfact
));
459 void CRevisionGraphDlg::OnViewZoomWidth()
461 // zoom the graph so that it is completely visible in the window
462 CRect graphRect
= m_Graph
.GetGraphRect();
463 CRect windowRect
= m_Graph
.GetWindowRect();
465 float horzfact
= (windowRect
.Width() - 4.0f
)/(4.0f
+ graphRect
.Width());
466 float vertfact
= (windowRect
.Height() - 4.0f
)/(4.0f
+ graphRect
.Height());
467 if ((vertfact
< horzfact
) && (vertfact
< MAX_ZOOM
))
468 horzfact
= (windowRect
.Width() - 20.0f
)/(4.0f
+ graphRect
.Width());
470 DoZoom (min (MAX_ZOOM
, horzfact
));
473 void CRevisionGraphDlg::OnViewZoomAll()
475 // zoom the graph so that it is completely visible in the window
476 CRect graphRect
= m_Graph
.GetGraphRect();
477 CRect windowRect
= m_Graph
.GetWindowRect();
479 float horzfact
= (windowRect
.Width() - 4.0f
)/(4.0f
+ graphRect
.Width());
480 float vertfact
= (windowRect
.Height() - 4.0f
)/(4.0f
+ graphRect
.Height());
482 DoZoom (min (MAX_ZOOM
, min(horzfact
, vertfact
)));
485 void CRevisionGraphDlg::OnMenuexit()
487 if (!m_Graph
.IsUpdateJobRunning())
491 void CRevisionGraphDlg::OnMenuhelp()
496 void CRevisionGraphDlg::OnViewCompareheadrevisions()
498 m_Graph
.CompareRevs(L
"HEAD");
501 void CRevisionGraphDlg::OnViewComparerevisions()
503 m_Graph
.CompareRevs(false);
506 void CRevisionGraphDlg::OnViewUnifieddiff()
508 m_Graph
.UnifiedDiffRevs(false);
511 void CRevisionGraphDlg::OnViewUnifieddiffofheadrevisions()
513 m_Graph
.UnifiedDiffRevs(true);
516 void CRevisionGraphDlg::UpdateFullHistory()
518 m_Graph
.SetDlgTitle (false);
524 m_Graph
.SetDlgTitle (false);
527 LogCache::CRepositoryInfo
& cachedProperties
528 = svn
.GetLogCachePool()->GetRepositoryInfo();
529 CString root
= m_Graph
.m_state
.GetRepositoryRoot();
530 CString uuid
= m_Graph
.m_state
.GetRepositoryUUID();
532 cachedProperties
.ResetHeadRevision (uuid
, root
);
539 void CRevisionGraphDlg::SetOption (UINT
/*controlID*/)
542 CMenu
* pMenu
= GetMenu();
546 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(controlID
);
549 if (m_Graph
.m_state
.GetOptions()->IsSelected (controlID
))
551 pMenu
->CheckMenuItem(controlID
, MF_BYCOMMAND
| MF_CHECKED
);
552 m_ToolBar
.GetToolBarCtrl().SetState(controlID
, tbstate
| TBSTATE_CHECKED
);
556 pMenu
->CheckMenuItem(controlID
, MF_BYCOMMAND
| MF_UNCHECKED
);
557 m_ToolBar
.GetToolBarCtrl().SetState(controlID
, tbstate
& (~TBSTATE_CHECKED
));
563 BOOL
CRevisionGraphDlg::ToggleOption (UINT controlID
)
565 // check request for validity
567 if (m_Graph
.IsUpdateJobRunning())
569 // restore previous state
571 int state
= m_ToolBar
.GetToolBarCtrl().GetState(controlID
);
572 if (state
& TBSTATE_CHECKED
)
573 state
&= ~TBSTATE_CHECKED
;
575 state
|= TBSTATE_CHECKED
;
576 m_ToolBar
.GetToolBarCtrl().SetState (controlID
, state
);
581 CMenu
* pMenu
= GetMenu();
585 // actually toggle the option
587 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(controlID
);
588 UINT state
= pMenu
->GetMenuState(controlID
, MF_BYCOMMAND
);
589 if (state
& MF_CHECKED
)
591 pMenu
->CheckMenuItem(controlID
, MF_BYCOMMAND
| MF_UNCHECKED
);
592 m_ToolBar
.GetToolBarCtrl().SetState(controlID
, tbstate
& (~TBSTATE_CHECKED
));
596 pMenu
->CheckMenuItem(controlID
, MF_BYCOMMAND
| MF_CHECKED
);
597 m_ToolBar
.GetToolBarCtrl().SetState(controlID
, tbstate
| TBSTATE_CHECKED
);
600 // CSyncPointer<CAllRevisionGraphOptions>
601 // options (m_Graph.m_state.GetOptions());
602 // if (((state & MF_CHECKED) != 0) == options->IsSelected (controlID))
603 // options->ToggleSelection (controlID);
608 BOOL
CRevisionGraphDlg::OnToggleOption (UINT controlID
)
610 if (!ToggleOption (controlID
))
613 // re-process the data
620 BOOL
CRevisionGraphDlg::OnToggleReloadOption (UINT controlID
)
623 if (!m_Graph
.m_state
.GetFetchedWCState())
626 return OnToggleOption (controlID
);
629 BOOL
CRevisionGraphDlg::OnToggleRedrawOption (UINT controlID
)
631 if (!ToggleOption (controlID
))
634 m_Graph
.BuildPreview();
640 void CRevisionGraphDlg::StartWorkerThread()
642 if (!m_Graph
.IsUpdateJobRunning())
643 m_Graph
.updateJob
.reset (new CFuture
<bool>(this, &CRevisionGraphDlg::UpdateData
));
646 void CRevisionGraphDlg::OnCancel()
648 if (!m_Graph
.IsUpdateJobRunning())
652 void CRevisionGraphDlg::OnOK()
657 void CRevisionGraphDlg::OnFileSavegraphas()
661 if (CAppUtils::FileOpenSave(tempfile
, &filterindex
, IDS_REVGRAPH_SAVEPIC
, IDS_PICTUREFILEFILTER
, false, m_hWnd
))
663 // if the user doesn't specify a file extension, default to
664 // svg and add that extension to the filename. But only if the
665 // user chose the 'pictures' filter. The filename isn't changed
666 // if the 'All files' filter was chosen.
668 int dotPos
= tempfile
.ReverseFind('.');
669 int slashPos
= tempfile
.ReverseFind('\\');
670 if (dotPos
> slashPos
)
671 extension
= tempfile
.Mid(dotPos
);
672 if ((filterindex
== 1)&&(extension
.IsEmpty()))
675 tempfile
+= extension
;
677 if ((filterindex
== 2)&&(extension
.IsEmpty()))
680 tempfile
+= extension
;
682 m_Graph
.SaveGraphAs(tempfile
);
686 CRect
CRevisionGraphDlg::GetGraphRect()
689 GetClientRect(&rect
);
692 m_StatusBar
.GetClientRect(&statusbarrect
);
693 rect
.bottom
-= statusbarrect
.Height();
696 m_ToolBar
.GetClientRect(&toolbarrect
);
697 rect
.top
+= toolbarrect
.Height();
702 void CRevisionGraphDlg::UpdateStatusBar()
705 // sFormat.Format(IDS_REVGRAPH_STATUSBARURL, (LPCTSTR)m_Graph.m_sPath);
706 // m_StatusBar.SetText(sFormat,1,0);
707 // sFormat.Format(IDS_REVGRAPH_STATUSBARNUMNODES, m_Graph.m_state.GetNodeCount());
708 // m_StatusBar.SetText(sFormat,0,0);
711 void CRevisionGraphDlg::OnChangeZoom()
713 if (!IsWindow(m_Graph
.GetSafeHwnd()))
716 CComboBoxEx
* pCBox
= (CComboBoxEx
*)m_ToolBar
.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO
);
717 pCBox
->GetWindowText(strItem
);
718 if (strItem
.IsEmpty())
721 DoZoom ((float)(_wtof(strItem
) / 100.0));
724 void CRevisionGraphDlg::UpdateZoomBox()
728 CComboBoxEx
* pCBox
= (CComboBoxEx
*)m_ToolBar
.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO
);
729 pCBox
->GetWindowText(strItem
);
730 strText
.Format(L
"%.0f%%", (m_fZoomFactor
* 100.0));
731 if (strText
.Compare(strItem
) != 0)
732 pCBox
->SetWindowText(strText
);
735 BOOL
CRevisionGraphDlg::OnToolTipNotify(UINT
/*id*/, NMHDR
*pNMHDR
, LRESULT
*pResult
)
737 // need to handle both ANSI and UNICODE versions of the message
738 TOOLTIPTEXTA
* pTTTA
= (TOOLTIPTEXTA
*)pNMHDR
;
739 TOOLTIPTEXTW
* pTTTW
= (TOOLTIPTEXTW
*)pNMHDR
;
742 UINT_PTR nID
= pNMHDR
->idFrom
;
744 if (pNMHDR
->code
== TTN_NEEDTEXTA
&& (pTTTA
->uFlags
& TTF_IDISHWND
) ||
745 pNMHDR
->code
== TTN_NEEDTEXTW
&& (pTTTW
->uFlags
& TTF_IDISHWND
))
747 // idFrom is actually the HWND of the tool
748 nID
= ::GetDlgCtrlID((HWND
)nID
);
751 if (nID
!= 0) // will be zero on a separator
752 strTipText
.LoadString (static_cast<UINT
>(nID
));
755 if (strTipText
.IsEmpty())
758 if (strTipText
.GetLength() >= MAX_TT_LENGTH
)
759 strTipText
= strTipText
.Left(MAX_TT_LENGTH
);
761 if (pNMHDR
->code
== TTN_NEEDTEXTA
)
763 ::SendMessage(pNMHDR
->hwndFrom
, TTM_SETMAXTIPWIDTH
, 0, 600);
764 pTTTA
->lpszText
= m_szTip
;
765 WideCharToMultiByte(CP_ACP
, 0, strTipText
, -1, m_szTip
, strTipText
.GetLength()+1, 0, 0);
769 ::SendMessage(pNMHDR
->hwndFrom
, TTM_SETMAXTIPWIDTH
, 0, 600);
770 lstrcpyn(m_wszTip
, strTipText
, strTipText
.GetLength()+1);
771 pTTTW
->lpszText
= m_wszTip
;
773 // bring the tooltip window above other pop up windows
774 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
775 SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOOWNERZORDER
);
776 return TRUE
; // message was handled
779 void CRevisionGraphDlg::OnViewFilter()
781 /* CSyncPointer<CAllRevisionGraphOptions>
782 options (m_Graph.m_state.GetOptions());
784 CRevisionInRange* revisionRange = options->GetOption<CRevisionInRange>();
785 svn_revnum_t head = m_Graph.m_state.GetHeadRevision();
786 svn_revnum_t lowerLimit = revisionRange->GetLowerLimit();
787 svn_revnum_t upperLimit = revisionRange->GetUpperLimit();
789 CRemovePathsBySubString* pathFilter = options->GetOption<CRemovePathsBySubString>();
791 CRevGraphFilterDlg dlg
;
793 dlg
.m_bCurrentBranch
= this->m_Graph
.m_bCurrentBranch
;
794 dlg
.m_bLocalBranches
= m_Graph
.m_bLocalBranches
;
795 dlg
.SetRevisionRange(m_Graph
.m_FromRev
, m_Graph
.m_ToRev
);
797 if (dlg
.DoModal()==IDOK
)
799 // user pressed OK to dismiss the dialog, which means
800 // we have to accept the new filter settings and apply them
802 dlg
.GetRevisionRange(m_Graph
.m_FromRev
, m_Graph
.m_ToRev
);
803 // update menu & toolbar
805 this->m_Graph
.m_bCurrentBranch
= dlg
.m_bCurrentBranch
;
806 m_Graph
.m_bLocalBranches
= dlg
.m_bLocalBranches
;
808 CMenu
* pMenu
= GetMenu();
809 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(ID_VIEW_FILTER
);
810 if (m_Graph
.m_bCurrentBranch
|| m_Graph
.m_bLocalBranches
|| !m_Graph
.m_FromRev
.IsEmpty() || !m_Graph
.m_ToRev
.IsEmpty())
813 pMenu
->CheckMenuItem(ID_VIEW_FILTER
, MF_BYCOMMAND
| MF_CHECKED
);
814 m_ToolBar
.GetToolBarCtrl().SetState(ID_VIEW_FILTER
, tbstate
| TBSTATE_CHECKED
);
819 pMenu
->CheckMenuItem(ID_VIEW_FILTER
, MF_BYCOMMAND
| MF_UNCHECKED
);
820 m_ToolBar
.GetToolBarCtrl().SetState(ID_VIEW_FILTER
, tbstate
& (~TBSTATE_CHECKED
));
829 void CRevisionGraphDlg::OnViewShowoverview()
831 CMenu
* pMenu
= GetMenu();
834 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW
);
835 UINT state
= pMenu
->GetMenuState(ID_VIEW_SHOWOVERVIEW
, MF_BYCOMMAND
);
836 if (state
& MF_CHECKED
)
838 pMenu
->CheckMenuItem(ID_VIEW_SHOWOVERVIEW
, MF_BYCOMMAND
| MF_UNCHECKED
);
839 m_ToolBar
.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW
, tbstate
& (~TBSTATE_CHECKED
));
840 m_Graph
.SetShowOverview (false);
844 pMenu
->CheckMenuItem(ID_VIEW_SHOWOVERVIEW
, MF_BYCOMMAND
| MF_CHECKED
);
845 m_ToolBar
.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW
, tbstate
| TBSTATE_CHECKED
);
846 m_Graph
.SetShowOverview (true);
849 CRegDWORD
reg(L
"Software\\TortoiseGit\\ShowRevGraphOverview", FALSE
);
850 reg
= m_Graph
.GetShowOverview();
851 m_Graph
.Invalidate(FALSE
);
854 void CRevisionGraphDlg::UpdateOptionAvailability (UINT id
, bool available
)
856 CMenu
* pMenu
= GetMenu();
860 pMenu
->EnableMenuItem (id
, available
? MF_ENABLED
: MF_GRAYED
);
862 int tbstate
= m_ToolBar
.GetToolBarCtrl().GetState(id
);
863 int newTbstate
= available
864 ? tbstate
| TBSTATE_ENABLED
865 : tbstate
& ~TBSTATE_ENABLED
;
867 if (tbstate
!= newTbstate
)
868 m_ToolBar
.GetToolBarCtrl().SetState(id
, newTbstate
);
871 void CRevisionGraphDlg::UpdateOptionAvailability()
874 bool multipleTrees
= m_Graph
.m_state
.GetTreeCount() > 1;
875 bool isWCPath
= !CTGitPath (m_Graph
.m_sPath
).IsUrl();
877 UpdateOptionAvailability (ID_VIEW_TOPALIGNTREES
, multipleTrees
);
878 UpdateOptionAvailability (ID_VIEW_SHOWTREESTRIPES
, multipleTrees
);
879 UpdateOptionAvailability (ID_VIEW_SHOWWCREV
, isWCPath
);
880 UpdateOptionAvailability (ID_VIEW_SHOWWCMODIFICATION
, isWCPath
);
886 void CRevisionGraphDlg::OnWindowPosChanging(WINDOWPOS
* lpwndpos
)
889 lpwndpos
->flags
&= ~SWP_SHOWWINDOW
;
890 CResizableStandAloneDialog::OnWindowPosChanging(lpwndpos
);