/////////////////////////////////////////////////////////////////////////////\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
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
rSelRegion = rNewRegion;\r
RequestRedrawRegion(&rSelRegion);\r
pView->SetCaretPosition(rSelRegion.posStart);\r
+ pDoc->CloseUndoRegion();\r
}\r
\r
void YAEditImpl::CmdSelEndOfLogicalLine()\r
rSelRegion = rNewRegion;\r
RequestRedrawRegion(&rSelRegion);\r
pView->SetCaretPosition(rSelRegion.posEnd);\r
+ pDoc->CloseUndoRegion();\r
+\r
}\r
\r
void YAEditImpl::CmdSelTopOfDoc()\r
rSelRegion = rNewRegion;\r
RequestRedrawRegion(&rSelRegion);\r
pView->SetCaretPosition(rSelRegion.posStart);\r
+ pDoc->CloseUndoRegion();\r
}\r
\r
void YAEditImpl::CmdSelEndOfDoc()\r
rSelRegion = rNewRegion;\r
RequestRedrawRegion(&rSelRegion);\r
pView->SetCaretPosition(rSelRegion.posEnd);\r
+ pDoc->CloseUndoRegion();\r
}\r
\r
void YAEditImpl::CmdReplaceString(LPCTSTR p)\r
{\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
{\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
{\r
if (pDoc->IsReadOnly()) return;\r
\r
+ pDoc->CloseUndoRegion();\r
if (IsRegionSelected()) {\r
ReplaceText(SelectedRegion(), TEXT(""));\r
} else {\r
{\r
if (pDoc->IsReadOnly()) return;\r
\r
+ pDoc->CloseUndoRegion();\r
if (IsRegionSelected()) {\r
ReplaceText(SelectedRegion(), TEXT(""));\r
} else {\r
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
}\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
\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
BOOL YAEditDoc::Undo()\r
{\r
if (pUndo == NULL) return TRUE;\r
-\r
BOOL bResult = pUndo->CmdUndo(this);\r
return bResult;\r
}\r
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
#ifndef YAEDITDOC_H\r
#define YAEDITDOC_H\r
\r
+#include "TString.h"\r
+\r
class YAEditImpl;\r
class Region;\r
class PhysicalLineManager;\r
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
#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
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
>\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
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
UndoTest3();\r
UndoTest4();\r
UndoTest5();\r
+ UndoTest6();\r
}\r
\r
////////////////////////////////////////////////\r
}\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
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
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