[Winmerge-svn] SF.net SVN: winmerge:[5774] trunk/Src
Windows visual diff and merge for files and directories
Brought to you by:
christianlist,
grimmdp
From: <ki...@us...> - 2008-08-09 09:21:55
|
Revision: 5774 http://winmerge.svn.sourceforge.net/winmerge/?rev=5774&view=rev Author: kimmov Date: 2008-08-09 09:21:52 +0000 (Sat, 09 Aug 2008) Log Message: ----------- Add our default SVN properties for new files. Modified Paths: -------------- trunk/Src/HexMergeDoc.cpp trunk/Src/HexMergeDoc.h trunk/Src/HexMergeFrm.cpp trunk/Src/HexMergeFrm.h trunk/Src/HexMergeView.cpp trunk/Src/HexMergeView.h Property Changed: ---------------- trunk/Src/HexMergeDoc.cpp trunk/Src/HexMergeDoc.h trunk/Src/HexMergeFrm.cpp trunk/Src/HexMergeFrm.h trunk/Src/HexMergeView.cpp trunk/Src/HexMergeView.h Modified: trunk/Src/HexMergeDoc.cpp =================================================================== --- trunk/Src/HexMergeDoc.cpp 2008-08-09 08:44:31 UTC (rev 5773) +++ trunk/Src/HexMergeDoc.cpp 2008-08-09 09:21:52 UTC (rev 5774) @@ -1,636 +1,636 @@ -///////////////////////////////////////////////////////////////////////////// -// WinMerge: an interactive diff/merge utility -// Copyright (C) 1997-2000 Thingamahoochie Software -// Author: Dean Grimm -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -///////////////////////////////////////////////////////////////////////////// -/** - * @file HexMergeDoc.cpp - * - * @brief Implementation file for CHexMergeDoc - * - */ -// ID line follows -- this is updated by SVN -// $Id: $ - -#include "stdafx.h" -#include <afxinet.h> -#include "UnicodeString.h" -#include "FileTextEncoding.h" -#include "Merge.h" -#include "HexMergeDoc.h" -#include "HexMergeFrm.h" -#include "HexMergeView.h" -#include "DiffItem.h" -#include "FolderCmp.h" -#include "MainFrm.h" -#include "Environment.h" -#include "diffcontext.h" // FILE_SAME -#include "getopt.h" -#include "fnmatch.h" -#include "coretools.h" -#include "dirdoc.h" -#include "files.h" -#include "OptionsDef.h" -#include "DiffFileInfo.h" -#include "SaveClosingDlg.h" -#include "DiffList.h" -#include "paths.h" -#include "OptionsMgr.h" -#include "FileOrFolderSelect.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -static void UpdateDiffItem(DIFFITEM &di, CDiffContext *pCtxt); -static int Try(HRESULT hr, UINT type = MB_OKCANCEL|MB_ICONSTOP); - -/** - * @brief Update diff item - */ -static void UpdateDiffItem(DIFFITEM &di, CDiffContext *pCtxt) -{ - di.diffcode.diffcode |= DIFFCODE::SIDEFLAGS; - di.left.ClearPartial(); - di.right.ClearPartial(); - if (!pCtxt->UpdateInfoFromDiskHalf(di, TRUE)) - di.diffcode.diffcode &= ~DIFFCODE::LEFT; - if (!pCtxt->UpdateInfoFromDiskHalf(di, FALSE)) - di.diffcode.diffcode &= ~DIFFCODE::RIGHT; - // 1. Clear flags - di.diffcode.diffcode &= ~(DIFFCODE::TEXTFLAGS | DIFFCODE::COMPAREFLAGS); - // 2. Process unique files - // We must compare unique files to itself to detect encoding - if (di.diffcode.isSideLeftOnly() || di.diffcode.isSideRightOnly()) - { - if (pCtxt->m_nCompMethod != CMP_DATE && - pCtxt->m_nCompMethod != CMP_DATE_SIZE && - pCtxt->m_nCompMethod != CMP_SIZE) - { - di.diffcode.diffcode |= DIFFCODE::SAME; - FolderCmp folderCmp; - int diffCode = folderCmp.prepAndCompareTwoFiles(pCtxt, di); - // Add possible binary flag for unique items - if (diffCode & DIFFCODE::BIN) - di.diffcode.diffcode |= DIFFCODE::BIN; - } - } - // 3. Compare two files - else - { - // Really compare - FolderCmp folderCmp; - di.diffcode.diffcode |= folderCmp.prepAndCompareTwoFiles(pCtxt, di); - } -} - -/** - * @brief Issue an error popup if passed in HRESULT is nonzero - */ -static int Try(HRESULT hr, UINT type) -{ - return hr ? CInternetException(hr).ReportError(type) : 0; -} - -///////////////////////////////////////////////////////////////////////////// -// CHexMergeDoc - -IMPLEMENT_DYNCREATE(CHexMergeDoc, CDocument) - -BEGIN_MESSAGE_MAP(CHexMergeDoc, CDocument) - //{{AFX_MSG_MAP(CHexMergeDoc) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_FILE_SAVE_LEFT, OnFileSaveLeft) - ON_COMMAND(ID_FILE_SAVE_RIGHT, OnFileSaveRight) - ON_COMMAND(ID_FILE_SAVEAS_LEFT, OnFileSaveAsLeft) - ON_COMMAND(ID_FILE_SAVEAS_RIGHT, OnFileSaveAsRight) - ON_UPDATE_COMMAND_UI(ID_STATUS_DIFFNUM, OnUpdateStatusNum) - ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_LEFT, OnUpdateFileSaveLeft) - ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_RIGHT, OnUpdateFileSaveRight) - ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave) - ON_COMMAND(ID_L2R, OnL2r) - ON_COMMAND(ID_R2L, OnR2l) - ON_COMMAND(ID_ALL_LEFT, OnAllLeft) - ON_COMMAND(ID_ALL_RIGHT, OnAllRight) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CHexMergeDoc construction/destruction - -/** - * @brief Constructor. - */ -CHexMergeDoc::CHexMergeDoc() -: m_pDirDoc(NULL) -{ - m_pView[MERGE_VIEW_LEFT] = NULL; - m_pView[MERGE_VIEW_RIGHT] = NULL; -} - -/** - * @brief Destructor. - * - * Informs associated dirdoc that mergedoc is closing. - */ -CHexMergeDoc::~CHexMergeDoc() -{ - if (m_pDirDoc) - m_pDirDoc->MergeDocClosing(this); -} - -/** - * @brief Update associated diff item - */ -void CHexMergeDoc::UpdateDiffItem(CDirDoc *pDirDoc) -{ - // If directory compare has results - if (pDirDoc && pDirDoc->HasDiffs()) - { - const String &pathLeft = m_filePaths.GetLeft(); - const String &pathRight = m_filePaths.GetRight(); - CDiffContext &ctxt = const_cast<CDiffContext &>(pDirDoc->GetDiffContext()); - if (POSITION pos = pDirDoc->FindItemFromPaths(pathLeft.c_str(), pathRight.c_str())) - { - DIFFITEM &di = pDirDoc->GetDiffRefByKey(pos); - ::UpdateDiffItem(di, &ctxt); - } - } - int lengthLeft = m_pView[MERGE_VIEW_LEFT]->GetLength(); - void *bufferLeft = m_pView[MERGE_VIEW_LEFT]->GetBuffer(lengthLeft); - int lengthRight = m_pView[MERGE_VIEW_RIGHT]->GetLength(); - void *bufferRight = m_pView[MERGE_VIEW_RIGHT]->GetBuffer(lengthRight); - GetParentFrame()->SetLastCompareResult(lengthLeft != lengthRight || - bufferLeft && bufferRight && memcmp(bufferLeft, bufferRight, lengthLeft)); -} - -/** - * @brief Asks and then saves modified files - */ -BOOL CHexMergeDoc::PromptAndSaveIfNeeded(BOOL bAllowCancel) -{ - const BOOL bLModified = m_pView[MERGE_VIEW_LEFT]->GetModified(); - const BOOL bRModified = m_pView[MERGE_VIEW_RIGHT]->GetModified(); - - if (!bLModified && !bRModified) //Both files unmodified - return TRUE; - - const String &pathLeft = m_filePaths.GetLeft(); - const String &pathRight = m_filePaths.GetRight(); - - BOOL result = TRUE; - BOOL bLSaveSuccess = FALSE; - BOOL bRSaveSuccess = FALSE; - - SaveClosingDlg dlg; - dlg.DoAskFor(bLModified, bRModified); - if (!bAllowCancel) - dlg.m_bDisableCancel = TRUE; - if (!pathLeft.empty()) - dlg.m_sLeftFile = pathLeft.c_str(); - else - dlg.m_sLeftFile = m_strDesc[0].c_str(); - if (!pathRight.empty()) - dlg.m_sRightFile = pathRight.c_str(); - else - dlg.m_sRightFile = m_strDesc[1].c_str(); - - if (dlg.DoModal() == IDOK) - { - if (bLModified) - { - if (dlg.m_leftSave == SaveClosingDlg::SAVECLOSING_SAVE) - { - switch (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str()))) - { - case 0: - bLSaveSuccess = TRUE; - break; - case IDCANCEL: - result = FALSE; - break; - } - } - else - { - m_pView[MERGE_VIEW_LEFT]->SetModified(FALSE); - } - } - if (bRModified) - { - if (dlg.m_rightSave == SaveClosingDlg::SAVECLOSING_SAVE) - { - switch (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str()))) - { - case 0: - bRSaveSuccess = TRUE; - break; - case IDCANCEL: - result = FALSE; - break; - } - } - else - { - m_pView[MERGE_VIEW_RIGHT]->SetModified(FALSE); - } - } - } - else - { - result = FALSE; - } - - // If file were modified and saving was successfull, - // update status on dir view - if (bLSaveSuccess || bRSaveSuccess) - { - UpdateDiffItem(m_pDirDoc); - } - - return result; -} - -/** - * @brief Save modified documents - */ -BOOL CHexMergeDoc::SaveModified() -{ - return PromptAndSaveIfNeeded(TRUE); -} - -/** - * @brief Saves both files - */ -void CHexMergeDoc::OnFileSave() -{ - BOOL bUpdate = FALSE; - if (m_pView[MERGE_VIEW_LEFT]->GetModified()) - { - const String &pathLeft = m_filePaths.GetLeft(); - if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str())) == IDCANCEL) - return; - bUpdate = TRUE; - } - if (m_pView[MERGE_VIEW_RIGHT]->GetModified()) - { - const String &pathRight = m_filePaths.GetRight(); - if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str())) == IDCANCEL) - return; - bUpdate = TRUE; - } - if (bUpdate) - UpdateDiffItem(m_pDirDoc); -} - -/** - * @brief Saves left-side file - */ -void CHexMergeDoc::OnFileSaveLeft() -{ - if (m_pView[MERGE_VIEW_LEFT]->GetModified()) - { - const String &pathLeft = m_filePaths.GetLeft(); - if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str())) == IDCANCEL) - return; - UpdateDiffItem(m_pDirDoc); - } -} - -/** - * @brief Saves right-side file - */ -void CHexMergeDoc::OnFileSaveRight() -{ - if (m_pView[MERGE_VIEW_RIGHT]->GetModified()) - { - const String &pathRight = m_filePaths.GetRight(); - if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str())) == IDCANCEL) - return; - UpdateDiffItem(m_pDirDoc); - } -} - -/** - * @brief Saves left-side file with name asked - */ -void CHexMergeDoc::OnFileSaveAsLeft() -{ - const String &pathLeft = m_filePaths.GetLeft(); - CString strPath; - if (SelectFile(0, strPath, pathLeft.c_str(), IDS_SAVE_LEFT_AS, NULL, FALSE)) - { - if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(strPath)) == IDCANCEL) - return; - m_filePaths.SetLeft(strPath); - UpdateDiffItem(m_pDirDoc); - } -} - -/** - * @brief Saves right-side file with name asked - */ -void CHexMergeDoc::OnFileSaveAsRight() -{ - const String &pathRight = m_filePaths.GetRight(); - CString strPath; - if (SelectFile(0, strPath, pathRight.c_str(), IDS_SAVE_LEFT_AS, NULL, FALSE)) - { - if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(strPath)) == IDCANCEL) - return; - m_filePaths.SetRight(strPath); - UpdateDiffItem(m_pDirDoc); - } -} - -/** - * @brief Update diff-number pane text - */ -void CHexMergeDoc::OnUpdateStatusNum(CCmdUI* pCmdUI) -{ - String s; - pCmdUI->SetText(s.c_str()); -} - -/** - * @brief DirDoc gives us its identity just after it creates us - */ -void CHexMergeDoc::SetDirDoc(CDirDoc * pDirDoc) -{ - ASSERT(pDirDoc && !m_pDirDoc); - m_pDirDoc = pDirDoc; -} - -/** - * @brief Return pointer to parent frame - */ -CHexMergeFrame * CHexMergeDoc::GetParentFrame() -{ - return static_cast<CHexMergeFrame *>(m_pView[MERGE_VIEW_LEFT]->GetParentFrame()); -} - -/** - * @brief DirDoc is closing - */ -void CHexMergeDoc::DirDocClosing(CDirDoc * pDirDoc) -{ - ASSERT(m_pDirDoc == pDirDoc); - m_pDirDoc = 0; -} - -/** - * @brief DirDoc commanding us to close - */ -BOOL CHexMergeDoc::CloseNow() -{ - // Allow user to cancel closing - if (!PromptAndSaveIfNeeded(TRUE)) - return FALSE; - - GetParentFrame()->CloseNow(); - return TRUE; -} - -/** - * @brief Load files and initialize frame's compare result icon - */ -HRESULT CHexMergeDoc::OpenDocs(LPCTSTR pathLeft, LPCTSTR pathRight, BOOL bROLeft, BOOL bRORight) -{ - if (Try(m_pView[MERGE_VIEW_LEFT]->LoadFile(pathLeft), MB_ICONSTOP) == 0) - { - m_pView[MERGE_VIEW_LEFT]->SetReadOnly(bROLeft); - m_filePaths.SetLeft(pathLeft); - m_strDesc[MERGE_VIEW_LEFT] = pathLeft; - UpdateHeaderPath(MERGE_VIEW_LEFT); - } - if (Try(m_pView[MERGE_VIEW_RIGHT]->LoadFile(pathRight), MB_ICONSTOP) == 0) - { - m_pView[MERGE_VIEW_RIGHT]->SetReadOnly(bRORight); - m_filePaths.SetRight(pathRight); - m_strDesc[MERGE_VIEW_RIGHT] = pathRight; - UpdateHeaderPath(MERGE_VIEW_RIGHT); - } - m_pView[MERGE_VIEW_LEFT]->ResizeWindow(); - m_pView[MERGE_VIEW_RIGHT]->ResizeWindow(); - UpdateDiffItem(0); - if (GetOptionsMgr()->GetBool(OPT_SCROLL_TO_FIRST)) - m_pView[MERGE_VIEW_LEFT]->SendMessage(WM_COMMAND, ID_FIRSTDIFF); - return S_OK; -} - -/** - * @brief Write path and filename to headerbar - * @note SetText() does not repaint unchanged text - */ -void CHexMergeDoc::UpdateHeaderPath(int pane) -{ - CHexMergeFrame *pf = GetParentFrame(); - ASSERT(pf); - String sText; - - if (m_nBufferType[pane] == BUFFER_UNNAMED || - m_nBufferType[pane] == BUFFER_NORMAL_NAMED) - { - sText = m_strDesc[pane]; - } - else - { - sText = m_filePaths.GetPath(pane); - if (m_pDirDoc) - { - if (pane == 0) - m_pDirDoc->ApplyLeftDisplayRoot(sText); - else - m_pDirDoc->ApplyRightDisplayRoot(sText); - } - } - if (m_pView[pane]->GetModified()) - sText.insert(0, _T("* ")); - pf->GetHeaderInterface()->SetText(pane, sText.c_str()); - - SetTitle(NULL); -} - -/** - * @brief Update document filenames to title - */ -void CHexMergeDoc::SetTitle(LPCTSTR lpszTitle) -{ - const TCHAR pszSeparator[] = _T(" - "); - String sTitle; - - if (lpszTitle) - sTitle = lpszTitle; - else - { - if (!m_strDesc[0].empty()) - sTitle += m_strDesc[0]; - else - { - String file; - String ext; - SplitFilename(m_filePaths.GetLeft().c_str(), NULL, &file, &ext); - sTitle += file.c_str(); - if (!ext.empty()) - { - sTitle += _T("."); - sTitle += ext.c_str(); - } - } - - sTitle += pszSeparator; - - if (!m_strDesc[1].empty()) - sTitle += m_strDesc[1]; - else - { - String file; - String ext; - SplitFilename(m_filePaths.GetRight().c_str(), NULL, &file, &ext); - sTitle += file.c_str(); - if (!ext.empty()) - { - sTitle += _T("."); - sTitle += ext.c_str(); - } - } - } - CDocument::SetTitle(sTitle.c_str()); -} - -/** - * @brief We have two child views (left & right), so we keep pointers directly - * at them (the MFC view list doesn't have them both) - */ -void CHexMergeDoc::SetMergeViews(CHexMergeView * pLeft, CHexMergeView * pRight) -{ - ASSERT(pLeft && !m_pView[MERGE_VIEW_LEFT]); - m_pView[MERGE_VIEW_LEFT] = pLeft; - ASSERT(pRight && !m_pView[MERGE_VIEW_RIGHT]); - m_pView[MERGE_VIEW_RIGHT] = pRight; -} - -/** - * @brief Called when "Save left" item is updated - */ -void CHexMergeDoc::OnUpdateFileSaveLeft(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(m_pView[MERGE_VIEW_LEFT]->GetModified()); -} - -/** - * @brief Called when "Save right" item is updated - */ -void CHexMergeDoc::OnUpdateFileSaveRight(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(m_pView[MERGE_VIEW_RIGHT]->GetModified()); -} - -/** - * @brief Called when "Save" item is updated - */ -void CHexMergeDoc::OnUpdateFileSave(CCmdUI* pCmdUI) -{ - const BOOL bLModified = m_pView[MERGE_VIEW_LEFT]->GetModified(); - const BOOL bRModified = m_pView[MERGE_VIEW_RIGHT]->GetModified(); - pCmdUI->Enable(bLModified || bRModified); -} - -/** - * @brief Copy selected bytes from source view to destination view - * @note Grows destination buffer as appropriate - */ -void CHexMergeDoc::CopySel(CHexMergeView *pViewSrc, CHexMergeView *pViewDst) -{ - const IHexEditorWindow::Status *pStatSrc = pViewSrc->GetStatus(); - int i = min(pStatSrc->iStartOfSelection, pStatSrc->iEndOfSelection); - int j = max(pStatSrc->iStartOfSelection, pStatSrc->iEndOfSelection); - int u = pViewSrc->GetLength(); - int v = pViewDst->GetLength(); - if (pStatSrc->bSelected && i <= v) - { - if (v <= j) - v = j + 1; - BYTE *p = pViewSrc->GetBuffer(u); - BYTE *q = pViewDst->GetBuffer(v); - memcpy(q + i, p + i, j - i + 1); - CWnd *pwndFocus = CWnd::GetFocus(); - if (pwndFocus != pViewSrc) - pViewDst->RepaintRange(i, j); - if (pwndFocus != pViewDst) - pViewSrc->RepaintRange(i, j); - pViewDst->SetModified(TRUE); - } -} - -/** - * @brief Copy all bytes from source view to destination view - * @note Grows destination buffer as appropriate - */ -void CHexMergeDoc::CopyAll(CHexMergeView *pViewSrc, CHexMergeView *pViewDst) -{ - if (int i = pViewSrc->GetLength()) - { - int j = pViewDst->GetLength(); - BYTE *p = pViewSrc->GetBuffer(i); - BYTE *q = pViewDst->GetBuffer(max(i, j)); - if (q == 0) - AfxThrowMemoryException(); - memcpy(q, p, i); - CWnd *pwndFocus = CWnd::GetFocus(); - if (pwndFocus != pViewSrc) - pViewDst->RepaintRange(0, i); - if (pwndFocus != pViewDst) - pViewSrc->RepaintRange(0, i); - pViewDst->SetModified(TRUE); - } -} - -/** - * @brief Copy selected bytes from left to right - */ -void CHexMergeDoc::OnL2r() -{ - CopySel(m_pView[MERGE_VIEW_LEFT], m_pView[MERGE_VIEW_RIGHT]); -} - -/** - * @brief Copy selected bytes from right to left - */ -void CHexMergeDoc::OnR2l() -{ - CopySel(m_pView[MERGE_VIEW_RIGHT], m_pView[MERGE_VIEW_LEFT]); -} - -/** - * @brief Copy all bytes from left to right - */ -void CHexMergeDoc::OnAllRight() -{ - CopyAll(m_pView[MERGE_VIEW_LEFT], m_pView[MERGE_VIEW_RIGHT]); -} - -/** - * @brief Copy all bytes from right to left - */ -void CHexMergeDoc::OnAllLeft() -{ - CopyAll(m_pView[MERGE_VIEW_RIGHT], m_pView[MERGE_VIEW_LEFT]); -} +///////////////////////////////////////////////////////////////////////////// +// WinMerge: an interactive diff/merge utility +// Copyright (C) 1997-2000 Thingamahoochie Software +// Author: Dean Grimm +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +///////////////////////////////////////////////////////////////////////////// +/** + * @file HexMergeDoc.cpp + * + * @brief Implementation file for CHexMergeDoc + * + */ +// ID line follows -- this is updated by SVN +// $Id$ + +#include "stdafx.h" +#include <afxinet.h> +#include "UnicodeString.h" +#include "FileTextEncoding.h" +#include "Merge.h" +#include "HexMergeDoc.h" +#include "HexMergeFrm.h" +#include "HexMergeView.h" +#include "DiffItem.h" +#include "FolderCmp.h" +#include "MainFrm.h" +#include "Environment.h" +#include "diffcontext.h" // FILE_SAME +#include "getopt.h" +#include "fnmatch.h" +#include "coretools.h" +#include "dirdoc.h" +#include "files.h" +#include "OptionsDef.h" +#include "DiffFileInfo.h" +#include "SaveClosingDlg.h" +#include "DiffList.h" +#include "paths.h" +#include "OptionsMgr.h" +#include "FileOrFolderSelect.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +static void UpdateDiffItem(DIFFITEM &di, CDiffContext *pCtxt); +static int Try(HRESULT hr, UINT type = MB_OKCANCEL|MB_ICONSTOP); + +/** + * @brief Update diff item + */ +static void UpdateDiffItem(DIFFITEM &di, CDiffContext *pCtxt) +{ + di.diffcode.diffcode |= DIFFCODE::SIDEFLAGS; + di.left.ClearPartial(); + di.right.ClearPartial(); + if (!pCtxt->UpdateInfoFromDiskHalf(di, TRUE)) + di.diffcode.diffcode &= ~DIFFCODE::LEFT; + if (!pCtxt->UpdateInfoFromDiskHalf(di, FALSE)) + di.diffcode.diffcode &= ~DIFFCODE::RIGHT; + // 1. Clear flags + di.diffcode.diffcode &= ~(DIFFCODE::TEXTFLAGS | DIFFCODE::COMPAREFLAGS); + // 2. Process unique files + // We must compare unique files to itself to detect encoding + if (di.diffcode.isSideLeftOnly() || di.diffcode.isSideRightOnly()) + { + if (pCtxt->m_nCompMethod != CMP_DATE && + pCtxt->m_nCompMethod != CMP_DATE_SIZE && + pCtxt->m_nCompMethod != CMP_SIZE) + { + di.diffcode.diffcode |= DIFFCODE::SAME; + FolderCmp folderCmp; + int diffCode = folderCmp.prepAndCompareTwoFiles(pCtxt, di); + // Add possible binary flag for unique items + if (diffCode & DIFFCODE::BIN) + di.diffcode.diffcode |= DIFFCODE::BIN; + } + } + // 3. Compare two files + else + { + // Really compare + FolderCmp folderCmp; + di.diffcode.diffcode |= folderCmp.prepAndCompareTwoFiles(pCtxt, di); + } +} + +/** + * @brief Issue an error popup if passed in HRESULT is nonzero + */ +static int Try(HRESULT hr, UINT type) +{ + return hr ? CInternetException(hr).ReportError(type) : 0; +} + +///////////////////////////////////////////////////////////////////////////// +// CHexMergeDoc + +IMPLEMENT_DYNCREATE(CHexMergeDoc, CDocument) + +BEGIN_MESSAGE_MAP(CHexMergeDoc, CDocument) + //{{AFX_MSG_MAP(CHexMergeDoc) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_FILE_SAVE_LEFT, OnFileSaveLeft) + ON_COMMAND(ID_FILE_SAVE_RIGHT, OnFileSaveRight) + ON_COMMAND(ID_FILE_SAVEAS_LEFT, OnFileSaveAsLeft) + ON_COMMAND(ID_FILE_SAVEAS_RIGHT, OnFileSaveAsRight) + ON_UPDATE_COMMAND_UI(ID_STATUS_DIFFNUM, OnUpdateStatusNum) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_LEFT, OnUpdateFileSaveLeft) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_RIGHT, OnUpdateFileSaveRight) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave) + ON_COMMAND(ID_L2R, OnL2r) + ON_COMMAND(ID_R2L, OnR2l) + ON_COMMAND(ID_ALL_LEFT, OnAllLeft) + ON_COMMAND(ID_ALL_RIGHT, OnAllRight) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CHexMergeDoc construction/destruction + +/** + * @brief Constructor. + */ +CHexMergeDoc::CHexMergeDoc() +: m_pDirDoc(NULL) +{ + m_pView[MERGE_VIEW_LEFT] = NULL; + m_pView[MERGE_VIEW_RIGHT] = NULL; +} + +/** + * @brief Destructor. + * + * Informs associated dirdoc that mergedoc is closing. + */ +CHexMergeDoc::~CHexMergeDoc() +{ + if (m_pDirDoc) + m_pDirDoc->MergeDocClosing(this); +} + +/** + * @brief Update associated diff item + */ +void CHexMergeDoc::UpdateDiffItem(CDirDoc *pDirDoc) +{ + // If directory compare has results + if (pDirDoc && pDirDoc->HasDiffs()) + { + const String &pathLeft = m_filePaths.GetLeft(); + const String &pathRight = m_filePaths.GetRight(); + CDiffContext &ctxt = const_cast<CDiffContext &>(pDirDoc->GetDiffContext()); + if (POSITION pos = pDirDoc->FindItemFromPaths(pathLeft.c_str(), pathRight.c_str())) + { + DIFFITEM &di = pDirDoc->GetDiffRefByKey(pos); + ::UpdateDiffItem(di, &ctxt); + } + } + int lengthLeft = m_pView[MERGE_VIEW_LEFT]->GetLength(); + void *bufferLeft = m_pView[MERGE_VIEW_LEFT]->GetBuffer(lengthLeft); + int lengthRight = m_pView[MERGE_VIEW_RIGHT]->GetLength(); + void *bufferRight = m_pView[MERGE_VIEW_RIGHT]->GetBuffer(lengthRight); + GetParentFrame()->SetLastCompareResult(lengthLeft != lengthRight || + bufferLeft && bufferRight && memcmp(bufferLeft, bufferRight, lengthLeft)); +} + +/** + * @brief Asks and then saves modified files + */ +BOOL CHexMergeDoc::PromptAndSaveIfNeeded(BOOL bAllowCancel) +{ + const BOOL bLModified = m_pView[MERGE_VIEW_LEFT]->GetModified(); + const BOOL bRModified = m_pView[MERGE_VIEW_RIGHT]->GetModified(); + + if (!bLModified && !bRModified) //Both files unmodified + return TRUE; + + const String &pathLeft = m_filePaths.GetLeft(); + const String &pathRight = m_filePaths.GetRight(); + + BOOL result = TRUE; + BOOL bLSaveSuccess = FALSE; + BOOL bRSaveSuccess = FALSE; + + SaveClosingDlg dlg; + dlg.DoAskFor(bLModified, bRModified); + if (!bAllowCancel) + dlg.m_bDisableCancel = TRUE; + if (!pathLeft.empty()) + dlg.m_sLeftFile = pathLeft.c_str(); + else + dlg.m_sLeftFile = m_strDesc[0].c_str(); + if (!pathRight.empty()) + dlg.m_sRightFile = pathRight.c_str(); + else + dlg.m_sRightFile = m_strDesc[1].c_str(); + + if (dlg.DoModal() == IDOK) + { + if (bLModified) + { + if (dlg.m_leftSave == SaveClosingDlg::SAVECLOSING_SAVE) + { + switch (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str()))) + { + case 0: + bLSaveSuccess = TRUE; + break; + case IDCANCEL: + result = FALSE; + break; + } + } + else + { + m_pView[MERGE_VIEW_LEFT]->SetModified(FALSE); + } + } + if (bRModified) + { + if (dlg.m_rightSave == SaveClosingDlg::SAVECLOSING_SAVE) + { + switch (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str()))) + { + case 0: + bRSaveSuccess = TRUE; + break; + case IDCANCEL: + result = FALSE; + break; + } + } + else + { + m_pView[MERGE_VIEW_RIGHT]->SetModified(FALSE); + } + } + } + else + { + result = FALSE; + } + + // If file were modified and saving was successfull, + // update status on dir view + if (bLSaveSuccess || bRSaveSuccess) + { + UpdateDiffItem(m_pDirDoc); + } + + return result; +} + +/** + * @brief Save modified documents + */ +BOOL CHexMergeDoc::SaveModified() +{ + return PromptAndSaveIfNeeded(TRUE); +} + +/** + * @brief Saves both files + */ +void CHexMergeDoc::OnFileSave() +{ + BOOL bUpdate = FALSE; + if (m_pView[MERGE_VIEW_LEFT]->GetModified()) + { + const String &pathLeft = m_filePaths.GetLeft(); + if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str())) == IDCANCEL) + return; + bUpdate = TRUE; + } + if (m_pView[MERGE_VIEW_RIGHT]->GetModified()) + { + const String &pathRight = m_filePaths.GetRight(); + if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str())) == IDCANCEL) + return; + bUpdate = TRUE; + } + if (bUpdate) + UpdateDiffItem(m_pDirDoc); +} + +/** + * @brief Saves left-side file + */ +void CHexMergeDoc::OnFileSaveLeft() +{ + if (m_pView[MERGE_VIEW_LEFT]->GetModified()) + { + const String &pathLeft = m_filePaths.GetLeft(); + if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(pathLeft.c_str())) == IDCANCEL) + return; + UpdateDiffItem(m_pDirDoc); + } +} + +/** + * @brief Saves right-side file + */ +void CHexMergeDoc::OnFileSaveRight() +{ + if (m_pView[MERGE_VIEW_RIGHT]->GetModified()) + { + const String &pathRight = m_filePaths.GetRight(); + if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(pathRight.c_str())) == IDCANCEL) + return; + UpdateDiffItem(m_pDirDoc); + } +} + +/** + * @brief Saves left-side file with name asked + */ +void CHexMergeDoc::OnFileSaveAsLeft() +{ + const String &pathLeft = m_filePaths.GetLeft(); + CString strPath; + if (SelectFile(0, strPath, pathLeft.c_str(), IDS_SAVE_LEFT_AS, NULL, FALSE)) + { + if (Try(m_pView[MERGE_VIEW_LEFT]->SaveFile(strPath)) == IDCANCEL) + return; + m_filePaths.SetLeft(strPath); + UpdateDiffItem(m_pDirDoc); + } +} + +/** + * @brief Saves right-side file with name asked + */ +void CHexMergeDoc::OnFileSaveAsRight() +{ + const String &pathRight = m_filePaths.GetRight(); + CString strPath; + if (SelectFile(0, strPath, pathRight.c_str(), IDS_SAVE_LEFT_AS, NULL, FALSE)) + { + if (Try(m_pView[MERGE_VIEW_RIGHT]->SaveFile(strPath)) == IDCANCEL) + return; + m_filePaths.SetRight(strPath); + UpdateDiffItem(m_pDirDoc); + } +} + +/** + * @brief Update diff-number pane text + */ +void CHexMergeDoc::OnUpdateStatusNum(CCmdUI* pCmdUI) +{ + String s; + pCmdUI->SetText(s.c_str()); +} + +/** + * @brief DirDoc gives us its identity just after it creates us + */ +void CHexMergeDoc::SetDirDoc(CDirDoc * pDirDoc) +{ + ASSERT(pDirDoc && !m_pDirDoc); + m_pDirDoc = pDirDoc; +} + +/** + * @brief Return pointer to parent frame + */ +CHexMergeFrame * CHexMergeDoc::GetParentFrame() +{ + return static_cast<CHexMergeFrame *>(m_pView[MERGE_VIEW_LEFT]->GetParentFrame()); +} + +/** + * @brief DirDoc is closing + */ +void CHexMergeDoc::DirDocClosing(CDirDoc * pDirDoc) +{ + ASSERT(m_pDirDoc == pDirDoc); + m_pDirDoc = 0; +} + +/** + * @brief DirDoc commanding us to close + */ +BOOL CHexMergeDoc::CloseNow() +{ + // Allow user to cancel closing + if (!PromptAndSaveIfNeeded(TRUE)) + return FALSE; + + GetParentFrame()->CloseNow(); + return TRUE; +} + +/** + * @brief Load files and initialize frame's compare result icon + */ +HRESULT CHexMergeDoc::OpenDocs(LPCTSTR pathLeft, LPCTSTR pathRight, BOOL bROLeft, BOOL bRORight) +{ + if (Try(m_pView[MERGE_VIEW_LEFT]->LoadFile(pathLeft), MB_ICONSTOP) == 0) + { + m_pView[MERGE_VIEW_LEFT]->SetReadOnly(bROLeft); + m_filePaths.SetLeft(pathLeft); + m_strDesc[MERGE_VIEW_LEFT] = pathLeft; + UpdateHeaderPath(MERGE_VIEW_LEFT); + } + if (Try(m_pView[MERGE_VIEW_RIGHT]->LoadFile(pathRight), MB_ICONSTOP) == 0) + { + m_pView[MERGE_VIEW_RIGHT]->SetReadOnly(bRORight); + m_filePaths.SetRight(pathRight); + m_strDesc[MERGE_VIEW_RIGHT] = pathRight; + UpdateHeaderPath(MERGE_VIEW_RIGHT); + } + m_pView[MERGE_VIEW_LEFT]->ResizeWindow(); + m_pView[MERGE_VIEW_RIGHT]->ResizeWindow(); + UpdateDiffItem(0); + if (GetOptionsMgr()->GetBool(OPT_SCROLL_TO_FIRST)) + m_pView[MERGE_VIEW_LEFT]->SendMessage(WM_COMMAND, ID_FIRSTDIFF); + return S_OK; +} + +/** + * @brief Write path and filename to headerbar + * @note SetText() does not repaint unchanged text + */ +void CHexMergeDoc::UpdateHeaderPath(int pane) +{ + CHexMergeFrame *pf = GetParentFrame(); + ASSERT(pf); + String sText; + + if (m_nBufferType[pane] == BUFFER_UNNAMED || + m_nBufferType[pane] == BUFFER_NORMAL_NAMED) + { + sText = m_strDesc[pane]; + } + else + { + sText = m_filePaths.GetPath(pane); + if (m_pDirDoc) + { + if (pane == 0) + m_pDirDoc->ApplyLeftDisplayRoot(sText); + else + m_pDirDoc->ApplyRightDisplayRoot(sText); + } + } + if (m_pView[pane]->GetModified()) + sText.insert(0, _T("* ")); + pf->GetHeaderInterface()->SetText(pane, sText.c_str()); + + SetTitle(NULL); +} + +/** + * @brief Update document filenames to title + */ +void CHexMergeDoc::SetTitle(LPCTSTR lpszTitle) +{ + const TCHAR pszSeparator[] = _T(" - "); + String sTitle; + + if (lpszTitle) + sTitle = lpszTitle; + else + { + if (!m_strDesc[0].empty()) + sTitle += m_strDesc[0]; + else + { + String file; + String ext; + SplitFilename(m_filePaths.GetLeft().c_str(), NULL, &file, &ext); + sTitle += file.c_str(); + if (!ext.empty()) + { + sTitle += _T("."); + sTitle += ext.c_str(); + } + } + + sTitle += pszSeparator; + + if (!m_strDesc[1].empty()) + sTitle += m_strDesc[1]; + else + { + String file; + String ext; + SplitFilename(m_filePaths.GetRight().c_str(), NULL, &file, &ext); + sTitle += file.c_str(); + if (!ext.empty()) + { + sTitle += _T("."); + sTitle += ext.c_str(); + } + } + } + CDocument::SetTitle(sTitle.c_str()); +} + +/** + * @brief We have two child views (left & right), so we keep pointers directly + * at them (the MFC view list doesn't have them both) + */ +void CHexMergeDoc::SetMergeViews(CHexMergeView * pLeft, CHexMergeView * pRight) +{ + ASSERT(pLeft && !m_pView[MERGE_VIEW_LEFT]); + m_pView[MERGE_VIEW_LEFT] = pLeft; + ASSERT(pRight && !m_pView[MERGE_VIEW_RIGHT]); + m_pView[MERGE_VIEW_RIGHT] = pRight; +} + +/** + * @brief Called when "Save left" item is updated + */ +void CHexMergeDoc::OnUpdateFileSaveLeft(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pView[MERGE_VIEW_LEFT]->GetModified()); +} + +/** + * @brief Called when "Save right" item is updated + */ +void CHexMergeDoc::OnUpdateFileSaveRight(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pView[MERGE_VIEW_RIGHT]->GetModified()); +} + +/** + * @brief Called when "Save" item is updated + */ +void CHexMergeDoc::OnUpdateFileSave(CCmdUI* pCmdUI) +{ + const BOOL bLModified = m_pView[MERGE_VIEW_LEFT]->GetModified(); + const BOOL bRModified = m_pView[MERGE_VIEW_RIGHT]->GetModified(); + pCmdUI->Enable(bLModified || bRModified); +} + +/** + * @brief Copy selected bytes from source view to destination view + * @note Grows destination buffer as appropriate + */ +void CHexMergeDoc::CopySel(CHexMergeView *pViewSrc, CHexMergeView *pViewDst) +{ + const IHexEditorWindow::Status *pStatSrc = pViewSrc->GetStatus(); + int i = min(pStatSrc->iStartOfSelection, pStatSrc->iEndOfSelection); + int j = max(pStatSrc->iStartOfSelection, pStatSrc->iEndOfSelection); + int u = pViewSrc->GetLength(); + int v = pViewDst->GetLength(); + if (pStatSrc->bSelected && i <= v) + { + if (v <= j) + v = j + 1; + BYTE *p = pViewSrc->GetBuffer(u); + BYTE *q = pViewDst->GetBuffer(v); + memcpy(q + i, p + i, j - i + 1); + CWnd *pwndFocus = CWnd::GetFocus(); + if (pwndFocus != pViewSrc) + pViewDst->RepaintRange(i, j); + if (pwndFocus != pViewDst) + pViewSrc->RepaintRange(i, j); + pViewDst->SetModified(TRUE); + } +} + +/** + * @brief Copy all bytes from source view to destination view + * @note Grows destination buffer as appropriate + */ +void CHexMergeDoc::CopyAll(CHexMergeView *pViewSrc, CHexMergeView *pViewDst) +{ + if (int i = pViewSrc->GetLength()) + { + int j = pViewDst->GetLength(); + BYTE *p = pViewSrc->GetBuffer(i); + BYTE *q = pViewDst->GetBuffer(max(i, j)); + if (q == 0) + AfxThrowMemoryException(); + memcpy(q, p, i); + CWnd *pwndFocus = CWnd::GetFocus(); + if (pwndFocus != pViewSrc) + pViewDst->RepaintRange(0, i); + if (pwndFocus != pViewDst) + pViewSrc->RepaintRange(0, i); + pViewDst->SetModified(TRUE); + } +} + +/** + * @brief Copy selected bytes from left to right + */ +void CHexMergeDoc::OnL2r() +{ + CopySel(m_pView[MERGE_VIEW_LEFT], m_pView[MERGE_VIEW_RIGHT]); +} + +/** + * @brief Copy selected bytes from right to left + */ +void CHexMergeDoc::OnR2l() +{ + CopySel(m_pView[MERGE_VIEW_RIGHT], m_pView[MERGE_VIEW_LEFT]); +} + +/** + * @brief Copy all bytes from left to right + */ +void CHexMergeDoc::OnAllRight() +{ + CopyAll(m_pView[MERGE_VIEW_LEFT], m_pView[MERGE_VIEW_RIGHT]); +} + +/** + * @brief Copy all bytes from right to left + */ +void CHexMergeDoc::OnAllLeft() +{ + CopyAll(m_pView[MERGE_VIEW_RIGHT], m_pView[MERGE_VIEW_LEFT]); +} Property changes on: trunk/Src/HexMergeDoc.cpp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/Src/HexMergeDoc.h =================================================================== --- trunk/Src/HexMergeDoc.h 2008-08-09 08:44:31 UTC (rev 5773) +++ trunk/Src/HexMergeDoc.h 2008-08-09 09:21:52 UTC (rev 5774) @@ -1,109 +1,109 @@ -///////////////////////////////////////////////////////////////////////////// -// WinMerge: an interactive diff/merge utility -// Copyright (C) 1997 Dean P. Grimm -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -///////////////////////////////////////////////////////////////////////////// -/** - * @file HexMergeDoc.h - * - * @brief Declaration of CHexMergeDoc class - */ -// RCS ID line follows -- this is updated by CVS -// $Id: $ - -#include "TempFile.h" -#include "PathContext.h" -#include "DiffFileInfo.h" - -class CDirDoc; -class CHexMergeFrame; -class CHexMergeView; - -/** - * @brief Document class for bytewise merging two files presented as hexdumps - */ -class CHexMergeDoc : public CDocument -{ -// Attributes -public: - PathContext m_filePaths; /**< Filepaths for this document */ - -// Begin declaration of CHexMergeDoc - -protected: // create from serialization only - CHexMergeDoc(); - DECLARE_DYNCREATE(CHexMergeDoc) - - - // Operations -public: - void SetMergeViews(CHexMergeView * pLeft, CHexMergeView * pRight); - - // Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMergeDoc) - public: - virtual BOOL SaveModified(); - virtual void SetTitle(LPCTSTR lpszTitle); - //}}AFX_VIRTUAL - -// Implementation -public: - ~CHexMergeDoc(); - void UpdateDiffItem(CDirDoc * pDirDoc); - BOOL PromptAndSaveIfNeeded(BOOL bAllowCancel); - void SetDirDoc(CDirDoc * pDirDoc); - void DirDocClosing(CDirDoc * pDirDoc); - BOOL CloseNow(); - CHexMergeFrame * GetParentFrame(); - void UpdateHeaderPath(int pane); - HRESULT OpenDocs(LPCTSTR pathLeft, LPCTSTR pathRight, BOOL bROLeft, BOOL bRORight); -protected: - static void CopySel(CHexMergeView *pViewSrc, CHexMergeView *pViewDst); - static void CopyAll(CHexMergeView *pViewSrc, CHexMergeView *pViewDst); -// Implementation data -protected: - CHexMergeView * m_pView[MERGE_VIEW_COUNT]; /**< Pointer to left/right view */ - CDirDoc * m_pDirDoc; - TempFile m_tempFiles[2]; /**< Temp files for compared files */ - String m_strDesc[2]; /**< Left/right side description text */ - BUFFERTYPE m_nBufferType[2]; - -// Generated message map functions -protected: - //{{AFX_MSG(CMergeDoc) - afx_msg void OnFileSave(); - afx_msg void OnFileSaveLeft(); - afx_msg void OnFileSaveRight(); - afx_msg void OnFileSaveAsLeft(); - afx_msg void OnFileSaveAsRight(); - afx_msg void OnUpdateStatusNum(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileSaveLeft(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileSaveRight(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI); - afx_msg void OnL2r(); - afx_msg void OnR2l(); - afx_msg void OnAllRight(); - afx_msg void OnAllLeft(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. +///////////////////////////////////////////////////////////////////////////// +// WinMerge: an interactive diff/merge utility +// Copyright (C) 1997 Dean P. Grimm +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +///////////////////////////////////////////////////////////////////////////// +/** + * @file HexMergeDoc.h + * + * @brief Declaration of CHexMergeDoc class + */ +// RCS ID line follows -- this is updated by CVS +// $Id$ + +#include "TempFile.h" +#include "PathContext.h" +#include "DiffFileInfo.h" + +class CDirDoc; +class CHexMergeFrame; +class CHexMergeView; + +/** + * @brief Document class for bytewise merging two files presented as hexdumps + */ +class CHexMergeDoc : public CDocument +{ +// Attributes +public: + PathContext m_filePaths; /**< Filepaths for this document */ + +// Begin declaration of CHexMergeDoc + +protected: // create from serialization only + CHexMergeDoc(); + DECLARE_DYNCREATE(CHexMergeDoc) + + + // Operations +public: + void SetMergeViews(CHexMergeView * pLeft, CHexMergeView * pRight); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMergeDoc) + public: + virtual BOOL SaveModified(); + virtual void SetTitle(LPCTSTR lpszTitle); + //}}AFX_VIRTUAL + +// Implementation +public: + ~CHexMergeDoc(); + void UpdateDiffItem(CDirDoc * pDirDoc); + BOOL PromptAndSaveIfNeeded(BOOL bAllowCancel); + void SetDirDoc(CDirDoc * pDirDoc); + void DirDocClosing(CDirDoc * pDirDoc); + BOOL CloseNow(); + CHexMergeFrame * GetParentFrame(); + void UpdateHeaderPath(int pane); + HRESULT OpenDocs(LPCTSTR pathLeft, LPCTSTR pathRight, BOOL bROLeft, BOOL bRORight); +protected: + static void CopySel(CHexMergeView *pViewSrc, CHexMergeView *pViewDst); + static void CopyAll(CHexMergeView *pViewSrc, CHexMergeView *pViewDst); +// Implementation data +protected: + CHexMergeView * m_pView[MERGE_VIEW_COUNT]; /**< Pointer to left/right view */ + CDirDoc * m_pDirDoc; + TempFile m_tempFiles[2]; /**< Temp files for compared files */ + String m_strDesc[2]; /**< Left/right side description text */ + BUFFERTYPE m_nBufferType[2]; + +// Generated message map functions +protected: + //{{AFX_MSG(CMergeDoc) + afx_msg void OnFileSave(); + afx_msg void OnFileSaveLeft(); + afx_msg void OnFileSaveRight(); + afx_msg void OnFileSaveAsLeft(); + afx_msg void OnFileSaveAsRight(); + afx_msg void OnUpdateStatusNum(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSaveLeft(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSaveRight(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI); + afx_msg void OnL2r(); + afx_msg void OnR2l(); + afx_msg void OnAllRight(); + afx_msg void OnAllLeft(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. Property changes on: trunk/Src/HexMergeDoc.h ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/Src/HexMergeFrm.cpp =================================================================== --- trunk/Src/HexMergeFrm.cpp 2008-08-09 08:44:31 UTC (rev 5773) +++ trunk/Src/HexMergeFrm.cpp 2008-08-09 09:21:52 UTC (rev 5774) @@ -1,479 +1,479 @@ -///////////////////////////////////////////////////////////////////////////// -// WinMerge: an interactive diff/merge utility -// Copyright (C) 1997-2000 Thingamahoochie Software -// Author: Dean Grimm -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -///////////////////////////////////////////////////////////////////////////// -/** - * @file HexMergeFrm.cpp - * - * @brief Implementation file for CHexMergeFrame - * - */ -// ID line follows -- this is updated by SVN -// $Id: $ - -#include "stdafx.h" -#include "Merge.h" -#include "MainFrm.h" -#include "HexMergeFrm.h" -#include "HexMergeDoc.h" -#include "HexMergeView.h" -#include "OptionsDef.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/** - * @brief RO status panel width - */ -static UINT RO_PANEL_WIDTH = 40; - -///////////////////////////////////////////////////////////////////////////// -// CHexMergeFrame - -IMPLEMENT_DYNCREATE(CHexMergeFrame, CMDIChildWnd) - -BEGIN_MESSAGE_MAP(CHexMergeFrame, CMDIChildWnd) - //{{AFX_MSG_MAP(CHexMergeFrame) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_SIZE() - ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) - ON_UPDATE_COMMAND_UI(ID_VIEW_DETAIL_BAR, OnUpdateControlBarMenu) - ON_COMMAND_EX(ID_VIEW_DETAIL_BAR, OnBarCheck) - ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATION_BAR, OnUpdateControlBarMenu) - ON_COMMAND_EX(ID_VIEW_LOCATION_BAR, OnBarCheck) - ON_MESSAGE(MSG_STORE_PANESIZES, OnStorePaneSizes) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -/** - * @brief Statusbar pane indexes - */ -enum -{ - PANE_LEFT_INFO = 0, - PANE_LEFT_RO, - PANE_LEFT_EOL, - PANE_RIGHT_INFO, - PANE_RIGHT_RO, - PANE_RIGHT_EOL, -}; - -/** - * @brief Bottom statusbar panels and indicators - */ -static UINT indicatorsBottom[] = -{ - ID_SEPARATOR, - ID_SEPARATOR, - ID_SEPARATOR, - ID_SEPARATOR, - ID_SEPARATOR, - ID_SEPARATOR, -}; - -///////////////////////////////////////////////////////////////////////////// -// CHexMergeFrame construction/destruction - -CHexMergeFrame::CHexMergeFrame() -: m_hIdentical(NULL) -, m_hDifferent(NULL) -{ - m_bActivated = FALSE; - m_nLastSplitPos = 0; - m_pMergeDoc = 0; -} - -CHexMergeFrame::~CHexMergeFrame() -{ -} - -/** - * @brief Customize a heksedit control's settings - */ -static void Customize(IHexEditorWindow::Settings *settings) -{ - settings->bSaveIni = FALSE; - settings->iAutomaticBPL = FALSE; - settings->iBytesPerLine = 16; - settings->iFontSize = 8; -} - -/** - * @brief Customize a heksedit control's colors - */ -static void Customize(IHexEditorWindow::Colors *colors) -{ - COptionsMgr *pOptionsMgr = GetOptionsMgr(); - colors->iSelBkColorValue = RGB(224, 224, 224); - colors->iDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF); - colors->iSelDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF); - colors->iDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF_TEXT); - colors->iSelDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF_TEXT); -} - -/** - * @brief Customize a heksedit control's settings and colors - */ -static void Customize(IHexEditorWindow *pif) -{ - Customize(pif->get_settings()); - Customize(pif->get_colors()); -} - -/** - * @brief Create a status bar to be associated with a heksedit control - */ -void CHexMergeFrame::CreateHexWndStatusBar(CStatusBar &wndStatusBar) -{ - wndStatusBar.Create(this, WS_CHILD|WS_VISIBLE); - wndStatusBar.SetIndicators(0, 3); - wndStatusBar.SetPaneInfo(0, 0, SBPS_STRETCH, 0); - wndStatusBar.SetPaneInfo(1, 0, 0, 72); - wndStatusBar.SetPaneInfo(2, 0, 0, 72); -} - -/** - * @brief Create the splitter, the filename bar, the status bar, and the two views - */ -BOOL CHexMergeFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/, - CCreateContext* pContext) -{ - // create a splitter with 1 row, 2 columns - if (!m_wndSplitter.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL) ) - { - TRACE0("Failed to CreateStaticSplitter\n"); - return FALSE; - } - - if (!m_wndSplitter.CreateView(0, 0, - RUNTIME_CLASS(CHexMergeView), CSize(-1, 200), pContext)) - { - TRACE0("Failed to create first pane\n"); - return FALSE; - } - - // add the second splitter pane - an input view in column 1 - if (!m_wndSplitter.CreateView(0, 1, - RUNTIME_CLASS(CHexMergeView), CSize(-1, 200), pContext)) - { - TRACE0("Failed to create second pane\n"); - return FALSE; - } - m_wndSplitter.ResizablePanes(TRUE); - m_wndSplitter.AutoResizePanes(GetOptionsMgr()->GetBool(OPT_RESIZE_PANES)); - - // Merge frame has a header bar at top - if (!m_wndFilePathBar.Create(this)) - { - TRACE0("Failed to create dialog bar\n"); - return FALSE; // fail to create - } - // Set filename bars inactive so colors get initialized - m_wndFilePathBar.SetActive(0, FALSE); - m_wndFilePathBar.SetActive(1, FALSE); - - m_wndLeftStatusBar.m_cxRightBorder = 4; - ModifyStyle(WS_THICKFRAME, 0); // Prevent SBARS_SIZEGRIP - CreateHexWndStatusBar(m_wndLeftStatusBar); - ModifyStyle(0, WS_THICKFRAME); - CreateHexWndStatusBar(m_wndRightStatusBar); - CSize size = m_wndLeftStatusBar.CalcFixedLayout(TRUE, TRUE); - m_rectBorder.bottom = size.cy; - - m_hIdentical = AfxGetApp()->LoadIcon(IDI_EQUALFILE); - m_hDifferent = AfxGetApp()->LoadIcon(IDI_NOTEQUALFILE); - - // stash left & right pointers into the mergedoc - CHexMergeView *pLeft = static_cast<CHexMergeView *>(m_wndSplitter.GetPane(0,0)); - CHexMergeView *pRight = static_cast<CHexMergeView *>(m_wndSplitter.GetPane(0,1)); - - IHexEditorWindow *pifLeft = reinterpret_cast<IHexEditorWindow *>( - ::GetWindowLongPtr(pLeft->m_hWnd, GWL_USERDATA)); - IHexEditorWindow *pifRight = reinterpret_cast<IHexEditorWindow *>( - ::GetWindowLongPtr(pRight->m_hWnd, GWL_USERDATA)); - - if (pifLeft && pifRight) - { - pifLeft->set_sibling(pifRight); - pifRight->set_sibling(pifLeft); - pifLeft->set_status_bar(m_wndLeftStatusBar.m_hWnd); - pifRight->set_status_bar(m_wndRightStatusBar.m_hWnd); - Customize(pifLeft); - Customize(pifRight); - } - - // tell merge doc about these views - m_pMergeDoc = dynamic_cast<CHexMergeDoc *>(pContext->m_pCurrentDoc); - m_pMergeDoc->SetMergeViews(pLeft, pRight); - pLeft->m_nThisPane = 0; - pRight->m_nThisPane = 1; - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CHexMergeFrame message handlers - -/** - * @brief Handle translation of default messages on the status bar - */ -void CHexMergeFrame::GetMessageString(UINT nID, CString& rMessage) const -{ - // load appropriate string - const String s = theApp.LoadString(nID); - if (!AfxExtractSubString(rMessage, &*s.begin(), 0)) - { - // not found - TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID); - } -} - -/** - * @brief Save the window's position, free related resources, and destroy the window - */ -BOOL CHexMergeFrame::DestroyWindow() -{ - SavePosition(); - // If we are active, save the restored/maximized state - // If we are not, do nothing and let the active frame do the job. - if (GetParentFrame()->GetActiveFrame() == this) - { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(&wp); - theApp.WriteProfileInt(_T("Settings"), _T("ActiveFrameMax"), (wp.showCmd == SW_MAXIMIZE)); - } - - if (m_hIdentical != NULL) - { - DestroyIcon(m_hIdentical); - m_hIdentical = NULL; - } - - if (m_hDifferent != NULL) - { - DestroyIcon(m_hDifferent); - m_hDifferent = NULL; - } - - return CMDIChildWnd::DestroyWindow(); -} - -/** - * @brief Save coordinates of the frame, splitters, and bars - * - * @note Do not save the maximized/restored state here. We are interested - * in the state of the active frame, and maybe this frame is not active - */ -void CHexMergeFrame::SavePosition() -{ - if (CWnd *pLeft = m_wndSplitter.GetPane(0,0)) - { - CRect rc; - pLeft->GetWindowRect(&rc); - theApp.WriteProfileInt(_T("Settings"), _T("WLeft"), rc.Width()); - } -} - -void CHexMergeFrame::OnSize(UINT nType, int cx, int cy) -{ - CMDIChildWnd::OnSize(nType, cx, cy); - UpdateHeaderSizes(); -} - -/// update splitting position for panels 1/2 and headerbar and statusbar -void CHexMergeFrame::UpdateHeaderSizes() -{ - if (IsWindowVisible()) - { - int w0, w1, wmin; - m_wndSplitter.GetColumnInfo(0, w0, wmin); - m_wndSplitter.GetColumnInfo(1, w1, wmin); - if (w0 < 1) w0 = 1; // Perry 2003-01-22 (I don't know why this happens) - if (w1 < 1) w1 = 1; // Perry 2003-01-22 (I don't know why this happens) - // resize controls in header dialog bar - m_wndFilePathBar.Resize(w0, w1); - RECT rc; - GetClientRect(&rc); - rc.top = rc.bottom - m_rectBorder.bottom; - rc.left = w0 + 8; - m_wndRightStatusBar.MoveWindow(&rc); - rc.right = rc.left; - rc.left = 0; - m_wndLeftStatusBar.MoveWindow(&rc); - } -} - -IHeaderBar *CHexMergeFrame::GetHeaderInterface() -{ - return &m_wndFilePathBar; -} - -/** - * @brief Reflect comparison result in window's icon. - * @param nResult [in] Last comparison result which the application returns. - */ -void CHexMergeFrame::SetLastCompareResult(int nResult) -{ - HICON hCurrent = GetIcon(FALSE); - HICON hReplace = (nResult == 0) ? m_hIdentical : m_hDifferent; - - if (hCurrent != hReplace) - { - SetIcon(hReplace, TRUE); - - BOOL bMaximized; - GetMDIFrame()->MDIGetActive(&bMaximized); - - // When MDI maximized the window icon is drawn on the menu bar, so we - // need to notify it that our icon has changed. - if (bMaximized) - { - GetMDIFrame()->DrawMenuBar(); - } - } - - theApp.SetLastCompareResult(nResult); -} - -void CHexMergeFrame::UpdateAutoPaneResize() -{ - m_wndSplitter.AutoResizePanes(GetOptionsMgr()->GetBool(OPT_RESIZE_PANES)); -} - -void CHexMergeFrame::UpdateSplitter() -{ - m_wndSplitter.RecalcLayout(); -} - -/** - * @brief Synchronize control and status bar placements with splitter position, - * update mod indicators, synchronize scrollbars - */ -void CHexMergeFrame::OnIdleUpdateCmdUI() -{ - if (IsWindowVisible()) - { - int w,wmin; - m_wndSplitter.GetColumnInfo(0, w, wmin); - if (w != m_nLastSplitPos && w > 0) - { - UpdateHeaderSizes(); - m_nLastSplitPos = w; - } - CHexMergeView *pLeft = (CHexMergeView *)m_wndSplitter.GetPane(0, MERGE_VIEW_LEFT); - CHexMergeView *pRight = (CHexMergeView *)m_wndSplitter.GetPane(0, MERGE_VIEW_RIGHT); - - // Update mod indicators - TCHAR ind[2]; - - if (m_wndFilePathBar.GetDlgItemText(IDC_STATIC_TITLE_LEFT, ind, 2)) - if (pLeft->GetModified() ? ind[0] != _T('*') : ind[0] == _T('*')) - m_pMergeDoc->UpdateHeaderPath(MERGE_VIEW_LEFT); - - if (m_wndFilePathBar.GetDlgItemText(IDC_STATIC_TITLE_RIGHT, ind, 2)) - if (pRight->GetModified() ? ind[0] != _T('*') : ind[0] == _T('*')) - m_pMergeDoc->UpdateHeaderPath(MERGE_VIEW_RIGHT); - - // Synchronize scrollbars - SCROLLINFO si, siLeft, siRight; - // Synchronize horizontal scrollbars - pLeft->GetScrollInfo(SB_HORZ, &si, SIF_ALL | SIF_DISABLENOSCROLL); - siLeft = si; - pRight->GetScrollInfo(SB_HORZ, &si, SIF_ALL | SIF_DISABLENOSCROLL); - siRight = si; - if (si.nMin > siLeft.nMin) - si.nMin = siLeft.nMin; - if (si.nPage < siLeft.nPage) - si.nPage = siLeft.nPage; - if (si.nMax < siLeft.nMax) - si.nMax = siLeft.nMax; - if (GetFocus() != pRight) - { - si.nPos = siLeft.nPos; - si.nTrackPos = siLeft.nTrackPos; - } - if (memcmp(&si, &siLeft, sizeof si)) - { - pLeft->SetScrollInfo(SB_HORZ, &si); - pLeft->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, si.nTrackPos)); - } - if (memcmp(&si, &siRight, sizeof si)) - { - pRight->SetScrollInfo(SB_HORZ, &si); - pRight->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, si.nTrackPos)); - } - m_wndSplitter.GetScrollBarCtrl(pLeft, SB_HORZ)->SetScrollInfo(&si); - m_wndSplitter.GetScrollBarCtrl(pRight, SB_HORZ)->SetScrollInfo(&si); - // Synchronize vertical scrollbars - pLeft->GetScrollInfo(SB_VERT, &si, SIF_ALL | SIF_DISABLENOSCROLL); - siLeft = si; - pRight->GetScrollInfo(SB_VERT, &si, SIF_ALL | SIF_DISABLENOSCROLL); - siRight = si; - if (si.nMin > siLeft.nMin) - si.nMin = siLeft.nMin; - if (si.nMax < siLeft.nMax) - si.nMax = siLeft.nMax; - if (GetFocus() != pRight) - { - si.nPos = siLeft.nPos; - si.nTrackPos = siLeft.nTrackPos; - } - if (memcmp(&si, &siLeft, sizeof si)) - { - pLeft->SetScrollInfo(SB_VERT, &si); - pLeft->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, si.nTrackPos)); - } - if (memcmp(&si, &siRight, sizeof si)) - { - pRight->SetScrollInfo(SB_VERT, &si); - pRight->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, si.nTrackPos)); - } - m_wndSplitter.GetScrollBarCtrl(pRight, SB_VERT)->SetScrollInfo(&si); - } - CMDIChildWnd::OnIdleUpdateCmdUI(); -} - -/// Document commanding us to close -void CHexMergeFrame::CloseNow() -{ - SavePosition(); // Save settings before closing! - MDIActivate(); - MDIDestroy(); -} - -/** - * @brief Update any resources necessary after a GUI language change - */ -void CHexMergeFrame::UpdateResources() -{ -} - -/** - * @brief Save pane sizes and positions when one of panes requests it. - */ -LRESULT CHexMergeFrame::OnStorePaneSizes(WPARAM wParam, LPARAM lParam) -{ - SavePosition(); - return 0; -} +///////////////////////////////////////////////////////////////////////////// +// WinMerge: an interactive diff/merge utility +// Copyright (C) 1997-2000 Thingamahoochie Software +// Author: Dean Grimm +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +///////////////////////////////////////////////////////////////////////////// +/** + * @file HexMergeFrm.cpp + * + * @brief Implementation file for CHexMergeFrame + * + */ +// ID line follows -- this is updated by SVN +// $Id$ + +#include "stdafx.h" +#include "Merge.h" +#include "MainFrm.h" +#include "HexMergeFrm.h" +#include "HexMergeDoc.h" +#include "HexMergeView.h" +#include "OptionsDef.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/** + * @brief RO status panel width + */ +static UINT RO_PANEL_WIDTH = 40; + +///////////////////////////////////////////////////////////////////////////// +// CHexMergeFrame + +IMPLEMENT_DYNCREATE(CHexMergeFrame, CMDIChildWnd) + +BEGIN_MESSAGE_MAP(CHexMergeFrame, CMDIChildWnd) + //{{AFX_MSG_MAP(CHexMergeFrame) + ON_WM_CREATE() + ON_WM_CLOSE() + ON_WM_SIZE() + ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) + ON_UPDATE_COMMAND_UI(ID_VIEW_DETAIL_BAR, OnUpdateControlBarMenu) + ON_COMMAND_EX(ID_VIEW_DETAIL_BAR, OnBarCheck) + ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATION_BAR, OnUpdateControlBarMenu) + ON_COMMAND_EX(ID_VIEW_LOCATION_BAR, OnBarCheck) + ON_MESSAGE(MSG_STORE_PANESIZES, OnStorePaneSizes) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +/** + * @brief Statusbar pane indexes + */ +enum +{ + PANE_LEFT_INFO = 0, + PANE_LEFT_RO, + PANE_LEFT_EOL, + PANE_RIGHT_INFO, + PANE_RIGHT_RO, + PANE_RIGHT_EOL, +}; + +/** + * @brief Bottom statusbar panels and indicators + */ +static UINT indicatorsBottom[] = +{ + ID_SEPARATOR, + ID_SEPARATOR, + ID_SEPARATOR, + ID_SEPARATOR, + ID_SEPARATOR, + ID_SEPARATOR, +}; + +///////////////////////////////////////////////////////////////////////////// +// CHexMergeFrame construction/destruction + +CHexMergeFrame::CHexMergeFrame() +: m_hIdentical(NULL) +, m_hDifferent(NULL) +{ + m_bActivated = FALSE; + m_nLastSplitPos = 0; + m_pMergeDoc = 0; +} + +CHexMergeFrame::~CHexMergeFrame() +{ +} + +/** + * @brief Customize a heksedit control's settings + */ +static void Customize(IHexEditorWindow::Settings *settings) +{ + settings->bSaveIni = FALSE; + settings->iAutomaticBPL = FALSE; + settings->iBytesPerLine = 16; + settings->iFontSize = 8; +} + +/** + * @brief Customize a heksedit control's colors + */ +static void Customize(IHexEditorWindow::Colors *colors) +{ + COptionsMgr *pOptionsMgr = GetOptionsMgr(); + colors->iSelBkColorValue = RGB(224, 224, 224); + colors->iDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF); + colors->iSelDiffBkColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF); + colors->iDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_DIFF_TEXT); + colors->iSelDiffTextColorValue = pOptionsMgr->GetInt(OPT_CLR_SELECTED_DIFF_TEXT); +} + +/** + * @brief Customize a heksedit control's settings and colors + */ +static void Customize(IHexEditorWindow *pif) +{ + Customize(pif->get_settings()); + Customize(pif->get_colors()); +} + +/** + * @brief Create a status bar to be associated with a heksedit control + */ +void CHexMergeFrame::CreateHexWndStatusBar(CStatusBar &wndStatusBar) +{ + wndStatusBar.Create(this, WS_CHILD|WS_VISIBLE); + wndStatusBar.SetIndicators(0, 3); + wndStatusBar.SetPaneInfo(0, 0, SBPS_STRETCH, 0); + wndStatusBar.SetPaneInfo(1, 0, 0, 72); + wndStatusBar.SetPaneInfo(2, 0, 0, 72); +} + +/** + * @brief Create the splitter, the filename bar, the status bar, and the two views + */ +BOOL CHexMergeFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/, + CCreateContext* pContext) +{ + // create a splitter with 1 row, 2 columns + if (!m_wndSplitter.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL) ) + { + TRACE0("Failed to CreateStaticSplitter\n"); + return FALSE; + } + + if (!m_wndSplitter.CreateView(0, 0, + RUNTIME_CLASS(CHexMergeView), CSize(-1, 200), pContext)) + { + TRACE0("Failed to create first pane\n"); + return FALSE; + } + + // add the second splitter pane - an input view in column 1 + if (!m_wndSplitter.CreateView(0, 1, + RUNTIME_CLASS(CHexMergeView), CSize(-1, 200), pContext)) + { + TRACE0("Failed to cr... [truncated message content] |