Fixed issue #2931: Make “ChangeList” grids in “Git synchronization” multi-selectable
[TortoiseGit.git] / src / TortoiseGitBlame / OutputWnd.cpp
blobbfaac6b2423ada6da1cbbe40bb635bcf14914849
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.
21 #include "stdafx.h"
23 #include "OutputWnd.h"
24 #include "Resource.h"
25 #include "MainFrm.h"
26 #include "TortoiseGitBlameDoc.h"
27 #include "TortoiseGitBlameView.h"
29 #ifdef _DEBUG
30 #define new DEBUG_NEW
31 #undef THIS_FILE
32 static char THIS_FILE[] = __FILE__;
33 #endif
35 /////////////////////////////////////////////////////////////////////////////
36 // COutputBar
38 COutputWnd::COutputWnd()
42 COutputWnd::~COutputWnd()
46 IMPLEMENT_DYNAMIC(COutputWnd, CDockablePane)
48 BEGIN_MESSAGE_MAP(COutputWnd, CDockablePane)
49 ON_WM_CREATE()
50 ON_WM_SIZE()
51 ON_NOTIFY(LVN_ITEMCHANGED, IDC_LOG, OnLvnItemchangedLoglist)
52 END_MESSAGE_MAP()
54 int COutputWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
56 if (CDockablePane::OnCreate(lpCreateStruct) == -1)
57 return -1;
59 TRACE(L"%u\n", LVN_ITEMCHANGED);
60 m_Font.CreateStockObject(DEFAULT_GUI_FONT);
62 CRect rectDummy;
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
75 m_LogList.SetStyle();
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);
82 if (bEnableGravatar)
83 m_Gravatar.Init();
85 CString strTabName;
86 BOOL bNameValid;
88 // Attach list windows to tab:
89 bNameValid = strTabName.LoadString(IDS_GIT_LOG_TAB);
90 ASSERT(bNameValid);
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)));
100 return 0;
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);
112 return;
114 m_LogList.SetWindowPos(nullptr, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
117 void COutputWnd::AdjustHorzScroll(CListBox& wndListBox)
119 CClientDC dc(this);
120 CFont* pOldFont = dc.SelectObject(&m_Font);
122 int cxExtentMax = 0;
124 for (int i = 0; i < wndListBox.GetCount(); ++i)
126 CString strItem;
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)
138 CTGitPath path;
139 path.SetFromGit(filename);
141 m_LogList.Clear();
142 m_LogList.ShowGraphColumn(!follow);
143 if (m_LogList.FillGitLog(&path, &revision, follow ? CGit::LOG_INFO_FOLLOW : 0))
144 return -1;
145 m_LogList.UpdateProjectProperties();
146 return 0;
149 int COutputWnd::LoadHistory(std::unordered_set<CGitHash>& hashes)
151 m_LogList.Clear();
152 m_LogList.ShowGraphColumn(false);
153 if (m_LogList.FillGitLog(hashes))
154 return -1;
155 m_LogList.UpdateProjectProperties();
156 return 0;
159 void COutputWnd::OnLvnItemchangedLoglist(NMHDR *pNMHDR, LRESULT *pResult)
161 LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
162 *pResult = 0;
164 //if (this->IsThreadRunning())
165 if (pNMLV->iItem >= 0)
167 if (pNMLV->iSubItem != 0)
168 return;
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 /////////////////////////////////////////////////////////////////////////////
181 // COutputList1
183 COutputList::COutputList()
187 COutputList::~COutputList()
191 BEGIN_MESSAGE_MAP(COutputList, CListBox)
192 ON_WM_CONTEXTMENU()
193 ON_COMMAND(ID_VIEW_OUTPUTWND, OnViewOutput)
194 ON_WM_WINDOWPOSCHANGING()
195 END_MESSAGE_MAP()
196 /////////////////////////////////////////////////////////////////////////////
197 // COutputList message handlers
199 void COutputList::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
201 CMenu menu;
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))
211 return;
213 ((CMDIFrameWndEx*)AfxGetMainWnd())->OnShowPopupMenu(pPopupMenu);
214 UpdateDialogControls(this, FALSE);
217 SetFocus();
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();