Load files into QList of PageBase objects

A document is first loaded as a generic PageBase before being converted to
level one pages afterwards.

This is preparation for loading pages of other types such as DRCS and Public
Object Pages. The latter will need further work as the non-TTI file loaders
blindly assume X/1 to X/25 are 7-bit odd parity coded.

This also reverts 0a1c018 putting back the copy constructor that allows
a PageBase to be converted to a LevelOnePage.
This commit is contained in:
Gavin MacGregor
2025-05-27 17:34:18 +01:00
parent 42fd870749
commit 8675cef6c5
7 changed files with 69 additions and 30 deletions

View File

@@ -33,6 +33,24 @@ LevelOnePage::LevelOnePage()
clearPage();
}
LevelOnePage::LevelOnePage(const PageBase &other)
{
m_enhancements.reserve(maxEnhancements());
clearPage();
for (int y=0; y<26; y++)
if (other.packetExists(y))
setPacket(y, other.packet(y));
for (int y=26; y<29; y++)
for (int d=0; d<16; d++)
if (other.packetExists(y, d))
setPacket(y, d, other.packet(y, d));
for (int b=PageBase::C4ErasePage; b<=PageBase::C14NOS; b++)
setControlBit(b, other.controlBit(b));
}
// So far we only call clearPage() once, within the constructor
void LevelOnePage::clearPage()
{

View File

@@ -40,6 +40,7 @@ public:
enum CycleTypeEnum { CTcycles, CTseconds };
LevelOnePage();
LevelOnePage(const PageBase &other);
PageFunctionEnum pageFunction() const override { return PFLevelOnePage; }
PacketCodingEnum packetCoding() const override { return Coding7bit; }

View File

@@ -187,6 +187,14 @@ void TeletextDocument::unDeleteSubPageFromRecycle(int subPage)
m_recycleSubPages.removeLast();
}
void TeletextDocument::loadFromList(QList<PageBase> const &subPageList)
{
*m_subPages[0] = subPageList.at(0);
for (int i=1; i<subPageList.size(); i++)
m_subPages.append(new LevelOnePage(subPageList.at(i)));
}
void TeletextDocument::loadMetaData(QVariantHash const &metadata)
{
bool valueOk;

View File

@@ -65,6 +65,7 @@ public:
void deleteSubPage(int subPageToDelete);
void deleteSubPageToRecycle(int subPageToRecycle);
void unDeleteSubPageFromRecycle(int subPage);
void loadFromList(QList<PageBase> const &subPageList);
void loadMetaData(QVariantHash const &metadata);
int pageNumber() const { return m_pageNumber; }
void setPageNumber(int pageNumber);

View File

@@ -22,16 +22,16 @@
#include <QByteArray>
#include <QDataStream>
#include <QFile>
#include <QList>
#include <QString>
#include <QStringList>
#include <QVariant>
#include "document.h"
#include "hamming.h"
#include "levelonepage.h"
#include "pagebase.h"
bool LoadTTIFormat::load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata)
bool LoadTTIFormat::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash *metadata)
{
m_warnings.clear();
m_error.clear();
@@ -42,7 +42,10 @@ bool LoadTTIFormat::load(QFile *inFile, TeletextDocument *document, QVariantHash
bool firstSubPageAlreadyFound = false;
bool pageBodyPacketsFound = false;
LevelOnePage* loadingPage = document->subPage(0);
// subPages.clear();
subPages.append(PageBase { } );
PageBase* loadingPage = &subPages[0];
for (;;) {
inLine = inFile->readLine(160).trimmed();
@@ -67,8 +70,8 @@ bool LoadTTIFormat::load(QFile *inFile, TeletextDocument *document, QVariantHash
} else {
// Subsequent PN command found; this assumes that PN is the first command of a new subpage
currentSubPageNum++;
document->insertSubPage(document->numberOfSubPages(), false);
loadingPage = document->subPage(document->numberOfSubPages()-1);
subPages.append(PageBase { } );
loadingPage = &subPages[subPages.size()-1];
}
}
/* if (lineType == "SC,") {
@@ -208,7 +211,7 @@ bool LoadT42Format::readPacket()
return m_inFile->read((char *)m_inLine, 42) == 42;
}
bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata)
bool LoadT42Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash *metadata)
{
int readMagazineNumber, readPacketNumber;
int foundMagazineNumber = -1;
@@ -222,6 +225,11 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
m_error.clear();
m_reExportWarning = false;
// subPages.clear();
subPages.append(PageBase { });
PageBase* loadingPage = &subPages[0];
for (;;) {
if (!readPacket())
// Reached end of .t42 file, or less than 42 bytes left
@@ -280,15 +288,15 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
metadata->insert("pageNumber", (foundMagazineNumber << 8) | foundPageNumber);
}
document->subPage(0)->setControlBit(PageBase::C4ErasePage, m_inLine[5] & 0x08);
document->subPage(0)->setControlBit(PageBase::C5Newsflash, m_inLine[7] & 0x04);
document->subPage(0)->setControlBit(PageBase::C6Subtitle, m_inLine[7] & 0x08);
loadingPage->setControlBit(PageBase::C4ErasePage, m_inLine[5] & 0x08);
loadingPage->setControlBit(PageBase::C5Newsflash, m_inLine[7] & 0x04);
loadingPage->setControlBit(PageBase::C6Subtitle, m_inLine[7] & 0x08);
for (int i=0; i<4; i++)
document->subPage(0)->setControlBit(PageBase::C7SuppressHeader+i, m_inLine[8] & (1 << i));
document->subPage(0)->setControlBit(PageBase::C11SerialMagazine, m_inLine[9] & 0x01);
document->subPage(0)->setControlBit(PageBase::C12NOS, m_inLine[9] & 0x08);
document->subPage(0)->setControlBit(PageBase::C13NOS, m_inLine[9] & 0x04);
document->subPage(0)->setControlBit(PageBase::C14NOS, m_inLine[9] & 0x02);
loadingPage->setControlBit(PageBase::C7SuppressHeader+i, m_inLine[8] & (1 << i));
loadingPage->setControlBit(PageBase::C11SerialMagazine, m_inLine[9] & 0x01);
loadingPage->setControlBit(PageBase::C12NOS, m_inLine[9] & 0x08);
loadingPage->setControlBit(PageBase::C13NOS, m_inLine[9] & 0x04);
loadingPage->setControlBit(PageBase::C14NOS, m_inLine[9] & 0x02);
// See if there's text in the header row
bool headerText = false;
@@ -304,7 +312,7 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
for (int i=0; i<10; i++)
m_inLine[i] = 0x20;
document->subPage(0)->setPacket(0, QByteArray((const char *)&m_inLine[2], 40));
loadingPage->setPacket(0, QByteArray((const char *)&m_inLine[2], 40));
}
continue;
}
@@ -327,7 +335,7 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
for (int i=2; i<42; i++)
// TODO - obey odd parity?
m_inLine[i] &= 0x7f;
document->subPage(0)->setPacket(readPacketNumber, QByteArray((const char *)&m_inLine[2], 40));
loadingPage->setPacket(readPacketNumber, QByteArray((const char *)&m_inLine[2], 40));
continue;
}
@@ -365,7 +373,7 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
m_inLine[b+5] = 0x3;
}
}
document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&m_inLine[2], 40));
loadingPage->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&m_inLine[2], 40));
continue;
}
@@ -415,7 +423,7 @@ bool LoadT42Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
m_inLine[b+2] = d >> 12;
}
}
document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&m_inLine[2], 40));
loadingPage->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&m_inLine[2], 40));
}
if (!firstPacket0Found) {
@@ -451,7 +459,7 @@ bool LoadHTTFormat::readPacket()
}
bool LoadEP1Format::load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata)
bool LoadEP1Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash *metadata)
{
m_warnings.clear();
m_error.clear();
@@ -460,7 +468,10 @@ bool LoadEP1Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
unsigned char inLine[42];
unsigned char numOfSubPages = 1;
LevelOnePage* loadingPage = document->subPage(0);
// subPages.clear();
subPages.append(PageBase { } );
PageBase* loadingPage = &subPages[0];
for (;;) {
// Read six bytes, will either be a header for a (sub)page
@@ -564,8 +575,8 @@ bool LoadEP1Format::load(QFile *inFile, TeletextDocument *document, QVariantHash
if (inFile->read((char *)inLine, 42) != 42)
return false;
document->insertSubPage(document->numberOfSubPages(), false);
loadingPage = document->subPage(document->numberOfSubPages()-1);
subPages.append(PageBase { } );
loadingPage = &subPages[subPages.size()-1];
}
return true;
}

View File

@@ -23,12 +23,11 @@
#include <QByteArray>
#include <QDataStream>
#include <QFile>
#include <QList>
#include <QString>
#include <QStringList>
#include <QVariant>
#include "document.h"
#include "levelonepage.h"
#include "pagebase.h"
class LoadFormat
@@ -36,7 +35,7 @@ class LoadFormat
public:
virtual ~LoadFormat() {};
virtual bool load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata = nullptr) =0;
virtual bool load(QFile *inFile, QList<PageBase> &subPages, QVariantHash *metadata = nullptr) =0;
virtual QString description() const =0;
virtual QStringList extensions() const =0;
@@ -46,7 +45,6 @@ public:
bool reExportWarning() const { return m_reExportWarning; };
protected:
TeletextDocument const *m_document;
QStringList m_warnings;
QString m_error;
bool m_reExportWarning = false;
@@ -55,7 +53,7 @@ protected:
class LoadTTIFormat : public LoadFormat
{
public:
bool load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata = nullptr) override;
bool load(QFile *inFile, QList<PageBase> &subPages, QVariantHash *metadata = nullptr) override;
QString description() const override { return QString("MRG Systems TTI"); };
QStringList extensions() const override { return QStringList { "tti", "ttix" }; };
@@ -64,7 +62,7 @@ public:
class LoadT42Format : public LoadFormat
{
public:
bool load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata = nullptr) override;
bool load(QFile *inFile, QList<PageBase> &subPages, QVariantHash *metadata = nullptr) override;
QString description() const override { return QString("t42 packet stream"); };
QStringList extensions() const override { return QStringList { "t42" }; };
@@ -89,7 +87,7 @@ protected:
class LoadEP1Format : public LoadFormat
{
public:
bool load(QFile *inFile, TeletextDocument *document, QVariantHash *metadata = nullptr) override;
bool load(QFile *inFile, QList<PageBase> &subPages, QVariantHash *metadata = nullptr) override;
QString description() const override { return QString("Softel EP1"); };
QStringList extensions() const override { return QStringList { "ep1", "epx" }; };

View File

@@ -1069,9 +1069,11 @@ void MainWindow::loadFile(const QString &fileName)
QApplication::setOverrideCursor(Qt::WaitCursor);
QList<PageBase> subPages;
QVariantHash metadata;
if (loadingFormat->load(&file, m_textWidget->document(), &metadata)) {
if (loadingFormat->load(&file, subPages, &metadata)) {
m_textWidget->document()->loadFromList(subPages);
m_textWidget->document()->loadMetaData(metadata);
if (m_saveFormats.isExportOnly(QFileInfo(file).suffix()))