From abba8127d94c88cf48cfb2d30c564fedcc1fdda9 Mon Sep 17 00:00:00 2001 From: "G.K.MacGregor" Date: Tue, 27 Oct 2020 15:17:54 +0000 Subject: [PATCH] Implement row insertion and deletion --- document.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++++++-- document.h | 29 +++++++++++++++ mainwindow.cpp | 28 ++++++++++++++ mainwindow.h | 2 + 4 files changed, 155 insertions(+), 3 deletions(-) diff --git a/document.cpp b/document.cpp index dce76dd..cf0d1d5 100644 --- a/document.cpp +++ b/document.cpp @@ -279,10 +279,12 @@ void TeletextDocument::cursorRight() emit cursorMoved(); } -void TeletextDocument::moveCursor(int newCursorRow, int newCursorColumn) +void TeletextDocument::moveCursor(int cursorRow, int cursorColumn) { - m_cursorRow = newCursorRow; - m_cursorColumn = newCursorColumn; + if (cursorRow != -1) + m_cursorRow = cursorRow; + if (cursorColumn != -1) + m_cursorColumn = cursorColumn; emit cursorMoved(); } @@ -410,6 +412,97 @@ void BackspaceCommand::undo() } +InsertRowCommand::InsertRowCommand(TeletextDocument *teletextDocument, bool copyRow, QUndoCommand *parent) : QUndoCommand(parent) +{ + m_teletextDocument = teletextDocument; + m_subPageIndex = teletextDocument->currentSubPageIndex(); + m_row = teletextDocument->cursorRow(); + m_copyRow = copyRow; +} + +void InsertRowCommand::redo() +{ + m_teletextDocument->selectSubPageIndex(m_subPageIndex); + m_teletextDocument->moveCursor(m_row, -1); + // Store copy of the bottom row we're about to push out, for undo + for (int c=0; c<40; c++) + m_deletedBottomRow[c] = m_teletextDocument->currentSubPage()->character(23, c); + // Shuffle lines below the inserting row downwards without affecting the FastText row + for (int r=22; r>=m_row; r--) + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(r+1, c, m_teletextDocument->currentSubPage()->character(r, c)); + if (m_copyRow) + setText(QObject::tr("insert copy row")); + else { + // The above shuffle leaves a duplicate of the current row, so blank it if requested + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(m_row, c, ' '); + setText(QObject::tr("insert blank row")); + } + emit m_teletextDocument->refreshNeeded(); +} + +void InsertRowCommand::undo() +{ + m_teletextDocument->selectSubPageIndex(m_subPageIndex); + m_teletextDocument->moveCursor(m_row, -1); + // Shuffle lines below the deleting row upwards without affecting the FastText row + for (int r=m_row; r<23; r++) + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(r, c, m_teletextDocument->currentSubPage()->character(r+1, c)); + // Now repair the bottom row we pushed out + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(23, c, m_deletedBottomRow[c]); + if (m_copyRow) + setText(QObject::tr("insert copy row")); + else + setText(QObject::tr("insert blank row")); + emit m_teletextDocument->refreshNeeded(); +} + + +DeleteRowCommand::DeleteRowCommand(TeletextDocument *teletextDocument, QUndoCommand *parent) : QUndoCommand(parent) +{ + m_teletextDocument = teletextDocument; + m_subPageIndex = teletextDocument->currentSubPageIndex(); + m_row = teletextDocument->cursorRow(); +} + +void DeleteRowCommand::redo() +{ + m_teletextDocument->selectSubPageIndex(m_subPageIndex); + m_teletextDocument->moveCursor(m_row, -1); + // Store copy of the row we're going to delete, for undo + for (int c=0; c<40; c++) + m_deletedRow[c] = m_teletextDocument->currentSubPage()->character(m_row, c); + // Shuffle lines below the deleting row upwards without affecting the FastText row + for (int r=m_row; r<23; r++) + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(r, c, m_teletextDocument->currentSubPage()->character(r+1, c)); + // If we deleted the FastText row blank that row, otherwise blank the last row + int blankingRow = (m_row < 24) ? 23 : 24; + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(blankingRow, c, ' '); + setText(QObject::tr("delete row")); + emit m_teletextDocument->refreshNeeded(); +} + +void DeleteRowCommand::undo() +{ + m_teletextDocument->selectSubPageIndex(m_subPageIndex); + m_teletextDocument->moveCursor(m_row, -1); + // Shuffle lines below the inserting row downwards without affecting the FastText row + for (int r=22; r>=m_row; r--) + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(r+1, c, m_teletextDocument->currentSubPage()->character(r, c)); + // Now repair the row we deleted + for (int c=0; c<40; c++) + m_teletextDocument->currentSubPage()->setCharacter(m_row, c, m_deletedRow[c]); + setText(QObject::tr("delete row")); + emit m_teletextDocument->refreshNeeded(); +} + + InsertSubPageCommand::InsertSubPageCommand(TeletextDocument *teletextDocument, bool afterCurrentSubPage, bool copySubPage, QUndoCommand *parent) : QUndoCommand(parent) { m_teletextDocument = teletextDocument; diff --git a/document.h b/document.h index 89adce2..54ab7be 100644 --- a/document.h +++ b/document.h @@ -152,6 +152,35 @@ private: bool m_copySubPage; }; +class InsertRowCommand : public QUndoCommand +{ +public: + InsertRowCommand(TeletextDocument *, bool, QUndoCommand *parent = 0); + + void redo() override; + void undo() override; + +private: + TeletextDocument *m_teletextDocument; + int m_subPageIndex, m_row; + bool m_copyRow; + unsigned char m_deletedBottomRow[40]; +}; + +class DeleteRowCommand : public QUndoCommand +{ +public: + DeleteRowCommand(TeletextDocument *, QUndoCommand *parent = 0); + + void redo() override; + void undo() override; + +private: + TeletextDocument *m_teletextDocument; + int m_subPageIndex, m_row; + unsigned char m_deletedRow[40]; +}; + class SetColourCommand : public QUndoCommand { public: diff --git a/mainwindow.cpp b/mainwindow.cpp index 888204e..dc66f07 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -324,6 +324,20 @@ void MainWindow::createActions() */ #endif // !QT_NO_CLIPBOARD + QAction *insertBlankRowAct = editMenu->addAction(tr("Insert blank row")); + insertBlankRowAct->setStatusTip(tr("Insert a blank row at the cursor position")); + connect(insertBlankRowAct, &QAction::triggered, [=]() { insertRow(false); } ); + + QAction *insertCopyRowAct = editMenu->addAction(tr("Insert copy row")); + insertCopyRowAct->setStatusTip(tr("Insert a row that's a copy of the row at the cursor position")); + connect(insertCopyRowAct, &QAction::triggered, [=]() { insertRow(true); } ); + + QAction *deleteRowAct = editMenu->addAction(tr("Delete row")); + deleteRowAct->setStatusTip(tr("Delete the row at the cursor position")); + connect(deleteRowAct, &QAction::triggered, this, &MainWindow::deleteRow); + + editMenu->addSeparator(); + QAction *insertBeforeAct = editMenu->addAction(tr("&Insert subpage before")); insertBeforeAct->setStatusTip(tr("Insert a blank subpage before this subpage")); connect(insertBeforeAct, &QAction::triggered, [=]() { insertSubPage(false, false); }); @@ -538,6 +552,20 @@ void MainWindow::setSceneDimensions() } } +void MainWindow::insertRow(bool copyRow) +{ + if (m_textWidget->document()->cursorRow() == 24) + return; + QUndoCommand *insertRowCommand = new InsertRowCommand(m_textWidget->document(), copyRow); + m_textWidget->document()->undoStack()->push(insertRowCommand); +} + +void MainWindow::deleteRow() +{ + QUndoCommand *deleteRowCommand = new DeleteRowCommand(m_textWidget->document()); + m_textWidget->document()->undoStack()->push(deleteRowCommand); +} + void MainWindow::insertSubPage(bool afterCurrentSubPage, bool copyCurrentSubPage) { QUndoCommand *insertSubPageCommand = new InsertSubPageCommand(m_textWidget->document(), afterCurrentSubPage, copyCurrentSubPage); diff --git a/mainwindow.h b/mainwindow.h index 0f4adc1..68eaa1f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -63,6 +63,8 @@ private slots: void updatePageWidgets(); void updateCursorPosition(); + void insertRow(bool); + void deleteRow(); void insertSubPage(bool, bool); void setSceneDimensions();