Revision Graph: Add filter to walk from Only Local Branches
[TortoiseGit.git] / src / TortoiseProc / RevisionGraph / RevisionGraphWnd.h
blob62b67a263d5adaf2d992d6de6637c5306f52da7d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2011 - TortoiseSVN
4 // Copyright (C) 2012-2014 - 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 BOOL m_bLocalBranches;
156 CString m_FromRev;
157 CString m_ToRev;
159 void ReloadHashMap()
161 m_HashMap.clear();
162 if (g_Git.GetMapHashToFriendName(m_HashMap))
163 MessageBox(g_Git.GetGitLastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
164 m_CurrentBranch=g_Git.GetCurrentBranch();
165 if (g_Git.GetHash(m_HeadHash, _T("HEAD")))
166 MessageBox(g_Git.GetGitLastErr(_T("Could not get HEAD hash.")), _T("TortoiseGit"), MB_ICONERROR);
169 std::auto_ptr<CFuture<bool>> updateJob;
170 // CRevisionGraphState m_state;
172 void InitView();
173 void Init(CWnd * pParent, LPRECT rect);
174 void SaveGraphAs(CString sSavePath);
176 bool FetchRevisionData ( const CString& path
177 , GitRev pegRevision
178 , CProgressDlg* progress
179 , ITaskbarList3* pTaskbarList
180 , HWND hWnd);
181 bool AnalyzeRevisionData();
182 bool IsUpdateJobRunning() const;
184 bool GetShowOverview() const;
185 void SetShowOverview (bool value);
187 void GetSelected (const CVisibleGraphNode* node, bool head, CTGitPath& path, GitRev& rev, GitRev& peg);
188 void CompareRevs(const CString& revTo);
189 void UnifiedDiffRevs(bool bHead);
191 CRect GetGraphRect();
192 CRect GetClientRect();
193 CRect GetWindowRect();
194 CRect GetViewRect();
195 void DoZoom (float nZoomFactor, bool updateScrollbars = true);
196 bool CancelMouseZoom();
198 void SetDlgTitle (bool offline);
200 void BuildPreview();
202 protected:
203 DWORD m_dwTicks;
204 CRect m_OverviewPosRect;
205 CRect m_OverviewRect;
207 bool m_bShowOverview;
209 CRevisionGraphDlg *m_parent;
211 ogdf::node m_HeadNode;
212 ogdf::node m_SelectedEntry1;
213 ogdf::node m_SelectedEntry2;
214 LOGFONT m_lfBaseFont;
215 CFont * m_apFonts[MAXFONTS];
216 int m_nFontSize;
217 CToolTipCtrl * m_pDlgTip;
218 char m_szTip[MAX_TT_LENGTH+1];
219 wchar_t m_wszTip[MAX_TT_LENGTH+1];
220 CString m_sTitle;
222 float m_fZoomFactor;
223 CColors m_Colors;
224 bool m_bTweakTrunkColors;
225 bool m_bTweakTagsColors;
226 bool m_bIsCanvasMove;
227 CPoint m_ptMoveCanvas;
228 CPoint m_ptRubberEnd;
230 CBitmap m_Preview;
231 int m_previewWidth;
232 int m_previewHeight;
233 float m_previewZoom;
235 // index_t m_hoverIndex; // node the cursor currently hovers over
236 ogdf::node m_hoverIndex;
237 DWORD m_hoverGlyphs; // the glyphs shown for \ref m_hoverIndex
238 mutable ogdf::node m_tooltipIndex; // the node index we fetched the tooltip for
239 bool m_showHoverGlyphs; // if true, show the glyphs we currently hover over
240 // (will be activated only after some delay)
242 CString GetFriendRefName(ogdf::node);
243 STRING_VECTOR GetFriendRefNames(ogdf::node, CGit::REF_TYPE *refTypes = NULL, int refTypeCount = 0);
245 ogdf::Graph m_Graph;
246 ogdf::GraphAttributes m_GraphAttr;
247 ogdf::SugiyamaLayout m_SugiyamLayout;
249 CRect m_GraphRect;
251 int GetLeftRightMargin() {return 20;};
252 int GetTopBottomMargin() {return 5;};
253 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
254 afx_msg void OnPaint();
255 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
256 afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
257 afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
258 afx_msg void OnSize(UINT nType, int cx, int cy);
259 afx_msg INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
260 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
261 afx_msg BOOL OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
262 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
263 afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
264 afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
265 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
266 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
267 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
268 afx_msg void OnTimer(UINT_PTR nIDEvent);
269 afx_msg void OnCaptureChanged(CWnd *pWnd);
270 afx_msg LRESULT OnWorkerThreadDone(WPARAM, LPARAM);
272 DECLARE_MESSAGE_MAP()
273 private:
275 double m_ArrowCos;
276 double m_ArrowSin;
277 double m_ArrowSize;
279 enum MarkerPosition
281 mpLeft = 0,
282 mpRight = 1,
285 enum GlyphType
287 NoGlyph = -1,
288 ExpandGlyph = 0, // "+"
289 CollapseGlyph = 1, // "-"
290 SplitGlyph = 2, // "x"
291 JoinGlyph = 3, // "o"
294 enum GlyphPosition
296 Above = 0,
297 Right = 4,
298 Below = 8,
301 class GraphicsDevice
303 public:
304 GraphicsDevice()
305 : pDC(NULL)
306 , graphics(NULL)
307 , pSVG(NULL)
308 , pGraphviz(NULL)
311 ~GraphicsDevice() {}
312 public:
313 CDC * pDC;
314 Graphics * graphics;
315 SVG * pSVG;
316 Graphviz * pGraphviz;
319 class SVGGrouper
321 public:
322 SVGGrouper(SVG * pSVG)
324 m_pSVG = pSVG;
325 if (m_pSVG)
326 m_pSVG->StartGroup();
328 ~SVGGrouper()
330 if (m_pSVG)
331 m_pSVG->EndGroup();
333 private:
334 SVGGrouper() {}
336 SVG * m_pSVG;
339 bool UpdateSelectedEntry (ogdf::node clickedentry);
340 void AppendMenu (CMenu& popup, UINT title, UINT command, UINT flags = MF_ENABLED);
341 void AppendMenu (CMenu &popup, CString title, UINT command, CString *extra = NULL, CMenu *submenu = NULL);
342 void AddGitOps (CMenu& popup);
343 void AddGraphOps (CMenu& popup, const CVisibleGraphNode * node);
344 CString GetSelectedURL() const;
345 CString GetWCURL() const;
346 void DoShowLog();
347 void DoCheckForModification();
348 void DoMergeTo();
349 void DoUpdate();
350 void DoSwitch(CString rev);
351 void DoSwitchToHead();
352 void DoBrowseRepo();
353 void ResetNodeFlags (DWORD flags);
354 void ToggleNodeFlag (const CVisibleGraphNode *node, DWORD flag);
355 void DoCopyRefs();
357 void SetScrollbar (int bar, int newPos, int clientMax, int graphMax);
358 void SetScrollbars (int nVert = -1, int nHorz = -1);
359 CFont* GetFont(BOOL bItalic = FALSE, BOOL bBold = FALSE);
361 CSize UsableTooltipRect();
362 CString DisplayableText (const CString& wholeText, const CSize& tooltipSize);
363 CString TooltipText (ogdf::node index);
365 CPoint GetLogCoordinates (CPoint point) const;
366 ogdf::node GetHitNode (CPoint point, CSize border = CSize (0, 0)) const;
367 DWORD GetHoverGlyphs (CPoint point) const;
368 PointF cutPoint(ogdf::node v,double lw,PointF ps, PointF pt);
370 // const CRevisionGraphState::SVisibleGlyph* GetHitGlyph (CPoint point) const;
372 void ClearVisibleGlyphs (const CRect& rect);
374 typedef PointF TCutRectangle[8];
375 void CutawayPoints (const RectF& rect, float cutLen, TCutRectangle& result);
376 enum
378 ROUND_UP = 0x1,
379 ROUND_DOWN = 0x2,
380 ROUND_BOTH = 0x3,
382 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);
383 void DrawOctangle (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect);
384 void DrawShape (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect, NodeShape shape);
385 void DrawShadow(GraphicsDevice& graphics, const RectF& rect,
386 Color shadowColor, NodeShape shape);
387 void DrawNode(GraphicsDevice& graphics, const RectF& rect,
388 Color contour, Color overlayColor,
389 const CVisibleGraphNode *node, NodeShape shape);
390 RectF TransformRectToScreen (const CRect& rect, const CSize& offset) const;
391 RectF GetNodeRect (const ogdf::node& v, const CSize& offset) const;
392 // RectF GetBranchCover (const ILayoutNodeList* nodeList, index_t nodeIndex, bool upward, const CSize& offset);
394 void DrawSquare (GraphicsDevice& graphics, const PointF& leftTop,
395 const Color& lightColor, const Color& darkColor, const Color& penColor);
396 void DrawGlyph (GraphicsDevice& graphics, Image* glyphs, const PointF& leftTop,
397 GlyphType glyph, GlyphPosition position);
398 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const PointF& center,
399 GlyphType glyph1, GlyphType glyph2, GlyphPosition position, DWORD state1, DWORD state2, bool showAll);
400 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const RectF& nodeRect,
401 DWORD state, DWORD allowed, bool upsideDown);
402 void DrawMarker ( GraphicsDevice& graphics, const RectF& noderect
403 , MarkerPosition position, int relPosition, const Color& penColor, int num);
404 // void IndicateGlyphDirection ( GraphicsDevice& graphics, const ILayoutNodeList* nodeList
405 // , const ILayoutNodeList::SNode& node, const RectF& nodeRect
406 // , DWORD glyphs, bool upsideDown, const CSize& offset);
408 void DrawStripes (GraphicsDevice& graphics, const CSize& offset);
410 void DrawShadows (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
411 void DrawNodes (GraphicsDevice& graphics, Image* glyphs, const CRect& logRect, const CSize& offset);
412 void DrawConnections (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
413 void DrawTexts (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
414 void DrawCurrentNodeGlyphs (GraphicsDevice& graphics, Image* glyphs, const CSize& offset);
415 void DrawGraph(GraphicsDevice& graphics, const CRect& rect, int nVScrollPos, int nHScrollPos, bool bDirectDraw);
417 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
418 void DrawRubberBand();
419 void SetNodeRect(GraphicsDevice& graphics, ogdf::node *pnode, CGitHash rev, int mode = 0);