Skip to content

Commit bd281a8

Browse files
committed
Fix issue #2702: [BUG} Phantom line added when identical blocks of text pasted
1 parent e5231fd commit bd281a8

File tree

2 files changed

+174
-7
lines changed

2 files changed

+174
-7
lines changed

Src/GhostTextBuffer.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ InsertText (CCrystalTextView * pSource, int nLine,
274274
// when inserting an EOL terminated text into a ghost line,
275275
// there is a discrepancy between nInsertedLines and nEndLine-nRealLine
276276
bool bDiscrepancyInInsertedLines;
277-
if (bFirstLineGhost && nEndChar == 0 && ApparentLastRealLine() >= nEndLine)
277+
if (bFirstLineGhost && nEndChar == 0 &&
278+
(ApparentLastRealLine() >= nEndLine || (nEndLine + 1 < m_aLines.size() && m_aLines[nEndLine + 1].FullLength() == 0)))
278279
bDiscrepancyInInsertedLines = true;
279280
else
280281
bDiscrepancyInInsertedLines = false;
@@ -294,12 +295,6 @@ InsertText (CCrystalTextView * pSource, int nLine,
294295
bDiscrepancyInInsertedLines = false;
295296
}
296297

297-
// compute the number of real lines created (for undo)
298-
int nRealLinesCreated = nEndLine - nLine;
299-
if (bFirstLineGhost && (nEndChar > 0 || ApparentLastRealLine() < nEndLine))
300-
// we create one more real line
301-
nRealLinesCreated ++;
302-
303298
int i;
304299
for (i = nLine ; i < nEndLine ; i++)
305300
{

Src/Test.cpp

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "SyntaxColors.h"
2323
#include "MergeCmdLineInfo.h"
2424
#include "editcmd.h"
25+
#include "ClipBoard.h"
2526
#include "gtest/gtest.h"
2627

2728
String getProjectRoot()
@@ -291,6 +292,177 @@ TEST(FileCompare, LastLineEOL)
291292
dlg2.SetFormerResult(nPrevFormerResult2);
292293
}
293294

295+
bool PutToClipboard2(const String& text, HWND hwnd)
296+
{
297+
bool result = false;
298+
for (int i = 0; i < 10; ++i)
299+
{
300+
SetFocus(hwnd);
301+
result = PutToClipboard(text, hwnd);
302+
EXPECT_EQ(true, result);
303+
if (result)
304+
break;
305+
Sleep(10);
306+
}
307+
return result;
308+
}
309+
310+
TEST(FileCompare, Issue2702)
311+
{
312+
CMessageBoxDialog dlg(nullptr, IDS_FILESSAME, 0U, 0U, IDS_FILESSAME);
313+
const int nPrevFormerResult = dlg.SetFormerResult(IDOK);
314+
EXPECT_TRUE(GetMainFrame()->DoFileNew(ID_MERGE_COMPARE_TEXT, 2));
315+
CFrameWnd* pFrame = GetMainFrame()->GetActiveFrame();
316+
EXPECT_NE(nullptr, pFrame);
317+
if (pFrame == nullptr)
318+
return;
319+
CMergeDoc* pDoc = dynamic_cast<CMergeDoc *>(pFrame->GetActiveDocument());
320+
EXPECT_NE(nullptr, pDoc);
321+
if (pDoc == nullptr)
322+
return;
323+
CMergeEditView *pViewLeft = pDoc->GetView(0, 0);
324+
String text = _T("aaa\r\nbbb\r\nccc\r\n");
325+
EXPECT_EQ(true, PutToClipboard2(text, pViewLeft->m_hWnd));
326+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
327+
pViewLeft->SendMessage(WM_COMMAND, ID_REFRESH);
328+
for (int l = 0; l < 4; ++l)
329+
{
330+
EXPECT_EQ(1, pDoc->GetDiffCount());
331+
CMergeEditView *pView = pDoc->GetView(0, 1);
332+
pView->SetCursorPos({ 0, l });
333+
pView->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
334+
pView->SendMessage(WM_COMMAND, ID_REFRESH);
335+
EXPECT_EQ(0, pDoc->GetDiffCount());
336+
pView->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
337+
}
338+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
339+
pFrame->PostMessage(WM_CLOSE);
340+
dlg.SetFormerResult(nPrevFormerResult);
341+
}
342+
343+
TEST(FileCompare, Issue2702_2)
344+
{
345+
CMessageBoxDialog dlg(nullptr, IDS_FILESSAME, 0U, 0U, IDS_FILESSAME);
346+
const int nPrevFormerResult = dlg.SetFormerResult(IDOK);
347+
EXPECT_TRUE(GetMainFrame()->DoFileNew(ID_MERGE_COMPARE_TEXT, 2));
348+
CFrameWnd* pFrame = GetMainFrame()->GetActiveFrame();
349+
EXPECT_NE(nullptr, pFrame);
350+
if (pFrame == nullptr)
351+
return;
352+
CMergeDoc* pDoc = dynamic_cast<CMergeDoc *>(pFrame->GetActiveDocument());
353+
EXPECT_NE(nullptr, pDoc);
354+
if (pDoc == nullptr)
355+
return;
356+
CMergeEditView *pViewLeft = pDoc->GetView(0, 0);
357+
String text = _T("aaa\r\nbbb\r\nccc\r\nddd\r\n");
358+
EXPECT_EQ(true, PutToClipboard2(text, pViewLeft->m_hWnd));
359+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
360+
CMergeEditView *pViewRight = pDoc->GetView(0, 1);
361+
text = _T("ddd\r\n");
362+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
363+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
364+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
365+
for (int l = 0; l < 4; ++l)
366+
{
367+
EXPECT_EQ(1, pDoc->GetDiffCount()) << "l=" << l;
368+
pViewRight->SetCursorPos({ 0, l });
369+
text = _T("aaa\r\nbbb\r\nccc\r\n");
370+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
371+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
372+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
373+
CString left, right;
374+
pViewLeft->GetTextWithoutEmptys(0, 0, pViewLeft->GetLineCount() - 1, 0, left);
375+
pViewRight->GetTextWithoutEmptys(0, 0, pViewRight->GetLineCount() - 1, 0, right);
376+
ASSERT_EQ(0, pDoc->GetDiffCount()) << "l=" << l << " left=" << (const tchar_t*)left << " right=" << (const tchar_t*)right;
377+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
378+
}
379+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
380+
pFrame->PostMessage(WM_CLOSE);
381+
dlg.SetFormerResult(nPrevFormerResult);
382+
}
383+
384+
TEST(FileCompare, Issue2702_3)
385+
{
386+
CMessageBoxDialog dlg(nullptr, IDS_FILESSAME, 0U, 0U, IDS_FILESSAME);
387+
const int nPrevFormerResult = dlg.SetFormerResult(IDOK);
388+
EXPECT_TRUE(GetMainFrame()->DoFileNew(ID_MERGE_COMPARE_TEXT, 2));
389+
CFrameWnd* pFrame = GetMainFrame()->GetActiveFrame();
390+
EXPECT_NE(nullptr, pFrame);
391+
if (pFrame == nullptr)
392+
return;
393+
CMergeDoc* pDoc = dynamic_cast<CMergeDoc *>(pFrame->GetActiveDocument());
394+
EXPECT_NE(nullptr, pDoc);
395+
if (pDoc == nullptr)
396+
return;
397+
CMergeEditView *pViewLeft = pDoc->GetView(0, 0);
398+
String text = _T("aaa\r\nbbb\r\nccc\r\nddd\r\n");
399+
EXPECT_EQ(true, PutToClipboard2(text, pViewLeft->m_hWnd));
400+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
401+
CMergeEditView *pViewRight = pDoc->GetView(0, 1);
402+
text = _T("aaa\r\n");
403+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
404+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
405+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
406+
for (int l = 1; l < 5; ++l)
407+
{
408+
EXPECT_EQ(1, pDoc->GetDiffCount()) << "l=" << l;
409+
pViewRight->SetCursorPos({ 0, l });
410+
text = _T("bbb\r\nccc\r\nddd\r\n");
411+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
412+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
413+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
414+
CString left, right;
415+
pViewLeft->GetTextWithoutEmptys(0, 0, pViewLeft->GetLineCount() - 1, 0, left);
416+
pViewRight->GetTextWithoutEmptys(0, 0, pViewRight->GetLineCount() - 1, 0, right);
417+
ASSERT_EQ(0, pDoc->GetDiffCount()) << "l=" << l << " left=" << (const tchar_t*)left << " right=" << (const tchar_t*)right;
418+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
419+
}
420+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
421+
pFrame->PostMessage(WM_CLOSE);
422+
dlg.SetFormerResult(nPrevFormerResult);
423+
}
424+
425+
TEST(FileCompare, Issue2702_4)
426+
{
427+
CMessageBoxDialog dlg(nullptr, IDS_FILESSAME, 0U, 0U, IDS_FILESSAME);
428+
const int nPrevFormerResult = dlg.SetFormerResult(IDOK);
429+
EXPECT_TRUE(GetMainFrame()->DoFileNew(ID_MERGE_COMPARE_TEXT, 2));
430+
CFrameWnd* pFrame = GetMainFrame()->GetActiveFrame();
431+
EXPECT_NE(nullptr, pFrame);
432+
if (pFrame == nullptr)
433+
return;
434+
CMergeDoc* pDoc = dynamic_cast<CMergeDoc *>(pFrame->GetActiveDocument());
435+
EXPECT_NE(nullptr, pDoc);
436+
if (pDoc == nullptr)
437+
return;
438+
CMergeEditView *pViewLeft = pDoc->GetView(0, 0);
439+
String text = _T("aaa\r\nbbb\r\nccc\r\nddd\r\neee\r\n");
440+
EXPECT_EQ(true, PutToClipboard2(text, pViewLeft->m_hWnd));
441+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
442+
CMergeEditView *pViewRight = pDoc->GetView(0, 1);
443+
text = _T("aaa\r\neee\r\n");
444+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
445+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
446+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
447+
for (int l = 1; l < 5; ++l)
448+
{
449+
EXPECT_EQ(1, pDoc->GetDiffCount()) << "l=" << l;
450+
pViewRight->SetCursorPos({ 0, l });
451+
text = _T("bbb\r\nccc\r\nddd\r\n");
452+
EXPECT_EQ(true, PutToClipboard2(text, pViewRight->m_hWnd));
453+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_PASTE);
454+
pViewRight->SendMessage(WM_COMMAND, ID_REFRESH);
455+
CString left, right;
456+
pViewLeft->GetTextWithoutEmptys(0, 0, pViewLeft->GetLineCount() - 1, 0, left);
457+
pViewRight->GetTextWithoutEmptys(0, 0, pViewRight->GetLineCount() - 1, 0, right);
458+
ASSERT_EQ(0, pDoc->GetDiffCount()) << "l=" << l << " left=" << (const tchar_t*)left << " right=" << (const tchar_t*)right;
459+
pViewRight->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
460+
}
461+
pViewLeft->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
462+
pFrame->PostMessage(WM_CLOSE);
463+
dlg.SetFormerResult(nPrevFormerResult);
464+
}
465+
294466
TEST(FolderCompare, IgnoreEOL)
295467
{
296468
String projectRoot = getProjectRoot();

0 commit comments

Comments
 (0)