Allow header row editing
This commit is contained in:
@@ -68,6 +68,7 @@ TeletextDocument::TeletextDocument()
|
||||
m_undoStack = new QUndoStack(this);
|
||||
m_cursorRow = 1;
|
||||
m_cursorColumn = 0;
|
||||
m_rowZeroAllowed = false;
|
||||
m_selectionCornerRow = m_selectionCornerColumn = -1;
|
||||
m_selectionSubPage = nullptr;
|
||||
|
||||
@@ -252,7 +253,7 @@ void TeletextDocument::cursorUp(bool shiftKey)
|
||||
if (shiftKey && !selectionActive())
|
||||
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||
|
||||
if (--m_cursorRow == 0)
|
||||
if (--m_cursorRow == 0 - (int)m_rowZeroAllowed)
|
||||
m_cursorRow = 24;
|
||||
|
||||
if (shiftKey)
|
||||
@@ -269,7 +270,7 @@ void TeletextDocument::cursorDown(bool shiftKey)
|
||||
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||
|
||||
if (++m_cursorRow == 25)
|
||||
m_cursorRow = 1;
|
||||
m_cursorRow = (int)!m_rowZeroAllowed;
|
||||
|
||||
if (shiftKey)
|
||||
emit selectionMoved();
|
||||
@@ -333,6 +334,13 @@ void TeletextDocument::moveCursor(int cursorRow, int cursorColumn, bool selectio
|
||||
emit cursorMoved();
|
||||
}
|
||||
|
||||
void TeletextDocument::setRowZeroAllowed(bool allowed)
|
||||
{
|
||||
m_rowZeroAllowed = allowed;
|
||||
if (m_cursorRow == 0 && !allowed)
|
||||
cursorDown();
|
||||
}
|
||||
|
||||
void TeletextDocument::setSelectionCorner(int row, int column)
|
||||
{
|
||||
if (m_selectionCornerRow != row || m_selectionCornerColumn != column) {
|
||||
|
||||
@@ -89,6 +89,8 @@ public:
|
||||
void cursorLeft(bool shiftKey=false);
|
||||
void cursorRight(bool shiftKey=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 selectionBottomRow() const { return qMax(m_selectionCornerRow, m_cursorRow); }
|
||||
int selectionLeftColumn() const { return m_selectionCornerColumn == -1 ? m_cursorColumn : qMin(m_selectionCornerColumn, m_cursorColumn); }
|
||||
@@ -123,6 +125,7 @@ private:
|
||||
std::vector<LevelOnePage *> m_recycleSubPages;
|
||||
QUndoStack *m_undoStack;
|
||||
int m_cursorRow, m_cursorColumn, m_selectionCornerRow, m_selectionCornerColumn;
|
||||
bool m_rowZeroAllowed;
|
||||
LevelOnePage *m_selectionSubPage;
|
||||
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::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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,8 +543,10 @@ QPair<int, int> TeletextWidget::mouseToRowAndColumn(const QPoint &mousePosition)
|
||||
{
|
||||
int row = mousePosition.y() / 10;
|
||||
int column = mousePosition.x() / 12 - m_pageDecode.leftSidePanelColumns();
|
||||
if (row < 1)
|
||||
row = 1;
|
||||
const int topRow = (int)!m_teletextDocument->rowZeroAllowed();
|
||||
|
||||
if (row < topRow)
|
||||
row = topRow;
|
||||
if (row > 24)
|
||||
row = 24;
|
||||
if (column < 0)
|
||||
@@ -647,6 +649,9 @@ LevelOneScene::LevelOneScene(QWidget *levelOneWidget, QObject *parent) : QGraphi
|
||||
m_mainGridItemGroup = new QGraphicsItemGroup;
|
||||
m_mainGridItemGroup->setVisible(false);
|
||||
addItem(m_mainGridItemGroup);
|
||||
m_rowZeroGridItemGroup = new QGraphicsItemGroup;
|
||||
m_rowZeroGridItemGroup->setVisible(false);
|
||||
addItem(m_rowZeroGridItemGroup);
|
||||
// Additional vertical pieces of grid for side panels
|
||||
for (int i=0; i<32; i++) {
|
||||
m_sidePanelGridNeeded[i] = false;
|
||||
@@ -654,14 +659,17 @@ LevelOneScene::LevelOneScene(QWidget *levelOneWidget, QObject *parent) : QGraphi
|
||||
m_sidePanelGridItemGroup[i]->setVisible(false);
|
||||
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++) {
|
||||
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(c*12, r*10, 12, 10);
|
||||
gridPiece->setPen(QPen(QBrush(QColor(128, 128, 128, r<24 ? 192 : 128)), 0));
|
||||
m_mainGridItemGroup->addToGroup(gridPiece);
|
||||
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);
|
||||
}
|
||||
|
||||
if (r < 24)
|
||||
if (r != 0 && r != 24)
|
||||
for (int c=0; c<32; c++) {
|
||||
QGraphicsRectItem *gridPiece = new QGraphicsRectItem(0, r*10, 12, 10);
|
||||
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
|
||||
m_mainGridItemGroup->setPos(leftRightBorders + leftSidePanelColumns*12, topBottomBorders);
|
||||
m_rowZeroGridItemGroup->setPos(leftRightBorders + leftSidePanelColumns*12, topBottomBorders);
|
||||
|
||||
updateCursor();
|
||||
updateSelection();
|
||||
@@ -772,12 +781,23 @@ void LevelOneScene::setRenderMode(TeletextPageRender::RenderMode renderMode)
|
||||
void LevelOneScene::toggleGrid(bool gridOn)
|
||||
{
|
||||
m_grid = 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++)
|
||||
if (m_sidePanelGridNeeded[i])
|
||||
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)
|
||||
{
|
||||
if (hidden) {
|
||||
|
||||
@@ -125,6 +125,7 @@ public slots:
|
||||
void updateSelection();
|
||||
void setRenderMode(TeletextPageRender::RenderMode renderMode);
|
||||
void toggleGrid(bool gridOn);
|
||||
void toggleRowZeroAllowed(bool allowed);
|
||||
void hideGUIElements(bool hidden);
|
||||
void setFullScreenColour(const QColor &newColor);
|
||||
void setFullRowColour(int row, const QColor &newColor);
|
||||
@@ -143,7 +144,7 @@ private:
|
||||
QGraphicsRectItem *m_fullRowLeftRectItem[25], *m_fullRowRightRectItem[25];
|
||||
QGraphicsProxyWidget *m_levelOneProxyWidget;
|
||||
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];
|
||||
};
|
||||
|
||||
|
||||
@@ -576,6 +576,13 @@ void MainWindow::createActions()
|
||||
m_deleteSubPageAction->setStatusTip(tr("Delete this subpage"));
|
||||
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"));
|
||||
|
||||
QAction *revealAct = viewMenu->addAction(tr("&Reveal"));
|
||||
@@ -1090,6 +1097,12 @@ void MainWindow::loadFile(const QString &fileName)
|
||||
|
||||
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);
|
||||
statusBar()->showMessage(tr("File loaded"), 2000);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ private:
|
||||
QAction *m_borderActs[3];
|
||||
QAction *m_aspectRatioActs[4];
|
||||
QAction *m_smoothTransformAction;
|
||||
QAction *m_rowZeroAct;
|
||||
|
||||
QLabel *m_subPageLabel, *m_cursorPositionLabel;
|
||||
QToolButton *m_previousSubPageButton, *m_nextSubPageButton;
|
||||
|
||||
@@ -202,6 +202,10 @@ void SaveTTIFormat::writeSubPageStart(const PageBase &subPage, int subPageNumber
|
||||
|
||||
void SaveTTIFormat::writeSubPageBody(const PageBase &subPage)
|
||||
{
|
||||
// Header row
|
||||
if (subPage.packetExists(0))
|
||||
writePacket(format7BitPacket(subPage.packet(0)), 0);
|
||||
|
||||
// FLOF links
|
||||
bool writeFLCommand = false;
|
||||
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)
|
||||
{
|
||||
QByteArray packet;
|
||||
|
||||
// Convert integer to Binary Coded Decimal
|
||||
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;
|
||||
if (m_magazineNumber == 8)
|
||||
m_magazineNumber = 0;
|
||||
|
||||
// Write X/0 separately as it features both Hamming 8/4 and 7-bit odd parity within
|
||||
packet[0] = m_magazineNumber & 0x07;
|
||||
packet[1] = 0; // Packet number 0
|
||||
// Retrieve and apply odd parity to header row if there's text there,
|
||||
// otherwise create an initial packet of (odd parity valid) spaces
|
||||
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[3] = (m_document->pageNumber() & 0x0f0) >> 4;
|
||||
packet[4] = subPageNumber & 0xf;
|
||||
|
||||
Reference in New Issue
Block a user