Improve type safety
[TortoiseGit.git] / src / TortoiseProc / RefLogDlg.cpp
blob22b8a74d372989d82db4ed68525f76b28892e98d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2009-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.
19 // RefLogDlg.cpp : implementation file
22 #include "stdafx.h"
23 #include "resource.h"
24 #include "RefLogDlg.h"
25 #include "Git.h"
26 #include "AppUtils.h"
27 #include "MessageBox.h"
28 #include "UnicodeUtils.h"
30 // CRefLogDlg dialog
32 IMPLEMENT_DYNAMIC(CRefLogDlg, CResizableStandAloneDialog)
34 UINT CRefLogDlg::m_FindDialogMessage = ::RegisterWindowMessage(FINDMSGSTRING);
36 CRefLogDlg::CRefLogDlg(CWnd* pParent /*=NULL*/)
37 : CResizableStandAloneDialog(CRefLogDlg::IDD, pParent)
38 , m_pFindDialog(NULL)
39 , m_nSearchLine(0)
44 CRefLogDlg::~CRefLogDlg()
48 void CRefLogDlg::DoDataExchange(CDataExchange* pDX)
50 CDialog::DoDataExchange(pDX);
51 DDX_Control(pDX, IDC_COMBOBOXEX_REF, m_ChooseRef);
52 DDX_Control(pDX, IDC_REFLOG_LIST, m_RefList);
56 BEGIN_MESSAGE_MAP(CRefLogDlg, CResizableStandAloneDialog)
57 ON_BN_CLICKED(IDOK, &CRefLogDlg::OnBnClickedOk)
58 ON_BN_CLICKED(IDC_REFLOG_BUTTONCLEARSTASH, &CRefLogDlg::OnBnClickedClearStash)
59 ON_CBN_SELCHANGE(IDC_COMBOBOXEX_REF, &CRefLogDlg::OnCbnSelchangeRef)
60 ON_MESSAGE(MSG_REFLOG_CHANGED,OnRefLogChanged)
61 ON_REGISTERED_MESSAGE(m_FindDialogMessage, OnFindDialogMessage)
62 END_MESSAGE_MAP()
64 LRESULT CRefLogDlg::OnRefLogChanged(WPARAM /*wParam*/, LPARAM /*lParam*/)
66 m_RefList.m_RevCache.clear();
67 OnCbnSelchangeRef();
68 return 0;
71 BOOL CRefLogDlg::OnInitDialog()
73 CResizableStandAloneDialog::OnInitDialog();
74 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
76 AddAnchor(IDOK,BOTTOM_RIGHT);
77 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
78 AddAnchor(IDC_REFLOG_BUTTONCLEARSTASH, BOTTOM_LEFT);
79 AddAnchor(IDC_REFLOG_LIST,TOP_LEFT,BOTTOM_RIGHT);
80 AddAnchor(IDHELP, BOTTOM_RIGHT);
81 AddAnchor(IDC_COMBOBOXEX_REF, TOP_LEFT, TOP_RIGHT);
83 AddOthersToAnchor();
84 this->EnableSaveRestore(_T("RefLogDlg"));
86 CString sWindowTitle;
87 GetWindowText(sWindowTitle);
88 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);
90 m_ChooseRef.SetMaxHistoryItems(0x7FFFFFFF);
92 m_RefList.m_hasWC = !GitAdminDir::IsBareRepo(g_Git.m_CurrentDir);
94 this->m_RefList.InsertRefLogColumn();
96 Refresh();
98 return TRUE;
100 // CRefLogDlg message handlers
102 void CRefLogDlg::OnBnClickedOk()
104 if (m_RefList.GetSelectedCount() == 1)
106 // get the selected row
107 POSITION pos = m_RefList.GetFirstSelectedItemPosition();
108 size_t selIndex = m_RefList.GetNextSelectedItem(pos);
109 if (selIndex < m_RefList.m_arShownList.size())
111 // all ok, pick up the revision
112 GitRev* pLogEntry = m_RefList.m_arShownList.SafeGetAt(selIndex);
113 // extract the hash
114 m_SelectedHash = pLogEntry->m_CommitHash;
118 OnOK();
120 void CRefLogDlg::OnBnClickedClearStash()
122 size_t count = m_RefList.m_arShownList.size();
123 CString msg;
124 msg.Format(IDS_PROC_DELETEALLSTASH, count);
125 if (CMessageBox::Show(this->GetSafeHwnd(), msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 1)
127 CString cmdOut;
128 if (g_Git.Run(_T("git.exe stash clear"), &cmdOut, CP_UTF8))
130 MessageBox(cmdOut, _T("TortoiseGit"), MB_ICONERROR);
131 return;
134 m_RefList.m_RevCache.clear();
136 OnCbnSelchangeRef();
140 void CRefLogDlg::OnCbnSelchangeRef()
142 CString ref=m_ChooseRef.GetString();
143 m_RefList.ClearText();
145 m_RefList.SetRedraw(false);
147 CString err;
148 if (GitRevLoglist::GetRefLog(ref, m_RefList.m_RevCache, err))
149 MessageBox(_T("Error while loading reflog.\n") + err, _T("TortoiseGit"), MB_ICONERROR);
151 m_RefList.SetItemCountEx((int)m_RefList.m_RevCache.size());
153 this->m_RefList.m_arShownList.clear();
155 for (unsigned int i = 0; i < m_RefList.m_RevCache.size(); ++i)
157 GitRevLoglist* rev = &m_RefList.m_RevCache[i];
158 rev->m_IsFull = TRUE;
159 this->m_RefList.m_arShownList.SafeAdd(rev);
162 m_RefList.SetRedraw(true);
164 m_RefList.Invalidate();
166 if (ref == _T("refs/stash"))
168 GetDlgItem(IDC_REFLOG_BUTTONCLEARSTASH)->ShowWindow(SW_SHOW);
169 BOOL enabled = !m_RefList.m_arShownList.empty();
170 GetDlgItem(IDC_REFLOG_BUTTONCLEARSTASH)->EnableWindow(enabled);
171 if (!enabled)
172 GetDlgItem(IDOK)->SetFocus();
174 else
175 GetDlgItem(IDC_REFLOG_BUTTONCLEARSTASH)->ShowWindow(SW_HIDE);
178 BOOL CRefLogDlg::PreTranslateMessage(MSG* pMsg)
180 if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F5)
181 Refresh();
182 else if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_F3 || (pMsg->wParam == 'F' && (GetAsyncKeyState(VK_CONTROL) & 0x8000))))
183 OnFind();
185 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
188 void CRefLogDlg::Refresh()
190 STRING_VECTOR list;
191 list.push_back(_T("HEAD"));
192 if (g_Git.GetRefList(list))
193 MessageBox(g_Git.GetGitLastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
195 m_ChooseRef.SetList(list);
197 if (m_CurrentBranch.IsEmpty())
199 m_CurrentBranch.Format(_T("refs/heads/%s"), (LPCTSTR)g_Git.GetCurrentBranch());
200 m_ChooseRef.SetCurSel(0); /* Choose HEAD */
202 else
204 bool found = false;
205 for (int i = 0; i < (int)list.size(); ++i)
207 if(list[i] == m_CurrentBranch)
209 m_ChooseRef.SetCurSel(i);
210 found = true;
211 break;
214 if (!found)
215 m_ChooseRef.SetCurSel(0);
218 m_RefList.m_RevCache.clear();
220 OnCbnSelchangeRef();
223 void CRefLogDlg::OnFind()
225 m_nSearchLine = 0;
226 m_pFindDialog = new CFindReplaceDialog();
227 m_pFindDialog->Create(TRUE, _T(""), NULL, FR_DOWN | FR_HIDEWHOLEWORD | FR_HIDEUPDOWN, this);
230 LRESULT CRefLogDlg::OnFindDialogMessage(WPARAM /*wParam*/, LPARAM /*lParam*/)
232 ASSERT(m_pFindDialog != NULL);
234 if (m_RefList.m_arShownList.empty())
235 return 0;
237 // If the FR_DIALOGTERM flag is set,
238 // invalidate the handle identifying the dialog box.
239 if (m_pFindDialog->IsTerminating())
241 m_pFindDialog = NULL;
242 return 0;
245 // If the FR_FINDNEXT flag is set,
246 // call the application-defined search routine
247 // to search for the requested string.
248 if (m_pFindDialog->FindNext())
250 //read data from dialog
251 CString findString = m_pFindDialog->GetFindString();
253 bool bFound = false;
254 bool bCaseSensitive = !!(m_pFindDialog->m_nFlags & FR_MATCHCASE);
256 if (!bCaseSensitive)
257 findString.MakeLower();
259 size_t i = m_nSearchLine;
260 if (i >= m_RefList.m_arShownList.size())
261 i = 0;
265 GitRevLoglist* data = m_RefList.m_arShownList.SafeGetAt(i);
267 CString str;
268 str += data->m_Ref;
269 str += _T("\n");
270 str += data->m_RefAction;
271 str += _T("\n");
272 str += data->m_CommitHash.ToString();
273 str += _T("\n");
274 str += data->GetSubject();
275 str += _T("\n");
276 str += data->GetBody();
277 str += _T("\n");
279 if (!bCaseSensitive)
280 str.MakeLower();
282 if (str.Find(findString) >= 0)
283 bFound = true;
285 ++i;
286 if(!bFound && i >= m_RefList.m_arShownList.size())
287 i=0;
288 } while (i != m_nSearchLine && (!bFound));
290 if (bFound)
292 m_RefList.SetHotItem((int)i - 1);
293 m_RefList.EnsureVisible((int)i - 1, FALSE);
294 m_nSearchLine = i;
296 else
297 MessageBox(_T("\"") + findString + _T("\" ") + CString(MAKEINTRESOURCE(IDS_NOTFOUND)), _T("TortoiseGit"), MB_ICONINFORMATION);
300 return 0;