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] |