1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997-2000 Thingamahoochie Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /////////////////////////////////////////////////////////////////////////////
22 * @file HexMergeDoc.cpp
24 * @brief Implementation file for CHexMergeDoc
29 #include "HexMergeDoc.h"
31 #include "UnicodeString.h"
32 #include "HexMergeFrm.h"
33 #include "HexMergeView.h"
35 #include "FolderCmp.h"
36 #include "DiffContext.h" // FILE_SAME
38 #include "DirActions.h"
39 #include "OptionsDef.h"
40 #include "DiffFileInfo.h"
41 #include "SaveClosingDlg.h"
44 #include "OptionsMgr.h"
45 #include "FileOrFolderSelect.h"
46 #include "DiffWrapper.h"
47 #include "SyntaxColors.h"
49 #include "Constants.h"
56 int CHexMergeDoc::m_nBuffersTemp = 2;
58 static void UpdateDiffItem(int nBuffers, DIFFITEM &di, CDiffContext *pCtxt);
59 static int Try(HRESULT hr, UINT type = MB_OKCANCEL|MB_ICONSTOP);
62 * @brief Update diff item
64 static void UpdateDiffItem(int nBuffers, DIFFITEM &di, CDiffContext *pCtxt)
66 di.diffcode.setSideNone();
67 for (int nBuffer = 0; nBuffer < nBuffers; nBuffer++)
69 di.diffFileInfo[nBuffer].ClearPartial();
70 if (pCtxt->UpdateInfoFromDiskHalf(di, nBuffer))
71 di.diffcode.diffcode |= DIFFCODE::FIRST << nBuffer;
74 di.diffcode.diffcode &= ~(DIFFCODE::TEXTFLAGS | DIFFCODE::COMPAREFLAGS | DIFFCODE::COMPAREFLAGS3WAY);
77 di.diffcode.diffcode |= folderCmp.prepAndCompareFiles(pCtxt, di);
81 * @brief Issue an error popup if passed in HRESULT is nonzero
83 static int Try(HRESULT hr, UINT type)
85 return hr ? CInternetException(hr).ReportError(type) : 0;
88 /////////////////////////////////////////////////////////////////////////////
91 IMPLEMENT_DYNCREATE(CHexMergeDoc, CDocument)
93 BEGIN_MESSAGE_MAP(CHexMergeDoc, CDocument)
94 //{{AFX_MSG_MAP(CHexMergeDoc)
95 ON_COMMAND(ID_FILE_SAVE, OnFileSave)
96 ON_COMMAND(ID_FILE_SAVE_LEFT, OnFileSaveLeft)
97 ON_COMMAND(ID_FILE_SAVE_RIGHT, OnFileSaveRight)
98 ON_COMMAND(ID_FILE_SAVEAS_LEFT, OnFileSaveAsLeft)
99 ON_COMMAND(ID_FILE_SAVEAS_RIGHT, OnFileSaveAsRight)
100 ON_UPDATE_COMMAND_UI(ID_STATUS_DIFFNUM, OnUpdateStatusNum)
101 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_LEFT, OnUpdateFileSaveLeft)
102 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_RIGHT, OnUpdateFileSaveRight)
103 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
104 ON_COMMAND(ID_RESCAN, OnFileReload)
105 ON_COMMAND(ID_L2R, OnL2r)
106 ON_COMMAND(ID_R2L, OnR2l)
107 ON_COMMAND(ID_COPY_FROM_LEFT, OnCopyFromLeft)
108 ON_COMMAND(ID_COPY_FROM_RIGHT, OnCopyFromRight)
109 ON_COMMAND(ID_ALL_LEFT, OnAllLeft)
110 ON_COMMAND(ID_ALL_RIGHT, OnAllRight)
111 ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomIn)
112 ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomOut)
113 ON_COMMAND(ID_VIEW_ZOOMNORMAL, OnViewZoomNormal)
114 ON_COMMAND(ID_REFRESH, OnRefresh)
115 ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnFileRecompareAs)
116 ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateFileRecompareAs)
120 /////////////////////////////////////////////////////////////////////////////
121 // CHexMergeDoc construction/destruction
124 * @brief Constructor.
126 CHexMergeDoc::CHexMergeDoc()
128 , m_nBuffers(m_nBuffersTemp)
130 , m_nBufferType{BUFFER_NORMAL, BUFFER_NORMAL, BUFFER_NORMAL}
132 m_filePaths.SetSize(m_nBuffers);
138 * Informs associated dirdoc that mergedoc is closing.
140 CHexMergeDoc::~CHexMergeDoc()
142 if (m_pDirDoc != nullptr)
143 m_pDirDoc->MergeDocClosing(this);
147 * @brief Return active merge edit view (or left one if neither active)
149 CHexMergeView * CHexMergeDoc::GetActiveMergeView() const
151 CView * pActiveView = GetParentFrame()->GetActiveView();
152 CHexMergeView * pHexMergeView = dynamic_cast<CHexMergeView *>(pActiveView);
153 if (pHexMergeView == nullptr)
154 pHexMergeView = m_pView[0]; // default to left view (in case some location or detail view active)
155 return pHexMergeView;
159 * @brief Update associated diff item
161 int CHexMergeDoc::UpdateDiffItem(CDirDoc *pDirDoc)
163 // If directory compare has results
164 if (pDirDoc != nullptr && pDirDoc->HasDiffs())
166 CDiffContext &ctxt = pDirDoc->GetDiffContext();
167 if (DIFFITEM *pos = FindItemFromPaths(ctxt, m_filePaths))
169 DIFFITEM &di = ctxt.GetDiffRefAt(pos);
170 ::UpdateDiffItem(m_nBuffers, di, &ctxt);
174 int lengthFirst = m_pView[0]->GetLength();
175 void *bufferFirst = m_pView[0]->GetBuffer(lengthFirst);
176 for (int nBuffer = 1; nBuffer < m_nBuffers; nBuffer++)
178 int length = m_pView[nBuffer]->GetLength();
179 if (lengthFirst != length)
183 void *buffer = m_pView[nBuffer]->GetBuffer(length);
184 bDiff = (memcmp(bufferFirst, buffer, lengthFirst) != 0);
189 GetParentFrame()->SetLastCompareResult(bDiff);
190 return bDiff ? 1 : 0;
194 * @brief Asks and then saves modified files
196 bool CHexMergeDoc::PromptAndSaveIfNeeded(bool bAllowCancel)
198 bool bLModified = false, bMModified = false, bRModified = false;
202 bLModified = m_pView[0]->GetModified();
203 bMModified = m_pView[1]->GetModified();
204 bRModified = m_pView[2]->GetModified();
208 bLModified = m_pView[0]->GetModified();
209 bRModified = m_pView[1]->GetModified();
211 if (!bLModified && !bMModified && !bRModified)
214 const String &pathLeft = m_filePaths.GetLeft();
215 const String &pathMiddle = m_filePaths.GetMiddle();
216 const String &pathRight = m_filePaths.GetRight();
219 bool bLSaveSuccess = false, bMSaveSuccess = false, bRSaveSuccess = false;
222 dlg.DoAskFor(bLModified, bMModified, bRModified);
224 dlg.m_bDisableCancel = true;
225 if (!pathLeft.empty())
226 dlg.m_sLeftFile = pathLeft;
228 dlg.m_sLeftFile = m_strDesc[0];
231 if (!pathMiddle.empty())
232 dlg.m_sMiddleFile = pathMiddle;
234 dlg.m_sMiddleFile = m_strDesc[1];
236 if (!pathRight.empty())
237 dlg.m_sRightFile = pathRight;
239 dlg.m_sRightFile = m_strDesc[1];
241 if (dlg.DoModal() == IDOK)
245 if (dlg.m_leftSave == SaveClosingDlg::SAVECLOSING_SAVE)
247 switch (Try(m_pView[0]->SaveFile(pathLeft.c_str())))
250 bLSaveSuccess = true;
259 m_pView[0]->SetSavePoint();
264 if (dlg.m_middleSave == SaveClosingDlg::SAVECLOSING_SAVE)
266 switch (Try(m_pView[1]->SaveFile(pathMiddle.c_str())))
269 bMSaveSuccess = true;
278 m_pView[1]->SetSavePoint();
283 if (dlg.m_rightSave == SaveClosingDlg::SAVECLOSING_SAVE)
285 switch (Try(m_pView[m_nBuffers - 1]->SaveFile(pathRight.c_str())))
288 bRSaveSuccess = true;
297 m_pView[m_nBuffers - 1]->SetSavePoint();
306 // If file were modified and saving was successfull,
307 // update status on dir view
308 if (bLSaveSuccess || bMSaveSuccess || bRSaveSuccess)
310 UpdateDiffItem(m_pDirDoc);
317 * @brief Save modified documents
319 BOOL CHexMergeDoc::SaveModified()
321 return PromptAndSaveIfNeeded(true);
325 * @brief Saves both files
327 void CHexMergeDoc::OnFileSave()
329 for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
333 void CHexMergeDoc::DoFileSave(int nBuffer)
335 if (m_pView[nBuffer]->GetModified())
337 if (m_nBufferType[nBuffer] == BUFFER_UNNAMED)
338 DoFileSaveAs(nBuffer);
341 const String &path = m_filePaths.GetPath(nBuffer);
342 if (Try(m_pView[nBuffer]->SaveFile(path.c_str())) == IDCANCEL)
345 UpdateDiffItem(m_pDirDoc);
349 void CHexMergeDoc::DoFileSaveAs(int nBuffer)
351 const String &path = m_filePaths.GetPath(nBuffer);
355 title = _("Save Left File As");
356 else if (nBuffer == m_nBuffers - 1)
357 title = _("Save Right File As");
359 title = _("Save Middle File As");
360 if (SelectFile(AfxGetMainWnd()->GetSafeHwnd(), strPath, false, path.c_str(), title))
362 if (Try(m_pView[nBuffer]->SaveFile(strPath.c_str())) == IDCANCEL)
366 // We are saving scratchpad (unnamed file)
367 m_nBufferType[nBuffer] = BUFFER_UNNAMED_SAVED;
368 m_strDesc[nBuffer].erase();
371 m_filePaths.SetPath(nBuffer, strPath);
372 UpdateDiffItem(m_pDirDoc);
373 UpdateHeaderPath(nBuffer);
378 * @brief Saves left-side file
380 void CHexMergeDoc::OnFileSaveLeft()
386 * @brief Saves middle-side file
388 void CHexMergeDoc::OnFileSaveMiddle()
394 * @brief Saves right-side file
396 void CHexMergeDoc::OnFileSaveRight()
398 DoFileSave(m_nBuffers - 1);
402 * @brief Saves left-side file with name asked
404 void CHexMergeDoc::OnFileSaveAsLeft()
410 * @brief Saves right-side file with name asked
412 void CHexMergeDoc::OnFileSaveAsMiddle()
418 * @brief Saves right-side file with name asked
420 void CHexMergeDoc::OnFileSaveAsRight()
422 DoFileSaveAs(m_nBuffers - 1);
426 * @brief Update diff-number pane text
428 void CHexMergeDoc::OnUpdateStatusNum(CCmdUI* pCmdUI)
431 pCmdUI->SetText(s.c_str());
435 * @brief DirDoc gives us its identity just after it creates us
437 void CHexMergeDoc::SetDirDoc(CDirDoc * pDirDoc)
439 ASSERT(pDirDoc != nullptr && m_pDirDoc == nullptr);
444 * @brief Return pointer to parent frame
446 CHexMergeFrame * CHexMergeDoc::GetParentFrame() const
448 return static_cast<CHexMergeFrame *>(m_pView[0]->GetParentFrame());
452 * @brief DirDoc is closing
454 void CHexMergeDoc::DirDocClosing(CDirDoc * pDirDoc)
456 ASSERT(m_pDirDoc == pDirDoc);
461 * @brief DirDoc commanding us to close
463 bool CHexMergeDoc::CloseNow()
465 // Allow user to cancel closing
466 if (!PromptAndSaveIfNeeded(true))
469 GetParentFrame()->CloseNow();
474 * @brief Load one file
476 HRESULT CHexMergeDoc::LoadOneFile(int index, LPCTSTR filename, bool readOnly, const String& strDesc)
480 if (Try(m_pView[index]->LoadFile(filename), MB_ICONSTOP) != 0)
482 m_pView[index]->SetReadOnly(readOnly);
483 m_filePaths.SetPath(index, filename);
484 ASSERT(m_nBufferType[index] == BUFFER_NORMAL); // should have been initialized to BUFFER_NORMAL in constructor
485 if (!strDesc.empty())
487 m_strDesc[index] = strDesc;
488 m_nBufferType[index] = BUFFER_NORMAL_NAMED;
493 m_nBufferType[index] = BUFFER_UNNAMED;
494 m_strDesc[index] = strDesc;
496 UpdateHeaderPath(index);
497 m_pView[index]->ResizeWindow();
502 * @brief Load files and initialize frame's compare result icon
504 bool CHexMergeDoc::OpenDocs(int nFiles, const FileLocation fileloc[], const bool bRO[], const String strDesc[])
506 CHexMergeFrame *pf = GetParentFrame();
507 ASSERT(pf != nullptr);
508 bool bSucceeded = true;
510 for (nBuffer = 0; nBuffer < nFiles; nBuffer++)
512 if (FAILED(LoadOneFile(nBuffer, fileloc[nBuffer].filepath.c_str(), bRO[nBuffer], strDesc ? strDesc[nBuffer] : _T(""))))
518 if (nBuffer == nFiles)
520 // An extra ResizeWindow() on the left view aligns scroll ranges, and
521 // also triggers initial diff coloring by invalidating the client area.
522 m_pView[0]->ResizeWindow();
528 // Use verify macro to trap possible error in debug.
529 VERIFY(pf->DestroyWindow());
534 void CHexMergeDoc::MoveOnLoad(int nPane, int)
538 nPane = GetOptionsMgr()->GetInt(OPT_ACTIVE_PANE);
539 if (nPane < 0 || nPane >= m_nBuffers)
543 GetParentFrame()->SetActivePane(nPane);
545 if (GetOptionsMgr()->GetBool(OPT_SCROLL_TO_FIRST))
546 m_pView[0]->SendMessage(WM_COMMAND, ID_FIRSTDIFF);
549 void CHexMergeDoc::CheckFileChanged(void)
551 for (int pane = 0; pane < m_nBuffers; ++pane)
553 if (m_pView[pane]->IsFileChangedOnDisk(m_filePaths[pane].c_str()))
555 String msg = strutils::format_string1(_("Another application has updated file\n%1\nsince WinMerge scanned it last time.\n\nDo you want to reload the file?"), m_filePaths[pane]);
556 if (AfxMessageBox(msg.c_str(), MB_YESNO | MB_ICONWARNING) == IDYES)
566 * @brief Write path and filename to headerbar
567 * @note SetText() does not repaint unchanged text
569 void CHexMergeDoc::UpdateHeaderPath(int pane)
571 CHexMergeFrame *pf = GetParentFrame();
572 ASSERT(pf != nullptr);
575 if (m_nBufferType[pane] == BUFFER_UNNAMED ||
576 m_nBufferType[pane] == BUFFER_NORMAL_NAMED)
578 sText = m_strDesc[pane];
582 sText = m_filePaths.GetPath(pane);
583 if (m_pDirDoc != nullptr)
584 m_pDirDoc->ApplyDisplayRoot(pane, sText);
586 if (m_pView[pane]->GetModified())
587 sText.insert(0, _T("* "));
588 pf->GetHeaderInterface()->SetText(pane, sText);
595 * @brief Customize a heksedit control's settings
597 static void Customize(IHexEditorWindow::Settings *settings)
599 settings->bSaveIni = false;
600 //settings->iAutomaticBPL = false;
601 //settings->iBytesPerLine = 16;
602 //settings->iFontSize = 8;
606 * @brief Customize a heksedit control's colors
608 static void Customize(IHexEditorWindow::Colors *colors)
610 COptionsMgr *pOptionsMgr = GetOptionsMgr();
611 colors->iSelBkColorValue = RGB(224, 224, 224);
612 colors->iDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF);
613 colors->iSelDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF);
614 colors->iDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF_TEXT);
615 if (colors->iDiffTextColorValue == 0xFFFFFFFF)
616 colors->iDiffTextColorValue = 0;
617 colors->iSelDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF_TEXT);
618 if (colors->iSelDiffTextColorValue == 0xFFFFFFFF)
619 colors->iSelDiffTextColorValue = 0;
620 SyntaxColors *pSyntaxColors = theApp.GetMainSyntaxColors();
621 colors->iTextColorValue = pSyntaxColors->GetColor(COLORINDEX_NORMALTEXT);
622 colors->iBkColorValue = pSyntaxColors->GetColor(COLORINDEX_BKGND);
623 colors->iSelTextColorValue = pSyntaxColors->GetColor(COLORINDEX_SELTEXT);
624 colors->iSelBkColorValue = pSyntaxColors->GetColor(COLORINDEX_SELBKGND);
628 * @brief Customize a heksedit control's settings and colors
630 static void Customize(IHexEditorWindow *pif)
632 Customize(pif->get_settings());
633 Customize(pif->get_colors());
634 //LANGID wLangID = (LANGID)GetThreadLocale();
635 //pif->load_lang(wLangID);
638 void CHexMergeDoc::RefreshOptions()
640 for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
642 IHexEditorWindow *pif = m_pView[nBuffer]->GetInterface();
643 pif->read_ini_data();
645 pif->resize_window();
650 * @brief Update document filenames to title
652 void CHexMergeDoc::SetTitle(LPCTSTR lpszTitle)
657 if (lpszTitle != nullptr)
661 for (int nBuffer = 0; nBuffer < m_filePaths.GetSize(); nBuffer++)
662 sFileName[nBuffer] = !m_strDesc[nBuffer].empty() ? m_strDesc[nBuffer] : paths::FindFileName(m_filePaths[nBuffer]);
663 if (std::count(&sFileName[0], &sFileName[0] + m_nBuffers, sFileName[0]) == m_nBuffers)
664 sTitle = sFileName[0] + strutils::format(_T(" x %d"), m_nBuffers);
666 sTitle = strutils::join(&sFileName[0], &sFileName[0] + m_nBuffers, _T(" - "));
668 CDocument::SetTitle(sTitle.c_str());
672 * @brief We have two child views (left & right), so we keep pointers directly
673 * at them (the MFC view list doesn't have them both)
675 void CHexMergeDoc::SetMergeViews(CHexMergeView *pView[])
677 for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
679 ASSERT(pView[nBuffer] != nullptr && m_pView[nBuffer] == nullptr);
680 m_pView[nBuffer] = pView[nBuffer];
681 m_pView[nBuffer]->m_nThisPane = nBuffer;
686 * @brief Called when "Save left" item is updated
688 void CHexMergeDoc::OnUpdateFileSaveLeft(CCmdUI* pCmdUI)
690 pCmdUI->Enable(m_pView[0]->GetModified());
694 * @brief Called when "Save middle" item is updated
696 void CHexMergeDoc::OnUpdateFileSaveMiddle(CCmdUI* pCmdUI)
698 pCmdUI->Enable(m_nBuffers == 3 && m_pView[1]->GetModified());
702 * @brief Called when "Save right" item is updated
704 void CHexMergeDoc::OnUpdateFileSaveRight(CCmdUI* pCmdUI)
706 pCmdUI->Enable(m_pView[m_nBuffers - 1]->GetModified());
710 * @brief Called when "Save" item is updated
712 void CHexMergeDoc::OnUpdateFileSave(CCmdUI* pCmdUI)
714 bool bModified = false;
715 for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
716 bModified |= m_pView[nBuffer]->GetModified();
717 pCmdUI->Enable(bModified);
721 * @brief Reloads the opened files
723 void CHexMergeDoc::OnFileReload()
725 if (!PromptAndSaveIfNeeded(true))
728 FileLocation fileloc[3];
730 for (int pane = 0; pane < m_nBuffers; pane++)
732 fileloc[pane].setPath(m_filePaths[pane]);
733 bRO[pane] = m_pView[pane]->GetReadOnly();
735 OpenDocs(m_nBuffers, fileloc, bRO, m_strDesc);
736 MoveOnLoad(GetActiveMergeView()->m_nThisPane);
740 * @brief Copy selected bytes from left to right
742 void CHexMergeDoc::OnL2r()
744 int dstPane = (GetActiveMergeView()->m_nThisPane < m_nBuffers - 1) ? GetActiveMergeView()->m_nThisPane + 1 : m_nBuffers - 1;
745 int srcPane = dstPane - 1;
746 CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
750 * @brief Copy selected bytes from right to left
752 void CHexMergeDoc::OnR2l()
754 int dstPane = (GetActiveMergeView()->m_nThisPane > 0) ? GetActiveMergeView()->m_nThisPane - 1 : 0;
755 int srcPane = dstPane + 1;
756 CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
760 * @brief Copy selected bytes from left to active pane
762 void CHexMergeDoc::OnCopyFromLeft()
764 int dstPane = GetActiveMergeView()->m_nThisPane;
765 int srcPane = (dstPane - 1 < 0) ? 0 : dstPane - 1;
766 CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
770 * @brief Copy selected bytes from right to active pane
772 void CHexMergeDoc::OnCopyFromRight()
774 int dstPane = GetActiveMergeView()->m_nThisPane;
775 int srcPane = (dstPane + 1 > m_nBuffers - 1) ? m_nBuffers - 1 : dstPane + 1;
776 CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
780 * @brief Copy all bytes from left to right
782 void CHexMergeDoc::OnAllRight()
784 int dstPane = (GetActiveMergeView()->m_nThisPane < m_nBuffers - 1) ? GetActiveMergeView()->m_nThisPane + 1 : m_nBuffers - 1;
785 int srcPane = dstPane - 1;
786 CHexMergeView::CopyAll(m_pView[srcPane], m_pView[dstPane]);
790 * @brief Copy all bytes from right to left
792 void CHexMergeDoc::OnAllLeft()
794 int dstPane = (GetActiveMergeView()->m_nThisPane > 0) ? GetActiveMergeView()->m_nThisPane - 1 : 0;
795 int srcPane = dstPane + 1;
796 CHexMergeView::CopyAll(m_pView[srcPane], m_pView[dstPane]);
800 * @brief Called when user selects View/Zoom In from menu.
802 void CHexMergeDoc::OnViewZoomIn()
804 for (int pane = 0; pane < m_nBuffers; pane++)
805 m_pView[pane]->ZoomText(1);
809 * @brief Called when user selects View/Zoom Out from menu.
811 void CHexMergeDoc::OnViewZoomOut()
813 for (int pane = 0; pane < m_nBuffers; pane++)
814 m_pView[pane]->ZoomText(-1);
818 * @brief Called when user selects View/Zoom Normal from menu.
820 void CHexMergeDoc::OnViewZoomNormal()
822 for (int pane = 0; pane < m_nBuffers; pane++)
823 m_pView[pane]->ZoomText(0);
826 void CHexMergeDoc::OnRefresh()
828 if (UpdateDiffItem(m_pDirDoc) == 0)
829 LangMessageBox(IDS_FILESSAME, MB_ICONINFORMATION | MB_DONT_DISPLAY_AGAIN);
832 void CHexMergeDoc::OnFileRecompareAs(UINT nID)
834 FileLocation fileloc[3];
837 int nBuffers = m_nBuffers;
838 CDirDoc *pDirDoc = m_pDirDoc->GetMainView() ? m_pDirDoc :
839 static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
840 for (int nBuffer = 0; nBuffer < nBuffers; ++nBuffer)
842 fileloc[nBuffer].setPath(m_filePaths[nBuffer]);
843 dwFlags[nBuffer] = m_pView[nBuffer]->GetReadOnly() ? FFILEOPEN_READONLY : 0;
844 strDesc[nBuffer] = m_strDesc[nBuffer];
847 if (nID == ID_MERGE_COMPARE_TEXT)
848 GetMainFrame()->ShowMergeDoc(pDirDoc, nBuffers, fileloc, dwFlags, strDesc);
850 GetMainFrame()->ShowImgMergeDoc(pDirDoc, nBuffers, fileloc, dwFlags, strDesc);
853 void CHexMergeDoc::OnUpdateFileRecompareAs(CCmdUI* pCmdUI)
855 pCmdUI->Enable(pCmdUI->m_nID != ID_MERGE_COMPARE_XML);