Cleanup
[TortoiseGit.git] / src / TortoiseProc / RevisionGraph / RevisionGraphWnd.h
blob5a74b88ad21a4502858edfe6f0f14780106e8461
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2011 - 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 #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"
30 #include <ogdf/layered/SugiyamaLayout.h>
31 #include <ogdf/layered/OptimalRanking.h>
32 #include <ogdf/layered/MedianHeuristic.h>
33 #include <ogdf/layered/OptimalHierarchyLayout.h>
34 #include <ogdf/layered/FastHierarchyLayout.h>
36 typedef void CVisibleGraphNode;
37 typedef int index_t;
39 using namespace Gdiplus;
40 using namespace async;
42 enum
44 REVGRAPH_PREVIEW_WIDTH = 100,
45 REVGRAPH_PREVIEW_HEIGHT = 200,
47 // don't draw pre-views with more than that number of nodes
49 REVGRAPH_PREVIEW_MAX_NODES = 10000
52 // don't try to draw nodes smaller than that:
54 #define REVGRAPH_MIN_NODE_HIGHT (0.5f)
56 enum
58 // size of the node marker
60 MARKER_SIZE = 11,
62 // radius of the rounded / slanted box corners of the expand / collapse / split / join square gylphs
64 CORNER_SIZE = 12,
66 // font sizes
68 DEFAULT_ZOOM_FONT = 9, // default font size
69 SMALL_ZOOM_FONT = 11, // rel. larger font size for small zoom factors
70 SMALL_ZOOM_FONT_THRESHOLD = 6, // max. "small zoom" font size after scaling
72 // size of the expand / collapse / split / join square gylphs
74 GLYPH_BITMAP_SIZE = 16,
75 GLYPH_SIZE = 12,
77 // glyph display delay definitions
79 GLYPH_HOVER_EVENT = 10, // timer ID for the glyph display delay
80 GLYPH_HOVER_DELAY = 250, // delay until the glyphs are shown [ms]
83 // zoom control
85 const float MIN_ZOOM = 0.01f;
86 const float MAX_ZOOM = 2.0f;
87 const float DEFAULT_ZOOM = 1.0f;
88 const float ZOOM_STEP = 0.9f;
90 // don't draw shadows below this zoom level
92 const float SHADOW_ZOOM_THRESHOLD = 0.2f;
94 /**
95 * \ingroup TortoiseProc
96 * node shapes for the revision graph
98 enum NodeShape
100 TSVNRectangle,
101 TSVNRoundRect,
102 TSVNOctangle,
103 TSVNEllipse
106 #define MAXFONTS 4
107 #define MAX_TT_LENGTH 60000
108 #define MAX_TT_LENGTH_DEFAULT 1000
110 // forward declarations
112 class CRevisionGraphDlg;
114 // simplify usage of classes from other namespaces
116 //using async::IJob;
117 //using async::CFuture;
120 * \ingroup TortoiseProc
121 * Window class showing a revision graph.
123 * The analyzation of the log data is done in the child class CRevisionGraph.
124 * Here, we handle the window notifications.
126 class CRevisionGraphWnd : public CWnd //, public CRevisionGraph
128 public:
129 CRevisionGraphWnd(); // standard constructor
130 virtual ~CRevisionGraphWnd();
131 enum
133 IDD = IDD_REVISIONGRAPH,
134 WM_WORKERTHREADDONE = WM_APP +1
138 CString m_sPath;
139 GitRev m_pegRev;
141 CLogCache m_LogCache;
142 CLogDataVector m_logEntries;
143 MAP_HASH_NAME m_HashMap;
144 CString m_CurrentBranch;
145 CGitHash m_HeadHash;
147 BOOL m_bCurrentBranch;
148 CString m_FromRev;
149 CString m_ToRev;
151 void ReloadHashMap()
153 m_HashMap.clear();
154 g_Git.GetMapHashToFriendName(m_HashMap);
155 m_CurrentBranch=g_Git.GetCurrentBranch();
156 this->m_HeadHash=g_Git.GetHash(_T("HEAD"));
159 std::auto_ptr<CFuture<bool>> updateJob;
160 // CRevisionGraphState m_state;
162 void InitView();
163 void Init(CWnd * pParent, LPRECT rect);
164 void SaveGraphAs(CString sSavePath);
166 bool FetchRevisionData ( const CString& path
167 , GitRev pegRevision
168 , CProgressDlg* progress
169 , ITaskbarList3* pTaskbarList
170 , HWND hWnd);
171 bool AnalyzeRevisionData();
172 bool IsUpdateJobRunning() const;
174 bool GetShowOverview() const;
175 void SetShowOverview (bool value);
177 void GetSelected (const CVisibleGraphNode* node, bool head, CTGitPath& path, GitRev& rev, GitRev& peg);
178 void CompareRevs(bool bHead);
179 void UnifiedDiffRevs(bool bHead);
181 CRect GetGraphRect();
182 CRect GetClientRect();
183 CRect GetWindowRect();
184 CRect GetViewRect();
185 void DoZoom (float nZoomFactor, bool updateScrollbars = true);
186 bool CancelMouseZoom();
188 void SetDlgTitle (bool offline);
190 void BuildPreview();
192 protected:
193 DWORD m_dwTicks;
194 CRect m_OverviewPosRect;
195 CRect m_OverviewRect;
197 bool m_bShowOverview;
199 CRevisionGraphDlg *m_parent;
201 ogdf::node m_SelectedEntry1;
202 ogdf::node m_SelectedEntry2;
203 LOGFONT m_lfBaseFont;
204 CFont * m_apFonts[MAXFONTS];
205 int m_nFontSize;
206 CToolTipCtrl * m_pDlgTip;
207 char m_szTip[MAX_TT_LENGTH+1];
208 wchar_t m_wszTip[MAX_TT_LENGTH+1];
209 CString m_sTitle;
211 float m_fZoomFactor;
212 CColors m_Colors;
213 bool m_bTweakTrunkColors;
214 bool m_bTweakTagsColors;
215 bool m_bIsRubberBand;
216 CPoint m_ptRubberStart;
217 CPoint m_ptRubberEnd;
219 CBitmap m_Preview;
220 int m_previewWidth;
221 int m_previewHeight;
222 float m_previewZoom;
224 // index_t m_hoverIndex; // node the cursor currently hovers over
225 ogdf::node m_hoverIndex;
226 DWORD m_hoverGlyphs; // the glyphs shown for \ref m_hoverIndex
227 mutable ogdf::node m_tooltipIndex; // the node index we fetched the tooltip for
228 bool m_showHoverGlyphs; // if true, show the glyphs we currently hover over
229 // (will be activated only after some delay)
231 CString GetFriendRefName(ogdf::node);
233 ogdf::Graph m_Graph;
234 ogdf::GraphAttributes m_GraphAttr;
235 ogdf::SugiyamaLayout m_SugiyamLayout;
237 CRect m_GraphRect;
239 int GetLeftRightMargin() {return 20;};
240 int GetTopBottomMargin() {return 5;};
241 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
242 afx_msg void OnPaint();
243 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
244 afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
245 afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
246 afx_msg void OnSize(UINT nType, int cx, int cy);
247 afx_msg INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
248 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
249 afx_msg BOOL OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
250 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
251 afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
252 afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
253 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
254 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
255 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
256 afx_msg void OnTimer(UINT_PTR nIDEvent);
257 afx_msg void OnCaptureChanged(CWnd *pWnd);
258 afx_msg LRESULT OnWorkerThreadDone(WPARAM, LPARAM);
260 DECLARE_MESSAGE_MAP()
261 private:
263 double m_ArrowCos;
264 double m_ArrowSin;
265 double m_ArrowSize;
267 enum MarkerPosition
269 mpLeft = 0,
270 mpRight = 1,
273 enum GlyphType
275 NoGlyph = -1,
276 ExpandGlyph = 0, // "+"
277 CollapseGlyph = 1, // "-"
278 SplitGlyph = 2, // "x"
279 JoinGlyph = 3, // "o"
282 enum GlyphPosition
284 Above = 0,
285 Right = 4,
286 Below = 8,
289 class GraphicsDevice
291 public:
292 GraphicsDevice()
293 : pDC(NULL)
294 , graphics(NULL)
295 , pSVG(NULL)
298 ~GraphicsDevice() {}
299 public:
300 CDC * pDC;
301 Graphics * graphics;
302 SVG * pSVG;
305 class SVGGrouper
307 public:
308 SVGGrouper(SVG * pSVG)
310 m_pSVG = pSVG;
311 if (m_pSVG)
312 m_pSVG->StartGroup();
314 ~SVGGrouper()
316 if (m_pSVG)
317 m_pSVG->EndGroup();
319 private:
320 SVGGrouper() {}
322 SVG * m_pSVG;
325 bool UpdateSelectedEntry (ogdf::node clickedentry);
326 void AppendMenu (CMenu& popup, UINT title, UINT command, UINT flags = MF_ENABLED);
327 void AddGitOps (CMenu& popup);
328 void AddGraphOps (CMenu& popup, const CVisibleGraphNode * node);
329 CString GetSelectedURL() const;
330 CString GetWCURL() const;
331 void DoShowLog();
332 void DoCheckForModification();
333 void DoMergeTo();
334 void DoUpdate();
335 void DoSwitch();
336 void DoSwitchToHead();
337 void DoBrowseRepo();
338 void ResetNodeFlags (DWORD flags);
339 void ToggleNodeFlag (const CVisibleGraphNode *node, DWORD flag);
340 void DoCopyUrl();
342 void SetScrollbar (int bar, int newPos, int clientMax, int graphMax);
343 void SetScrollbars (int nVert = -1, int nHorz = -1);
344 CFont* GetFont(BOOL bItalic = FALSE, BOOL bBold = FALSE);
346 CSize UsableTooltipRect();
347 CString DisplayableText (const CString& wholeText, const CSize& tooltipSize);
348 CString TooltipText (ogdf::node index);
350 CPoint GetLogCoordinates (CPoint point) const;
351 ogdf::node GetHitNode (CPoint point, CSize border = CSize (0, 0)) const;
352 DWORD GetHoverGlyphs (CPoint point) const;
353 PointF cutPoint(ogdf::node v,double lw,PointF ps, PointF pt);
355 // const CRevisionGraphState::SVisibleGlyph* GetHitGlyph (CPoint point) const;
357 void ClearVisibleGlyphs (const CRect& rect);
359 typedef PointF TCutRectangle[8];
360 void CutawayPoints (const RectF& rect, float cutLen, TCutRectangle& result);
361 enum
363 ROUND_UP = 0x1,
364 ROUND_DOWN = 0x2,
365 ROUND_BOTH = 0x3,
367 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);
368 void DrawOctangle (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect);
369 void DrawShape (GraphicsDevice& graphics, const Color& penColor, int penWidth, const Pen* pen, const Color& fillColor, const Brush* brush, const RectF& rect, NodeShape shape);
370 void DrawShadow(GraphicsDevice& graphics, const RectF& rect,
371 Color shadowColor, NodeShape shape);
372 void DrawNode(GraphicsDevice& graphics, const RectF& rect,
373 Color contour, Color overlayColor,
374 const CVisibleGraphNode *node, NodeShape shape);
375 RectF TransformRectToScreen (const CRect& rect, const CSize& offset) const;
376 RectF GetNodeRect (const ogdf::node& v, const CSize& offset) const;
377 // RectF GetBranchCover (const ILayoutNodeList* nodeList, index_t nodeIndex, bool upward, const CSize& offset);
379 void DrawSquare (GraphicsDevice& graphics, const PointF& leftTop,
380 const Color& lightColor, const Color& darkColor, const Color& penColor);
381 void DrawGlyph (GraphicsDevice& graphics, Image* glyphs, const PointF& leftTop,
382 GlyphType glyph, GlyphPosition position);
383 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const PointF& center,
384 GlyphType glyph1, GlyphType glyph2, GlyphPosition position, DWORD state1, DWORD state2, bool showAll);
385 void DrawGlyphs (GraphicsDevice& graphics, Image* glyphs, const CVisibleGraphNode* node, const RectF& nodeRect,
386 DWORD state, DWORD allowed, bool upsideDown);
387 void DrawMarker ( GraphicsDevice& graphics, const RectF& noderect
388 , MarkerPosition position, int relPosition, Color &penColor);
389 // void IndicateGlyphDirection ( GraphicsDevice& graphics, const ILayoutNodeList* nodeList
390 // , const ILayoutNodeList::SNode& node, const RectF& nodeRect
391 // , DWORD glyphs, bool upsideDown, const CSize& offset);
393 void DrawStripes (GraphicsDevice& graphics, const CSize& offset);
395 void DrawShadows (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
396 void DrawNodes (GraphicsDevice& graphics, Image* glyphs, const CRect& logRect, const CSize& offset);
397 void DrawConnections (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
398 void DrawTexts (GraphicsDevice& graphics, const CRect& logRect, const CSize& offset);
399 void DrawCurrentNodeGlyphs (GraphicsDevice& graphics, Image* glyphs, const CSize& offset);
400 void DrawGraph(GraphicsDevice& graphics, const CRect& rect, int nVScrollPos, int nHScrollPos, bool bDirectDraw);
402 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
403 void DrawRubberBand();
404 void SetNodeRect(GraphicsDevice& graphics, ogdf::node *pnode, CGitHash rev, int mode = 0);