Use correct length for buffer
[TortoiseGit.git] / src / TortoiseProc / PatchListCtrl.cpp
blob1e6dfed64bdd20bae725e7dcb57ff6ba194ce73d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2009-2013, 2015-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 // PathListCtrl.cpp : implementation file
22 #include "stdafx.h"
23 #include "TortoiseProc.h"
24 #include "PatchListCtrl.h"
25 #include "IconMenu.h"
26 #include "AppUtils.h"
27 #include "Git.h"
28 #include "AppUtils.h"
29 // CPatchListCtrl
31 IMPLEMENT_DYNAMIC(CPatchListCtrl, CListCtrl)
33 CPatchListCtrl::CPatchListCtrl()
35 m_ContextMenuMask=0xFFFFFFFF;
37 HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
38 LOGFONT lf = {0};
39 GetObject(hFont, sizeof(LOGFONT), &lf);
40 lf.lfWeight = FW_BOLD;
41 m_boldFont.CreateFontIndirect(&lf);
44 CPatchListCtrl::~CPatchListCtrl()
49 BEGIN_MESSAGE_MAP(CPatchListCtrl, CListCtrl)
50 ON_NOTIFY_REFLECT(NM_DBLCLK, &CPatchListCtrl::OnNMDblclk)
51 ON_WM_CONTEXTMENU()
52 ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CPatchListCtrl::OnNMCustomdraw)
53 ON_WM_DROPFILES()
54 END_MESSAGE_MAP()
58 // CPatchListCtrl message handlers
62 void CPatchListCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
64 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
66 CString path=GetItemText(pNMItemActivate->iItem,0);
67 CTGitPath gitpath;
68 gitpath.SetFromWin(path);
70 CAppUtils::StartUnifiedDiffViewer(path,gitpath.GetFilename());
72 *pResult = 0;
75 void CPatchListCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
77 int selected=this->GetSelectedCount();
78 int index=0;
79 POSITION pos=this->GetFirstSelectedItemPosition();
80 index=this->GetNextSelectedItem(pos);
82 CIconMenu popup;
83 if (popup.CreatePopupMenu())
85 if(selected == 1)
87 if( m_ContextMenuMask&GetMenuMask(MENU_VIEWPATCH))
88 popup.AppendMenuIcon(MENU_VIEWPATCH, IDS_MENU_VIEWPATCH, 0);
90 if( m_ContextMenuMask&GetMenuMask(MENU_VIEWWITHMERGE))
91 popup.AppendMenuIcon(MENU_VIEWWITHMERGE, IDS_MENU_VIEWWITHMERGE, 0);
93 popup.SetDefaultItem(MENU_VIEWPATCH, FALSE);
95 if(selected >= 1)
97 if( m_ContextMenuMask&GetMenuMask(MENU_SENDMAIL))
98 popup.AppendMenuIcon(MENU_SENDMAIL, IDS_MENU_SENDMAIL, IDI_MENUSENDMAIL);
100 if( m_ContextMenuMask&GetMenuMask(MENU_APPLY))
101 popup.AppendMenuIcon(MENU_APPLY, IDS_MENU_APPLY, 0);
104 int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);
106 switch (cmd)
108 case MENU_VIEWPATCH:
110 CString path=GetItemText(index,0);
111 CTGitPath gitpath;
112 gitpath.SetFromWin(path);
114 CAppUtils::StartUnifiedDiffViewer(path,gitpath.GetFilename());
115 break;
117 case MENU_VIEWWITHMERGE:
119 CString path=GetItemText(index,0);
120 CTGitPath gitpath;
121 gitpath.SetFromWin(path);
123 CTGitPath dir;
124 dir.SetFromGit(g_Git.m_CurrentDir);
126 CAppUtils::StartExtPatch(gitpath,dir);
127 break;
129 case MENU_SENDMAIL:
131 LaunchProc(_T("sendmail"));
132 break;
134 case MENU_APPLY:
136 LaunchProc(_T("importpatch"));
138 break;
140 default:
141 break;
146 int CPatchListCtrl::LaunchProc(const CString& command)
148 CString tempfile=GetTempFile();
149 POSITION pos=this->GetFirstSelectedItemPosition();
150 CFile file;
151 file.Open(tempfile,CFile::modeWrite|CFile::modeCreate);
153 while(pos)
155 int index = this->GetNextSelectedItem(pos);
156 CString one=this->GetItemText(index,0);
157 file.Write((LPCTSTR)one, sizeof(TCHAR) * one.GetLength());
158 file.Write(_T("\n"),sizeof(TCHAR)*1);
161 file.Close();
163 CString cmd = _T("/command:");
164 cmd += command;
165 cmd +=_T(" /pathfile:\"");
166 cmd += tempfile;
167 cmd += _T("\" /deletepathfile");
168 CAppUtils::RunTortoiseGitProc(cmd);
169 return 0;
172 void CPatchListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
174 NMLVCUSTOMDRAW *pNMCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
176 *pResult = 0;
178 switch (pNMCD->nmcd.dwDrawStage)
180 case CDDS_PREPAINT:
182 *pResult = CDRF_NOTIFYITEMDRAW;
183 return;
185 break;
186 case CDDS_ITEMPREPAINT:
188 // This is the prepaint stage for an item. Here's where we set the
189 // item's text color.
191 // Tell Windows to send draw notifications for each subitem.
192 *pResult = CDRF_NOTIFYSUBITEMDRAW;
194 DWORD_PTR data = this->GetItemData((int)pNMCD->nmcd.dwItemSpec);
195 if(data & (STATUS_APPLY_FAIL | STATUS_APPLY_SUCCESS | STATUS_APPLY_SKIP))
196 pNMCD->clrTextBk = RGB(200,200,200);
198 switch(data & STATUS_MASK)
200 case STATUS_APPLY_SUCCESS:
201 pNMCD->clrText = RGB(0,128,0);
202 break;
203 case STATUS_APPLY_FAIL:
204 pNMCD->clrText = RGB(255,0,0);
205 break;
206 case STATUS_APPLY_SKIP:
207 pNMCD->clrText = RGB(128,64,0);
208 break;
211 if(data & STATUS_APPLYING)
213 SelectObject(pNMCD->nmcd.hdc, m_boldFont.GetSafeHandle());
214 *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;
218 break;
220 *pResult = CDRF_DODEFAULT;
223 void CPatchListCtrl::OnDropFiles(HDROP hDropInfo)
225 UINT nNumFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, nullptr, 0);
226 for (UINT i = 0; i < nNumFiles; ++i)
228 CString file;
229 DragQueryFile(hDropInfo, i, file.GetBufferSetLength(MAX_PATH), MAX_PATH);
230 file.ReleaseBuffer();
231 if (PathIsDirectory(file))
232 continue;
234 // no duplicates
235 LVFINDINFO lvInfo;
236 lvInfo.flags = LVFI_STRING;
237 lvInfo.psz = file;
238 if (FindItem(&lvInfo, -1) != -1)
239 continue;
241 int index = InsertItem(GetItemCount(), file);
242 if (index >= 0)
243 SetCheck(index, true);
245 DragFinish(hDropInfo);
246 SetColumnWidth(0, LVSCW_AUTOSIZE);