Fixed issue #3096: Duplicate 'Save as...' context menu items appear when closing...
[TortoiseGit.git] / src / TortoiseProc / PatchViewDlg.cpp
blobf257b3a4361748a66a2b355b0858975d790160ac
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2017 - 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 // PatchViewDlg.cpp : implementation file
22 #include "stdafx.h"
23 #include "TortoiseProc.h"
24 #include "PatchViewDlg.h"
25 #include "CommonAppUtils.h"
26 #include "StringUtils.h"
28 // CPatchViewDlg dialog
30 IMPLEMENT_DYNAMIC(CPatchViewDlg, CDialog)
32 CPatchViewDlg::CPatchViewDlg(CWnd* pParent /*=nullptr*/)
33 : CDialog(CPatchViewDlg::IDD, pParent)
34 , m_ParentDlg(nullptr)
35 , m_hAccel(nullptr)
36 , m_bShowFindBar(false)
37 , m_nPopupSave(0)
41 CPatchViewDlg::~CPatchViewDlg()
45 void CPatchViewDlg::DoDataExchange(CDataExchange* pDX)
47 CDialog::DoDataExchange(pDX);
48 DDX_Control(pDX, IDC_PATCH, m_ctrlPatchView);
51 BEGIN_MESSAGE_MAP(CPatchViewDlg, CDialog)
52 ON_WM_SIZE()
53 ON_WM_MOVING()
54 ON_WM_CLOSE()
55 ON_WM_DESTROY()
56 ON_COMMAND(IDM_SHOWFINDBAR, OnShowFindBar)
57 ON_COMMAND(IDM_FINDEXIT, OnEscape)
58 ON_COMMAND(IDM_FINDNEXT, OnFindNext)
59 ON_COMMAND(IDM_FINDPREV, OnFindPrev)
60 ON_REGISTERED_MESSAGE(CFindBar::WM_FINDEXIT, OnFindExitMessage)
61 ON_REGISTERED_MESSAGE(CFindBar::WM_FINDNEXT, OnFindNextMessage)
62 ON_REGISTERED_MESSAGE(CFindBar::WM_FINDPREV, OnFindPrevMessage)
63 ON_REGISTERED_MESSAGE(CFindBar::WM_FINDRESET, OnFindResetMessage)
64 ON_WM_SYSCOLORCHANGE()
65 END_MESSAGE_MAP()
67 // CPatchViewDlg message handlers
69 BOOL CPatchViewDlg::OnInitDialog()
71 CDialog::OnInitDialog();
73 m_ctrlPatchView.Init(-1);
75 m_ctrlPatchView.SetUDiffStyle();
77 m_ctrlPatchView.RegisterContextMenuHandler(this);
79 m_hAccel = LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_ACC_PATCHVIEW));
81 m_FindBar.Create(IDD_FINDBAR, this);
83 return TRUE; // return TRUE unless you set the focus to a control
84 // EXCEPTION: OCX Property Pages should return FALSE
87 void CPatchViewDlg::SetText(const CString& text)
89 m_ctrlPatchView.Call(SCI_SETREADONLY, FALSE);
90 m_ctrlPatchView.SetText(text);
91 m_ctrlPatchView.Call(SCI_SETREADONLY, TRUE);
92 if (!text.IsEmpty())
94 m_ctrlPatchView.Call(SCI_GOTOPOS, 0);
95 CRect rect;
96 m_ctrlPatchView.GetClientRect(rect);
97 m_ctrlPatchView.Call(SCI_SETSCROLLWIDTH, rect.Width() - 4);
101 void CPatchViewDlg::ClearView()
103 SetText(CString());
106 void CPatchViewDlg::OnSize(UINT nType, int cx, int cy)
108 CDialog::OnSize(nType, cx, cy);
110 if (this->IsWindowVisible())
112 CRect rect;
113 GetClientRect(rect);
114 GetDlgItem(IDC_PATCH)->MoveWindow(0, 0, cx, cy);
116 if (m_bShowFindBar)
118 ::SetWindowPos(m_ctrlPatchView.GetSafeHwnd(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - 30, SWP_SHOWWINDOW);
119 ::SetWindowPos(m_FindBar.GetSafeHwnd(), HWND_TOP, rect.left, rect.bottom - 30, rect.right - rect.left, 30, SWP_SHOWWINDOW);
121 else
123 ::SetWindowPos(m_ctrlPatchView.GetSafeHwnd(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW);
124 m_FindBar.ShowWindow(SW_HIDE);
127 CRect rect2;
128 m_ctrlPatchView.GetClientRect(rect2);
129 m_ctrlPatchView.Call(SCI_SETSCROLLWIDTH, rect2.Width() - 4);
133 void CPatchViewDlg::OnMoving(UINT fwSide, LPRECT pRect)
135 #define STICKYSIZE 5
136 RECT parentRect;
137 m_ParentDlg->GetPatchViewParentWnd()->GetWindowRect(&parentRect);
138 if (abs(parentRect.right - pRect->left) < STICKYSIZE)
140 int width = pRect->right - pRect->left;
141 pRect->left = parentRect.right;
142 pRect->right = pRect->left + width;
144 CDialog::OnMoving(fwSide, pRect);
147 void CPatchViewDlg::OnClose()
149 CDialog::OnClose();
150 m_ParentDlg->TogglePatchView();
153 BOOL CPatchViewDlg::PreTranslateMessage(MSG* pMsg)
155 if (m_hAccel)
157 if (TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
158 return TRUE;
160 return __super::PreTranslateMessage(pMsg);
163 void CPatchViewDlg::OnEscape()
165 if (::IsWindowVisible(m_FindBar))
167 OnFindExit();
168 return;
170 SendMessage(WM_CLOSE);
173 void CPatchViewDlg::OnShowFindBar()
175 m_bShowFindBar = true;
176 m_FindBar.ShowWindow(SW_SHOW);
177 RECT rect;
178 GetClientRect(&rect);
179 ::SetWindowPos(m_ctrlPatchView.GetSafeHwnd(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - 30, SWP_SHOWWINDOW);
180 ::SetWindowPos(m_FindBar, HWND_TOP, rect.left, rect.bottom - 30, rect.right - rect.left, 30, SWP_SHOWWINDOW);
181 m_FindBar.SetFocusTextBox();
182 m_ctrlPatchView.Call(SCI_SETSELECTIONSTART, 0);
183 m_ctrlPatchView.Call(SCI_SETSELECTIONEND, 0);
184 m_ctrlPatchView.Call(SCI_SEARCHANCHOR);
187 void CPatchViewDlg::OnFindNext()
189 m_ctrlPatchView.Call(SCI_CHARRIGHT);
190 m_ctrlPatchView.Call(SCI_SEARCHANCHOR);
191 m_ctrlPatchView.Call(SCI_SEARCHNEXT, m_FindBar.IsMatchCase() ? SCFIND_MATCHCASE : 0, (LPARAM)(LPCSTR)CUnicodeUtils::GetUTF8(m_FindBar.GetFindText()));
192 m_ctrlPatchView.Call(SCI_SCROLLCARET);
195 void CPatchViewDlg::OnFindPrev()
197 m_ctrlPatchView.Call(SCI_SEARCHANCHOR);
198 m_ctrlPatchView.Call(SCI_SEARCHPREV, m_FindBar.IsMatchCase() ? SCFIND_MATCHCASE : 0, (LPARAM)(LPCSTR)CUnicodeUtils::GetUTF8(m_FindBar.GetFindText()));
199 m_ctrlPatchView.Call(SCI_SCROLLCARET);
202 void CPatchViewDlg::OnFindExit()
204 if (!::IsWindowVisible(m_FindBar))
205 return;
207 RECT rect;
208 GetClientRect(&rect);
209 m_bShowFindBar = false;
210 m_FindBar.ShowWindow(SW_HIDE);
211 ::SetWindowPos(m_ctrlPatchView.GetSafeHwnd(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW);
212 m_ctrlPatchView.SetFocus();
215 void CPatchViewDlg::OnFindReset()
217 m_ctrlPatchView.Call(SCI_SETSELECTIONSTART, 0);
218 m_ctrlPatchView.Call(SCI_SETSELECTIONEND, 0);
219 m_ctrlPatchView.Call(SCI_SEARCHANCHOR);
222 LRESULT CPatchViewDlg::OnFindNextMessage(WPARAM, LPARAM)
224 OnFindNext();
225 return 0;
228 LRESULT CPatchViewDlg::OnFindPrevMessage(WPARAM, LPARAM)
230 OnFindPrev();
231 return 0;
234 LRESULT CPatchViewDlg::OnFindExitMessage(WPARAM, LPARAM)
236 OnFindExit();
237 return 0;
240 LRESULT CPatchViewDlg::OnFindResetMessage(WPARAM, LPARAM)
242 OnFindReset();
243 return 0;
246 void CPatchViewDlg::OnSysColorChange()
248 __super::OnSysColorChange();
250 m_ctrlPatchView.SetUDiffStyle();
253 void CPatchViewDlg::OnDestroy()
255 __super::OnDestroy();
256 CRect rect;
257 GetWindowRect(&rect);
258 CRegStdDWORD(L"Software\\TortoiseGit\\TortoiseProc\\PatchDlgWidth") = rect.Width();
259 m_ctrlPatchView.ClearContextMenuHandlers();
262 // CSciEditContextMenuInterface
263 void CPatchViewDlg::InsertMenuItems(CMenu& mPopup, int& nCmd)
265 CString sMenuItemText;
266 sMenuItemText.LoadString(IDS_REPOBROWSE_SAVEAS);
267 m_nPopupSave = nCmd++;
268 mPopup.AppendMenu(MF_STRING | MF_ENABLED, m_nPopupSave, sMenuItemText);
271 bool CPatchViewDlg::HandleMenuItemClick(int cmd, CSciEdit*)
273 if (cmd == m_nPopupSave)
275 CString filename;
276 if (CCommonAppUtils::FileOpenSave(filename, nullptr, 0, IDS_PATCHFILEFILTER, false, GetSafeHwnd(), L"diff"))
277 CStringUtils::WriteStringToTextFile(filename, m_ctrlPatchView.GetText());
278 return true;
280 return false;