Don't import ogdf namespace
[TortoiseGit.git] / src / TortoiseProc / RevisionGraph / RevisionGraphWnd.h
blob3fbbf7c8ffed6b5f825a22545dd89ddb91fb6c1f
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2011 - TortoiseSVN
4 // Copyright (C) 2012-2018 - 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 #pragma once
21 //#include "RevisionGraph/RevisionGraphState.h"
22 #include "Future.h"
23 #include "ProgressDlg.h"
24 #include "Colors.h"
25 //#include "SVNDiff.h"
26 #include "AppUtils.h"
27 #include "SVG.h"
28 #include "LogDlgHelper.h"
29 #include "Graphviz.h"
31 #pragma warning(push)
32 #pragma warning(disable: 4100) // unreferenced formal parameter
33 #include <ogdf/layered/SugiyamaLayout.h>
34 #include <ogdf/layered/OptimalRanking.h>
35 #include <ogdf/layered/MedianHeuristic.h>
36 #include <ogdf/layered/OptimalHierarchyLayout.h>
37 #include <ogdf/layered/FastHierarchyLayout.h>
38 #pragma warning(pop)
40 typedef void CVisibleGraphNode;
41 typedef int index_t;
43 using namespace Gdiplus;
44 using namespace async;
46 enum
48 REVGRAPH_PREVIEW_WIDTH = 100,
49 REVGRAPH_PREVIEW_HEIGHT = 200,
51 // don't draw pre-views with more than that number of nodes
53 REVGRAPH_PREVIEW_MAX_NODES = 10000
56 // don't try to draw nodes smaller than that:
58 #define REVGRAPH_MIN_NODE_HIGHT (0.5f)
60 enum
62 // size of the node marker
64 MARKER_SIZE = 11,
66 // radius of the rounded / slanted box corners of the expand / collapse / split / join square gylphs
68 CORNER_SIZE = 12,
70 // font sizes
72 DEFAULT_ZOOM_FONT = 9, // default font size
73 SMALL_ZOOM_FONT = 11, // rel. larger font size for small zoom factors
74 SMALL_ZOOM_FONT_THRESHOLD = 6, // max. "small zoom" font size after scaling
76 // size of the expand / collapse / split / join square gylphs
78 GLYPH_BITMAP_SIZE = 16,
79 GLYPH_SIZE = 12,
81 // glyph display delay definitions
83 GLYPH_HOVER_EVENT = 10, // timer ID for the glyph display delay
84 GLYPH_HOVER_DELAY = 250, // delay until the glyphs are shown [ms]
87 // zoom control
89 const float MIN_ZOOM = 0.01f;
90 const float MAX_ZOOM = 2.0f;
91 const float DEFAULT_ZOOM = 1.0f;
92 const float ZOOM_STEP = 0.9f;
94 // don't draw shadows below this zoom level
96 const float SHADOW_ZOOM_THRESHOLD = 0.2f;
98 /**
99 * \ingroup TortoiseProc
100 * node shapes for the revision graph
102 enum NodeShape
104 TSVNRectangle,
105 TSVNRoundRect,
106 TSVNOctangle,
107 TSVNEllipse
110 #define MAXFONTS 4
111 #define MAX_TT_LENGTH 60000
112 #define MAX_TT_LENGTH_DEFAULT 1000
114 // forward declarations
116 class CRevisionGraphDlg;
118 // simplify usage of classes from other namespaces
120 //using async::IJob;
121 //using async::CFuture;
124 * \ingroup TortoiseProc
125 * Window class showing a revision graph.
127 * The analyzation of the log data is done in the child class CRevisionGraph.
128 * Here, we handle the window notifications.
130 class CRevisionGraphWnd : public CWnd //, public CRevisionGraph
132 public:
133 CRevisionGraphWnd(); // standard constructor
134 virtual ~CRevisionGraphWnd();
135 enum
137 IDD = IDD_REVISIONGRAPH,
138 WM_WORKERTHREADDONE = WM_APP +1
142 CString m_sPath;
143 GitRev m_pegRev;
145 CLogCache m_LogCache;
146 CLogDataVector m_logEntries;
147 MAP_HASH_NAME m_HashMap;
148 CString m_CurrentBranch;
149 CGitHash m_HeadHash;
151 BOOL m_bCurrentBranch;
152 BOOL m_bLocalBranches;
153 CString m_FromRev;
154 CString m_ToRev;
156 void ReloadHashMap()
158 m_HashMap.clear();
159 if (g_Git.GetMapHashToFriendName(m_HashMap))
160 MessageBox(g_Git.GetGitLastErr(L"Could not get all refs."), L"TortoiseGit", MB_ICONERROR);
161 m_CurrentBranch=g_Git.GetCurrentBranch();
162 if (g_Git.GetHash(m_HeadHash, L"HEAD"))
163 MessageBox(g_Git.GetGitLastErr(L"Could not get HEAD hash."), L"TortoiseGit", MB_ICONERROR);
166 std::unique_ptr<CFuture<bool>> updateJob;
167 // CRevisionGraphState m_state;
169 void InitView();
170 void Init(CWnd * pParent, LPRECT rect);
171 void SaveGraphAs(CString sSavePath);
173 bool FetchRevisionData ( const CString& path
174 , CProgressDlg* progress
175 , ITaskbarList3* pTaskbarList
176 , HWND hWnd);
177 bool AnalyzeRevisionData();
178 bool IsUpdateJobRunning() const;
180 bool GetShowOverview() const;
181 void SetShowOverview (bool value);
183 void GetSelected (const CVisibleGraphNode* node, bool head, CTGitPath& path, GitRev& rev, GitRev& peg);
184 void CompareRevs(const CString& revTo);
185 void UnifiedDiffRevs(bool bHead);
187 CRect GetGraphRect();
188 CRect GetClientRect();
189 CRect GetWindowRect();
190 CRect GetViewRect();
191 void DoZoom (float nZoomFactor, bool updateScrollbars = true);
192 bool CancelMouseZoom();
194 void SetDlgTitle (bool offline);
196 void BuildPreview();
198 protected:
199 ULONGLONG m_ullTicks;
200 CRect m_OverviewPosRect;
201 CRect m_OverviewRect;
203 bool m_bShowOverview;
205 CRevisionGraphDlg *m_parent;
207 ogdf::node m_HeadNode;
208 ogdf::node m_SelectedEntry1;
209 ogdf::node m_SelectedEntry2;
210 LOGFONT m_lfBaseFont;
211 CFont * m_apFonts[MAXFONTS];
212 int m_nFontSize;
213 CToolTipCtrl * m_pDlgTip;
214 char m_szTip[MAX_TT_LENGTH+1];
215 wchar_t m_wszTip[MAX_TT_LENGTH+1];
216 CString m_sTitle;
218 float m_fZoomFactor;
219 CColors m_Colors;
220 bool m_bTweakTrunkColors;
221 bool m_bTweakTagsColors;
222 bool m_bIsCanvasMove;
223 CPoint m_ptMoveCanvas;
224 CPoint m_ptRubberEnd;
226 CBitmap m_Preview;
227 int m_previewWidth;
228 int m_previewHeight;
229 float m_previewZoom;
231 // index_t m_hoverIndex; // node the cursor currently hovers over
232 ogdf::node m_hoverIndex;
233 DWORD m_hoverGlyphs; // the glyphs shown for \ref m_hoverIndex
234 mutable ogdf::node m_tooltipIndex; // the node index we fetched the tooltip for
235 bool m_showHoverGlyphs; // if true, show the glyphs we currently hover over
236 // (will be activated only after some delay)
238 CString GetFriendRefName(ogdf::node);
239 STRING_VECTOR GetFriendRefNames(ogdf::node, const CString* exclude = nullptr, CGit::REF_TYPE* onlyRefType = nullptr);
241 ogdf::Graph m_Graph;
242 ogdf::GraphAttributes m_GraphAttr;
243 ogdf::SugiyamaLayout m_SugiyamLayout;
245 CRect m_GraphRect;
247 int GetLeftRightMargin() {return 20;};
248 int GetTopBottomMargin() {return 5;};
249 virtual void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support
250 afx_msg void OnPaint();
251 virtual ULONG GetGestureStatus(CPoint ptTouch) override;
252 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
253 afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
254 afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
255 afx_msg void OnSize(UINT nType, int cx, int cy);
256 afx_msg INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
257 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
258 afx_msg BOOL OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
259 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
260 afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
261 afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
262 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
263 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
264 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
265 afx_msg void OnTimer(UINT_PTR nIDEvent);
266 afx_msg void OnCaptureChanged(CWnd *pWnd);
267 afx_msg LRESULT OnWorkerThreadDone(WPARAM, LPARAM);
269 DECLARE_MESSAGE_MAP()
270 private:
272 double m_ArrowCos;
273 double m_ArrowSin;
274 double m_ArrowSize;
276 enum MarkerPosition
278 mpLeft = 0,
279 mpRight = 1,
282 enum GlyphType
284 NoGlyph = -1,
285 ExpandGlyph = 0, // "+"
286 CollapseGlyph = 1, // "-"
287 SplitGlyph = 2, // "x"
288 JoinGlyph = 3, // "o"
291 enum GlyphPosition
293 Above = 0,
294 Right = 4,
295 Below = 8,
298 class GraphicsDevice
300 public:
301 GraphicsDevice()
302 : pDC(nullptr)
303 , graphics(nullptr)
304 , pSVG(nullptr)
305 , pGraphviz(nullptr)
308 ~GraphicsDevice() {}
309 public:
310 CDC * pDC;
311 Graphics * graphics;
312 SVG * pSVG;
313 Graphviz * pGraphviz;
316 class SVGGrouper
318 public:
319 SVGGrouper(SVG * pSVG)
321 m_pSVG = pSVG;
322 if (m_pSVG)
323 m_pSVG->StartGroup();
325 ~SVGGrouper()
327 if (m_pSVG)
328 m_pSVG->EndGroup();
330 private:
331 SVGGrouper() {}
333 SVG * m_pSVG;
336 bool UpdateSelectedEntry (ogdf::node clickedentry);
337 void AppendMenu (CMenu& popup, UINT title, UINT command, UINT flags = MF_ENABLED);
338 void AppendMenu(CMenu& popup, CString title, UINT command, CString* extra = nullptr, CMenu* submenu = nullptr);
339 void AddGraphOps (CMenu& popup, const CVisibleGraphNode * node);
340 CString GetSelectedURL() const;
341 CString GetWCURL() const;
342 void DoShowLog();
343 void DoCheckForModification();
344 void DoMergeTo();
345 void DoUpdate();
346 void DoSwitch(CString rev);
347 void DoSwitchToHead();
348 void DoBrowseRepo();
349 void ResetNodeFlags (DWORD flags);
350 void ToggleNodeFlag (const CVisibleGraphNode *node, DWORD flag);
351 void DoCopyRefs();
353 void SetScrollbar (int bar, int newPos, int clientMax, int graphMax);
354 void SetScrollbars (int nVert = -1, int nHorz = -1);
355 CFont* GetFont(BOOL bItalic = FALSE, BOOL bBold = FALSE);
357 CSize UsableTooltipRect();
358 CString DisplayableText (const CString& wholeText, const CSize& tooltipSize);
359 CString TooltipText (ogdf::node index);
361 CPoint GetLogCoordinates (CPoint point) const;
362 ogdf::node GetHitNode (CPoint point, CSize border = CSize (0, 0)) const;
363 DWORD GetHoverGlyphs (CPoint point) const;
364 PointF cutPoint(ogdf::node v,double lw,PointF ps, PointF pt);
366 // const CRevisionGraphState::SVisibleGlyph* GetHitGlyph (CPoint point) const;
368 void ClearVisibleGlyphs (const CRect& rect);
370 typedef PointF TCutRectangle[8];
371 void CutawayPoints (const RectF& rect, float cutLen, TCutRectangle& result);
372 enum
374 ROUND_UP = 0x1,
375 ROUND_DOWN = 0x2,
376 ROUND_BOTH = 0x3,
378 void DrawRoundedRect (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect, int mask=ROUND_BOTH);
379 void DrawOctangle (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect);
380 void DrawShape (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect, NodeShape shape);
381 void DrawShadow(GraphicsDevice& graphics, const RectF& rect,
382 Color shadowColor, NodeShape shape);
383 RectF TransformRectToScreen (const CRect& rect, const CSize& offset) const;
384 RectF GetNodeRect (const ogdf::node& v, const CSize& offset) const;
385 // RectF GetBranchCover (const ILayoutNodeList* nodeList, index_t nodeIndex, bool upward, const CSize& offset);
387 void DrawSquare (GraphicsDevice& graphics, const PointF& leftTop,
388 const Color& lightColor, const Color& darkColor, const Color& penColor);
389 void DrawGlyph (GraphicsDevice& graphics, Image* glyphs, const PointF& leftTop,
390 GlyphType glyph, GlyphPosition position);
391 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const PointF& center,
392 GlyphType glyph1, GlyphType glyph2, GlyphPosition position, DWORD state1, DWORD state2, bool showAll);
393 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const RectF& nodeRect,
394 DWORD state, DWORD allowed, bool upsideDown);
395 void DrawMarker ( GraphicsDevice& graphics, const RectF& noderect
396 , MarkerPosition position, int relPosition, const Color& penColor, int num);
397 // void IndicateGlyphDirection ( GraphicsDevice& graphics, const ILayoutNodeList* nodeList
398 // , const ILayoutNodeList::SNode& node, const RectF& nodeRect
399 // , DWORD glyphs, bool upsideDown, const CSize& offset);
401 void DrawStripes (GraphicsDevice& graphics, const CSize& offset);
403 void DrawShadows (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
404 void DrawConnections (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
405 void DrawTexts (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
406 void DrawCurrentNodeGlyphs (GraphicsDevice& graphics, Image* glyphs, const CSize& offset);
407 void DrawGraph(GraphicsDevice& graphics, const CRect& rect, int nVScrollPos, int nHScrollPos, bool bDirectDraw);
409 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
410 void SetNodeRect(GraphicsDevice& graphics, ogdf::node *pnode, CGitHash rev, int mode = 0);