If creating the ITaskbarList3 interface fails, set it to NULL
[TortoiseGit.git] / src / TortoiseProc / RevisionGraph / RevisionGraphDlg.cpp
blob1667a7b693ece9a8eb834ca98b6eb409a3a260fb
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2012 - TortoiseSVN
4 // Copyright (C) 2012 - 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.
20 #include "stdafx.h"
21 #include "TortoiseProc.h"
22 #include "Revisiongraphdlg.h"
23 #include "MessageBox.h"
24 #include "Git.h"
25 #include "AppUtils.h"
26 #include "StringUtils.h"
27 #include "TempFile.h"
28 #include "UnicodeUtils.h"
29 #include "TGitPath.h"
30 //#include "SVNInfo.h"
31 //#include "SVNDiff.h"
32 #include "RevGraphFilterDlg.h"
33 #include ".\revisiongraphdlg.h"
34 //#include "RepositoryInfo.h"
35 //#include "RevisionInRange.h"
36 //#include "RemovePathsBySubString.h"
38 #ifdef _DEBUG
39 #define new DEBUG_NEW
40 #undef THIS_FILE
41 static char THIS_FILE[] = __FILE__;
42 #endif
44 using namespace Gdiplus;
46 IMPLEMENT_DYNAMIC(CRevisionGraphDlg, CResizableStandAloneDialog)
47 CRevisionGraphDlg::CRevisionGraphDlg(CWnd* pParent /*=NULL*/)
48 : CResizableStandAloneDialog(CRevisionGraphDlg::IDD, pParent)
49 , m_hAccel(NULL)
50 , m_bFetchLogs(true)
51 , m_fZoomFactor(DEFAULT_ZOOM)
52 , m_bVisible(true)
54 // GDI+ initialization
56 GdiplusStartupInput input;
57 GdiplusStartup (&m_gdiPlusToken, &input, NULL);
59 // restore option state
61 // DWORD dwOpts = CRegStdDWORD(_T("Software\\TortoiseGit\\RevisionGraphOptions"), 0x1ff199);
62 // m_Graph.m_state.GetOptions()->SetRegistryFlags (dwOpts, 0x407fbf);
64 m_szTip[0] = 0;
65 m_wszTip[0] = 0;
68 CRevisionGraphDlg::~CRevisionGraphDlg()
70 // save option state
72 CRegStdDWORD regOpts = CRegStdDWORD(_T("Software\\TortoiseGit\\RevisionGraphOptions"), 1);
73 // regOpts = m_Graph.m_state.GetOptions()->GetRegistryFlags();
75 // GDI+ cleanup
77 GdiplusShutdown (m_gdiPlusToken);
80 void CRevisionGraphDlg::DoDataExchange(CDataExchange* pDX)
82 CResizableStandAloneDialog::DoDataExchange(pDX);
86 BEGIN_MESSAGE_MAP(CRevisionGraphDlg, CResizableStandAloneDialog)
87 ON_WM_SIZE()
88 ON_WM_LBUTTONDOWN()
90 ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
91 ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
92 ON_COMMAND(ID_VIEW_ZOOM100, OnViewZoom100)
93 ON_COMMAND(ID_VIEW_ZOOMHEIGHT, OnViewZoomHeight)
94 ON_COMMAND(ID_VIEW_ZOOMWIDTH, OnViewZoomWidth)
95 ON_COMMAND(ID_VIEW_ZOOMALL, OnViewZoomAll)
96 ON_CBN_SELCHANGE(ID_REVGRAPH_ZOOMCOMBO, OnChangeZoom)
97 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
98 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
99 ON_COMMAND(ID_MENUEXIT, OnMenuexit)
100 ON_COMMAND(ID_MENUHELP, OnMenuhelp)
101 ON_COMMAND(ID_FILE_SAVEGRAPHAS, OnFileSavegraphas)
102 ON_COMMAND(ID_VIEW_SHOWOVERVIEW, OnViewShowoverview)
103 ON_COMMAND(ID_VIEW_FILTER, OnViewFilter)
104 ON_COMMAND(ID_VIEW_COMPAREHEADREVISIONS, OnViewCompareheadrevisions)
105 ON_COMMAND(ID_VIEW_COMPAREREVISIONS, OnViewComparerevisions)
106 ON_COMMAND(ID_VIEW_UNIFIEDDIFF, OnViewUnifieddiff)
107 ON_COMMAND(ID_VIEW_UNIFIEDDIFFOFHEADREVISIONS, OnViewUnifieddiffofheadrevisions)
109 #if 0
110 ON_COMMAND_EX(ID_VIEW_SHOWALLREVISIONS, OnToggleOption)
111 ON_COMMAND_EX(ID_VIEW_GROUPBRANCHES, OnToggleOption)
112 ON_COMMAND_EX(ID_VIEW_TOPDOWN, OnToggleOption)
113 ON_COMMAND_EX(ID_VIEW_TOPALIGNTREES, OnToggleOption)
114 ON_COMMAND_EX(ID_VIEW_SHOWHEAD, OnToggleOption)
115 ON_COMMAND_EX(ID_VIEW_EXACTCOPYSOURCE, OnToggleOption)
116 ON_COMMAND_EX(ID_VIEW_FOLDTAGS, OnToggleOption)
117 ON_COMMAND_EX(ID_VIEW_REDUCECROSSLINES, OnToggleOption)
118 ON_COMMAND_EX(ID_VIEW_REMOVEDELETEDONES, OnToggleOption)
119 ON_COMMAND_EX(ID_VIEW_SHOWWCREV, OnToggleReloadOption)
120 ON_COMMAND_EX(ID_VIEW_REMOVEUNCHANGEDBRANCHES, OnToggleOption)
121 ON_COMMAND_EX(ID_VIEW_REMOVETAGS, OnToggleOption)
122 ON_COMMAND_EX(ID_VIEW_SHOWWCMODIFICATION, OnToggleReloadOption)
123 ON_COMMAND_EX(ID_VIEW_SHOWDIFFPATHS, OnToggleOption)
124 ON_COMMAND_EX(ID_VIEW_SHOWTREESTRIPES, OnToggleRedrawOption)
125 #endif
126 ON_WM_WINDOWPOSCHANGING()
128 END_MESSAGE_MAP()
130 BOOL CRevisionGraphDlg::InitializeToolbar()
132 // set up the toolbar
133 // add the tool bar to the dialog
134 m_ToolBar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT | CBRS_SIZE_DYNAMIC);
135 m_ToolBar.LoadToolBar(IDR_REVGRAPHBAR);
136 m_ToolBar.ShowWindow(SW_SHOW);
137 m_ToolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY);
139 // toolbars aren't true-color without some tweaking:
141 CImageList cImageList;
142 CBitmap cBitmap;
143 BITMAP bmBitmap;
145 cBitmap.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_REVGRAPHBAR),
146 IMAGE_BITMAP, 0, 0,
147 LR_DEFAULTSIZE|LR_CREATEDIBSECTION));
148 cBitmap.GetBitmap(&bmBitmap);
150 CSize cSize(bmBitmap.bmWidth, bmBitmap.bmHeight);
151 int nNbBtn = cSize.cx/20;
152 RGBTRIPLE * rgb = (RGBTRIPLE*)(bmBitmap.bmBits);
153 COLORREF rgbMask = RGB(rgb[0].rgbtRed, rgb[0].rgbtGreen, rgb[0].rgbtBlue);
155 cImageList.Create(20, cSize.cy, ILC_COLOR32|ILC_MASK, nNbBtn, 0);
156 cImageList.Add(&cBitmap, rgbMask);
157 m_ToolBar.SendMessage(TB_SETIMAGELIST, 0, (LPARAM)cImageList.m_hImageList);
158 cImageList.Detach();
159 cBitmap.Detach();
161 RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
164 #define SNAP_WIDTH 60 //the width of the combo box
165 // set up the ComboBox control as a snap mode select box
166 // First get the index of the placeholders position in the toolbar
167 int zoomComboIndex = 0;
168 while (m_ToolBar.GetItemID(zoomComboIndex) != ID_REVGRAPH_ZOOMCOMBO) zoomComboIndex++;
170 // next convert that button to a separator and get its position
171 m_ToolBar.SetButtonInfo(zoomComboIndex, ID_REVGRAPH_ZOOMCOMBO, TBBS_SEPARATOR,
172 SNAP_WIDTH);
173 RECT rect;
174 m_ToolBar.GetItemRect(zoomComboIndex, &rect);
176 // expand the rectangle to allow the combo box room to drop down
177 rect.top+=3;
178 rect.bottom += 200;
180 // then create the combo box and show it
181 if (!m_ToolBar.m_ZoomCombo.CreateEx(WS_EX_RIGHT, WS_CHILD|WS_VISIBLE|CBS_AUTOHSCROLL|CBS_DROPDOWN,
182 rect, &m_ToolBar, ID_REVGRAPH_ZOOMCOMBO))
184 TRACE(_T(": Failed to create combo-box\n"));
185 return FALSE;
187 m_ToolBar.m_ZoomCombo.ShowWindow(SW_SHOW);
189 // fill the combo box
191 TCHAR* texts[] = { _T("5%")
192 , _T("10%")
193 , _T("20%")
194 , _T("40%")
195 , _T("50%")
196 , _T("75%")
197 , _T("100%")
198 , _T("200%")
199 , NULL};
201 COMBOBOXEXITEM cbei;
202 SecureZeroMemory(&cbei, sizeof cbei);
203 cbei.mask = CBEIF_TEXT;
205 for (TCHAR** text = texts; *text != NULL; ++text)
207 cbei.pszText = *text;
208 m_ToolBar.m_ZoomCombo.InsertItem(&cbei);
211 m_ToolBar.m_ZoomCombo.SetCurSel(1);
213 UpdateOptionAvailability();
215 return TRUE;
218 BOOL CRevisionGraphDlg::OnInitDialog()
220 CResizableStandAloneDialog::OnInitDialog();
221 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
223 EnableToolTips();
225 CString sWindowTitle;
226 GetWindowText(sWindowTitle);
227 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);
230 // set up the status bar
231 m_StatusBar.Create(WS_CHILD|WS_VISIBLE|SBT_OWNERDRAW,
232 CRect(0,0,0,0), this, 1);
233 int strPartDim[2]= {120, -1};
234 m_StatusBar.SetParts(2, strPartDim);
236 if (InitializeToolbar() != TRUE)
237 return FALSE;
239 m_pTaskbarList.Release();
240 if (FAILED(m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList)))
241 m_pTaskbarList = nullptr;
243 // CSyncPointer<CAllRevisionGraphOptions>
244 // options (m_Graph.m_state.GetOptions());
246 // for (size_t i = 0; i < options->count(); ++i)
247 // if ((*options)[i]->CommandID() != 0)
248 // SetOption ((*options)[i]->CommandID());
250 #if 0
251 CMenu * pMenu = GetMenu();
252 if (pMenu)
254 CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseGit\\ShowRevGraphOverview"), FALSE);
255 m_Graph.SetShowOverview ((DWORD)reg != FALSE);
256 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | (DWORD(reg) ? MF_CHECKED : 0));
257 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW);
258 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate | (DWORD(reg) ? TBSTATE_CHECKED : 0));
260 #endif
262 // m_hAccel = LoadAccelerators(AfxGetResourceHandle(),MAKEINTRESOURCE(IDR_ACC_REVISIONGRAPH));
265 CRect graphrect = GetGraphRect();
266 m_Graph.Init(this, &graphrect);
267 m_Graph.SetOwner(this);
268 m_Graph.UpdateWindow();
269 DoZoom (DEFAULT_ZOOM);
271 // begin background operation
272 StartWorkerThread();
274 EnableSaveRestore(_T("RevisionGraphDlg"));
275 // if (GetExplorerHWND())
276 // CenterWindow(CWnd::FromHandle(GetExplorerHWND()));
278 return TRUE; // return TRUE unless you set the focus to a control
281 bool CRevisionGraphDlg::UpdateData()
283 CoInitialize(NULL);
285 if (!m_Graph.FetchRevisionData (m_Graph.m_sPath, GitRev(), NULL, m_pTaskbarList, m_hWnd))
287 // only show the error dialog if we're not in hidden mode
288 //if (m_bVisible)
290 // TGitMessageBox( m_hWnd
291 // , // m_Graph.m_state.GetLastErrorMessage()
292 // , _T("TortoiseGit")
293 // , MB_ICONERROR);
297 #if 0
298 if (m_bFetchLogs)
300 CProgressDlg progress;
301 progress.SetTitle(IDS_REVGRAPH_PROGTITLE);
302 progress.SetCancelMsg(IDS_REVGRAPH_PROGCANCEL);
303 progress.SetTime();
304 progress.SetProgress(0, 100);
305 if (m_pTaskbarList)
307 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
308 m_pTaskbarList->SetProgressValue(m_hWnd, 0, 100);
311 svn_revnum_t pegRev = m_Graph.m_pegRev.IsNumber()
312 ? (svn_revnum_t)m_Graph.m_pegRev
313 : (svn_revnum_t)-1;
315 if (!m_Graph.FetchRevisionData (m_Graph.m_sPath, pegRev, &progress, m_pTaskbarList, m_hWnd))
317 // only show the error dialog if we're not in hidden mode
318 if (m_bVisible)
320 TSVNMessageBox( m_hWnd
321 , m_Graph.m_state.GetLastErrorMessage()
322 , _T("TortoiseGit")
323 , MB_ICONERROR);
327 progress.Stop();
328 if (m_pTaskbarList)
330 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
333 m_bFetchLogs = false; // we've got the logs, no need to fetch them a second time
336 // standard plus user settings
339 if (m_Graph.AnalyzeRevisionData())
341 UpdateStatusBar();
342 UpdateOptionAvailability();
344 #endif
346 CoUninitialize();
347 m_Graph.PostMessage (CRevisionGraphWnd::WM_WORKERTHREADDONE, 0, 0);
349 return true;
352 void CRevisionGraphDlg::OnSize(UINT nType, int cx, int cy)
354 __super::OnSize(nType, cx, cy);
355 CRect rect;
356 GetClientRect(&rect);
357 if (IsWindow(m_ToolBar))
359 RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
361 if (IsWindow(m_StatusBar))
363 CRect statusbarrect;
364 m_StatusBar.GetClientRect(&statusbarrect);
365 statusbarrect.top = rect.bottom - statusbarrect.top + statusbarrect.bottom;
366 m_StatusBar.MoveWindow(&statusbarrect);
368 if (IsWindow(m_Graph))
370 m_Graph.MoveWindow (GetGraphRect());
374 BOOL CRevisionGraphDlg::PreTranslateMessage(MSG* pMsg)
376 #define SCROLL_STEP 20
377 if (pMsg->message == WM_KEYDOWN)
379 int pos = 0;
380 switch (pMsg->wParam)
382 case VK_UP:
383 pos = m_Graph.GetScrollPos(SB_VERT);
384 m_Graph.SetScrollPos(SB_VERT, pos - SCROLL_STEP);
385 m_Graph.Invalidate();
386 break;
387 case VK_DOWN:
388 pos = m_Graph.GetScrollPos(SB_VERT);
389 m_Graph.SetScrollPos(SB_VERT, pos + SCROLL_STEP);
390 m_Graph.Invalidate();
391 break;
392 case VK_LEFT:
393 pos = m_Graph.GetScrollPos(SB_HORZ);
394 m_Graph.SetScrollPos(SB_HORZ, pos - SCROLL_STEP);
395 m_Graph.Invalidate();
396 break;
397 case VK_RIGHT:
398 pos = m_Graph.GetScrollPos(SB_HORZ);
399 m_Graph.SetScrollPos(SB_HORZ, pos + SCROLL_STEP);
400 m_Graph.Invalidate();
401 break;
402 case VK_PRIOR:
403 pos = m_Graph.GetScrollPos(SB_VERT);
404 m_Graph.SetScrollPos(SB_VERT, pos - GetGraphRect().Height() / 2);
405 m_Graph.Invalidate();
406 break;
407 case VK_NEXT:
408 pos = m_Graph.GetScrollPos(SB_VERT);
409 m_Graph.SetScrollPos(SB_VERT, pos + GetGraphRect().Height() / 2);
410 m_Graph.Invalidate();
411 break;
412 case VK_F5:
413 UpdateFullHistory();
414 break;
417 if ((m_hAccel)&&(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST))
419 if (pMsg->wParam == VK_ESCAPE)
420 if (m_Graph.CancelMouseZoom())
421 return TRUE;
422 return TranslateAccelerator(m_hWnd,m_hAccel,pMsg);
424 return __super::PreTranslateMessage(pMsg);
427 void CRevisionGraphDlg::DoZoom (float zoom)
429 m_fZoomFactor = zoom;
430 m_Graph.DoZoom (zoom);
431 UpdateZoomBox();
434 void CRevisionGraphDlg::OnViewZoomin()
436 DoZoom (min (MAX_ZOOM, m_fZoomFactor / ZOOM_STEP));
439 void CRevisionGraphDlg::OnViewZoomout()
441 DoZoom (max (MIN_ZOOM, m_fZoomFactor * ZOOM_STEP));
444 void CRevisionGraphDlg::OnViewZoom100()
446 DoZoom (DEFAULT_ZOOM);
449 void CRevisionGraphDlg::OnViewZoomHeight()
451 CRect graphRect = m_Graph.GetGraphRect();
452 CRect windowRect = m_Graph.GetWindowRect();
454 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
455 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
456 if ((horzfact < vertfact) && (horzfact < MAX_ZOOM))
457 vertfact = (windowRect.Height() - 20.0f)/(4.0f + graphRect.Height());
459 DoZoom (min (MAX_ZOOM, vertfact));
462 void CRevisionGraphDlg::OnViewZoomWidth()
464 // zoom the graph so that it is completely visible in the window
465 CRect graphRect = m_Graph.GetGraphRect();
466 CRect windowRect = m_Graph.GetWindowRect();
468 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
469 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
470 if ((vertfact < horzfact) && (vertfact < MAX_ZOOM))
471 horzfact = (windowRect.Width() - 20.0f)/(4.0f + graphRect.Width());
473 DoZoom (min (MAX_ZOOM, horzfact));
476 void CRevisionGraphDlg::OnViewZoomAll()
478 // zoom the graph so that it is completely visible in the window
479 CRect graphRect = m_Graph.GetGraphRect();
480 CRect windowRect = m_Graph.GetWindowRect();
482 float horzfact = (windowRect.Width() - 4.0f)/(4.0f + graphRect.Width());
483 float vertfact = (windowRect.Height() - 4.0f)/(4.0f + graphRect.Height());
485 DoZoom (min (MAX_ZOOM, min(horzfact, vertfact)));
488 void CRevisionGraphDlg::OnMenuexit()
490 if (!m_Graph.IsUpdateJobRunning())
491 EndDialog(IDOK);
494 void CRevisionGraphDlg::OnMenuhelp()
496 OnHelp();
499 void CRevisionGraphDlg::OnViewCompareheadrevisions()
501 m_Graph.CompareRevs(true);
504 void CRevisionGraphDlg::OnViewComparerevisions()
506 m_Graph.CompareRevs(false);
509 void CRevisionGraphDlg::OnViewUnifieddiff()
511 m_Graph.UnifiedDiffRevs(false);
514 void CRevisionGraphDlg::OnViewUnifieddiffofheadrevisions()
516 m_Graph.UnifiedDiffRevs(true);
519 void CRevisionGraphDlg::UpdateFullHistory()
521 #if 0
522 m_Graph.SetDlgTitle (false);
524 SVN svn;
525 LogCache::CRepositoryInfo& cachedProperties
526 = svn.GetLogCachePool()->GetRepositoryInfo();
527 CString root = m_Graph.m_state.GetRepositoryRoot();
528 CString uuid = m_Graph.m_state.GetRepositoryUUID();
530 cachedProperties.ResetHeadRevision (uuid, root);
532 m_bFetchLogs = true;
533 StartWorkerThread();
534 #endif
537 void CRevisionGraphDlg::SetOption (UINT /*controlID*/)
539 #if 0
540 CMenu * pMenu = GetMenu();
541 if (pMenu == NULL)
542 return;
544 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(controlID);
545 if (tbstate != -1)
547 if (m_Graph.m_state.GetOptions()->IsSelected (controlID))
549 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_CHECKED);
550 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate | TBSTATE_CHECKED);
552 else
554 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_UNCHECKED);
555 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate & (~TBSTATE_CHECKED));
558 #endif
561 BOOL CRevisionGraphDlg::ToggleOption (UINT controlID)
563 // check request for validity
565 if (m_Graph.IsUpdateJobRunning())
567 // restore previous state
569 int state = m_ToolBar.GetToolBarCtrl().GetState(controlID);
570 if (state & TBSTATE_CHECKED)
571 state &= ~TBSTATE_CHECKED;
572 else
573 state |= TBSTATE_CHECKED;
574 m_ToolBar.GetToolBarCtrl().SetState (controlID, state);
576 return FALSE;
579 CMenu * pMenu = GetMenu();
580 if (pMenu == NULL)
581 return FALSE;
583 // actually toggle the option
585 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(controlID);
586 UINT state = pMenu->GetMenuState(controlID, MF_BYCOMMAND);
587 if (state & MF_CHECKED)
589 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_UNCHECKED);
590 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate & (~TBSTATE_CHECKED));
592 else
594 pMenu->CheckMenuItem(controlID, MF_BYCOMMAND | MF_CHECKED);
595 m_ToolBar.GetToolBarCtrl().SetState(controlID, tbstate | TBSTATE_CHECKED);
598 // CSyncPointer<CAllRevisionGraphOptions>
599 // options (m_Graph.m_state.GetOptions());
600 // if (((state & MF_CHECKED) != 0) == options->IsSelected (controlID))
601 // options->ToggleSelection (controlID);
603 return TRUE;
606 BOOL CRevisionGraphDlg::OnToggleOption (UINT controlID)
608 if (!ToggleOption (controlID))
609 return FALSE;
611 // re-process the data
613 StartWorkerThread();
615 return TRUE;
618 BOOL CRevisionGraphDlg::OnToggleReloadOption (UINT controlID)
620 #if 0
621 if (!m_Graph.m_state.GetFetchedWCState())
622 m_bFetchLogs = true;
623 #endif
624 return OnToggleOption (controlID);
627 BOOL CRevisionGraphDlg::OnToggleRedrawOption (UINT controlID)
629 if (!ToggleOption (controlID))
630 return FALSE;
632 m_Graph.BuildPreview();
633 Invalidate();
635 return TRUE;
638 void CRevisionGraphDlg::StartWorkerThread()
640 if (!m_Graph.IsUpdateJobRunning())
641 m_Graph.updateJob.reset (new CFuture<bool>(this, &CRevisionGraphDlg::UpdateData));
644 void CRevisionGraphDlg::OnCancel()
646 if (!m_Graph.IsUpdateJobRunning())
647 __super::OnCancel();
650 void CRevisionGraphDlg::OnOK()
652 OnChangeZoom();
655 void CRevisionGraphDlg::OnFileSavegraphas()
657 CString tempfile;
658 int filterindex = 0;
659 if (CAppUtils::FileOpenSave(tempfile, &filterindex, IDS_REVGRAPH_SAVEPIC, IDS_PICTUREFILEFILTER, false, m_hWnd))
661 // if the user doesn't specify a file extension, default to
662 // svg and add that extension to the filename. But only if the
663 // user chose the 'pictures' filter. The filename isn't changed
664 // if the 'All files' filter was chosen.
665 CString extension;
666 int dotPos = tempfile.ReverseFind('.');
667 int slashPos = tempfile.ReverseFind('\\');
668 if (dotPos > slashPos)
669 extension = tempfile.Mid(dotPos);
670 if ((filterindex == 1)&&(extension.IsEmpty()))
672 extension = _T(".svg");
673 tempfile += extension;
675 m_Graph.SaveGraphAs(tempfile);
679 CRect CRevisionGraphDlg::GetGraphRect()
681 CRect rect;
682 GetClientRect(&rect);
684 CRect statusbarrect;
685 m_StatusBar.GetClientRect(&statusbarrect);
686 rect.bottom -= statusbarrect.Height();
688 CRect toolbarrect;
689 m_ToolBar.GetClientRect(&toolbarrect);
690 rect.top += toolbarrect.Height();
692 return rect;
695 void CRevisionGraphDlg::UpdateStatusBar()
697 // CString sFormat;
698 // sFormat.Format(IDS_REVGRAPH_STATUSBARURL, (LPCTSTR)m_Graph.m_sPath);
699 // m_StatusBar.SetText(sFormat,1,0);
700 // sFormat.Format(IDS_REVGRAPH_STATUSBARNUMNODES, m_Graph.m_state.GetNodeCount());
701 // m_StatusBar.SetText(sFormat,0,0);
704 void CRevisionGraphDlg::OnChangeZoom()
706 if (!IsWindow(m_Graph.GetSafeHwnd()))
707 return;
708 CString strText;
709 CString strItem;
710 CComboBoxEx* pCBox = (CComboBoxEx*)m_ToolBar.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO);
711 pCBox->GetWindowText(strItem);
712 if (strItem.IsEmpty())
713 return;
715 DoZoom ((float)(_tstof(strItem)/100.0));
718 void CRevisionGraphDlg::UpdateZoomBox()
720 CString strText;
721 CString strItem;
722 CComboBoxEx* pCBox = (CComboBoxEx*)m_ToolBar.GetDlgItem(ID_REVGRAPH_ZOOMCOMBO);
723 pCBox->GetWindowText(strItem);
724 strText.Format(_T("%.0f%%"), (m_fZoomFactor*100.0));
725 if (strText.Compare(strItem) != 0)
726 pCBox->SetWindowText(strText);
729 BOOL CRevisionGraphDlg::OnToolTipNotify(UINT /*id*/, NMHDR *pNMHDR, LRESULT *pResult)
731 // need to handle both ANSI and UNICODE versions of the message
732 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
733 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
734 CString strTipText;
736 UINT_PTR nID = pNMHDR->idFrom;
738 if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
739 pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
741 // idFrom is actually the HWND of the tool
742 nID = ::GetDlgCtrlID((HWND)nID);
745 if (nID != 0) // will be zero on a separator
747 strTipText.LoadString (static_cast<UINT>(nID));
750 *pResult = 0;
751 if (strTipText.IsEmpty())
752 return TRUE;
754 if (strTipText.GetLength() >= MAX_TT_LENGTH)
755 strTipText = strTipText.Left(MAX_TT_LENGTH);
757 if (pNMHDR->code == TTN_NEEDTEXTA)
759 ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 600);
760 pTTTA->lpszText = m_szTip;
761 WideCharToMultiByte(CP_ACP, 0, strTipText, -1, m_szTip, strTipText.GetLength()+1, 0, 0);
763 else
765 ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 600);
766 lstrcpyn(m_wszTip, strTipText, strTipText.GetLength()+1);
767 pTTTW->lpszText = m_wszTip;
769 // bring the tooltip window above other pop up windows
770 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
771 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
772 return TRUE; // message was handled
775 void CRevisionGraphDlg::OnViewFilter()
778 /* CSyncPointer<CAllRevisionGraphOptions>
779 options (m_Graph.m_state.GetOptions());
781 CRevisionInRange* revisionRange = options->GetOption<CRevisionInRange>();
782 svn_revnum_t head = m_Graph.m_state.GetHeadRevision();
783 svn_revnum_t lowerLimit = revisionRange->GetLowerLimit();
784 svn_revnum_t upperLimit = revisionRange->GetUpperLimit();
786 CRemovePathsBySubString* pathFilter = options->GetOption<CRemovePathsBySubString>();
788 CRevGraphFilterDlg dlg;
790 dlg.m_bCurrentBranch = this->m_Graph.m_bCurrentBranch;
791 dlg.SetRevisionRange(m_Graph.m_FromRev, m_Graph.m_ToRev);
793 if (dlg.DoModal()==IDOK)
796 // user pressed OK to dismiss the dialog, which means
797 // we have to accept the new filter settings and apply them
799 dlg.GetRevisionRange(m_Graph.m_FromRev, m_Graph.m_ToRev);
800 // update menu & toolbar
802 this->m_Graph.m_bCurrentBranch = dlg.m_bCurrentBranch;
804 CMenu * pMenu = GetMenu();
805 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_FILTER);
806 if (m_Graph.m_bCurrentBranch || !m_Graph.m_FromRev.IsEmpty() || !m_Graph.m_ToRev.IsEmpty())
808 if (pMenu != NULL)
809 pMenu->CheckMenuItem(ID_VIEW_FILTER, MF_BYCOMMAND | MF_CHECKED);
810 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_FILTER, tbstate | TBSTATE_CHECKED);
812 else
814 if (pMenu != NULL)
815 pMenu->CheckMenuItem(ID_VIEW_FILTER, MF_BYCOMMAND | MF_UNCHECKED);
816 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_FILTER, tbstate & (~TBSTATE_CHECKED));
819 // re-run query
821 StartWorkerThread();
827 void CRevisionGraphDlg::OnViewShowoverview()
829 CMenu * pMenu = GetMenu();
830 if (pMenu == NULL)
831 return;
832 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(ID_VIEW_SHOWOVERVIEW);
833 UINT state = pMenu->GetMenuState(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND);
834 if (state & MF_CHECKED)
836 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | MF_UNCHECKED);
837 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate & (~TBSTATE_CHECKED));
838 m_Graph.SetShowOverview (false);
840 else
842 pMenu->CheckMenuItem(ID_VIEW_SHOWOVERVIEW, MF_BYCOMMAND | MF_CHECKED);
843 m_ToolBar.GetToolBarCtrl().SetState(ID_VIEW_SHOWOVERVIEW, tbstate | TBSTATE_CHECKED);
844 m_Graph.SetShowOverview (true);
847 CRegDWORD reg = CRegDWORD(_T("Software\\TortoiseGit\\ShowRevGraphOverview"), FALSE);
848 reg = m_Graph.GetShowOverview();
849 m_Graph.Invalidate(FALSE);
852 void CRevisionGraphDlg::UpdateOptionAvailability (UINT id, bool available)
854 CMenu * pMenu = GetMenu();
855 if (pMenu == NULL)
856 return;
858 pMenu->EnableMenuItem (id, available ? MF_ENABLED : MF_GRAYED);
860 int tbstate = m_ToolBar.GetToolBarCtrl().GetState(id);
861 int newTbstate = available
862 ? tbstate | TBSTATE_ENABLED
863 : tbstate & ~TBSTATE_ENABLED;
865 if (tbstate != newTbstate)
866 m_ToolBar.GetToolBarCtrl().SetState(id, newTbstate);
869 void CRevisionGraphDlg::UpdateOptionAvailability()
871 #if 0
872 bool multipleTrees = m_Graph.m_state.GetTreeCount() > 1;
873 bool isWCPath = !CTGitPath (m_Graph.m_sPath).IsUrl();
875 UpdateOptionAvailability (ID_VIEW_TOPALIGNTREES, multipleTrees);
876 UpdateOptionAvailability (ID_VIEW_SHOWTREESTRIPES, multipleTrees);
877 UpdateOptionAvailability (ID_VIEW_SHOWWCREV, isWCPath);
878 UpdateOptionAvailability (ID_VIEW_SHOWWCMODIFICATION, isWCPath);
879 #endif
884 void CRevisionGraphDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
886 if (!m_bVisible)
888 lpwndpos->flags &= ~SWP_SHOWWINDOW;
890 CResizableStandAloneDialog::OnWindowPosChanging(lpwndpos);