我在为一个非常简单的文本编辑器插入新行作为类的项目时尝试实现撤消功能。在程序中,列是光标当前所在的位置,行是矢量所在的当前行。
我能够成功创建我的&#34; insertNewLine()&#34;使用能够在屏幕上显示文本的std::vector<std::string>
的函数。这就是我实现它的方式:
void Editor::insertNewLine()
{
// get a substring
prevLine = lines[row - 1];
size_t tempSize = prevLine.size();
int lengthOffset = getSubstringOffset(tempSize, (column - 1));
std::string cutTemp = prevLine.substr((column - 1), lengthOffset);
lines[row - 1].erase(column - 1);
// after incrementing, row and amount of lines, initialize the new row
row++;
numberOfLines++;
column = 1;
lines.push_back(cutTemp); // insert substring into new line
}
以下是当前输出的示例(其中|是光标):
hello world| (user enters hello world, column = 11, row = 1)
hello|world (user moves cursor to column 5, still on row 1)
(user presses button that calls insertNewLine())
hello
|world (splits where the cursor is to a new line, cursor begins at column 1)
现在,我可以撤消任何其他命令,但是当尝试撤消新行时,我需要让光标返回到上一列,并将该字推回原来的位置。我尝试通过这样做来实现:
void Editor::undoNewLine()
{
std::string source = lines[row - 1]; // save current line
lines[row-1].clear(); // clear current line
row--; // revert up one row
numberOfLines--; // revert amount of lines
lines.push_back(source); // append
}
使用此功能,我期望输出看起来像这样(来自上面的示例):
(user presses a button that calls undoNewLine())
hello|world
但问题是,这是我从当前代码得到的输出:
(user presses a button that calls undoNewLine())
|world
基本上,使用push_back(source)会覆盖原来的内容并将光标移到前面。我尝试将列增加到撤消阶段之前的原始位置,但是,这也没有用。我刚刚结束了这个输出:
(user presses a button that calls undoNewLine())
world|
那么我应该如何尝试实现这个撤销功能呢?关于我做错的任何提示或想法?
答案 0 :(得分:1)
在你的解决方案中,你通过调用clear()来删除前一行的内容(hello)。相反,只需附加当前行。字符串类使这很容易:
lines[row-1] += lines[row];
之后,您可以使用vector::erase删除当前行。
注意强> 请注意,这可能效率低下,因为下面的所有行都需要重新定位。 如果这确实成为一个问题,你可以切换到std :: list但是你失去了对你的行的随机访问。