diff --git a/document.cpp b/document.cpp index cf0d1d5..509fa12 100644 --- a/document.cpp +++ b/document.cpp @@ -29,8 +29,6 @@ TeletextDocument::TeletextDocument() { m_pageNumber = 0x198; m_description.clear(); - for (int i=0; i<6; i++) - m_fastTextLink[i] = 0x8ff; m_empty = true; m_subPages.push_back(new LevelOnePage); m_subPages[0]->setPageNumber(m_pageNumber); @@ -114,8 +112,14 @@ void TeletextDocument::loadDocument(QFile *inFile) if (flLine.count(',') == 5) for (int i=0; i<6; i++) { fastTextLinkRead = flLine.section(',', i, i).toInt(&fastTextLinkOk, 16); - if (fastTextLinkOk) - m_fastTextLink[i] = fastTextLinkRead == 0 ? 0x8ff : fastTextLinkRead; + if (fastTextLinkOk) { + if (fastTextLinkRead == 0) + fastTextLinkRead = 0x8ff; + // Stored as page link with relative magazine number, convert from absolute page number that was read + fastTextLinkRead ^= m_pageNumber & 0x700; + fastTextLinkRead &= 0x7ff; // Fixes magazine 8 to 0 + loadingPage->setFastTextLinkPageNumber(i, fastTextLinkRead); + } } } if (inLine.startsWith("OL,")) @@ -141,10 +145,16 @@ void TeletextDocument::saveDocument(QTextStream *outStream) for (auto &subPage : m_subPages) { subPage->savePage(outStream, m_pageNumber, subPageNumber++); - if (m_fastTextLink[0] != 0x8ff) { + if (subPage->fastTextLinkPageNumber(0) != 0x8ff) { *outStream << "FL,"; for (int i=0; i<6; i++) { - *outStream << QString("%1").arg(m_fastTextLink[i], 3, 16, QChar('0')); + // Stored as page link with relative magazine number, convert to absolute page number for display + int absoluteLinkPageNumber = subPage->fastTextLinkPageNumber(i) ^ (m_pageNumber & 0x700); + // Fix magazine 0 to 8 + if ((absoluteLinkPageNumber & 0x700) == 0x000) + absoluteLinkPageNumber |= 0x800; + + *outStream << QString("%1").arg(absoluteLinkPageNumber, 3, 16, QChar('0')); if (i<5) *outStream << ','; } @@ -203,17 +213,18 @@ void TeletextDocument::deleteSubPage(int subPageToDelete) m_subPages.erase(m_subPages.begin()+subPageToDelete); } -void TeletextDocument::setPageNumber(QString newPageNumberString) +void TeletextDocument::setPageNumber(QString pageNumberString) { // The LineEdit should check if a valid hex number was entered, but just in case... - bool newPageNumberOk; - int newPageNumberRead = newPageNumberString.toInt(&newPageNumberOk, 16); - if ((!newPageNumberOk) || newPageNumberRead < 0x100 || newPageNumberRead > 0x8fe) + bool pageNumberOk; + int pageNumberRead = pageNumberString.toInt(&pageNumberOk, 16); + if ((!pageNumberOk) || pageNumberRead < 0x100 || pageNumberRead > 0x8fe) return; - // If the magazine number was changed, we'll need to update the relative magazine numbers in X/27 + // If the magazine number was changed, we need to update the relative magazine numbers in FastText + // and page enhancement links int oldMagazine = (m_pageNumber & 0xf00); - int newMagazine = (newPageNumberRead & 0xf00); + int newMagazine = (pageNumberRead & 0xf00); // Fix magazine 0 to 8 if (oldMagazine == 0x800) oldMagazine = 0x000; @@ -221,13 +232,16 @@ void TeletextDocument::setPageNumber(QString newPageNumberString) newMagazine = 0x000; int magazineFlip = oldMagazine ^ newMagazine; - m_pageNumber = newPageNumberRead; + m_pageNumber = pageNumberRead; for (auto &subPage : m_subPages) { - subPage->setPageNumber(newPageNumberRead); - if (magazineFlip) + subPage->setPageNumber(pageNumberRead); + if (magazineFlip) { + for (int i=0; i<6; i++) + subPage->setFastTextLinkPageNumber(i, subPage->fastTextLinkPageNumber(i) ^ magazineFlip); for (int i=0; i<8; i++) subPage->setComposeLinkPageNumber(i, subPage->composeLinkPageNumber(i) ^ magazineFlip); + } } } @@ -236,15 +250,10 @@ void TeletextDocument::setDescription(QString newDescription) m_description = newDescription; } -void TeletextDocument::setFastTextLink(int linkNumber, QString newPageNumberString) +void TeletextDocument::setFastTextLinkPageNumberOnAllSubPages(int linkNumber, int pageNumber) { - // The LineEdit should check if a valid hex number was entered, but just in case... - bool newPageNumberOk; - int newPageNumberRead = newPageNumberString.toInt(&newPageNumberOk, 16); - if ((!newPageNumberOk) || newPageNumberRead < 0x100 || newPageNumberRead > 0x8ff) - return; - - m_fastTextLink[linkNumber] = newPageNumberRead; + for (auto &subPage : m_subPages) + subPage->setFastTextLinkPageNumber(linkNumber, pageNumber); } void TeletextDocument::cursorUp() diff --git a/document.h b/document.h index 54ab7be..b172e23 100644 --- a/document.h +++ b/document.h @@ -51,8 +51,7 @@ public: void setPageNumber(QString); QString description() const { return m_description; } void setDescription(QString); - int fastTextLink(int linkNumber) const { return m_fastTextLink[linkNumber]; } - void setFastTextLink(int, QString); + void setFastTextLinkPageNumberOnAllSubPages(int, int); QUndoStack *undoStack() const { return m_undoStack; } int cursorRow() const { return m_cursorRow; } int cursorColumn() const { return m_cursorColumn; } @@ -84,7 +83,6 @@ private: QString m_description; bool m_empty; int m_pageNumber, m_currentSubPageIndex; - int m_fastTextLink[6]; std::vector m_subPages; QUndoStack *m_undoStack; int m_cursorRow, m_cursorColumn, m_selectionTopRow, m_selectionBottomRow, m_selectionLeftColumn, m_selectionRightColumn; diff --git a/levelonepage.cpp b/levelonepage.cpp index ba7c798..bf2dae4 100644 --- a/levelonepage.cpp +++ b/levelonepage.cpp @@ -59,6 +59,8 @@ void LevelOnePage::clearPage() setControlBit(i, false); m_composeLink[i] = { (i<4) ? i : 0, false, i>=4, 0x0ff, 0x0000 }; } + for (int i=0; i<6; i++) + m_fastTextLink[i] = { 0x0ff, 0x37f7 }; /* m_subPageNumber = 0x0000; */ m_cycleValue = 8; @@ -124,7 +126,20 @@ QByteArray LevelOnePage::packet(int packetNumber, int designationCode) return result; } - // TODO packet 27/0 + if (packetNumber == 27 && designationCode == 0) { + for (int i=0; i<6; i++) { + result[i*6+1] = m_fastTextLink[i].pageNumber & 0x00f; + result[i*6+2] = (m_fastTextLink[i].pageNumber & 0x0f0) >> 4; + result[i*6+3] = m_fastTextLink[i].subPageNumber & 0x000f; + result[i*6+4] = ((m_fastTextLink[i].subPageNumber & 0x0070) >> 4) | ((m_fastTextLink[i].pageNumber & 0x100) >> 8); + result[i*6+5] = (m_fastTextLink[i].subPageNumber & 0x0f00) >> 8; + result[i*6+6] = ((m_fastTextLink[i].subPageNumber & 0x3000) >> 12) | ((m_fastTextLink[i].pageNumber & 0x600) >> 7); + } + result[43] = 0xf; + result[44] = result[45] = 0; + + return result; + } if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { @@ -205,7 +220,18 @@ bool LevelOnePage::setPacket(int packetNumber, int designationCode, QByteArray p return true; } - // TODO packet 27/0 + if (packetNumber == 27 && designationCode == 0) { + for (int i=0; i<6; i++) { + int relativeMagazine = (packetContents.at(i*6+4) >> 3) | ((packetContents.at(i*6+6) & 0xc) >> 1); + int pageNumber = (packetContents.at(i*6+2) << 4) | packetContents.at(i*6+1); + m_fastTextLink[i].pageNumber = (relativeMagazine << 8) | pageNumber; + m_fastTextLink[i].subPageNumber = packetContents.at(i*6+3) | ((packetContents.at(i*6+4) & 0x7) << 4) | (packetContents.at(i*6+5) << 8) | ((packetContents.at(i*6+6) & 0x3) << 12); + // TODO remove this warning when we can preserve FastText subpage links + if (m_fastTextLink[i].subPageNumber != 0x3f7f) + qDebug("FastText link %d has custom subPageNumber %x - will NOT be saved!", i, m_fastTextLink[i].subPageNumber); + } + return true; + } if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { @@ -266,7 +292,18 @@ bool LevelOnePage::packetNeeded(int packetNumber, int designationCode) const if (packetNumber == 26) return ((localEnhance.size()+12) / 13) > designationCode; - // TODO packet 27/0 + // FIXME don't save this raw packet yet as TeletextDocument::savePage currently uses fastTextLinkPageNumber + // to put the FL commands into the .tti file + // When we separate out loading and saving into its own cpp file, that will then become responsible for + // converting this packet into an FL command itself + +/* if (packetNumber == 27 && designationCode == 0) { + for (int i=0; i<6; i++) + if ((m_fastTextLink[i].pageNumber & 0x0ff) != 0xff) + return true; + + return false; + }*/ if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { @@ -474,6 +511,11 @@ void LevelOnePage::setRightSidePanelDisplayed(bool newRightSidePanelDisplayed) { void LevelOnePage::setSidePanelColumns(int newSidePanelColumns) { m_sidePanelColumns = newSidePanelColumns; } void LevelOnePage::setSidePanelStatusL25(bool newSidePanelStatusL25) { m_sidePanelStatusL25 = newSidePanelStatusL25; } +void LevelOnePage::setFastTextLinkPageNumber(int linkNumber, int pageNumber) +{ + m_fastTextLink[linkNumber].pageNumber = pageNumber; +} + void LevelOnePage::setComposeLinkFunction(int linkNumber, int newFunction) { m_composeLink[linkNumber].function = newFunction; diff --git a/levelonepage.h b/levelonepage.h index 4dbb4e0..508be5b 100644 --- a/levelonepage.h +++ b/levelonepage.h @@ -86,6 +86,8 @@ public: void setSidePanelColumns(int); bool sidePanelStatusL25() const { return m_sidePanelStatusL25; } void setSidePanelStatusL25(bool); + int fastTextLinkPageNumber(int linkNumber) const { return m_fastTextLink[linkNumber].pageNumber; } + void setFastTextLinkPageNumber(int, int); int composeLinkFunction(int linkNumber) const { return m_composeLink[linkNumber].function; } void setComposeLinkFunction(int, int); bool composeLinkLevel2p5(int linkNumber) const { return m_composeLink[linkNumber].level2p5; } @@ -112,6 +114,10 @@ private: int m_defaultScreenColour, m_defaultRowColour, m_colourTableRemap, m_sidePanelColumns; bool m_blackBackgroundSubst, m_leftSidePanelDisplayed, m_rightSidePanelDisplayed, m_sidePanelStatusL25; int m_CLUT[32]; + struct fastTextLink { + int pageNumber; + int subPageNumber; + } m_fastTextLink[6]; struct composeLink { int function; bool level2p5, level3p5; diff --git a/pageoptionsdockwidget.cpp b/pageoptionsdockwidget.cpp index 5f139d8..3b498e9 100644 --- a/pageoptionsdockwidget.cpp +++ b/pageoptionsdockwidget.cpp @@ -69,7 +69,7 @@ PageOptionsDockWidget::PageOptionsDockWidget(TeletextWidget *parent): QDockWidge m_fastTextEdit[i]->setInputMask("DHH"); //TODO restrict first digit of page number to 1-8 fastTextLayout->addWidget(m_fastTextEdit[i], 1, i, 1, 1); - connect(m_fastTextEdit[i], &QLineEdit::textEdited, [=](QString value) { m_parentMainWidget->document()->setFastTextLink(i, value); } ); + connect(m_fastTextEdit[i], &QLineEdit::textEdited, [=](QString value) { setFastTextLinkPageNumber(i, value); } ); } pageOptionsLayout->addLayout(fastTextLayout); @@ -161,8 +161,13 @@ void PageOptionsDockWidget::updateWidgets() m_pageDescriptionEdit->setText(m_parentMainWidget->document()->description()); m_pageDescriptionEdit->blockSignals(false); for (int i=0; i<6; i++) { + // Stored as page link with relative magazine number, convert to absolute page number for display + int absoluteLinkPageNumber = m_parentMainWidget->document()->currentSubPage()->fastTextLinkPageNumber(i) ^ (m_parentMainWidget->document()->pageNumber() & 0x700); + // Fix magazine 0 to 8 + if ((absoluteLinkPageNumber & 0x700) == 0x000) + absoluteLinkPageNumber |= 0x800; m_fastTextEdit[i]->blockSignals(true); - m_fastTextEdit[i]->setText(QString::number(m_parentMainWidget->document()->fastTextLink(i), 16).toUpper()); + m_fastTextEdit[i]->setText(QString::number(absoluteLinkPageNumber, 16).toUpper()); m_fastTextEdit[i]->blockSignals(false); } m_cycleValueSpinBox->blockSignals(true); @@ -192,6 +197,23 @@ void PageOptionsDockWidget::updateWidgets() m_secondNOSCombo->blockSignals(false); } +void PageOptionsDockWidget::setFastTextLinkPageNumber(int linkNumber, const QString &pageNumberString) +{ + // The LineEdit should check if a valid hex number was entered, but just in case... + bool pageNumberOk; + int pageNumberRead = pageNumberString.toInt(&pageNumberOk, 16); + if ((!pageNumberOk) || pageNumberRead < 0x100 || pageNumberRead > 0x8ff) + return; + + // Stored as page link with relative magazine number, convert from absolute page number that was entered + pageNumberRead ^= (m_parentMainWidget->document()->pageNumber() & 0x700); + pageNumberRead &= 0x7ff; // Fixes magazine 8 to 0 + + // TODO bring in option to allow different FastText links per subpage +// m_parentMainWidget->document()->currentSubPage()->setFastTextLinkPageNumber(linkNumber, pageNumberRead); + m_parentMainWidget->document()->setFastTextLinkPageNumberOnAllSubPages(linkNumber, pageNumberRead); +} + void PageOptionsDockWidget::updateDefaultNOSOptions() { while (m_defaultNOSCombo->count() > 0) diff --git a/pageoptionsdockwidget.h b/pageoptionsdockwidget.h index 0db7da2..53581b9 100644 --- a/pageoptionsdockwidget.h +++ b/pageoptionsdockwidget.h @@ -46,6 +46,7 @@ private: QLineEdit *m_fastTextEdit[6]; void addRegionList(QComboBox *); + void setFastTextLinkPageNumber(int, const QString &); void setDefaultRegion(); void setDefaultNOS(); void setSecondRegion();