Skip to content

Commit

Permalink
fix: crash when undoing column edit
Browse files Browse the repository at this point in the history
Delete command stores temporary reference variable,
which will be empty when changing cursor.
Change storage variable type to store data persistently.

Log: Fix crash when undoing column edit
Bug: https://pms.uniontech.com/bug-view-273663.html
Influence: column-editing
  • Loading branch information
rb-union committed Sep 25, 2024
1 parent 614802b commit 432c884
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 70 deletions.
56 changes: 25 additions & 31 deletions src/editor/deletebackcommond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@
#include "deletebackcommond.h"
#include <QTextBlock>

DeleteBackCommand::DeleteBackCommand(QTextCursor cursor, QPlainTextEdit *edit):
m_cursor(cursor),
m_edit(edit)
DeleteBackCommand::DeleteBackCommand(QTextCursor cursor, QPlainTextEdit *edit)
: m_cursor(cursor)
, m_edit(edit)
{
m_delText = m_cursor.selectedText();
m_delPos = std::min(m_cursor.position(), m_cursor.anchor());
m_insertPos = m_delPos;
}

DeleteBackCommand::~DeleteBackCommand()
{

}
DeleteBackCommand::~DeleteBackCommand() {}

void DeleteBackCommand::undo()
{
Expand All @@ -33,30 +30,30 @@ void DeleteBackCommand::undo()
void DeleteBackCommand::redo()
{
m_cursor.setPosition(m_delPos);
m_cursor.setPosition(m_delPos+m_delText.size(), QTextCursor::KeepAnchor);
m_cursor.setPosition(m_delPos + m_delText.size(), QTextCursor::KeepAnchor);
m_cursor.deleteChar();

// 撤销恢复时光标移回要撤销的位置
m_edit->setTextCursor(m_cursor);
}

DeleteBackAltCommand::DeleteBackAltCommand(QList<QTextEdit::ExtraSelection> &selections,QPlainTextEdit* edit):
m_ColumnEditSelections(selections),
m_edit(edit)
DeleteBackAltCommand::DeleteBackAltCommand(const QList<QTextEdit::ExtraSelection> &selections, QPlainTextEdit *edit)
: m_ColumnEditSelections(selections)
, m_edit(edit)
{
int size = m_ColumnEditSelections.size();
int sum=0;
for(int i=0;i<size;i++){
int sum = 0;
for (int i = 0; i < size; i++) {
QString text;
auto cursor = m_ColumnEditSelections[i].cursor;

if(!cursor.hasSelection() && !cursor.atBlockEnd()){
if (!cursor.hasSelection() && !cursor.atBlockEnd()) {
cursor.setPosition(cursor.position() + 1, QTextCursor::KeepAnchor);
}

text = cursor.selectedText();
if(!text.isEmpty()){
int pos = std::min(cursor.anchor(),cursor.position());
if (!text.isEmpty()) {
int pos = std::min(cursor.anchor(), cursor.position());
DelNode node;
node.m_cursor = cursor;
node.m_insertPos = pos;
Expand All @@ -70,43 +67,40 @@ DeleteBackAltCommand::DeleteBackAltCommand(QList<QTextEdit::ExtraSelection> &sel
}
}

DeleteBackAltCommand::~DeleteBackAltCommand()
{

}
DeleteBackAltCommand::~DeleteBackAltCommand() {}

void DeleteBackAltCommand::undo()
{

int size = m_deletions.size();
for(int i=0;i<size;i++){
for (int i = 0; i < size; i++) {
auto cursor = m_deletions[i].m_cursor;
int pos = m_deletions[i].m_insertPos;
QString text = m_deletions[i].m_delText;
cursor.setPosition(pos,QTextCursor::MoveAnchor);
cursor.setPosition(pos, QTextCursor::MoveAnchor);
cursor.insertText(text);

cursor.setPosition(pos,QTextCursor::MoveAnchor);
cursor.setPosition(pos, QTextCursor::MoveAnchor);
int id = m_deletions[i].m_id_in_Column;
m_ColumnEditSelections[id].cursor = cursor;
m_edit->setTextCursor(cursor);
}

if (0 <= id && id < m_ColumnEditSelections.size()) {
m_ColumnEditSelections[id].cursor = cursor;
m_edit->setTextCursor(cursor);
}
}
}

void DeleteBackAltCommand::redo()
{
int size = m_deletions.size();

for(int i=0;i<size;i++){
for (int i = 0; i < size; i++) {
auto cursor = m_deletions[i].m_cursor;
int pos = m_deletions[i].m_delPos;
QString text = m_deletions[i].m_delText;
cursor.setPosition(pos,QTextCursor::MoveAnchor);
cursor.setPosition(pos, QTextCursor::MoveAnchor);

for(int j=0;j<text.size();j++){
for (int j = 0; j < text.size(); j++) {
cursor.deleteChar();
}
}

}
27 changes: 13 additions & 14 deletions src/editor/deletebackcommond.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,29 @@
#include <QTextCursor>
#include <QTextEdit>
#include <qplaintextedit.h>
//向后删除单一文字或选中文字的撤销重做
class DeleteBackCommand:public QUndoCommand
// 向后删除单一文字或选中文字的撤销重做
class DeleteBackCommand : public QUndoCommand
{
public:
DeleteBackCommand(QTextCursor cursor,QPlainTextEdit* edit);
DeleteBackCommand(QTextCursor cursor, QPlainTextEdit *edit);
virtual ~DeleteBackCommand();
virtual void undo();
virtual void redo();

private:
QTextCursor m_cursor;
QString m_delText {QString()};
int m_delPos {0};
int m_insertPos {0};

QPlainTextEdit* m_edit;
QString m_delText{QString()};
int m_delPos{0};
int m_insertPos{0};

QPlainTextEdit *m_edit;
};

//列模式下向后删除的撤销重做
class DeleteBackAltCommand:public QUndoCommand
// 列模式下向后删除的撤销重做
class DeleteBackAltCommand : public QUndoCommand
{
public:
DeleteBackAltCommand(QList<QTextEdit::ExtraSelection> &selections,QPlainTextEdit* edit);
DeleteBackAltCommand(const QList<QTextEdit::ExtraSelection> &selections, QPlainTextEdit *edit);
virtual ~DeleteBackAltCommand();
virtual void undo();
virtual void redo();
Expand All @@ -47,9 +46,9 @@ class DeleteBackAltCommand:public QUndoCommand
};

private:
QList<QTextEdit::ExtraSelection>& m_ColumnEditSelections;
QList<QTextEdit::ExtraSelection> m_ColumnEditSelections;
QList<DelNode> m_deletions;
QPlainTextEdit* m_edit;
QPlainTextEdit *m_edit;
};

#endif // DELETEBACKCOMMOND_H
#endif // DELETEBACKCOMMOND_H
81 changes: 57 additions & 24 deletions tests/src/editor/ut_deletebackcommond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@

#include "ut_deletebackcommond.h"
#include "../src/editor/deletebackcommond.h"
#include"../../src/widgets/window.h"
#include "../../src/widgets/window.h"
#include "qplaintextedit.h"
#include "qtextcursor.h"
UT_Deletebackcommond::UT_Deletebackcommond()
{

}
UT_Deletebackcommond::UT_Deletebackcommond() {}

TEST(UT_Deletebackcommond_DeleteBackCommand, UT_Deletebackcommond_DeleteBackCommand)
{
Expand Down Expand Up @@ -64,10 +61,7 @@ TEST(UT_Deletebackcommond_undo, UT_Deletebackcommond_undo)
pWindow->deleteLater();
}

UT_Deletebackaltcommond::UT_Deletebackaltcommond()
{

}
UT_Deletebackaltcommond::UT_Deletebackaltcommond() {}

TEST(UT_Deletebackaltcommond_DeleteBackAltCommand, UT_Deletebackaltcommond_DeleteBackAltCommand)
{
Expand All @@ -81,8 +75,8 @@ TEST(UT_Deletebackaltcommond_DeleteBackAltCommand, UT_Deletebackaltcommond_Delet
list.push_back(sel);
list.push_back(sel);

QPlainTextEdit* edit = new QPlainTextEdit;
DeleteBackAltCommand* com = new DeleteBackAltCommand(list, edit);
QPlainTextEdit *edit = new QPlainTextEdit;
DeleteBackAltCommand *com = new DeleteBackAltCommand(list, edit);

delete com;
com = nullptr;
Expand All @@ -92,54 +86,93 @@ TEST(UT_Deletebackaltcommond_DeleteBackAltCommand, UT_Deletebackaltcommond_Delet

TEST(UT_Deletebackaltcommond_redo, UT_Deletebackaltcommond_redo)
{

Window* window = new Window;
Window *window = new Window;
EditWrapper *wrapper = window->createEditor();
TextEdit * edit = wrapper->textEditor();
TextEdit *edit = wrapper->textEditor();
QString text = "test";
QList<QTextEdit::ExtraSelection> list;
QTextEdit::ExtraSelection sel;
QTextCursor cursor;
cursor.insertText(text);
cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor);
cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
sel.cursor = cursor;
list.push_back(sel);
list.push_back(sel);
DeleteBackAltCommand * commond = new DeleteBackAltCommand(list,edit);
commond->m_deletions = {{"123",1,1,1,cursor}};
DeleteBackAltCommand *commond = new DeleteBackAltCommand(list, edit);
commond->m_deletions = {{"123", 1, 1, 1, cursor}};
commond->redo();

window->deleteLater();
wrapper->deleteLater();
edit->deleteLater();

delete commond;commond=nullptr;
delete commond;
commond = nullptr;
}


TEST(UT_Deletebackaltcommond_undo, UT_Deletebackaltcommond_undo)
{
Window* window = new Window;
Window *window = new Window;
EditWrapper *wrapper = window->createEditor();
TextEdit * edit = wrapper->textEditor();
TextEdit *edit = wrapper->textEditor();
QString text = "test";
QList<QTextEdit::ExtraSelection> list;
QTextEdit::ExtraSelection sel;
QTextCursor cursor;
cursor.insertText(text);
cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor);
cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
sel.cursor = cursor;
list.push_back(sel);
list.push_back(sel);

DeleteBackAltCommand* com = new DeleteBackAltCommand(list,edit);
com->m_deletions = {{"123",1,1,1,cursor}};
DeleteBackAltCommand *com = new DeleteBackAltCommand(list, edit);
com->m_deletions = {{"123", 1, 1, 1, cursor}};
com->undo();

window->deleteLater();
wrapper->deleteLater();
edit->deleteLater();
delete com;
com = nullptr;
}

TEST(UT_Deletebackaltcommond_MoveCursor, UT_Deletebackaltcommond_MoveCursor)
{
Window *window = new Window;
EditWrapper *wrapper = window->createEditor();
TextEdit *edit = wrapper->textEditor();
QString text = "123456\nabcdef";
edit->setPlainText(text);

QList<QTextEdit::ExtraSelection> list;
QTextEdit::ExtraSelection sel;
QTextCursor cursor = edit->textCursor();
// select the left 3 colums: 123|456
// abc|def
cursor.movePosition(QTextCursor::Start);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3);
sel.cursor = cursor;
list.append(sel);

cursor.movePosition(QTextCursor::NextBlock);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3);
sel.cursor = cursor;
list.append(sel);

DeleteBackAltCommand *com = new DeleteBackAltCommand(list, edit);
com->redo();
EXPECT_EQ(edit->toPlainText(), QString("456\ndef"));

list.clear();
cursor.movePosition(QTextCursor::End);
edit->setTextCursor(cursor);

com->undo();
EXPECT_EQ(edit->toPlainText(), text);

window->deleteLater();
wrapper->deleteLater();
edit->deleteLater();
delete com;
com = nullptr;
}
2 changes: 1 addition & 1 deletion tests/src/editor/ut_textedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9753,7 +9753,7 @@ TEST(UT_Textedit_onAppPaletteChanged, OnAppPaletteChanged_ChangeBackground_Pass)
edit->m_wrapper = wra;

Stub s;
s.set(ADDR(DGuiApplicationHelper, applicationPalette), stubApplicationPalette);
s.set((DPalette(DGuiApplicationHelper::*)() const)(&DGuiApplicationHelper::applicationPalette), stubApplicationPalette);

QTextEdit::ExtraSelection selection;
selection.format.setBackground(QBrush(Qt::white));
Expand Down

0 comments on commit 432c884

Please sign in to comment.