Can dynamically set show/hide checkboxes in GitStatusListCtrl
[TortoiseGit.git] / src / TortoiseProc / RevisionGraph / RevisionGraphWnd.h
blobe3145814ffca19a2dd3a5b4c2bda48e5499e6cd2
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2011 - TortoiseSVN
4 // Copyright (C) 2012-2013 - 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 #pragma warning(push)
23 #pragma warning(disable: 4481) // nonstandard extension used: override specifier 'override'
24 #include "Future.h"
25 #pragma warning(pop)
26 #include "ProgressDlg.h"
27 #include "Colors.h"
28 //#include "SVNDiff.h"
29 #include "AppUtils.h"
30 #include "SVG.h"
31 #include "LogDlgHelper.h"
32 #include "Graphviz.h"
34 #pragma warning(push)
35 #pragma warning(disable: 4100) // unreferenced formal parameter
36 #include <ogdf/layered/SugiyamaLayout.h>
37 #include <ogdf/layered/OptimalRanking.h>
38 #include <ogdf/layered/MedianHeuristic.h>
39 #include <ogdf/layered/OptimalHierarchyLayout.h>
40 #include <ogdf/layered/FastHierarchyLayout.h>
41 #pragma warning(pop)
43 typedef void CVisibleGraphNode;
44 typedef int index_t;
46 using namespace Gdiplus;
47 using namespace async;
49 enum
51 REVGRAPH_PREVIEW_WIDTH = 100,
52 REVGRAPH_PREVIEW_HEIGHT = 200,
54 // don't draw pre-views with more than that number of nodes
56 REVGRAPH_PREVIEW_MAX_NODES = 10000
59 // don't try to draw nodes smaller than that:
61 #define REVGRAPH_MIN_NODE_HIGHT (0.5f)
63 enum
65 // size of the node marker
67 MARKER_SIZE = 11,
69 // radius of the rounded / slanted box corners of the expand / collapse / split / join square gylphs
71 CORNER_SIZE = 12,
73 // font sizes
75 DEFAULT_ZOOM_FONT = 9, // default font size
76 SMALL_ZOOM_FONT = 11, // rel. larger font size for small zoom factors
77 SMALL_ZOOM_FONT_THRESHOLD = 6, // max. "small zoom" font size after scaling
79 // size of the expand / collapse / split / join square gylphs
81 GLYPH_BITMAP_SIZE = 16,
82 GLYPH_SIZE = 12,
84 // glyph display delay definitions
86 GLYPH_HOVER_EVENT = 10, // timer ID for the glyph display delay
87 GLYPH_HOVER_DELAY = 250, // delay until the glyphs are shown [ms]
90 // zoom control
92 const float MIN_ZOOM = 0.01f;
93 const float MAX_ZOOM = 2.0f;
94 const float DEFAULT_ZOOM = 1.0f;
95 const float ZOOM_STEP = 0.9f;
97 // don't draw shadows below this zoom level
99 const float SHADOW_ZOOM_THRESHOLD = 0.2f;
102 * \ingroup TortoiseProc
103 * node shapes for the revision graph
105 enum NodeShape
107 TSVNRectangle,
108 TSVNRoundRect,
109 TSVNOctangle,
110 TSVNEllipse
113 #define MAXFONTS 4
114 #define MAX_TT_LENGTH 60000
115 #define MAX_TT_LENGTH_DEFAULT 1000
117 // forward declarations
119 class CRevisionGraphDlg;
121 // simplify usage of classes from other namespaces
123 //using async::IJob;
124 //using async::CFuture;
127 * \ingroup TortoiseProc
128 * Window class showing a revision graph.
130 * The analyzation of the log data is done in the child class CRevisionGraph.
131 * Here, we handle the window notifications.
133 class CRevisionGraphWnd : public CWnd //, public CRevisionGraph
135 public:
136 CRevisionGraphWnd(); // standard constructor
137 virtual ~CRevisionGraphWnd();
138 enum
140 IDD = IDD_REVISIONGRAPH,
141 WM_WORKERTHREADDONE = WM_APP +1
145 CString m_sPath;
146 GitRev m_pegRev;
148 CLogCache m_LogCache;
149 CLogDataVector m_logEntries;
150 MAP_HASH_NAME m_HashMap;
151 CString m_CurrentBranch;
152 CGitHash m_HeadHash;
154 BOOL m_bCurrentBranch;
155 CString m_FromRev;
156 CString m_ToRev;
158 void ReloadHashMap()
160 m_HashMap.clear();
161 if (g_Git.GetMapHashToFriendName(m_HashMap))
162 MessageBox(g_Git.GetGitLastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
163 m_CurrentBranch=g_Git.GetCurrentBranch();
164 if (g_Git.GetHash(m_HeadHash, _T("HEAD")))
165 MessageBox(g_Git.GetGitLastErr(_T("Could not get HEAD hash.")), _T("TortoiseGit"), MB_ICONERROR);
168 std::auto_ptr<CFuture<bool>> updateJob;
169 // CRevisionGraphState m_state;
171 void InitView();
172 void Init(CWnd * pParent, LPRECT rect);
173 void SaveGraphAs(CString sSavePath);
175 bool FetchRevisionData ( const CString& path
176 , GitRev pegRevision
177 , CProgressDlg* progress
178 , ITaskbarList3* pTaskbarList
179 , HWND hWnd);
180 bool AnalyzeRevisionData();
181 bool IsUpdateJobRunning() const;
183 bool GetShowOverview() const;
184 void SetShowOverview (bool value);
186 void GetSelected (const CVisibleGraphNode* node, bool head, CTGitPath& path, GitRev& rev, GitRev& peg);
187 void CompareRevs(bool bHead);
188 void UnifiedDiffRevs(bool bHead);
190 CRect GetGraphRect();
191 CRect GetClientRect();
192 CRect GetWindowRect();
193 CRect GetViewRect();
194 void DoZoom (float nZoomFactor, bool updateScrollbars = true);
195 bool CancelMouseZoom();
197 void SetDlgTitle (bool offline);
199 void BuildPreview();
201 protected:
202 DWORD m_dwTicks;
203 CRect m_OverviewPosRect;
204 CRect m_OverviewRect;
206 bool m_bShowOverview;
208 CRevisionGraphDlg *m_parent;
210 ogdf::node m_SelectedEntry1;
211 ogdf::node m_SelectedEntry2;
212 LOGFONT m_lfBaseFont;
213 CFont * m_apFonts[MAXFONTS];
214 int m_nFontSize;
215 CToolTipCtrl * m_pDlgTip;
216 char m_szTip[MAX_TT_LENGTH+1];
217 wchar_t m_wszTip[MAX_TT_LENGTH+1];
218 CString m_sTitle;
220 float m_fZoomFactor;
221 CColors m_Colors;
222 bool m_bTweakTrunkColors;
223 bool m_bTweakTagsColors;
224 bool m_bIsCanvasMove;
225 CPoint m_ptMoveCanvas;
226 CPoint m_ptRubberEnd;
228 CBitmap m_Preview;
229 int m_previewWidth;
230 int m_previewHeight;
231 float m_previewZoom;
233 // index_t m_hoverIndex; // node the cursor currently hovers over
234 ogdf::node m_hoverIndex;
235 DWORD m_hoverGlyphs; // the glyphs shown for \ref m_hoverIndex
236 mutable ogdf::node m_tooltipIndex; // the node index we fetched the tooltip for
237 bool m_showHoverGlyphs; // if true, show the glyphs we currently hover over
238 // (will be activated only after some delay)
240 CString GetFriendRefName(ogdf::node);
242 ogdf::Graph m_Graph;
243 ogdf::GraphAttributes m_GraphAttr;
244 ogdf::SugiyamaLayout m_SugiyamLayout;
246 CRect m_GraphRect;
248 int GetLeftRightMargin() {return 20;};
249 int GetTopBottomMargin() {return 5;};
250 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
251 afx_msg void OnPaint();
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(NULL)
303 , graphics(NULL)
304 , pSVG(NULL)
305 , pGraphviz(NULL)
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 AddGitOps (CMenu& popup);
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();
347 void DoSwitchToHead();
348 void DoBrowseRepo();
349 void ResetNodeFlags (DWORD flags);
350 void ToggleNodeFlag (const CVisibleGraphNode *node, DWORD flag);
351 void DoCopyUrl();
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 void DrawNode(GraphicsDevice& graphics, const RectF& rect,
384 Color contour, Color overlayColor,
385 const CVisibleGraphNode *node, NodeShape shape);
386 RectF TransformRectToScreen (const CRect& rect, const CSize& offset) const;
387 RectF GetNodeRect (const ogdf::node& v, const CSize& offset) const;
388 // RectF GetBranchCover (const ILayoutNodeList* nodeList, index_t nodeIndex, bool upward, const CSize& offset);
390 void DrawSquare (GraphicsDevice& graphics, const PointF& leftTop,
391 const Color& lightColor, const Color& darkColor, const Color& penColor);
392 void DrawGlyph (GraphicsDevice& graphics, Image* glyphs, const PointF& leftTop,
393 GlyphType glyph, GlyphPosition position);
394 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const PointF& center,
395 GlyphType glyph1, GlyphType glyph2, GlyphPosition position, DWORD state1, DWORD state2, bool showAll);
396 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const RectF& nodeRect,
397 DWORD state, DWORD allowed, bool upsideDown);
398 void DrawMarker ( GraphicsDevice& graphics, const RectF& noderect
399 , MarkerPosition position, int relPosition, const Color& penColor, int num);
400 // void IndicateGlyphDirection ( GraphicsDevice& graphics, const ILayoutNodeList* nodeList
401 // , const ILayoutNodeList::SNode& node, const RectF& nodeRect
402 // , DWORD glyphs, bool upsideDown, const CSize& offset);
404 void DrawStripes (GraphicsDevice& graphics, const CSize& offset);
406 void DrawShadows (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
407 void DrawNodes (GraphicsDevice& graphics, Image* glyphs, const CRect& logRect, const CSize& offset);
408 void DrawConnections (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
409 void DrawTexts (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
410 void DrawCurrentNodeGlyphs (GraphicsDevice& graphics, Image* glyphs, const CSize& offset);
411 void DrawGraph(GraphicsDevice& graphics, const CRect& rect, int nVScrollPos, int nHScrollPos, bool bDirectDraw);
413 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
414 void DrawRubberBand();
415 void SetNodeRect(GraphicsDevice& graphics, ogdf::node *pnode, CGitHash rev, int mode = 0);