OSDN Git Service

add undo reagion
authorTomohisa Hirami <hirami@users.sourceforge.jp>
Thu, 5 Mar 2009 17:04:30 +0000 (02:04 +0900)
committerTomohisa Hirami <hirami@users.sourceforge.jp>
Thu, 5 Mar 2009 17:04:30 +0000 (02:04 +0900)
Src/YAEdit/YAEdit.cpp
Src/YAEdit/YAEditDoc.cpp
Src/YAEdit/YAEditDoc.h
UnitTest/UnitTest/UnitTest.vcproj
UnitTest/UnitTest/testcase/YAEditDocTest.cpp

index 4a7dbae..288014b 100644 (file)
@@ -573,8 +573,21 @@ void YAEditImpl::UpdateSelRegion()
 /////////////////////////////////////////////////////////////////////////////\r
 \r
 void YAEditImpl::CmdNOP() { /* NOP */ }\r
-void YAEditImpl::CmdMoveRight() { pView->ScrollCaret(); pView->MoveRight(); ClearRegion(); pView->ScrollCaret(); }\r
-void YAEditImpl::CmdMoveLeft()  { pView->ScrollCaret(); pView->MoveLeft();  ClearRegion(); pView->ScrollCaret(); }\r
+void YAEditImpl::CmdMoveRight() {\r
+       pView->ScrollCaret();\r
+       pView->MoveRight();\r
+       ClearRegion();\r
+       pView->ScrollCaret();\r
+       pDoc->CloseUndoRegion();\r
+}\r
+\r
+void YAEditImpl::CmdMoveLeft()  {\r
+       pView->ScrollCaret();\r
+       pView->MoveLeft();\r
+       ClearRegion();\r
+       pView->ScrollCaret();\r
+       pDoc->CloseUndoRegion();\r
+}\r
 \r
 void YAEditImpl::CmdMoveUp()\r
 {\r
@@ -582,11 +595,29 @@ void YAEditImpl::CmdMoveUp()
        pView->MoveUp();\r
        ClearRegion();\r
        pView->ScrollCaret(); \r
+       pDoc->CloseUndoRegion();\r
 }\r
 \r
-void YAEditImpl::CmdMoveEOL()   { pView->ScrollCaret(); pView->MoveEOL();   ClearRegion(); pView->ScrollCaret(); }\r
-void YAEditImpl::CmdMoveTOL()   { pView->ScrollCaret(); pView->MoveTOL();   ClearRegion(); }\r
-void YAEditImpl::CmdMoveDown()  { pView->ScrollCaret(); pView->MoveDown();  ClearRegion(); }\r
+void YAEditImpl::CmdMoveEOL()   {\r
+       pView->ScrollCaret();\r
+       pView->MoveEOL();\r
+       ClearRegion();\r
+       pView->ScrollCaret();\r
+       pDoc->CloseUndoRegion();\r
+}\r
+void YAEditImpl::CmdMoveTOL()   { \r
+       pView->ScrollCaret();\r
+       pView->MoveTOL();\r
+       ClearRegion();\r
+       pDoc->CloseUndoRegion();\r
+}\r
+\r
+void YAEditImpl::CmdMoveDown()  { \r
+       pView->ScrollCaret();\r
+       pView->MoveDown();\r
+       ClearRegion(); \r
+       pDoc->CloseUndoRegion();\r
+}\r
 \r
 void YAEditImpl::CmdSelRight() { pView->MoveRight(); UpdateSelRegion(); }\r
 void YAEditImpl::CmdSelLeft()  { pView->MoveLeft(); UpdateSelRegion(); }\r
@@ -607,6 +638,7 @@ void YAEditImpl::CmdSelTopOfLogicalLine()
        rSelRegion = rNewRegion;\r
        RequestRedrawRegion(&rSelRegion);\r
        pView->SetCaretPosition(rSelRegion.posStart);\r
+       pDoc->CloseUndoRegion();\r
 }\r
 \r
 void YAEditImpl::CmdSelEndOfLogicalLine()\r
@@ -622,6 +654,8 @@ void YAEditImpl::CmdSelEndOfLogicalLine()
        rSelRegion = rNewRegion;\r
        RequestRedrawRegion(&rSelRegion);\r
        pView->SetCaretPosition(rSelRegion.posEnd);\r
+       pDoc->CloseUndoRegion();\r
+\r
 }\r
 \r
 void YAEditImpl::CmdSelTopOfDoc()\r
@@ -634,6 +668,7 @@ void YAEditImpl::CmdSelTopOfDoc()
        rSelRegion = rNewRegion;\r
        RequestRedrawRegion(&rSelRegion);\r
        pView->SetCaretPosition(rSelRegion.posStart);\r
+       pDoc->CloseUndoRegion();\r
 }\r
 \r
 void YAEditImpl::CmdSelEndOfDoc()\r
@@ -649,6 +684,7 @@ void YAEditImpl::CmdSelEndOfDoc()
        rSelRegion = rNewRegion;\r
        RequestRedrawRegion(&rSelRegion);\r
        pView->SetCaretPosition(rSelRegion.posEnd);\r
+       pDoc->CloseUndoRegion();\r
 }\r
 \r
 void YAEditImpl::CmdReplaceString(LPCTSTR p)\r
@@ -661,6 +697,7 @@ void YAEditImpl::CmdCut()
 {\r
        if (pDoc->IsReadOnly()) return;\r
 \r
+       pDoc->CloseUndoRegion();\r
        if (IsRegionSelected()) {\r
                if (!CopyToClipboard()) {\r
                        MessageBox(pView->hViewWnd, TEXT("Copy to clipboard failed."), TEXT("ERROR"), MB_ICONWARNING | MB_OK);\r
@@ -681,6 +718,7 @@ void YAEditImpl::CmdPaste()
 {\r
        if (pDoc->IsReadOnly()) return;\r
 \r
+       pDoc->CloseUndoRegion();\r
        if (!InsertFromClipboard()) {\r
                MessageBox(pView->hViewWnd, TEXT("Paste from clipboard failed."), TEXT("ERROR"), MB_ICONWARNING | MB_OK);\r
        } else {\r
@@ -692,6 +730,7 @@ void YAEditImpl::CmdBackSpace()
 {\r
        if (pDoc->IsReadOnly()) return;\r
 \r
+       pDoc->CloseUndoRegion();\r
        if (IsRegionSelected()) {\r
                ReplaceText(SelectedRegion(), TEXT(""));\r
        } else {\r
@@ -707,6 +746,7 @@ void YAEditImpl::CmdDeleteChar()
 {\r
        if (pDoc->IsReadOnly()) return;\r
 \r
+       pDoc->CloseUndoRegion();\r
        if (IsRegionSelected()) {\r
                ReplaceText(SelectedRegion(), TEXT(""));\r
        } else {\r
@@ -823,6 +863,8 @@ void YAEditImpl::OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
        nMouseDrgStartX = LOWORD(lParam);\r
        nMouseDrgStartY = HIWORD(lParam);\r
 \r
+       pDoc->CloseUndoRegion();\r
+\r
        // move caret\r
        DWORD nNewRow = pView->DpLinePixelToLgLineNo(nMouseDrgStartY);\r
        if (nNewRow < pLineMgr->MaxLine()) {\r
index 276f755..5cc5ab4 100644 (file)
@@ -38,14 +38,21 @@ BOOL UndoInfo::CmdUndo(YAEditDoc *pDoc) {
 }\r
 \r
 BOOL UndoInfo::UpdateUndoRegion(const Region *pPrevRegion, LPCTSTR pPrev, const Region *pNewRegion, LPCTSTR pNew) {\r
-       rPrevRegion = *pPrevRegion;\r
        if (!sPrevStr.Set(pPrev)) return FALSE;\r
-//     pPrevStr = pPrev;\r
 \r
+       if (sNewStr.Get() != NULL && rNewRegion.posEnd == pPrevRegion->posStart && bOpenRegion) {\r
+               rNewRegion.posEnd = pNewRegion->posEnd;\r
+               return sNewStr.StrCat(pNew);\r
+       }\r
+       rPrevRegion = *pPrevRegion;\r
        rNewRegion = *pNewRegion;\r
        return sNewStr.Set(pNew);\r
 }\r
 \r
+void UndoInfo::CloseUndoRegion() {\r
+       bOpenRegion = FALSE;\r
+}\r
+\r
 /////////////////////////////////////////////////////////////////////////////\r
 // ctor & dtor\r
 /////////////////////////////////////////////////////////////////////////////\r
@@ -148,6 +155,11 @@ BOOL YAEditDoc::ReplaceString(const Region *pDelRegion, LPCTSTR pString, BOOL bK
 \r
        // preserve string and region after replaced.\r
        if (!bKeepUndo) {\r
+               if (!pUndo->IsOpened()) {\r
+                       delete pUndo;\r
+                       pUndo = new UndoInfo();\r
+                       if (pUndo == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }\r
+               }\r
                if (!pUndo->UpdateUndoRegion(pDelRegion, pPrevText, &rNewRegion, pString)) {\r
                        return FALSE;\r
                }\r
@@ -168,7 +180,6 @@ BOOL YAEditDoc::ReplaceString(const Region *pDelRegion, LPCTSTR pString, BOOL bK
 BOOL YAEditDoc::Undo()\r
 {\r
        if (pUndo == NULL) return TRUE;\r
-\r
        BOOL bResult = pUndo->CmdUndo(this);\r
        return bResult;\r
 }\r
@@ -255,3 +266,9 @@ void YAEditDoc::ConvertBytesToCoordinate(DWORD nPos, Coordinate *pPos)
        pPos->row = n - 1;\r
        pPos->col = p->pLine->nUsed;\r
 }\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void YAEditDoc::CloseUndoRegion() {\r
+       if (pUndo) pUndo->CloseUndoRegion(); \r
+}\r
index c569f19..969c9ed 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef YAEDITDOC_H\r
 #define YAEDITDOC_H\r
 \r
+#include "TString.h"\r
+\r
 class YAEditImpl;\r
 class Region;\r
 class PhysicalLineManager;\r
@@ -67,6 +69,10 @@ public:
        void ConvertBytesToCoordinate(DWORD nPos, Coordinate *pPos);\r
 \r
        ////////////////////////////////////////////////////\r
+       //\r
+       void CloseUndoRegion();\r
+\r
+       ////////////////////////////////////////////////////\r
        // only for testing\r
 #ifdef UNIT_TEST\r
        UndoInfo *GetUndoInfo() { return pUndo; }\r
@@ -81,11 +87,9 @@ class UndoInfo {
 #ifdef UNIT_TEST\r
 public:\r
 #endif\r
-//     LPTSTR pPrevStr;\r
        TString sPrevStr;\r
        Region rPrevRegion;\r
 \r
-//     LPTSTR pNewStr;\r
        TString sNewStr;\r
        Region rNewRegion;\r
 \r
@@ -104,6 +108,9 @@ public:
                                                        const Region *pNewRegion, LPCTSTR pNewStr);\r
 \r
        BOOL CmdUndo(YAEditDoc *pDoc);\r
+\r
+       void CloseUndoRegion();\r
+       BOOL IsOpened() { return bOpenRegion; }\r
 };\r
 \r
 #endif
\ No newline at end of file
index ba4300f..163e966 100644 (file)
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath="..\..\Src\YAEdit\YAEditDoc.h"\r
+                                       RelativePath="..\..\Src\YAEdit\YAEditDoc.cpp"\r
                                        >\r
                                </File>\r
                        </Filter>\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath="..\..\Src\YAEdit\YAEditDoc.cpp"\r
+                                       RelativePath="..\..\Src\YAEdit\YAEditDoc.h"\r
                                        >\r
                                </File>\r
                        </Filter>\r
index d4559f7..e63d296 100644 (file)
@@ -26,6 +26,8 @@ static void UndoTest2();
 static void UndoTest3();\r
 static void UndoTest4();\r
 static void UndoTest5();\r
+static void UndoTest6();\r
+\r
 \r
 void YAEditDocTest(TestRunner *r) {\r
        runner = r;\r
@@ -46,6 +48,7 @@ void YAEditDocTest(TestRunner *r) {
        UndoTest3();\r
        UndoTest4();\r
        UndoTest5();\r
+       UndoTest6();\r
 }\r
 \r
 ////////////////////////////////////////////////\r
@@ -355,6 +358,52 @@ void UndoTest3()
 }\r
 \r
 void UndoTest4() {\r
+       YAEditDoc *pDoc = new YAEditDoc();\r
+       ASSERT(pDoc->Init(TEXT("-----"), NULL, NULL));\r
+\r
+       // -----\r
+       Region rReplace(2, 0, 2, 0);\r
+       ASSERT(pDoc->ReplaceString(&rReplace, TEXT("a")));\r
+       // --a---\r
+\r
+       // Undo!\r
+       ASSERT(pDoc->Undo());\r
+\r
+       // expect is -----\r
+       DWORD nLen;\r
+       LPTSTR pResult;\r
+       pResult = pDoc->GetDocumentData(&nLen);\r
+       ASSERT(pResult != NULL);\r
+       ASSERT(_tcsncmp(pResult, TEXT("-----"), nLen) == 0);\r
+       ASSERT(nLen == 5);\r
+\r
+       // Undo(exactly say, this is Redo)\r
+       ASSERT(pDoc->Undo());\r
+\r
+       // expect is --a---\r
+       pResult = pDoc->GetDocumentData(&nLen);\r
+       ASSERT(pResult != NULL);\r
+       ASSERT(_tcsncmp(pResult, TEXT("--a---"), nLen) == 0);\r
+       ASSERT(nLen == 6);\r
+\r
+       // Undo\r
+       ASSERT(pDoc->Undo());\r
+       pResult = pDoc->GetDocumentData(&nLen);\r
+       ASSERT(pResult != NULL);\r
+       ASSERT(_tcsncmp(pResult, TEXT("-----"), nLen) == 0);\r
+       ASSERT(nLen == 5);\r
+\r
+       // Undo(exactly say, this is Redo)\r
+       ASSERT(pDoc->Undo());\r
+\r
+       // expect is --a---\r
+       pResult = pDoc->GetDocumentData(&nLen);\r
+       ASSERT(pResult != NULL);\r
+       ASSERT(_tcsncmp(pResult, TEXT("--a---"), nLen) == 0);\r
+       ASSERT(nLen == 6);\r
+}\r
+\r
+void UndoTest5() {\r
 \r
        YAEditDoc *pDoc = new YAEditDoc();\r
        ASSERT(pDoc->Init(TEXT("-----"), NULL, NULL));\r
@@ -383,10 +432,29 @@ void UndoTest4() {
        ASSERT(pResult != NULL);\r
        ASSERT(_tcsncmp(pResult, TEXT("-----"), nLen) == 0);\r
        ASSERT(nLen == 5);\r
+       // internal detail\r
+       UndoInfo *pui = pDoc->GetUndoInfo();\r
+       ASSERT(_tcscmp(pui->sPrevStr.Get(), TEXT("")) == 0);\r
+       ASSERT(_tcscmp(pui->sNewStr.Get(), TEXT("ab")) == 0);\r
+       Region rPrevExpect(2, 0, 2, 0);\r
+       ASSERT(pui->rPrevRegion == rPrevExpect);\r
+       Region rNewExpect(2, 0, 4, 0);\r
+       ASSERT(pui->rNewRegion == rNewExpect);\r
+\r
+       ASSERT(pDoc->Undo());\r
+\r
+       // Undo(Redo)\r
+       pResult = pDoc->GetDocumentData(&nLen);\r
+       ASSERT(pResult != NULL);\r
+       ASSERT(_tcsncmp(pResult, TEXT("--ab---"), nLen) == 0);\r
+       ASSERT(nLen == 7);\r
+       // expect is --ab---\r
 \r
 }\r
 \r
-void UndoTest5() {\r
+// CloseUndoRegion test\r
+void UndoTest6() {\r
+\r
        YAEditDoc *pDoc = new YAEditDoc();\r
        ASSERT(pDoc->Init(TEXT("-----"), NULL, NULL));\r
 \r
@@ -395,39 +463,37 @@ void UndoTest5() {
        ASSERT(pDoc->ReplaceString(&rReplace, TEXT("a")));\r
        // --a---\r
 \r
-       // Undo!\r
-       ASSERT(pDoc->Undo());\r
+       // Cursor moved so undo is applyed only to 'b'\r
+       pDoc->CloseUndoRegion();\r
+\r
+       Region rReplace2(3, 0, 3, 0);\r
+       ASSERT(pDoc->ReplaceString(&rReplace2, TEXT("b")));\r
+       // --ab---\r
 \r
-       // expect is -----\r
        DWORD nLen;\r
        LPTSTR pResult;\r
+\r
        pResult = pDoc->GetDocumentData(&nLen);\r
        ASSERT(pResult != NULL);\r
-       ASSERT(_tcsncmp(pResult, TEXT("-----"), nLen) == 0);\r
-       ASSERT(nLen == 5);\r
+       ASSERT(_tcsncmp(pResult, TEXT("--ab---"), nLen) == 0);\r
+       ASSERT(nLen == 7);\r
 \r
-       // Undo(exactly say, this is Redo)\r
+       // Undo!\r
        ASSERT(pDoc->Undo());\r
 \r
-       // expect is --a---\r
+       // expect is -----\r
        pResult = pDoc->GetDocumentData(&nLen);\r
        ASSERT(pResult != NULL);\r
        ASSERT(_tcsncmp(pResult, TEXT("--a---"), nLen) == 0);\r
        ASSERT(nLen == 6);\r
 \r
-       // Undo\r
        ASSERT(pDoc->Undo());\r
-       pResult = pDoc->GetDocumentData(&nLen);\r
-       ASSERT(pResult != NULL);\r
-       ASSERT(_tcsncmp(pResult, TEXT("-----"), nLen) == 0);\r
-       ASSERT(nLen == 5);\r
 \r
-       // Undo(exactly say, this is Redo)\r
-       ASSERT(pDoc->Undo());\r
-\r
-       // expect is --a---\r
+       // Undo(Redo)\r
        pResult = pDoc->GetDocumentData(&nLen);\r
        ASSERT(pResult != NULL);\r
-       ASSERT(_tcsncmp(pResult, TEXT("--a---"), nLen) == 0);\r
-       ASSERT(nLen == 6);\r
-}
\ No newline at end of file
+       ASSERT(_tcsncmp(pResult, TEXT("--ab---"), nLen) == 0);\r
+       ASSERT(nLen == 7);\r
+       // expect is --ab---\r
+\r
+}\r