Allow header row editing
This commit is contained in:
@@ -68,6 +68,7 @@ TeletextDocument::TeletextDocument()
|
|||||||
m_undoStack = new QUndoStack(this);
|
m_undoStack = new QUndoStack(this);
|
||||||
m_cursorRow = 1;
|
m_cursorRow = 1;
|
||||||
m_cursorColumn = 0;
|
m_cursorColumn = 0;
|
||||||
|
m_rowZeroAllowed = false;
|
||||||
m_selectionCornerRow = m_selectionCornerColumn = -1;
|
m_selectionCornerRow = m_selectionCornerColumn = -1;
|
||||||
m_selectionSubPage = nullptr;
|
m_selectionSubPage = nullptr;
|
||||||
|
|
||||||
@@ -252,7 +253,7 @@ void TeletextDocument::cursorUp(bool shiftKey)
|
|||||||
if (shiftKey && !selectionActive())
|
if (shiftKey && !selectionActive())
|
||||||
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (--m_cursorRow == 0)
|
if (--m_cursorRow == 0 - (int)m_rowZeroAllowed)
|
||||||
m_cursorRow = 24;
|
m_cursorRow = 24;
|
||||||
|
|
||||||
if (shiftKey)
|
if (shiftKey)
|
||||||
@@ -269,7 +270,7 @@ void TeletextDocument::cursorDown(bool shiftKey)
|
|||||||
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (++m_cursorRow == 25)
|
if (++m_cursorRow == 25)
|
||||||
m_cursorRow = 1;
|
m_cursorRow = (int)!m_rowZeroAllowed;
|
||||||
|
|
||||||
if (shiftKey)
|
if (shiftKey)
|
||||||
emit selectionMoved();
|
emit selectionMoved();
|
||||||
@@ -333,6 +334,13 @@ void TeletextDocument::moveCursor(int cursorRow, int cursorColumn, bool selectio
|
|||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeletextDocument::setRowZeroAllowed(bool allowed)
|
||||||
|
{
|
||||||
|
m_rowZeroAllowed = allowed;
|
||||||
|
if (m_cursorRow == 0 && !allowed)
|
||||||
|
cursorDown();
|
||||||
|
}
|
||||||
|
|
||||||
void TeletextDocument::setSelectionCorner(int row, int column)
|
void TeletextDocument::setSelectionCorner(int row, int column)
|
||||||
{
|
{
|
||||||
if (m_selectionCornerRow != row || m_selectionCornerColumn != column) {
|
if (m_selectionCornerRow != row || m_selectionCornerColumn != column) {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public:
|
|||||||
void cursorLeft(bool shiftKey=false);
|
void cursorLeft(bool shiftKey=false);
|
||||||
void cursorRight(bool shiftKey=false);
|
void cursorRight(bool shiftKey=false);
|
||||||
void moveCursor(int cursorRow, int cursorColumn, bool selectionInProgress=false);
|
void moveCursor(int cursorRow, int cursorColumn, bool selectionInProgress=false);
|
||||||
|
bool rowZeroAllowed() const { return m_rowZeroAllowed; };
|
||||||
|
void setRowZeroAllowed(bool allowed);
|
||||||
int selectionTopRow() const { return m_selectionCornerRow == -1 ? m_cursorRow : qMin(m_selectionCornerRow, m_cursorRow); }
|
int selectionTopRow() const { return m_selectionCornerRow == -1 ? m_cursorRow : qMin(m_selectionCornerRow, m_cursorRow); }
|
||||||
int selectionBottomRow() const { return qMax(m_selectionCornerRow, m_cursorRow); }
|
int selectionBottomRow() const { return qMax(m_selectionCornerRow, m_cursorRow); }
|
||||||
int selectionLeftColumn() const { return m_selectionCornerColumn == -1 ? m_cursorColumn : qMin(m_selectionCornerColumn, m_cursorColumn); }
|
int selectionLeftColumn() const { return m_selectionCornerColumn == -1 ? m_cursorColumn : qMin(m_selectionCornerColumn, m_cursorColumn); }
|
||||||
@@ -123,6 +125,7 @@ private:
|
|||||||
std::vector<LevelOnePage *> m_recycleSubPages;
|
std::vector<LevelOnePage *> m_recycleSubPages;
|
||||||
QUndoStack *m_undoStack;
|
QUndoStack *m_undoStack;
|
||||||
int m_cursorRow, m_cursorColumn, m_selectionCornerRow, m_selectionCornerColumn;
|
int m_cursorRow, m_cursorColumn, m_selectionCornerRow, m_selectionCornerColumn;
|
||||||
|
bool m_rowZeroAllowed;
|
||||||
LevelOnePage *m_selectionSubPage;
|
LevelOnePage *m_selectionSubPage;
|
||||||
ClutModel *m_clutModel;
|
ClutModel *m_clutModel;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -274,6 +274,22 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document)
|
|||||||
document->subPage(0)->setControlBit(PageBase::C13NOS, m_inLine[9] & 0x04);
|
document->subPage(0)->setControlBit(PageBase::C13NOS, m_inLine[9] & 0x04);
|
||||||
document->subPage(0)->setControlBit(PageBase::C14NOS, m_inLine[9] & 0x02);
|
document->subPage(0)->setControlBit(PageBase::C14NOS, m_inLine[9] & 0x02);
|
||||||
|
|
||||||
|
// See if there's text in the header row
|
||||||
|
bool headerText = false;
|
||||||
|
|
||||||
|
for (int i=10; i<42; i++)
|
||||||
|
if (m_inLine[i] != 0x20) {
|
||||||
|
// TODO - obey odd parity?
|
||||||
|
m_inLine[i] &= 0x7f;
|
||||||
|
headerText = true;
|
||||||
|
}
|
||||||
|
if (headerText) {
|
||||||
|
// Clear the page address and control bits to spaces before putting the row in
|
||||||
|
for (int i=0; i<10; i++)
|
||||||
|
m_inLine[i] = 0x20;
|
||||||
|
|
||||||
|
document->subPage(0)->setPacket(0, QByteArray((const char *)&m_inLine[2], 40));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -543,8 +543,10 @@ QPair<int, int> TeletextWidget::mouseToRowAndColumn(const QPoint &mousePosition)
|
|||||||
{
|
{
|
||||||
int row = mousePosition.y() / 10;
|
int row = mousePosition.y() / 10;
|
||||||
int column = mousePosition.x() / 12 - m_pageDecode.leftSidePanelColumns();
|
int column = mousePosition.x() / 12 - m_pageDecode.leftSidePanelColumns();
|
||||||
if (row < 1)
|
const int topRow = (int)!m_teletextDocument->rowZeroAllowed();
|
||||||
row = 1;
|
|
||||||
|
if (row < topRow)
|
||||||
|
row = topRow;
|
||||||
if (row > 24)
|
if (row > 24)
|
||||||
row = 24;
|
row = 24;
|
||||||
if (column < 0)
|
if (column < 0)
|
||||||
@@ -647,6 +649,9 @@ LevelOneScene::LevelOneScene(QWidget *levelOneWidget, QObject *parent) : QGraphi
|
|||||||
m_mainGridItemGroup = new QGraphicsItemGroup;
|
m_mainGridItemGroup = new QGraphicsItemGroup;
|
||||||
m_mainGridItemGroup->setVisible(false);
|
m_mainGridItemGroup->setVisible(false);
|
||||||
addItem(m_mainGridItemGroup);
|
addItem(m_mainGridItemGroup);
|
||||||
|
m_rowZeroGridItemGroup = new QGraphicsItemGroup;
|
||||||
|
m_rowZeroGridItemGroup->setVisible(false);
|
||||||
|
addItem(m_rowZeroGridItemGroup);
|
||||||
// Additional vertical pieces of grid for side panels
|
// Additional vertical pieces of grid for side panels
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
m_sidePanelGridNeeded[i] = false;
|
m_sidePanelGridNeeded[i] = false;
|
||||||
@@ -654,14 +659,17 @@ LevelOneScene::LevelOneScene(QWidget *levelOneWidget, QObject *parent) : QGraphi
|
|||||||
m_sidePanelGridItemGroup[i]->setVisible(false);
|
m_sidePanelGridItemGroup[i]->setVisible(false);
|
||||||
addItem(m_sidePanelGridItemGroup[i]);
|
addItem(m_sidePanelGridItemGroup[i]);
|
||||||
}
|
}
|
||||||
for (int r=1; r<25; r++) {
|
for (int r=0; r<25; r++) {
|
||||||
for (int c=0; c<40; c++) {
|
for (int c=0; c<40; c++) {
|
||||||
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(c*12, r*10, 12, 10);
|
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(c*12, r*10, 12, 10);
|
||||||
gridPiece->setPen(QPen(QBrush(QColor(128, 128, 128, r<24 ? 192 : 128)), 0));
|
gridPiece->setPen(QPen(QBrush(QColor(128, 128, 128, (r != 0 && r != 24) ? 192 : 128)), 0));
|
||||||
|
if (r == 0)
|
||||||
|
m_rowZeroGridItemGroup->addToGroup(gridPiece);
|
||||||
|
else
|
||||||
m_mainGridItemGroup->addToGroup(gridPiece);
|
m_mainGridItemGroup->addToGroup(gridPiece);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 24)
|
if (r != 0 && r != 24)
|
||||||
for (int c=0; c<32; c++) {
|
for (int c=0; c<32; c++) {
|
||||||
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(0, r*10, 12, 10);
|
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(0, r*10, 12, 10);
|
||||||
gridPiece->setPen(QPen(QBrush(QColor(128, 128, 128, 64)), 0));
|
gridPiece->setPen(QPen(QBrush(QColor(128, 128, 128, 64)), 0));
|
||||||
@@ -686,6 +694,7 @@ void LevelOneScene::setBorderDimensions(int sceneWidth, int sceneHeight, int wid
|
|||||||
|
|
||||||
// Position grid to cover central 40 columns
|
// Position grid to cover central 40 columns
|
||||||
m_mainGridItemGroup->setPos(leftRightBorders + leftSidePanelColumns*12, topBottomBorders);
|
m_mainGridItemGroup->setPos(leftRightBorders + leftSidePanelColumns*12, topBottomBorders);
|
||||||
|
m_rowZeroGridItemGroup->setPos(leftRightBorders + leftSidePanelColumns*12, topBottomBorders);
|
||||||
|
|
||||||
updateCursor();
|
updateCursor();
|
||||||
updateSelection();
|
updateSelection();
|
||||||
@@ -772,12 +781,23 @@ void LevelOneScene::setRenderMode(TeletextPageRender::RenderMode renderMode)
|
|||||||
void LevelOneScene::toggleGrid(bool gridOn)
|
void LevelOneScene::toggleGrid(bool gridOn)
|
||||||
{
|
{
|
||||||
m_grid = gridOn;
|
m_grid = gridOn;
|
||||||
|
|
||||||
m_mainGridItemGroup->setVisible(gridOn);
|
m_mainGridItemGroup->setVisible(gridOn);
|
||||||
|
if (static_cast<TeletextWidget *>(m_levelOneProxyWidget->widget())->document()->rowZeroAllowed())
|
||||||
|
m_rowZeroGridItemGroup->setVisible(gridOn);
|
||||||
for (int i=0; i<32; i++)
|
for (int i=0; i<32; i++)
|
||||||
if (m_sidePanelGridNeeded[i])
|
if (m_sidePanelGridNeeded[i])
|
||||||
m_sidePanelGridItemGroup[i]->setVisible(gridOn);
|
m_sidePanelGridItemGroup[i]->setVisible(gridOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LevelOneScene::toggleRowZeroAllowed(bool allowed)
|
||||||
|
{
|
||||||
|
static_cast<TeletextWidget *>(m_levelOneProxyWidget->widget())->document()->setRowZeroAllowed(allowed);
|
||||||
|
|
||||||
|
if (m_grid)
|
||||||
|
m_rowZeroGridItemGroup->setVisible(allowed);
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOneScene::hideGUIElements(bool hidden)
|
void LevelOneScene::hideGUIElements(bool hidden)
|
||||||
{
|
{
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ public slots:
|
|||||||
void updateSelection();
|
void updateSelection();
|
||||||
void setRenderMode(TeletextPageRender::RenderMode renderMode);
|
void setRenderMode(TeletextPageRender::RenderMode renderMode);
|
||||||
void toggleGrid(bool gridOn);
|
void toggleGrid(bool gridOn);
|
||||||
|
void toggleRowZeroAllowed(bool allowed);
|
||||||
void hideGUIElements(bool hidden);
|
void hideGUIElements(bool hidden);
|
||||||
void setFullScreenColour(const QColor &newColor);
|
void setFullScreenColour(const QColor &newColor);
|
||||||
void setFullRowColour(int row, const QColor &newColor);
|
void setFullRowColour(int row, const QColor &newColor);
|
||||||
@@ -143,7 +144,7 @@ private:
|
|||||||
QGraphicsRectItem *m_fullRowLeftRectItem[25], *m_fullRowRightRectItem[25];
|
QGraphicsRectItem *m_fullRowLeftRectItem[25], *m_fullRowRightRectItem[25];
|
||||||
QGraphicsProxyWidget *m_levelOneProxyWidget;
|
QGraphicsProxyWidget *m_levelOneProxyWidget;
|
||||||
QGraphicsRectItem *m_cursorRectItem, *m_selectionRectItem;
|
QGraphicsRectItem *m_cursorRectItem, *m_selectionRectItem;
|
||||||
QGraphicsItemGroup *m_mainGridItemGroup, *m_sidePanelGridItemGroup[32];
|
QGraphicsItemGroup *m_mainGridItemGroup, *m_rowZeroGridItemGroup, *m_sidePanelGridItemGroup[32];
|
||||||
bool m_grid, m_sidePanelGridNeeded[32];
|
bool m_grid, m_sidePanelGridNeeded[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -576,6 +576,13 @@ void MainWindow::createActions()
|
|||||||
m_deleteSubPageAction->setStatusTip(tr("Delete this subpage"));
|
m_deleteSubPageAction->setStatusTip(tr("Delete this subpage"));
|
||||||
connect(m_deleteSubPageAction, &QAction::triggered, this, &MainWindow::deleteSubPage);
|
connect(m_deleteSubPageAction, &QAction::triggered, this, &MainWindow::deleteSubPage);
|
||||||
|
|
||||||
|
editMenu->addSeparator();
|
||||||
|
|
||||||
|
m_rowZeroAct = editMenu->addAction(tr("Edit header row"));
|
||||||
|
m_rowZeroAct->setCheckable(true);
|
||||||
|
m_rowZeroAct->setStatusTip(tr("Allow editing of header row"));
|
||||||
|
connect(m_rowZeroAct, &QAction::toggled, m_textScene, &LevelOneScene::toggleRowZeroAllowed);
|
||||||
|
|
||||||
QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
|
QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
|
||||||
|
|
||||||
QAction *revealAct = viewMenu->addAction(tr("&Reveal"));
|
QAction *revealAct = viewMenu->addAction(tr("&Reveal"));
|
||||||
@@ -1090,6 +1097,12 @@ void MainWindow::loadFile(const QString &fileName)
|
|||||||
|
|
||||||
m_reExportWarning = loadingFormat->reExportWarning();
|
m_reExportWarning = loadingFormat->reExportWarning();
|
||||||
|
|
||||||
|
for (int i=0; i<m_textWidget->document()->numberOfSubPages(); i++)
|
||||||
|
if (m_textWidget->document()->subPage(i)->packetExists(0)) {
|
||||||
|
m_rowZeroAct->setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentFile(fileName);
|
setCurrentFile(fileName);
|
||||||
statusBar()->showMessage(tr("File loaded"), 2000);
|
statusBar()->showMessage(tr("File loaded"), 2000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ private:
|
|||||||
QAction *m_borderActs[3];
|
QAction *m_borderActs[3];
|
||||||
QAction *m_aspectRatioActs[4];
|
QAction *m_aspectRatioActs[4];
|
||||||
QAction *m_smoothTransformAction;
|
QAction *m_smoothTransformAction;
|
||||||
|
QAction *m_rowZeroAct;
|
||||||
|
|
||||||
QLabel *m_subPageLabel, *m_cursorPositionLabel;
|
QLabel *m_subPageLabel, *m_cursorPositionLabel;
|
||||||
QToolButton *m_previousSubPageButton, *m_nextSubPageButton;
|
QToolButton *m_previousSubPageButton, *m_nextSubPageButton;
|
||||||
|
|||||||
@@ -202,6 +202,10 @@ void SaveTTIFormat::writeSubPageStart(const PageBase &subPage, int subPageNumber
|
|||||||
|
|
||||||
void SaveTTIFormat::writeSubPageBody(const PageBase &subPage)
|
void SaveTTIFormat::writeSubPageBody(const PageBase &subPage)
|
||||||
{
|
{
|
||||||
|
// Header row
|
||||||
|
if (subPage.packetExists(0))
|
||||||
|
writePacket(format7BitPacket(subPage.packet(0)), 0);
|
||||||
|
|
||||||
// FLOF links
|
// FLOF links
|
||||||
bool writeFLCommand = false;
|
bool writeFLCommand = false;
|
||||||
if (m_document->pageFunction() == TeletextDocument::PFLevelOnePage && subPage.packetExists(27,0)) {
|
if (m_document->pageFunction() == TeletextDocument::PFLevelOnePage && subPage.packetExists(27,0)) {
|
||||||
@@ -358,19 +362,27 @@ int SaveT42Format::writePacket(QByteArray packet, int packetNumber, int designat
|
|||||||
|
|
||||||
void SaveT42Format::writeSubPageStart(const PageBase &subPage, int subPageNumber)
|
void SaveT42Format::writeSubPageStart(const PageBase &subPage, int subPageNumber)
|
||||||
{
|
{
|
||||||
|
QByteArray packet;
|
||||||
|
|
||||||
// Convert integer to Binary Coded Decimal
|
// Convert integer to Binary Coded Decimal
|
||||||
subPageNumber = QString::number(subPageNumber).toInt(nullptr, 16);
|
subPageNumber = QString::number(subPageNumber).toInt(nullptr, 16);
|
||||||
|
|
||||||
// Displayable row header we export as spaces, hence the (odd parity valid) 0x20 init value
|
|
||||||
QByteArray packet(42, 0x20);
|
|
||||||
|
|
||||||
m_magazineNumber = (m_document->pageNumber() & 0xf00) >> 8;
|
m_magazineNumber = (m_document->pageNumber() & 0xf00) >> 8;
|
||||||
if (m_magazineNumber == 8)
|
if (m_magazineNumber == 8)
|
||||||
m_magazineNumber = 0;
|
m_magazineNumber = 0;
|
||||||
|
|
||||||
// Write X/0 separately as it features both Hamming 8/4 and 7-bit odd parity within
|
// Retrieve and apply odd parity to header row if there's text there,
|
||||||
packet[0] = m_magazineNumber & 0x07;
|
// otherwise create an initial packet of (odd parity valid) spaces
|
||||||
packet[1] = 0; // Packet number 0
|
if (subPage.packetExists(0))
|
||||||
|
packet = format7BitPacket(subPage.packet(0));
|
||||||
|
else
|
||||||
|
packet.fill(0x20, 40);
|
||||||
|
|
||||||
|
// Byte 1 of MRAG - packet number 0
|
||||||
|
packet.prepend((char)0);
|
||||||
|
// Byte 0 of MRAG - magazine number, and packet number 0
|
||||||
|
packet.prepend(m_magazineNumber & 0x07);
|
||||||
|
|
||||||
packet[2] = m_document->pageNumber() & 0x00f;
|
packet[2] = m_document->pageNumber() & 0x00f;
|
||||||
packet[3] = (m_document->pageNumber() & 0x0f0) >> 4;
|
packet[3] = (m_document->pageNumber() & 0x0f0) >> 4;
|
||||||
packet[4] = subPageNumber & 0xf;
|
packet[4] = subPageNumber & 0xf;
|
||||||
|
|||||||
Reference in New Issue
Block a user