High DPI fixes for splitters and dialog resising
[TortoiseGit.git] / src / TortoiseProc / ImportPatchDlg.cpp
blob1580de8e21a6ea108d28244719d2080223c208d6
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2018 - 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 // ImportPatchDlg.cpp : implementation file
22 #include "stdafx.h"
23 #include "TortoiseProc.h"
24 #include "ImportPatchDlg.h"
25 #include "Git.h"
26 #include "MessageBox.h"
27 #include "AppUtils.h"
28 #include "SmartHandle.h"
29 #include "LoglistCommonResource.h"
30 #include "DPIAware.h"
32 // CImportPatchDlg dialog
34 IMPLEMENT_DYNAMIC(CImportPatchDlg, CResizableStandAloneDialog)
36 CImportPatchDlg::CImportPatchDlg(CWnd* pParent /*=nullptr*/)
37 : CResizableStandAloneDialog(CImportPatchDlg::IDD, pParent)
38 , m_LoadingThread(FALSE)
39 , m_CurrentItem(0)
40 , m_bExitThread(FALSE)
41 , m_bThreadRunning(FALSE)
42 , m_b3Way(BST_CHECKED)
43 , m_bIgnoreSpace(BST_CHECKED)
44 , m_bAddSignedOffBy(BST_UNCHECKED)
45 , m_bKeepCR(BST_CHECKED)
47 m_cList.m_ContextMenuMask &=~ m_cList.GetMenuMask(CPatchListCtrl::MENU_APPLY);
50 CImportPatchDlg::~CImportPatchDlg()
54 void CImportPatchDlg::DoDataExchange(CDataExchange* pDX)
56 CDialog::DoDataExchange(pDX);
57 DDX_Control(pDX, IDC_LIST_PATCH,m_cList);
58 DDX_Control(pDX, IDC_AM_SPLIT, m_wndSplitter);
59 DDX_Check(pDX, IDC_CHECK_3WAY, m_b3Way);
60 DDX_Check(pDX, IDC_CHECK_IGNORE_SPACE, m_bIgnoreSpace);
61 DDX_Check(pDX, IDC_SIGN_OFF, m_bAddSignedOffBy);
62 DDX_Check(pDX, IDC_KEEP_CR, m_bKeepCR);
65 void CImportPatchDlg::AddAmAnchor()
67 AddAnchor(IDC_AM_TAB,TOP_LEFT,BOTTOM_RIGHT);
68 AddAnchor(IDC_LIST_PATCH, TOP_LEFT, TOP_RIGHT);
69 AddAnchor(IDC_AM_SPLIT, TOP_LEFT, TOP_RIGHT);
70 AddAnchor(IDC_BUTTON_ADD, TOP_RIGHT);
71 AddAnchor(IDC_BUTTON_UP, TOP_RIGHT);
72 AddAnchor(IDC_BUTTON_DOWN, TOP_RIGHT);
73 AddAnchor(IDC_BUTTON_REMOVE, TOP_RIGHT);
75 AddAnchor(IDOK,BOTTOM_RIGHT);
76 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
77 AddAnchor(IDHELP, BOTTOM_RIGHT);
79 AddAnchor(IDC_AM_DUMY_TAB, TOP_LEFT, BOTTOM_RIGHT);
81 this->AddOthersToAnchor();
84 void CImportPatchDlg::SetSplitterRange()
86 if ((m_cList)&&(m_ctrlTabCtrl))
88 CRect rcTop;
89 m_cList.GetWindowRect(rcTop);
90 ScreenToClient(rcTop);
91 CRect rcMiddle;
92 m_ctrlTabCtrl.GetWindowRect(rcMiddle);
93 ScreenToClient(rcMiddle);
94 if (rcMiddle.Height() && rcMiddle.Width())
95 m_wndSplitter.SetRange(rcTop.top + CDPIAware::Instance().ScaleY(160), rcMiddle.bottom - CDPIAware::Instance().ScaleY(160));
99 BOOL CImportPatchDlg::OnInitDialog()
101 CResizableStandAloneDialog::OnInitDialog();
102 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
104 // Let the TaskbarButtonCreated message through the UIPI filter. If we don't
105 // do this, Explorer would be unable to send that message to our window if we
106 // were running elevated. It's OK to make the call all the time, since if we're
107 // not elevated, this is a no-op.
108 CHANGEFILTERSTRUCT cfs = { sizeof(CHANGEFILTERSTRUCT) };
109 typedef BOOL STDAPICALLTYPE ChangeWindowMessageFilterExDFN(HWND hWnd, UINT message, DWORD action, PCHANGEFILTERSTRUCT pChangeFilterStruct);
110 CAutoLibrary hUser = AtlLoadSystemLibraryUsingFullPath(L"user32.dll");
111 if (hUser)
113 ChangeWindowMessageFilterExDFN *pfnChangeWindowMessageFilterEx = (ChangeWindowMessageFilterExDFN*)GetProcAddress(hUser, "ChangeWindowMessageFilterEx");
114 if (pfnChangeWindowMessageFilterEx)
116 pfnChangeWindowMessageFilterEx(m_hWnd, TaskBarButtonCreated, MSGFLT_ALLOW, &cfs);
119 m_pTaskbarList.Release();
120 if (FAILED(m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList)))
121 m_pTaskbarList = nullptr;
123 CRect rectDummy;
125 GetClientRect(m_DlgOrigRect);
126 m_cList.GetClientRect(m_PatchListOrigRect);
128 CWnd *pwnd=this->GetDlgItem(IDC_AM_DUMY_TAB);
129 pwnd->GetWindowRect(&rectDummy);
130 this->ScreenToClient(rectDummy);
132 if (!m_ctrlTabCtrl.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, IDC_AM_TAB))
134 TRACE0("Failed to create output tab window\n");
135 return FALSE; // fail to create
137 m_ctrlTabCtrl.SetResizeMode(CMFCTabCtrl::RESIZE_NO);
138 // Create output panes:
140 if (!m_PatchCtrl.Create(L"Scintilla", L"source", 0, rectDummy, &m_ctrlTabCtrl, 0, 0))
142 TRACE0("Failed to create log message control");
143 return FALSE;
145 m_PatchCtrl.Init(-1);
146 m_PatchCtrl.Call(SCI_SETREADONLY, TRUE);
147 m_PatchCtrl.SetUDiffStyle();
149 if (!m_wndOutput.Create(L"Scintilla", L"source", 0, rectDummy, &m_ctrlTabCtrl, 0, 0))
151 TRACE0("Failed to create output windows\n");
152 return -1; // fail to create
154 m_wndOutput.Init(-1);
155 m_wndOutput.Call(SCI_SETREADONLY, TRUE);
157 m_tooltips.AddTool(IDC_CHECK_3WAY,IDS_AM_3WAY_TT);
158 m_tooltips.AddTool(IDC_CHECK_IGNORE_SPACE,IDS_AM_IGNORE_SPACE_TT);
160 m_ctrlTabCtrl.AddTab(&m_PatchCtrl, CString(MAKEINTRESOURCE(IDS_PATCH)), 0);
161 m_ctrlTabCtrl.AddTab(&m_wndOutput, CString(MAKEINTRESOURCE(IDS_LOG)), 1);
163 AdjustControlSize(IDC_CHECK_3WAY);
164 AdjustControlSize(IDC_CHECK_IGNORE_SPACE);
165 AdjustControlSize(IDC_SIGN_OFF);
166 AdjustControlSize(IDC_KEEP_CR);
168 AddAmAnchor();
170 m_PathList.SortByPathname(true);
171 m_cList.SetExtendedStyle(m_cList.GetExtendedStyle() | LVS_EX_CHECKBOXES | LVS_EX_DOUBLEBUFFER);
172 m_cList.InsertColumn(0, L"");
173 m_cList.SetExtendedStyle((CRegDWORD(L"Software\\TortoiseGit\\FullRowSelect", TRUE) ? LVS_EX_FULLROWSELECT : 0) | m_cList.GetExtendedStyle());
175 for (int i = 0; i < m_PathList.GetCount(); ++i)
177 m_cList.InsertItem(0,m_PathList[i].GetWinPath());
178 m_cList.SetCheck(0,true);
180 m_cList.SetColumnWidth(0, LVSCW_AUTOSIZE);
182 DWORD yPos = CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\ResizableState\\AMDlgSizer");
183 RECT rcDlg, rcLogMsg, rcFileList;
184 GetClientRect(&rcDlg);
185 m_cList.GetWindowRect(&rcLogMsg);
186 ScreenToClient(&rcLogMsg);
187 this->m_ctrlTabCtrl.GetWindowRect(&rcFileList);
188 ScreenToClient(&rcFileList);
189 if (yPos)
191 RECT rectSplitter;
192 m_wndSplitter.GetWindowRect(&rectSplitter);
193 ScreenToClient(&rectSplitter);
194 int delta = yPos - rectSplitter.top;
195 if ((rcLogMsg.bottom + delta > rcLogMsg.top) && (rcLogMsg.bottom + delta < rcFileList.bottom - CDPIAware::Instance().ScaleY(30)))
197 m_wndSplitter.SetWindowPos(nullptr, 0, yPos, 0, 0, SWP_NOSIZE);
198 DoSize(delta);
202 CAppUtils::SetListCtrlBackgroundImage(m_cList.GetSafeHwnd(), IDI_IMPORTPATHCES_BKG);
204 CString sWindowTitle;
205 GetWindowText(sWindowTitle);
206 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);
208 EnableSaveRestore(L"ImportDlg");
210 SetSplitterRange();
212 return TRUE;
215 BEGIN_MESSAGE_MAP(CImportPatchDlg, CResizableStandAloneDialog)
216 ON_LBN_SELCHANGE(IDC_LIST_PATCH, &CImportPatchDlg::OnLbnSelchangeListPatch)
217 ON_BN_CLICKED(IDC_BUTTON_ADD, &CImportPatchDlg::OnBnClickedButtonAdd)
218 ON_BN_CLICKED(IDC_BUTTON_UP, &CImportPatchDlg::OnBnClickedButtonUp)
219 ON_BN_CLICKED(IDC_BUTTON_DOWN, &CImportPatchDlg::OnBnClickedButtonDown)
220 ON_BN_CLICKED(IDC_BUTTON_REMOVE, &CImportPatchDlg::OnBnClickedButtonRemove)
221 ON_BN_CLICKED(IDOK, &CImportPatchDlg::OnBnClickedOk)
222 ON_WM_SIZE()
223 ON_WM_SYSCOLORCHANGE()
224 ON_WM_THEMECHANGED()
225 ON_BN_CLICKED(IDCANCEL, &CImportPatchDlg::OnBnClickedCancel)
226 ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_PATCH, &CImportPatchDlg::OnHdnItemchangedListPatch)
227 ON_REGISTERED_MESSAGE(TaskBarButtonCreated, OnTaskbarBtnCreated)
228 END_MESSAGE_MAP()
231 // CImportPatchDlg message handlers
233 void CImportPatchDlg::OnLbnSelchangeListPatch()
235 if(m_cList.GetSelectedCount() == 0)
237 this->GetDlgItem(IDC_BUTTON_UP)->EnableWindow(FALSE);
238 this->GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow(FALSE);
239 this->GetDlgItem(IDC_BUTTON_REMOVE)->EnableWindow(FALSE);
241 else
243 this->GetDlgItem(IDC_BUTTON_UP)->EnableWindow(TRUE);
244 this->GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow(TRUE);
245 this->GetDlgItem(IDC_BUTTON_REMOVE)->EnableWindow(TRUE);
249 void CImportPatchDlg::OnBnClickedButtonAdd()
251 CFileDialog dlg(TRUE, nullptr, nullptr, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, CString(MAKEINTRESOURCE(IDS_PATCHFILEFILTER)));
252 dlg.m_ofn.nMaxFile = 65536;
253 TCHAR path[65536] = { 0 };
254 dlg.m_ofn.lpstrFile = path;
255 INT_PTR ret = dlg.DoModal();
256 SetCurrentDirectory(g_Git.m_CurrentDir);
257 if (ret == IDOK)
259 POSITION pos;
260 pos = dlg.GetStartPosition();
261 while (pos)
263 CString file = dlg.GetNextPathName(pos);
264 file.Trim();
265 if(!file.IsEmpty())
267 int index = m_cList.InsertItem(m_cList.GetItemCount(), file);
268 if (index >= 0)
269 m_cList.SetCheck(index, true);
272 m_cList.SetColumnWidth(0, LVSCW_AUTOSIZE);
276 void CImportPatchDlg::OnBnClickedButtonUp()
278 POSITION pos;
279 pos = m_cList.GetFirstSelectedItemPosition();
281 // do nothing if the first selected item is the first item in the list
282 if (m_cList.GetNextSelectedItem(pos) == 0)
283 return;
285 pos = m_cList.GetFirstSelectedItemPosition();
287 while (pos)
289 int index = m_cList.GetNextSelectedItem(pos);
290 if(index >= 1)
292 CString old = m_cList.GetItemText(index, 0);
293 BOOL oldState = m_cList.GetCheck(index);
294 m_cList.DeleteItem(index);
295 m_cList.InsertItem(index - 1, old);
296 m_cList.SetCheck(index - 1, oldState);
297 m_cList.SetItemState(index - 1, LVIS_SELECTED, LVIS_SELECTED);
298 m_cList.SetItemState(index, 0, LVIS_SELECTED);
303 void CImportPatchDlg::OnBnClickedButtonDown()
305 if (m_cList.GetSelectedCount() == 0)
306 return;
308 POSITION pos;
309 pos = m_cList.GetFirstSelectedItemPosition();
310 // use an array to store all selected item indexes; the user won't select too much items
311 auto indexes = std::make_unique<int[]>(m_cList.GetSelectedCount());
312 int i = 0;
313 while(pos)
314 indexes[i++] = m_cList.GetNextSelectedItem(pos);
316 // don't move any item if the last selected item is the last item in the m_CommitList
317 // (that would change the order of the selected items)
318 if(indexes[m_cList.GetSelectedCount() - 1] < m_cList.GetItemCount() - 1)
320 // iterate over the indexes backwards in order to correctly move multiselected items
321 for (i = m_cList.GetSelectedCount() - 1; i >= 0; i--)
323 int index = indexes[i];
324 CString old = m_cList.GetItemText(index, 0);
325 BOOL oldState = m_cList.GetCheck(index);
326 m_cList.DeleteItem(index);
327 m_cList.InsertItem(index + 1, old);
328 m_cList.SetCheck(index + 1, oldState);
329 m_cList.SetItemState(index + 1, LVIS_SELECTED, LVIS_SELECTED);
330 m_cList.SetItemState(index, 0, LVIS_SELECTED);
335 void CImportPatchDlg::OnBnClickedButtonRemove()
337 POSITION pos;
338 pos = m_cList.GetFirstSelectedItemPosition();
339 while (pos)
341 int index = m_cList.GetNextSelectedItem(pos);
342 m_cList.DeleteItem(index);
343 pos = m_cList.GetFirstSelectedItemPosition();
345 m_cList.SetColumnWidth(0, LVSCW_AUTOSIZE);
348 UINT CImportPatchDlg::PatchThread()
350 CTGitPath path;
351 path.SetFromWin(g_Git.m_CurrentDir);
353 int i=0;
354 UpdateOkCancelText();
355 for (i = m_CurrentItem; i < m_cList.GetItemCount(); ++i)
357 if (m_pTaskbarList)
359 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
360 m_pTaskbarList->SetProgressValue(m_hWnd, i, m_cList.GetItemCount());
363 m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLYING|m_cList.GetItemData(i));
365 CRect rect;
366 this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
367 this->m_cList.InvalidateRect(rect);
369 m_cList.SetColumnWidth(0, LVSCW_AUTOSIZE);
370 m_cList.EnsureVisible(i, FALSE);
372 if(m_bExitThread)
373 break;
375 if(m_cList.GetCheck(i))
377 CString cmd;
379 while(path.HasRebaseApply())
381 if (m_pTaskbarList)
382 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);
384 int ret = CMessageBox::Show(GetSafeHwnd(), IDS_PROC_APPLYPATCH_REBASEDIRFOUND,
385 IDS_APPNAME,
386 1, IDI_ERROR, IDS_ABORTBUTTON, IDS_SKIPBUTTON, IDS_RESOLVEDBUTTON);
388 switch(ret)
390 case 1:
391 cmd = L"git.exe am --abort";
392 break;
393 case 2:
394 cmd = L"git.exe am --skip";
395 ++i;
396 break;
397 case 3:
398 cmd = L"git.exe am --resolved";
399 break;
400 default:
401 cmd.Empty();
403 if(cmd.IsEmpty())
405 m_bExitThread = TRUE;
406 break;
409 this->AddLogString(cmd);
410 CString output;
411 if (g_Git.Run(cmd, &output, CP_UTF8))
413 this->AddLogString(output);
414 this->AddLogString(CString(MAKEINTRESOURCE(IDS_FAIL)));
416 else
418 this->AddLogString(CString(MAKEINTRESOURCE(IDS_DONE)));
422 if(m_bExitThread)
423 break;
425 cmd = L"git.exe am ";
427 if(this->m_bAddSignedOffBy)
428 cmd += L"--signoff ";
430 if(this->m_b3Way)
431 cmd += L"--3way ";
433 if(this->m_bIgnoreSpace)
434 cmd += L"--ignore-space-change ";
436 if(this->m_bKeepCR)
437 cmd += L"--keep-cr ";
439 cmd += L'"';
440 cmd += m_cList.GetItemText(i,0);
441 cmd += L'"';
443 this->AddLogString(cmd);
444 CString output;
445 if (g_Git.Run(cmd, &output, CP_UTF8))
447 //keep STATUS_APPLYING to let user retry failed patch
448 m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_FAIL|CPatchListCtrl::STATUS_APPLYING);
449 this->AddLogString(output);
450 this->AddLogString(CString(MAKEINTRESOURCE(IDS_FAIL)));
451 if (m_pTaskbarList)
452 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);
453 break;
456 else
458 m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_SUCCESS);
459 this->AddLogString(CString(MAKEINTRESOURCE(IDS_SUCCESS)));
463 else
465 CString sMessage;
466 sMessage.Format(IDS_PROC_SKIPPATCH, (LPCTSTR)m_cList.GetItemText(i, 0));
467 AddLogString(sMessage);
468 m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_SKIP);
471 m_cList.SetItemData(m_CurrentItem, (~CPatchListCtrl::STATUS_APPLYING)&m_cList.GetItemData(i));
472 ++m_CurrentItem;
474 this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
475 this->m_cList.InvalidateRect(rect);
477 UpdateOkCancelText();
480 //in case am fail, need refresh finial item status
481 CRect rect;
482 this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
483 this->m_cList.InvalidateRect(rect);
485 this->m_cList.GetItemRect(m_CurrentItem,&rect,LVIR_BOUNDS);
486 this->m_cList.InvalidateRect(rect);
488 if (m_pTaskbarList)
490 m_pTaskbarList->SetProgressValue(m_hWnd, m_CurrentItem, m_cList.GetItemCount());
491 if (m_bExitThread && m_CurrentItem != m_cList.GetItemCount())
492 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED);
493 else if (!m_bExitThread && m_CurrentItem == m_cList.GetItemCount())
494 m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
497 EnableInputCtrl(true);
498 InterlockedExchange(&m_bThreadRunning, FALSE);
499 UpdateOkCancelText();
500 return 0;
503 void CImportPatchDlg::OnBnClickedOk()
505 m_PathList.Clear();
506 this->UpdateData();
508 SaveSplitterPos();
510 if (!CAppUtils::CheckUserData(GetSafeHwnd()))
511 return;
513 if(IsFinish())
515 this->OnOK();
516 return;
519 m_ctrlTabCtrl.SetActiveTab(1);
521 EnableInputCtrl(false);
522 InterlockedExchange(&m_bThreadRunning, TRUE);
523 InterlockedExchange(&this->m_bExitThread, FALSE);
524 if ((m_LoadingThread = AfxBeginThread(ThreadEntry, this)) == nullptr)
526 InterlockedExchange(&m_bThreadRunning, FALSE);
527 CMessageBox::Show(GetSafeHwnd(), IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
531 void CImportPatchDlg::DoSize(int delta)
533 this->RemoveAllAnchors();
535 auto hdwp = BeginDeferWindowPos(6);
536 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_LIST_PATCH), 0, 0, 0, delta);
537 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_AM_TAB), 0, delta, 0, 0);
538 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_CHECK_3WAY), 0, delta, 0, delta);
539 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_CHECK_IGNORE_SPACE), 0, delta, 0, delta);
540 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_SIGN_OFF), 0, delta, 0, delta);
541 hdwp = CSplitterControl::ChangeRect(hdwp, GetDlgItem(IDC_KEEP_CR), 0, delta, 0, delta);
542 EndDeferWindowPos(hdwp);
544 this->AddAmAnchor();
545 // adjust the minimum size of the dialog to prevent the resizing from
546 // moving the list control too far down.
547 CRect rcLogMsg;
548 m_cList.GetClientRect(rcLogMsg);
549 SetMinTrackSize(CSize(m_DlgOrigRect.Width(), m_DlgOrigRect.Height()-m_PatchListOrigRect.Height()+rcLogMsg.Height()));
551 SetSplitterRange();
552 // m_CommitList.Invalidate();
554 // GetDlgItem(IDC_LOGMESSAGE)->Invalidate();
556 this->m_ctrlTabCtrl.Invalidate();
559 void CImportPatchDlg::OnSize(UINT nType, int cx, int cy)
561 CResizableStandAloneDialog::OnSize(nType, cx, cy);
563 SetSplitterRange();
566 LRESULT CImportPatchDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
568 switch (message) {
569 case WM_NOTIFY:
570 if (wParam == IDC_AM_SPLIT)
572 SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
573 DoSize(pHdr->delta);
575 break;
578 return CResizableStandAloneDialog::DefWindowProc(message, wParam, lParam);
581 void CImportPatchDlg::SaveSplitterPos()
583 if (!IsIconic())
585 CRegDWORD regPos(L"Software\\TortoiseGit\\TortoiseProc\\ResizableState\\AMDlgSizer");
586 RECT rectSplitter;
587 m_wndSplitter.GetWindowRect(&rectSplitter);
588 ScreenToClient(&rectSplitter);
589 regPos = rectSplitter.top;
593 void CImportPatchDlg::EnableInputCtrl(BOOL b)
595 this->GetDlgItem(IDC_BUTTON_UP)->EnableWindow(b);
596 this->GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow(b);
597 this->GetDlgItem(IDC_BUTTON_REMOVE)->EnableWindow(b);
598 this->GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(b);
599 this->GetDlgItem(IDOK)->EnableWindow(b);
602 void CImportPatchDlg::UpdateOkCancelText()
604 if (this->m_bThreadRunning && !IsFinish())
606 this->GetDlgItem(IDOK)->EnableWindow(FALSE);
607 this->GetDlgItem(IDCANCEL)->SetWindowText(CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
609 else if (!IsFinish())
611 this->GetDlgItem(IDOK)->EnableWindow(TRUE);
613 else
615 this->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
616 this->GetDlgItem(IDOK)->SetWindowText(CString(MAKEINTRESOURCE(IDS_OKBUTTON)));
619 void CImportPatchDlg::OnBnClickedCancel()
621 if(this->m_bThreadRunning)
623 InterlockedExchange(&m_bExitThread,TRUE);
625 else
627 CTGitPath path;
628 path.SetFromWin(g_Git.m_CurrentDir);
629 if(path.HasRebaseApply())
630 if (CMessageBox::Show(GetSafeHwnd(), IDS_PROC_APPLYPATCH_GITAMACTIVE, IDS_APPNAME, MB_YESNO | MB_ICONQUESTION) == IDYES)
632 CString output;
633 if (g_Git.Run(L"git.exe am --abort", &output, CP_UTF8))
634 MessageBox(output, L"TortoiseGit", MB_OK | MB_ICONERROR);
636 OnCancel();
640 void CImportPatchDlg::AddLogString(CString str)
642 this->m_wndOutput.SendMessage(SCI_SETREADONLY, FALSE);
643 CStringA sTextA = m_wndOutput.StringForControl(str);//CUnicodeUtils::GetUTF8(str);
644 this->m_wndOutput.SendMessage(SCI_REPLACESEL, 0, (LPARAM)(LPCSTR)sTextA);
645 this->m_wndOutput.SendMessage(SCI_REPLACESEL, 0, (LPARAM)(LPCSTR)"\n");
646 this->m_wndOutput.SendMessage(SCI_SETREADONLY, TRUE);
647 //this->m_wndOutput.SendMessage(SCI_LINESCROLL,0,0x7FFFFFFF);
649 BOOL CImportPatchDlg::PreTranslateMessage(MSG* pMsg)
651 if (pMsg->message == WM_KEYDOWN)
653 switch (pMsg->wParam)
655 /* Avoid TAB control destroy but dialog exist*/
656 case VK_ESCAPE:
657 case VK_CANCEL:
659 TCHAR buff[129];
660 ::GetClassName(pMsg->hwnd, buff, _countof(buff) - 1);
662 /* Use MSFTEDIT_CLASS http://msdn.microsoft.com/en-us/library/bb531344.aspx */
663 if (_wcsnicmp(buff, MSFTEDIT_CLASS, _countof(buff) - 1) == 0 || //Unicode and MFC 2012 and later
664 _wcsnicmp(buff, RICHEDIT_CLASS, _countof(buff) - 1) == 0 || //ANSI or MFC 2010
665 _wcsnicmp(buff, L"Scintilla", _countof(buff) - 1) == 0 ||
666 _wcsnicmp(buff, L"SysListView32", _countof(buff) - 1) == 0 ||
667 ::GetParent(pMsg->hwnd) == this->m_ctrlTabCtrl.m_hWnd)
669 this->PostMessage(WM_KEYDOWN,VK_ESCAPE,0);
670 return TRUE;
675 return CResizableStandAloneDialog::PreTranslateMessage(pMsg);
678 void CImportPatchDlg::OnHdnItemchangedListPatch(NMHDR * /*pNMHDR*/, LRESULT *pResult)
680 *pResult = 0;
682 if(this->m_cList.GetSelectedCount() != 1)
684 m_PatchCtrl.SendMessage(SCI_SETREADONLY, FALSE);
685 m_PatchCtrl.SetText(CString());
686 m_PatchCtrl.SendMessage(SCI_SETREADONLY, TRUE);
688 else
690 CString text;
692 POSITION pos;
693 pos = m_cList.GetFirstSelectedItemPosition();
694 int selected = m_cList.GetNextSelectedItem(pos);
696 if(selected>=0&& selected< m_cList.GetItemCount())
698 CString str = m_cList.GetItemText(selected,0);
699 m_PatchCtrl.SendMessage(SCI_SETREADONLY, FALSE);
700 m_PatchCtrl.SetText(text);
701 m_PatchCtrl.LoadFromFile(str);
702 m_PatchCtrl.SendMessage(SCI_SETREADONLY, TRUE);
705 else
707 m_PatchCtrl.SendMessage(SCI_SETREADONLY, FALSE);
708 m_PatchCtrl.SetText(text);
709 m_PatchCtrl.SendMessage(SCI_SETREADONLY, TRUE);
714 LRESULT CImportPatchDlg::OnTaskbarBtnCreated(WPARAM wParam, LPARAM lParam)
716 m_pTaskbarList.Release();
717 m_pTaskbarList.CoCreateInstance(CLSID_TaskbarList);
718 return __super::OnTaskbarButtonCreated(wParam, lParam);
721 void CImportPatchDlg::OnSysColorChange()
723 __super::OnSysColorChange();
724 m_PatchCtrl.SetUDiffStyle();
725 m_wndOutput.SetColors(true);
726 CAppUtils::SetListCtrlBackgroundImage(m_cList.GetSafeHwnd(), IDI_IMPORTPATHCES_BKG);
729 LRESULT CImportPatchDlg::OnThemeChanged()
731 CMFCVisualManager::GetInstance()->DestroyInstance();
732 return 0;