1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013, 2016 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "OutputWnd.h"
26 #include "TortoiseGitBlameDoc.h"
27 #include "TortoiseGitBlameView.h"
32 static char THIS_FILE
[] = __FILE__
;
35 /////////////////////////////////////////////////////////////////////////////
38 COutputWnd::COutputWnd()
42 COutputWnd::~COutputWnd()
46 IMPLEMENT_DYNAMIC(COutputWnd
, CDockablePane
)
48 BEGIN_MESSAGE_MAP(COutputWnd
, CDockablePane
)
51 ON_NOTIFY(LVN_ITEMCHANGED
, IDC_LOG
, OnLvnItemchangedLoglist
)
54 int COutputWnd::OnCreate(LPCREATESTRUCT lpCreateStruct
)
56 if (CDockablePane::OnCreate(lpCreateStruct
) == -1)
59 TRACE(L
"%u\n", LVN_ITEMCHANGED
);
60 m_Font
.CreateStockObject(DEFAULT_GUI_FONT
);
63 rectDummy
.SetRectEmpty();
65 // Create output panes:
66 const DWORD dwStyle
=LVS_REPORT
| LVS_SHOWSELALWAYS
| LVS_ALIGNLEFT
| LVS_OWNERDATA
| WS_BORDER
| WS_TABSTOP
|LVS_SINGLESEL
|WS_CHILD
| WS_VISIBLE
;
68 if (!m_LogList
.Create(dwStyle
, rectDummy
, this, IDC_LOG
))
70 TRACE0("Failed to create output windows\n");
71 return -1; // fail to create
74 // for some unknown reason, the SetExtendedStyle in OnCreate/PreSubclassWindow is not working here
77 m_LogList
.SetFont(&m_Font
);
79 m_Gravatar
.Create(L
"", WS_CHILD
| WS_VISIBLE
, rectDummy
, this);
80 bool bEnableGravatar
= !!CRegDWORD(L
"Software\\TortoiseGit\\EnableGravatar", FALSE
);
81 m_Gravatar
.EnableGravatar(bEnableGravatar
);
88 // Attach list windows to tab:
89 bNameValid
= strTabName
.LoadString(IDS_GIT_LOG_TAB
);
92 m_LogList
.m_IsIDReplaceAction
=TRUE
;
93 m_LogList
.DeleteAllItems();
94 m_LogList
.m_ColumnRegKey
= L
"Blame";
95 m_LogList
.InsertGitColumn();
97 m_LogList
.hideUnimplementedCommands();
99 this->SetWindowTextW(CString(MAKEINTRESOURCE(IDS_GIT_LOG_TAB
)));
103 void COutputWnd::OnSize(UINT nType
, int cx
, int cy
)
105 CDockablePane::OnSize(nType
, cx
, cy
);
107 // Tab control should cover the whole client area:
108 if (m_Gravatar
.IsGravatarEnabled())
110 m_LogList
.SetWindowPos(nullptr, -1, -1, cx
- 80, cy
, SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
111 m_Gravatar
.SetWindowPos(nullptr, cx
- 80, 0, 80, 80, SWP_NOACTIVATE
| SWP_NOZORDER
);
114 m_LogList
.SetWindowPos(nullptr, -1, -1, cx
, cy
, SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
117 void COutputWnd::AdjustHorzScroll(CListBox
& wndListBox
)
120 CFont
* pOldFont
= dc
.SelectObject(&m_Font
);
124 for (int i
= 0; i
< wndListBox
.GetCount(); ++i
)
127 wndListBox
.GetText(i
, strItem
);
129 cxExtentMax
= max(cxExtentMax
, dc
.GetTextExtent(strItem
).cx
);
132 wndListBox
.SetHorizontalExtent(cxExtentMax
);
133 dc
.SelectObject(pOldFont
);
136 int COutputWnd::LoadHistory(CString filename
, CString revision
, bool follow
)
139 path
.SetFromGit(filename
);
142 m_LogList
.ShowGraphColumn(!follow
);
143 if (m_LogList
.FillGitLog(&path
, &revision
, follow
? CGit::LOG_INFO_FOLLOW
: 0))
145 m_LogList
.UpdateProjectProperties();
149 int COutputWnd::LoadHistory(std::unordered_set
<CGitHash
>& hashes
)
152 m_LogList
.ShowGraphColumn(false);
153 if (m_LogList
.FillGitLog(hashes
))
155 m_LogList
.UpdateProjectProperties();
159 void COutputWnd::OnLvnItemchangedLoglist(NMHDR
*pNMHDR
, LRESULT
*pResult
)
161 LPNMLISTVIEW pNMLV
= reinterpret_cast<LPNMLISTVIEW
>(pNMHDR
);
164 //if (this->IsThreadRunning())
165 if (pNMLV
->iItem
>= 0)
167 if (pNMLV
->iSubItem
!= 0)
170 if (pNMLV
->uNewState
& LVIS_SELECTED
)
172 CMainFrame
*pMain
=DYNAMIC_DOWNCAST(CMainFrame
,AfxGetApp()->GetMainWnd());
173 POSITION pos
=pMain
->GetActiveDocument()->GetFirstViewPosition();
174 CTortoiseGitBlameView
*pView
=DYNAMIC_DOWNCAST(CTortoiseGitBlameView
,pMain
->GetActiveDocument()->GetNextView(pos
));
175 pView
->FocusOn(&this->m_LogList
.m_logEntries
.GetGitRevAt(pNMLV
->iItem
));
176 m_Gravatar
.LoadGravatar(m_LogList
.m_logEntries
.GetGitRevAt(pNMLV
->iItem
).GetAuthorEmail());
180 /////////////////////////////////////////////////////////////////////////////
183 COutputList::COutputList()
187 COutputList::~COutputList()
191 BEGIN_MESSAGE_MAP(COutputList
, CListBox
)
193 ON_COMMAND(ID_VIEW_OUTPUTWND
, OnViewOutput
)
194 ON_WM_WINDOWPOSCHANGING()
196 /////////////////////////////////////////////////////////////////////////////
197 // COutputList message handlers
199 void COutputList::OnContextMenu(CWnd
* /*pWnd*/, CPoint point
)
202 menu
.LoadMenu(IDR_OUTPUT_POPUP
);
204 CMenu
* pSumMenu
= menu
.GetSubMenu(0);
206 if (AfxGetMainWnd()->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx
)))
208 CMFCPopupMenu
* pPopupMenu
= new CMFCPopupMenu
;
210 if (!pPopupMenu
->Create(this, point
.x
, point
.y
, (HMENU
)pSumMenu
->m_hMenu
, FALSE
, TRUE
))
213 ((CMDIFrameWndEx
*)AfxGetMainWnd())->OnShowPopupMenu(pPopupMenu
);
214 UpdateDialogControls(this, FALSE
);
220 void COutputList::OnViewOutput()
222 CDockablePane
* pParentBar
= DYNAMIC_DOWNCAST(CDockablePane
, GetOwner());
223 CMDIFrameWndEx
* pMainFrame
= DYNAMIC_DOWNCAST(CMDIFrameWndEx
, GetTopLevelFrame());
225 if (pMainFrame
&& pParentBar
)
227 pMainFrame
->SetFocus();
228 pMainFrame
->ShowPane(pParentBar
, FALSE
, FALSE
, FALSE
);
229 pMainFrame
->RecalcLayout();