OSDN Git Service

HexEditor: Add Undo & Redo feature
authorsdottaka <sdottaka@users.sourceforge.net>
Sun, 8 Feb 2015 16:13:41 +0000 (01:13 +0900)
committersdottaka <sdottaka@users.sourceforge.net>
Sun, 8 Feb 2015 16:13:41 +0000 (01:13 +0900)
--HG--
branch : stable

Src/HexMergeDoc.cpp
Src/HexMergeFrm.cpp
Src/HexMergeView.cpp
Src/HexMergeView.h
Src/heksedit.h

index eed7304..22f223e 100644 (file)
@@ -283,7 +283,7 @@ BOOL CHexMergeDoc::PromptAndSaveIfNeeded(BOOL bAllowCancel)
                        }
                        else
                        {
-                               m_pView[0]->SetModified(FALSE);
+                               m_pView[0]->SetSavePoint();
                        }
                }
                if (bMModified)
@@ -302,7 +302,7 @@ BOOL CHexMergeDoc::PromptAndSaveIfNeeded(BOOL bAllowCancel)
                        }
                        else
                        {
-                               m_pView[1]->SetModified(FALSE);
+                               m_pView[1]->SetSavePoint();
                        }
                }
                if (bRModified)
@@ -321,7 +321,7 @@ BOOL CHexMergeDoc::PromptAndSaveIfNeeded(BOOL bAllowCancel)
                        }
                        else
                        {
-                               m_pView[m_nBuffers - 1]->SetModified(FALSE);
+                               m_pView[m_nBuffers - 1]->SetSavePoint();
                        }
                }
        }
@@ -707,63 +707,13 @@ void CHexMergeDoc::OnFileReload()
 }
 
 /**
- * @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()
 {
        int dstPane = (GetActiveMergeView()->m_nThisPane < m_nBuffers - 1) ? GetActiveMergeView()->m_nThisPane + 1 : m_nBuffers - 1;
        int srcPane = dstPane - 1;
-       CopySel(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
@@ -773,7 +723,7 @@ void CHexMergeDoc::OnR2l()
 {
        int dstPane = (GetActiveMergeView()->m_nThisPane > 0) ? GetActiveMergeView()->m_nThisPane - 1 : 0;
        int srcPane = dstPane + 1;
-       CopySel(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
@@ -783,7 +733,7 @@ void CHexMergeDoc::OnCopyFromLeft()
 {
        int dstPane = GetActiveMergeView()->m_nThisPane;
        int srcPane = (dstPane - 1 < 0) ? 0 : dstPane - 1;
-       CopySel(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
@@ -793,7 +743,7 @@ void CHexMergeDoc::OnCopyFromRight()
 {
        int dstPane = GetActiveMergeView()->m_nThisPane;
        int srcPane = (dstPane + 1 > m_nBuffers - 1) ? m_nBuffers - 1 : dstPane + 1;
-       CopySel(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopySel(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
@@ -803,7 +753,7 @@ void CHexMergeDoc::OnAllRight()
 {
        int dstPane = (GetActiveMergeView()->m_nThisPane < m_nBuffers - 1) ? GetActiveMergeView()->m_nThisPane + 1 : m_nBuffers - 1;
        int srcPane = dstPane - 1;
-       CopyAll(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopyAll(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
@@ -813,7 +763,7 @@ void CHexMergeDoc::OnAllLeft()
 {
        int dstPane = (GetActiveMergeView()->m_nThisPane > 0) ? GetActiveMergeView()->m_nThisPane - 1 : 0;
        int srcPane = dstPane + 1;
-       CopyAll(m_pView[srcPane], m_pView[dstPane]);
+       CHexMergeView::CopyAll(m_pView[srcPane], m_pView[dstPane]);
 }
 
 /**
index 8aba13a..e750a1f 100644 (file)
@@ -214,12 +214,15 @@ BOOL CHexMergeFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/,
        {
                pif[0]->set_sibling(pif[1]);
                pif[1]->set_sibling(pif[0]);
+               pif[1]->share_undorecords(pif[0]);
        }
        else
        {
                pif[0]->set_sibling(pif[1]);
                pif[1]->set_sibling2(pif[0], pif[2]);
                pif[2]->set_sibling(pif[1]);
+               pif[1]->share_undorecords(pif[0]);
+               pif[2]->share_undorecords(pif[0]);
        }
        for (int nPane = 0; nPane < m_pMergeDoc->m_nBuffers; nPane++)
        {
index cf0781c..f99f4df 100644 (file)
@@ -82,6 +82,10 @@ BEGIN_MESSAGE_MAP(CHexMergeView, CView)
        ON_COMMAND(ID_EDIT_FIND, OnEditFind)
        ON_COMMAND(ID_EDIT_REPLACE, OnEditReplace)
        ON_COMMAND(ID_EDIT_REPEAT, OnEditRepeat)
+       ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
+       ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
+       ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
+       ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
        ON_COMMAND(ID_EDIT_CUT, OnEditCut)
        ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
        ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
@@ -341,7 +345,7 @@ HRESULT CHexMergeView::SaveFile(LPCTSTR path)
        if (hr != S_OK)
                return hr;
        m_mtime = mtime;
-       SetModified(FALSE);
+       SetSavePoint();
        hr = SE(DeleteFile(sIntermediateFilename.c_str()));
        if (hr != S_OK)
        {
@@ -352,27 +356,27 @@ HRESULT CHexMergeView::SaveFile(LPCTSTR path)
 }
 
 /**
- * @brief Get status
+ * @brief Get modified flag
  */
-IHexEditorWindow::Status *CHexMergeView::GetStatus()
+BOOL CHexMergeView::GetModified()
 {
-       return m_pif->get_status();
+       return m_pif->get_modified();
 }
 
 /**
- * @brief Get modified flag
+ * @brief Set modified flag
  */
-BOOL CHexMergeView::GetModified()
+void CHexMergeView::SetSavePoint()
 {
-       return m_pif->get_status()->iFileChanged;
+       m_pif->set_savepoint();
 }
 
 /**
- * @brief Set modified flag
+ * @brief Clear undo records
  */
-void CHexMergeView::SetModified(BOOL bModified)
+void CHexMergeView::ClearUndoRecords()
 {
-       m_pif->get_status()->iFileChanged = bModified;
+       m_pif->clear_undorecords();
 }
 
 /**
@@ -401,15 +405,6 @@ void CHexMergeView::ResizeWindow()
 }
 
 /**
- * @brief Repaint a range of bytes
- */
-void CHexMergeView::RepaintRange(int i, int j)
-{
-       int iBytesPerLine = m_pif->get_settings()->iBytesPerLine;
-       m_pif->repaint(i / iBytesPerLine, j / iBytesPerLine);
-}
-
-/**
  * @brief Find a sequence of bytes
  */
 void CHexMergeView::OnEditFind()
@@ -437,6 +432,38 @@ void CHexMergeView::OnEditRepeat()
 }
 
 /**
+* @brief Called when "Undo" item is updated
+*/
+void CHexMergeView::OnUpdateEditUndo(CCmdUI* pCmdUI)
+{
+       pCmdUI->Enable(m_pif->can_undo());
+}
+
+/**
+ * @brief Undo last action
+ */
+void CHexMergeView::OnEditUndo()
+{
+       m_pif->CMD_edit_undo();
+}
+
+/**
+* @brief Called when "Redo" item is updated
+*/
+void CHexMergeView::OnUpdateEditRedo(CCmdUI* pCmdUI)
+{
+       pCmdUI->Enable(m_pif->can_redo());
+}
+
+/**
+ * @brief Redo last action
+ */
+void CHexMergeView::OnEditRedo()
+{
+       m_pif->CMD_edit_redo();
+}
+
+/**
  * @brief Cut selected content
  */
 void CHexMergeView::OnEditCut()
@@ -531,3 +558,22 @@ void CHexMergeView::ZoomText(int amount)
 {
        m_pif->CMD_zoom(amount);
 }
+
+/**
+ * @brief Copy selected bytes from source view to destination view
+ * @note Grows destination buffer as appropriate
+ */
+void CHexMergeView::CopySel(const CHexMergeView *src, CHexMergeView *dst)
+{
+       dst->m_pif->copy_sel_from(src->m_pif);
+}
+
+/**
+ * @brief Copy all bytes from source view to destination view
+ * @note Grows destination buffer as appropriate
+ */
+void CHexMergeView::CopyAll(const CHexMergeView *src, CHexMergeView *dst)
+{
+       dst->m_pif->copy_all_from(src->m_pif);
+}
+
index 95946c8..7b9bb08 100644 (file)
@@ -47,18 +47,18 @@ protected: // create from serialization only
 public:
        HRESULT LoadFile(LPCTSTR);
        HRESULT SaveFile(LPCTSTR);
-       IHexEditorWindow *GetInterface() const { return m_pif; }
-       IHexEditorWindow::Status *GetStatus();
        BYTE *GetBuffer(int);
        int GetLength();
        BOOL GetModified();
-       void SetModified(BOOL);
+       void SetSavePoint();
+       void ClearUndoRecords();
        BOOL GetReadOnly();
        void SetReadOnly(BOOL);
        void ResizeWindow();
-       void RepaintRange(int, int);
        BOOL IsFileChangedOnDisk(LPCTSTR);
        void ZoomText(int amount);
+       static void CopySel(const CHexMergeView *src, CHexMergeView *dst);
+       static void CopyAll(const CHexMergeView *src, CHexMergeView *dst);
        // Overrides
 protected:
        virtual void OnDraw(CDC*);
@@ -84,6 +84,10 @@ protected:
        afx_msg void OnEditFind();
        afx_msg void OnEditReplace();
        afx_msg void OnEditRepeat();
+       afx_msg void OnEditUndo();
+       afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
+       afx_msg void OnEditRedo();
+       afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
        afx_msg void OnEditCut();
        afx_msg void OnEditCopy();
        afx_msg void OnEditPaste();
index 77503de..af21ffb 100644 (file)
@@ -27,7 +27,7 @@
 #define _HEKSEDIT_H_\r
 \r
 #ifndef HEKSEDIT_INTERFACE_VERSION\r
-#define HEKSEDIT_INTERFACE_VERSION 1\r
+#define HEKSEDIT_INTERFACE_VERSION 2\r
 #endif\r
 \r
 /**\r
@@ -54,25 +54,25 @@ public:
                COLORREF iDiffBkColorValue, iDiffTextColorValue, iSelDiffBkColorValue, iSelDiffTextColorValue;\r
        };\r
 \r
+       /** @brief Frhed settings. */\r
        struct Settings\r
        {\r
-               int iBytesPerLine;\r
-               int iAutomaticBPL;\r
-               BYTE_ENDIAN iBinaryMode;\r
-               int bReadOnly;\r
-               int bSaveIni;\r
+               int iBytesPerLine; /**< How many bytes in one line in hex view. */\r
+               int iAutomaticBPL; /**< Add max amount of bytes that fit to view. */\r
+               BYTE_ENDIAN iBinaryMode; /**< Binary mode, little/big endian. */\r
+               int bReadOnly; /**< Is editor in read-only mode? */\r
+               int bSaveIni; /**< Save INI file when required. */\r
                int iFontSize;\r
-               int iCharacterSet;\r
-               int iMinOffsetLen;\r
-               int iMaxOffsetLen;\r
-               int bAutoOffsetLen;\r
+               int iCharacterSet; /**< Use OEM or ANSI character set? */\r
+               int iMinOffsetLen; /**< Minimum numbers used in offset. */\r
+               int iMaxOffsetLen; /**< Maximum numbers used in offset. */\r
+               int bAutoOffsetLen; /**< Determine offset length automatically. */\r
                int bCenterCaret;\r
                int iFontZoom;\r
        };\r
 \r
        struct Status\r
        {\r
-               int iFileChanged;\r
                int iEnteringMode;\r
                int iCurByte;\r
                int iCurNibble;\r
@@ -80,7 +80,7 @@ public:
                int iVscrollPos;\r
                int iHscrollMax;\r
                int iHscrollPos;\r
-               int bSelected;\r
+               bool bSelected;\r
                int iStartOfSelection;\r
                int iEndOfSelection;\r
        };\r
@@ -111,6 +111,16 @@ public:
        virtual void STDMETHODCALLTYPE CMD_zoom(int) = 0;\r
        virtual void STDMETHODCALLTYPE CMD_select_all() = 0;\r
        virtual void STDMETHODCALLTYPE set_sibling2(IHexEditorWindow *, IHexEditorWindow *) = 0;\r
+       virtual void STDMETHODCALLTYPE copy_sel_from(IHexEditorWindow *) = 0;\r
+       virtual void STDMETHODCALLTYPE copy_all_from(IHexEditorWindow *) = 0;\r
+       virtual void STDMETHODCALLTYPE CMD_edit_undo() = 0;\r
+       virtual void STDMETHODCALLTYPE CMD_edit_redo() = 0;\r
+       virtual bool STDMETHODCALLTYPE can_undo() const = 0;\r
+       virtual bool STDMETHODCALLTYPE can_redo() const = 0;\r
+       virtual void STDMETHODCALLTYPE set_savepoint() = 0;\r
+       virtual bool STDMETHODCALLTYPE get_modified() const = 0;\r
+       virtual void STDMETHODCALLTYPE clear_undorecords() = 0;\r
+       virtual void STDMETHODCALLTYPE share_undorecords(IHexEditorWindow *) = 0;\r
 };\r
 \r
 #endif // _HEKSEDIT_H_\r