Compare commits
14 Commits
0.8.1-beta
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df7ce90d0f | ||
|
|
838a54d528 | ||
|
|
2682554b79 | ||
|
|
a7e93f463a | ||
|
|
fcca93e5a5 | ||
|
|
dbbeea9d30 | ||
|
|
53fb6f0aad | ||
|
|
eea73592f9 | ||
|
|
f708765d7b | ||
|
|
7ce848b4cf | ||
|
|
e6a90c061e | ||
|
|
973aeaa6cf | ||
|
|
1efa8c196d | ||
|
|
1b3623d61b |
@@ -306,7 +306,7 @@ bool QGifImagePrivate::save(QIODevice *device) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GraphicsControlBlock gcbBlock;
|
GraphicsControlBlock gcbBlock;
|
||||||
gcbBlock.DisposalMode = 0;
|
gcbBlock.DisposalMode = 2;
|
||||||
gcbBlock.UserInputFlag = false;
|
gcbBlock.UserInputFlag = false;
|
||||||
gcbBlock.TransparentColor = getFrameTransparentColorIndex(frameInfo);
|
gcbBlock.TransparentColor = getFrameTransparentColorIndex(frameInfo);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -36,6 +36,11 @@ DRCSPage::DRCSPage(const PageBase &other)
|
|||||||
setControlBit(b, other.controlBit(b));
|
setControlBit(b, other.controlBit(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageBase::PageFunctionEnum DRCSPage::pageFunction() const
|
||||||
|
{
|
||||||
|
return PFGlobalPOP;
|
||||||
|
}
|
||||||
|
|
||||||
int DRCSPage::drcsMode(int c) const
|
int DRCSPage::drcsMode(int c) const
|
||||||
{
|
{
|
||||||
if (!packetExists(28, 3))
|
if (!packetExists(28, 3))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -30,8 +30,7 @@ public:
|
|||||||
DRCSPage(const PageBase &other);
|
DRCSPage(const PageBase &other);
|
||||||
|
|
||||||
// TODO PFNormalPOP as well?
|
// TODO PFNormalPOP as well?
|
||||||
PageFunctionEnum pageFunction() const { return PFGlobalPOP; }
|
PageFunctionEnum pageFunction() const;
|
||||||
PacketCodingEnum packetCoding() const override { return Coding7bit; }
|
|
||||||
|
|
||||||
int drcsMode(int c) const;
|
int drcsMode(int c) const;
|
||||||
bool ptu(int c, uchar *data) const;
|
bool ptu(int c, uchar *data) const;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -295,10 +295,47 @@ bool LevelOnePage::setControlBit(int b, bool active)
|
|||||||
return PageX26Base::setControlBit(b, active);
|
return PageX26Base::setControlBit(b, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::maxEnhancements() const
|
||||||
|
{
|
||||||
|
return 208;
|
||||||
|
}
|
||||||
|
|
||||||
/* void LevelOnePage::setSubPageNumber(int newSubPageNumber) { m_subPageNumber = newSubPageNumber; } */
|
/* void LevelOnePage::setSubPageNumber(int newSubPageNumber) { m_subPageNumber = newSubPageNumber; } */
|
||||||
void LevelOnePage::setCycleValue(int newValue) { m_cycleValue = newValue; };
|
|
||||||
void LevelOnePage::setCycleType(CycleTypeEnum newType) { m_cycleType = newType; }
|
int LevelOnePage::cycleValue() const
|
||||||
void LevelOnePage::setDefaultCharSet(int newDefaultCharSet) { m_defaultCharSet = newDefaultCharSet; }
|
{
|
||||||
|
return m_cycleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setCycleValue(int newValue)
|
||||||
|
{
|
||||||
|
m_cycleValue = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelOnePage::CycleTypeEnum LevelOnePage::cycleType() const
|
||||||
|
{
|
||||||
|
return m_cycleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setCycleType(CycleTypeEnum newType)
|
||||||
|
{
|
||||||
|
m_cycleType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::defaultCharSet() const
|
||||||
|
{
|
||||||
|
return m_defaultCharSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setDefaultCharSet(int newDefaultCharSet)
|
||||||
|
{
|
||||||
|
m_defaultCharSet = newDefaultCharSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::defaultNOS() const
|
||||||
|
{
|
||||||
|
return m_defaultNOS;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setDefaultNOS(int defaultNOS)
|
void LevelOnePage::setDefaultNOS(int defaultNOS)
|
||||||
{
|
{
|
||||||
@@ -309,6 +346,11 @@ void LevelOnePage::setDefaultNOS(int defaultNOS)
|
|||||||
PageX26Base::setControlBit(C14NOS, m_defaultNOS & 0x4);
|
PageX26Base::setControlBit(C14NOS, m_defaultNOS & 0x4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::secondCharSet() const
|
||||||
|
{
|
||||||
|
return m_secondCharSet;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setSecondCharSet(int newSecondCharSet)
|
void LevelOnePage::setSecondCharSet(int newSecondCharSet)
|
||||||
{
|
{
|
||||||
m_secondCharSet = newSecondCharSet;
|
m_secondCharSet = newSecondCharSet;
|
||||||
@@ -316,8 +358,18 @@ void LevelOnePage::setSecondCharSet(int newSecondCharSet)
|
|||||||
m_secondNOS = 0x7;
|
m_secondNOS = 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::secondNOS() const
|
||||||
|
{
|
||||||
|
return m_secondNOS;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setSecondNOS(int newSecondNOS) { m_secondNOS = newSecondNOS; }
|
void LevelOnePage::setSecondNOS(int newSecondNOS) { m_secondNOS = newSecondNOS; }
|
||||||
|
|
||||||
|
unsigned char LevelOnePage::character(int r, int c) const
|
||||||
|
{
|
||||||
|
return PageX26Base::packetExists(r) ? PageX26Base::packet(r).at(c) : 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setCharacter(int r, int c, unsigned char newCharacter)
|
void LevelOnePage::setCharacter(int r, int c, unsigned char newCharacter)
|
||||||
{
|
{
|
||||||
QByteArray pkt;
|
QByteArray pkt;
|
||||||
@@ -338,10 +390,45 @@ void LevelOnePage::setCharacter(int r, int c, unsigned char newCharacter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelOnePage::setDefaultScreenColour(int newDefaultScreenColour) { m_defaultScreenColour = newDefaultScreenColour; }
|
int LevelOnePage::defaultScreenColour() const
|
||||||
void LevelOnePage::setDefaultRowColour(int newDefaultRowColour) { m_defaultRowColour = newDefaultRowColour; }
|
{
|
||||||
void LevelOnePage::setColourTableRemap(int newColourTableRemap) { m_colourTableRemap = newColourTableRemap; }
|
return m_defaultScreenColour;
|
||||||
void LevelOnePage::setBlackBackgroundSubst(bool newBlackBackgroundSubst) { m_blackBackgroundSubst = newBlackBackgroundSubst; }
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setDefaultScreenColour(int newDefaultScreenColour)
|
||||||
|
{
|
||||||
|
m_defaultScreenColour = newDefaultScreenColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::defaultRowColour() const
|
||||||
|
{
|
||||||
|
return m_defaultRowColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setDefaultRowColour(int newDefaultRowColour)
|
||||||
|
{
|
||||||
|
m_defaultRowColour = newDefaultRowColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::colourTableRemap() const
|
||||||
|
{
|
||||||
|
return m_colourTableRemap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setColourTableRemap(int newColourTableRemap)
|
||||||
|
{
|
||||||
|
m_colourTableRemap = newColourTableRemap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LevelOnePage::blackBackgroundSubst() const
|
||||||
|
{
|
||||||
|
return m_blackBackgroundSubst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setBlackBackgroundSubst(bool newBlackBackgroundSubst)
|
||||||
|
{
|
||||||
|
m_blackBackgroundSubst = newBlackBackgroundSubst;
|
||||||
|
}
|
||||||
|
|
||||||
int LevelOnePage::CLUT(int index, int renderLevel) const
|
int LevelOnePage::CLUT(int index, int renderLevel) const
|
||||||
{
|
{
|
||||||
@@ -420,7 +507,8 @@ int LevelOnePage::dCLUT(bool globalDrcs, int mode, int index) const
|
|||||||
|
|
||||||
void LevelOnePage::setDCLUT(bool globalDrcs, int mode, int index, int colour)
|
void LevelOnePage::setDCLUT(bool globalDrcs, int mode, int index, int colour)
|
||||||
{
|
{
|
||||||
const QByteArray defaultPkt = QByteArray("\x01\x00\x00\x00\x20\x20\x18\x00\x02\x22\x01\x08\x08\x06\x24\x22\x39\x20\x12\x2a\x05\x2b\x39\x1e\x20\x20\x18\x10\x0a\x26\x03\x0a\x29\x16\x2c\x26\x3b\x01\x00\x00", 40);
|
// Default DCLUT as per D.1.6 and D.2.2 in the ETSI spec
|
||||||
|
const QByteArray defaultPkt = QByteArrayLiteral("\x01\x00\x00\x00\x20\x20\x18\x00\x02\x22\x01\x08\x08\x06\x24\x22\x39\x20\x12\x2a\x05\x2b\x39\x1e\x20\x20\x18\x10\x0a\x26\x03\x0a\x29\x16\x2c\x26\x3b\x01\x00\x00");
|
||||||
|
|
||||||
if (!packetExists(28, 1))
|
if (!packetExists(28, 1))
|
||||||
setPacket(28, 1, defaultPkt);
|
setPacket(28, 1, defaultPkt);
|
||||||
@@ -552,36 +640,101 @@ int LevelOnePage::levelRequired() const
|
|||||||
return levelSeen;
|
return levelSeen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelOnePage::setLeftSidePanelDisplayed(bool newLeftSidePanelDisplayed) { m_leftSidePanelDisplayed = newLeftSidePanelDisplayed; }
|
bool LevelOnePage::leftSidePanelDisplayed() const
|
||||||
void LevelOnePage::setRightSidePanelDisplayed(bool newRightSidePanelDisplayed) { m_rightSidePanelDisplayed = newRightSidePanelDisplayed; }
|
{
|
||||||
void LevelOnePage::setSidePanelColumns(int newSidePanelColumns) { m_sidePanelColumns = newSidePanelColumns; }
|
return m_leftSidePanelDisplayed;
|
||||||
void LevelOnePage::setSidePanelStatusL25(bool newSidePanelStatusL25) { m_sidePanelStatusL25 = newSidePanelStatusL25; }
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setLeftSidePanelDisplayed(bool newLeftSidePanelDisplayed)
|
||||||
|
{
|
||||||
|
m_leftSidePanelDisplayed = newLeftSidePanelDisplayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LevelOnePage::rightSidePanelDisplayed() const
|
||||||
|
{
|
||||||
|
return m_rightSidePanelDisplayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setRightSidePanelDisplayed(bool newRightSidePanelDisplayed)
|
||||||
|
{
|
||||||
|
m_rightSidePanelDisplayed = newRightSidePanelDisplayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::sidePanelColumns() const
|
||||||
|
{
|
||||||
|
return m_sidePanelColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setSidePanelColumns(int newSidePanelColumns)
|
||||||
|
{
|
||||||
|
m_sidePanelColumns = newSidePanelColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LevelOnePage::sidePanelStatusL25() const
|
||||||
|
{
|
||||||
|
return m_sidePanelStatusL25;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelOnePage::setSidePanelStatusL25(bool newSidePanelStatusL25)
|
||||||
|
{
|
||||||
|
m_sidePanelStatusL25 = newSidePanelStatusL25;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::fastTextLinkPageNumber(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_fastTextLink[linkNumber].pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setFastTextLinkPageNumber(int linkNumber, int pageNumber)
|
void LevelOnePage::setFastTextLinkPageNumber(int linkNumber, int pageNumber)
|
||||||
{
|
{
|
||||||
m_fastTextLink[linkNumber].pageNumber = pageNumber;
|
m_fastTextLink[linkNumber].pageNumber = pageNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::composeLinkFunction(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_composeLink[linkNumber].function;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setComposeLinkFunction(int linkNumber, int newFunction)
|
void LevelOnePage::setComposeLinkFunction(int linkNumber, int newFunction)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].function = newFunction;
|
m_composeLink[linkNumber].function = newFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LevelOnePage::composeLinkLevel2p5(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_composeLink[linkNumber].level2p5;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setComposeLinkLevel2p5(int linkNumber, bool newRequired)
|
void LevelOnePage::setComposeLinkLevel2p5(int linkNumber, bool newRequired)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].level2p5 = newRequired;
|
m_composeLink[linkNumber].level2p5 = newRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LevelOnePage::composeLinkLevel3p5(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_composeLink[linkNumber].level3p5;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setComposeLinkLevel3p5(int linkNumber, bool newRequired)
|
void LevelOnePage::setComposeLinkLevel3p5(int linkNumber, bool newRequired)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].level3p5 = newRequired;
|
m_composeLink[linkNumber].level3p5 = newRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::composeLinkPageNumber(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_composeLink[linkNumber].pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setComposeLinkPageNumber(int linkNumber, int newPageNumber)
|
void LevelOnePage::setComposeLinkPageNumber(int linkNumber, int newPageNumber)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].pageNumber = newPageNumber;
|
m_composeLink[linkNumber].pageNumber = newPageNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelOnePage::composeLinkSubPageCodes(int linkNumber) const
|
||||||
|
{
|
||||||
|
return m_composeLink[linkNumber].subPageCodes;
|
||||||
|
}
|
||||||
|
|
||||||
void LevelOnePage::setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes)
|
void LevelOnePage::setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].subPageCodes = newSubPageCodes;
|
m_composeLink[linkNumber].subPageCodes = newSubPageCodes;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -42,9 +42,6 @@ public:
|
|||||||
LevelOnePage();
|
LevelOnePage();
|
||||||
LevelOnePage(const PageBase &other);
|
LevelOnePage(const PageBase &other);
|
||||||
|
|
||||||
PageFunctionEnum pageFunction() const override { return PFLevelOnePage; }
|
|
||||||
PacketCodingEnum packetCoding() const override { return Coding7bit; }
|
|
||||||
|
|
||||||
bool isEmpty() const override;
|
bool isEmpty() const override;
|
||||||
|
|
||||||
QByteArray packet(int y, int d) const override;
|
QByteArray packet(int y, int d) const override;
|
||||||
@@ -55,30 +52,30 @@ public:
|
|||||||
|
|
||||||
void clearPage();
|
void clearPage();
|
||||||
|
|
||||||
int maxEnhancements() const override { return 208; };
|
int maxEnhancements() const override;
|
||||||
|
|
||||||
/* void setSubPageNumber(int); */
|
/* void setSubPageNumber(int); */
|
||||||
int cycleValue() const { return m_cycleValue; };
|
int cycleValue() const;
|
||||||
void setCycleValue(int newValue);
|
void setCycleValue(int newValue);
|
||||||
CycleTypeEnum cycleType() const { return m_cycleType; };
|
CycleTypeEnum cycleType() const;
|
||||||
void setCycleType(CycleTypeEnum newType);
|
void setCycleType(CycleTypeEnum newType);
|
||||||
int defaultCharSet() const { return m_defaultCharSet; }
|
int defaultCharSet() const;
|
||||||
void setDefaultCharSet(int newDefaultCharSet);
|
void setDefaultCharSet(int newDefaultCharSet);
|
||||||
int defaultNOS() const { return m_defaultNOS; }
|
int defaultNOS() const;
|
||||||
void setDefaultNOS(int defaultNOS);
|
void setDefaultNOS(int defaultNOS);
|
||||||
int secondCharSet() const { return m_secondCharSet; }
|
int secondCharSet() const;
|
||||||
void setSecondCharSet(int newSecondCharSet);
|
void setSecondCharSet(int newSecondCharSet);
|
||||||
int secondNOS() const { return m_secondNOS; }
|
int secondNOS() const;
|
||||||
void setSecondNOS(int newSecondNOS);
|
void setSecondNOS(int newSecondNOS);
|
||||||
unsigned char character(int r, int c) const { return PageX26Base::packetExists(r) ? PageX26Base::packet(r).at(c) : 0x20; }
|
unsigned char character(int r, int c) const;
|
||||||
void setCharacter(int r, int c, unsigned char newChar);
|
void setCharacter(int r, int c, unsigned char newChar);
|
||||||
int defaultScreenColour() const { return m_defaultScreenColour; }
|
int defaultScreenColour() const;
|
||||||
void setDefaultScreenColour(int newDefaultScreenColour);
|
void setDefaultScreenColour(int newDefaultScreenColour);
|
||||||
int defaultRowColour() const { return m_defaultRowColour; }
|
int defaultRowColour() const;
|
||||||
void setDefaultRowColour(int newDefaultRowColour);
|
void setDefaultRowColour(int newDefaultRowColour);
|
||||||
int colourTableRemap() const { return m_colourTableRemap; }
|
int colourTableRemap() const;
|
||||||
void setColourTableRemap(int newColourTableRemap);
|
void setColourTableRemap(int newColourTableRemap);
|
||||||
bool blackBackgroundSubst() const { return m_blackBackgroundSubst; }
|
bool blackBackgroundSubst() const;
|
||||||
void setBlackBackgroundSubst(bool newBlackBackgroundSubst);
|
void setBlackBackgroundSubst(bool newBlackBackgroundSubst);
|
||||||
int CLUT(int index, int renderLevel=3) const;
|
int CLUT(int index, int renderLevel=3) const;
|
||||||
void setCLUT(int index, int newColour);
|
void setCLUT(int index, int newColour);
|
||||||
@@ -88,25 +85,25 @@ public:
|
|||||||
int dCLUT(bool globalDrcs, int mode, int index) const;
|
int dCLUT(bool globalDrcs, int mode, int index) const;
|
||||||
void setDCLUT(bool globalDrcs, int mode, int index, int colour);
|
void setDCLUT(bool globalDrcs, int mode, int index, int colour);
|
||||||
int levelRequired() const;
|
int levelRequired() const;
|
||||||
bool leftSidePanelDisplayed() const { return m_leftSidePanelDisplayed; }
|
bool leftSidePanelDisplayed() const;
|
||||||
void setLeftSidePanelDisplayed(bool newLeftSidePanelDisplayed);
|
void setLeftSidePanelDisplayed(bool newLeftSidePanelDisplayed);
|
||||||
bool rightSidePanelDisplayed() const { return m_rightSidePanelDisplayed; }
|
bool rightSidePanelDisplayed() const;
|
||||||
void setRightSidePanelDisplayed(bool newRightSidePanelDisplayed);
|
void setRightSidePanelDisplayed(bool newRightSidePanelDisplayed);
|
||||||
int sidePanelColumns() const { return m_sidePanelColumns; }
|
int sidePanelColumns() const;
|
||||||
void setSidePanelColumns(int newSidePanelColumns);
|
void setSidePanelColumns(int newSidePanelColumns);
|
||||||
bool sidePanelStatusL25() const { return m_sidePanelStatusL25; }
|
bool sidePanelStatusL25() const;
|
||||||
void setSidePanelStatusL25(bool newSidePanelStatusL25);
|
void setSidePanelStatusL25(bool newSidePanelStatusL25);
|
||||||
int fastTextLinkPageNumber(int linkNumber) const { return m_fastTextLink[linkNumber].pageNumber; }
|
int fastTextLinkPageNumber(int linkNumber) const;
|
||||||
void setFastTextLinkPageNumber(int linkNumber, int pageNumber);
|
void setFastTextLinkPageNumber(int linkNumber, int pageNumber);
|
||||||
int composeLinkFunction(int linkNumber) const { return m_composeLink[linkNumber].function; }
|
int composeLinkFunction(int linkNumber) const;
|
||||||
void setComposeLinkFunction(int linkNumber, int newFunction);
|
void setComposeLinkFunction(int linkNumber, int newFunction);
|
||||||
bool composeLinkLevel2p5(int linkNumber) const { return m_composeLink[linkNumber].level2p5; }
|
bool composeLinkLevel2p5(int linkNumber) const;
|
||||||
void setComposeLinkLevel2p5(int linkNumber, bool newRequired);
|
void setComposeLinkLevel2p5(int linkNumber, bool newRequired);
|
||||||
bool composeLinkLevel3p5(int linkNumber) const { return m_composeLink[linkNumber].level3p5; }
|
bool composeLinkLevel3p5(int linkNumber) const;
|
||||||
void setComposeLinkLevel3p5(int linkNumber, bool newRequired);
|
void setComposeLinkLevel3p5(int linkNumber, bool newRequired);
|
||||||
int composeLinkPageNumber(int linkNumber) const { return m_composeLink[linkNumber].pageNumber; }
|
int composeLinkPageNumber(int linkNumber) const;
|
||||||
void setComposeLinkPageNumber(int linkNumber, int newPageNumber);
|
void setComposeLinkPageNumber(int linkNumber, int newPageNumber);
|
||||||
int composeLinkSubPageCodes(int linkNumber) const { return m_composeLink[linkNumber].subPageCodes; }
|
int composeLinkSubPageCodes(int linkNumber) const;
|
||||||
void setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes);
|
void setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -27,6 +27,24 @@ PageBase::PageBase()
|
|||||||
m_controlBits[b] = false;
|
m_controlBits[b] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageBase::PageFunctionEnum PageBase::pageFunction() const
|
||||||
|
{
|
||||||
|
return PFLevelOnePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageBase::PacketCodingEnum PageBase::packetCoding() const
|
||||||
|
{
|
||||||
|
return Coding7bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageBase::PacketCodingEnum PageBase::packetCoding(int y, int d) const
|
||||||
|
{
|
||||||
|
if (y == 27 && d < 4)
|
||||||
|
return Coding4bit;
|
||||||
|
else
|
||||||
|
return Coding18bit;
|
||||||
|
}
|
||||||
|
|
||||||
bool PageBase::isEmpty() const
|
bool PageBase::isEmpty() const
|
||||||
{
|
{
|
||||||
for (int y=0; y<26; y++)
|
for (int y=0; y<26; y++)
|
||||||
@@ -40,6 +58,16 @@ bool PageBase::isEmpty() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray PageBase::packet(int y) const
|
||||||
|
{
|
||||||
|
return m_displayPackets[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray PageBase::packet(int y, int d) const
|
||||||
|
{
|
||||||
|
return m_designationPackets[y-26][d];
|
||||||
|
}
|
||||||
|
|
||||||
bool PageBase::setPacket(int y, QByteArray pkt)
|
bool PageBase::setPacket(int y, QByteArray pkt)
|
||||||
{
|
{
|
||||||
m_displayPackets[y] = pkt;
|
m_displayPackets[y] = pkt;
|
||||||
@@ -54,6 +82,16 @@ bool PageBase::setPacket(int y, int d, QByteArray pkt)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PageBase::packetExists(int y) const
|
||||||
|
{
|
||||||
|
return !m_displayPackets[y].isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PageBase::packetExists(int y, int d) const
|
||||||
|
{
|
||||||
|
return !m_designationPackets[y-26][d].isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
bool PageBase::clearPacket(int y)
|
bool PageBase::clearPacket(int y)
|
||||||
{
|
{
|
||||||
m_displayPackets[y] = QByteArray();
|
m_displayPackets[y] = QByteArray();
|
||||||
@@ -77,6 +115,11 @@ void PageBase::clearAllPackets()
|
|||||||
clearPacket(y, d);
|
clearPacket(y, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PageBase::controlBit(int b) const
|
||||||
|
{
|
||||||
|
return m_controlBits[b];
|
||||||
|
}
|
||||||
|
|
||||||
bool PageBase::setControlBit(int b, bool active)
|
bool PageBase::setControlBit(int b, bool active)
|
||||||
{
|
{
|
||||||
m_controlBits[b] = active;
|
m_controlBits[b] = active;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -22,36 +22,34 @@
|
|||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
|
||||||
// If we inherit from QObject then we can't copy construct, so "make a new subpage that's a copy of this one" wouldn't work
|
class PageBase
|
||||||
class PageBase //: public QObject
|
|
||||||
{
|
{
|
||||||
//Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum ControlBitsEnum { C4ErasePage, C5Newsflash, C6Subtitle, C7SuppressHeader, C8Update, C9InterruptedSequence, C10InhibitDisplay, C11SerialMagazine, C12NOS, C13NOS, C14NOS };
|
enum ControlBitsEnum { C4ErasePage, C5Newsflash, C6Subtitle, C7SuppressHeader, C8Update, C9InterruptedSequence, C10InhibitDisplay, C11SerialMagazine, C12NOS, C13NOS, C14NOS };
|
||||||
// Available Page Functions according to 9.4.2.1 of the spec
|
// Available Page Functions according to 9.4.2.1 of the spec
|
||||||
enum PageFunctionEnum { PFUnknown = -1, PFLevelOnePage, PFDataBroadcasting, PFGlobalPOP, PFNormalPOP, PFGlobalDRCS, PFNormalDRCS, PFMOT, PFMIP, PFBasicTOPTable, PFAdditionalInformationTable, PFMultiPageTable, PFMultiPageExtensionTable, PFTriggerMessages };
|
enum PageFunctionEnum { PFLevelOnePage, PFDataBroadcasting, PFGlobalPOP, PFNormalPOP, PFGlobalDRCS, PFNormalDRCS, PFMOT, PFMIP, PFBasicTOPTable, PFAdditionalInformationTable, PFMultiPageTable, PFMultiPageExtensionTable, PFTriggerMessages };
|
||||||
// Available Page Codings of X/1 to X/25 according to 9.4.2.1 of the spec
|
// Available Page Codings of X/1 to X/25 according to 9.4.2.1 of the spec
|
||||||
enum PacketCodingEnum { CodingUnknown = -1, Coding7bit, Coding8bit, Coding18bit, Coding4bit, Coding4bitThen7bit, CodingPerPacket };
|
enum PacketCodingEnum { Coding7bit, Coding8bit, Coding18bit, Coding4bit, Coding4bitThen7bit, CodingPerPacket };
|
||||||
|
|
||||||
PageBase();
|
PageBase();
|
||||||
|
|
||||||
virtual PageFunctionEnum pageFunction() const { return PFUnknown; }
|
virtual PageFunctionEnum pageFunction() const;
|
||||||
virtual PacketCodingEnum packetCoding() const { return CodingUnknown; }
|
virtual PacketCodingEnum packetCoding() const;
|
||||||
|
virtual PacketCodingEnum packetCoding(int y, int d) const;
|
||||||
|
|
||||||
virtual bool isEmpty() const;
|
virtual bool isEmpty() const;
|
||||||
|
|
||||||
virtual QByteArray packet(int y) const { return m_displayPackets[y]; }
|
virtual QByteArray packet(int y) const;
|
||||||
virtual QByteArray packet(int y, int d) const { return m_designationPackets[y-26][d]; }
|
virtual QByteArray packet(int y, int d) const;
|
||||||
virtual bool setPacket(int y, QByteArray pkt);
|
virtual bool setPacket(int y, QByteArray pkt);
|
||||||
virtual bool setPacket(int y, int d, QByteArray pkt);
|
virtual bool setPacket(int y, int d, QByteArray pkt);
|
||||||
virtual bool packetExists(int y) const { return !m_displayPackets[y].isEmpty(); }
|
virtual bool packetExists(int y) const;
|
||||||
virtual bool packetExists(int y, int d) const { return !m_designationPackets[y-26][d].isEmpty(); }
|
virtual bool packetExists(int y, int d) const;
|
||||||
virtual bool clearPacket(int y);
|
virtual bool clearPacket(int y);
|
||||||
virtual bool clearPacket(int y, int d);
|
virtual bool clearPacket(int y, int d);
|
||||||
virtual void clearAllPackets();
|
virtual void clearAllPackets();
|
||||||
|
|
||||||
virtual bool controlBit(int b) const { return m_controlBits[b]; }
|
virtual bool controlBit(int b) const;
|
||||||
virtual bool setControlBit(int b, bool active);
|
virtual bool setControlBit(int b, bool active);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -21,6 +21,11 @@
|
|||||||
|
|
||||||
#include "pagex26base.h"
|
#include "pagex26base.h"
|
||||||
|
|
||||||
|
X26TripletList *PageX26Base::enhancements()
|
||||||
|
{
|
||||||
|
return &m_enhancements;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray PageX26Base::packetFromEnhancementList(int p) const
|
QByteArray PageX26Base::packetFromEnhancementList(int p) const
|
||||||
{
|
{
|
||||||
QByteArray result(40, 0x00);
|
QByteArray result(40, 0x00);
|
||||||
@@ -31,9 +36,13 @@ QByteArray PageX26Base::packetFromEnhancementList(int p) const
|
|||||||
const int enhanceListPointer = p*13+t;
|
const int enhanceListPointer = p*13+t;
|
||||||
|
|
||||||
if (enhanceListPointer < m_enhancements.size()) {
|
if (enhanceListPointer < m_enhancements.size()) {
|
||||||
|
if (!m_enhancements.at(enhanceListPointer).isValid())
|
||||||
|
result[t*3+1] = result[t*3+2] = result[t*3+3] = 0xff;
|
||||||
|
else {
|
||||||
result[t*3+1] = m_enhancements.at(enhanceListPointer).address();
|
result[t*3+1] = m_enhancements.at(enhanceListPointer).address();
|
||||||
result[t*3+2] = m_enhancements.at(enhanceListPointer).mode() | ((m_enhancements.at(enhanceListPointer).data() & 1) << 5);
|
result[t*3+2] = m_enhancements.at(enhanceListPointer).mode() | ((m_enhancements.at(enhanceListPointer).data() & 1) << 5);
|
||||||
result[t*3+3] = m_enhancements.at(enhanceListPointer).data() >> 1;
|
result[t*3+3] = m_enhancements.at(enhanceListPointer).data() >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is the last triplet, get a copy to repeat to the end of the packet
|
// If this is the last triplet, get a copy to repeat to the end of the packet
|
||||||
if (enhanceListPointer == m_enhancements.size()-1) {
|
if (enhanceListPointer == m_enhancements.size()-1) {
|
||||||
@@ -59,19 +68,24 @@ QByteArray PageX26Base::packetFromEnhancementList(int p) const
|
|||||||
void PageX26Base::setEnhancementListFromPacket(int p, QByteArray pkt)
|
void PageX26Base::setEnhancementListFromPacket(int p, QByteArray pkt)
|
||||||
{
|
{
|
||||||
// Preallocate entries in the m_enhancements list to hold our incoming triplets.
|
// Preallocate entries in the m_enhancements list to hold our incoming triplets.
|
||||||
// We write "dummy" reserved 11110 Row Triplets in the allocated entries which then get overwritten by the packet contents.
|
// We write invalid triplets in the allocated entries which then get overwritten by the packet contents.
|
||||||
// This is in case of missing packets so we can keep Local Object pointers valid.
|
// This is in case of missing packets so we can keep Local Object pointers valid.
|
||||||
while (m_enhancements.size() < (p+1)*13)
|
while (m_enhancements.size() < (p+1)*13)
|
||||||
m_enhancements.append( X26Triplet{ 41, 0x1e, 0 } );
|
m_enhancements.append( X26Triplet{ 0xff, 0xff, 0xff } );
|
||||||
|
|
||||||
X26Triplet newX26Triplet;
|
X26Triplet newX26Triplet;
|
||||||
|
|
||||||
for (int t=0; t<13; t++) {
|
for (int t=0; t<13; t++) {
|
||||||
const int enhanceListPointer = p*13+t;
|
const int enhanceListPointer = p*13+t;
|
||||||
|
|
||||||
|
// Need the "& 0xff" since QByteArray.at() returns (signed) chars
|
||||||
|
if ((pkt.at(t*3+2) & 0xff) == 0xff)
|
||||||
|
newX26Triplet.setInvalid();
|
||||||
|
else {
|
||||||
newX26Triplet.setAddress(pkt.at(t*3+1) & 0x3f);
|
newX26Triplet.setAddress(pkt.at(t*3+1) & 0x3f);
|
||||||
newX26Triplet.setMode(pkt.at(t*3+2) & 0x1f);
|
newX26Triplet.setMode(pkt.at(t*3+2) & 0x1f);
|
||||||
newX26Triplet.setData(((pkt.at(t*3+3) & 0x3f) << 1) | ((pkt.at(t*3+2) & 0x20) >> 5));
|
newX26Triplet.setData(((pkt.at(t*3+3) & 0x3f) << 1) | ((pkt.at(t*3+2) & 0x20) >> 5));
|
||||||
|
}
|
||||||
m_enhancements.replace(enhanceListPointer, newX26Triplet);
|
m_enhancements.replace(enhanceListPointer, newX26Triplet);
|
||||||
}
|
}
|
||||||
if (newX26Triplet.mode() == 0x1f && newX26Triplet.address() == 0x3f && newX26Triplet.data() & 0x01)
|
if (newX26Triplet.mode() == 0x1f && newX26Triplet.address() == 0x3f && newX26Triplet.data() & 0x01)
|
||||||
@@ -79,3 +93,8 @@ void PageX26Base::setEnhancementListFromPacket(int p, QByteArray pkt)
|
|||||||
while (m_enhancements.size()>1 && m_enhancements.at(m_enhancements.size()-2).mode() == 0x1f && m_enhancements.at(m_enhancements.size()-2).address() == 0x3f && m_enhancements.at(m_enhancements.size()-2).data() == newX26Triplet.data())
|
while (m_enhancements.size()>1 && m_enhancements.at(m_enhancements.size()-2).mode() == 0x1f && m_enhancements.at(m_enhancements.size()-2).address() == 0x3f && m_enhancements.at(m_enhancements.size()-2).data() == newX26Triplet.data())
|
||||||
m_enhancements.removeLast();
|
m_enhancements.removeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PageX26Base::packetFromEnhancementListNeeded(int n) const
|
||||||
|
{
|
||||||
|
return ((m_enhancements.size()+12) / 13) > n;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -26,18 +26,16 @@
|
|||||||
#include "pagebase.h"
|
#include "pagebase.h"
|
||||||
#include "x26triplets.h"
|
#include "x26triplets.h"
|
||||||
|
|
||||||
class PageX26Base : public PageBase //: public QObject
|
class PageX26Base : public PageBase
|
||||||
{
|
{
|
||||||
//Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
X26TripletList *enhancements() { return &m_enhancements; };
|
X26TripletList *enhancements();
|
||||||
virtual int maxEnhancements() const =0;
|
virtual int maxEnhancements() const =0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QByteArray packetFromEnhancementList(int p) const;
|
QByteArray packetFromEnhancementList(int p) const;
|
||||||
void setEnhancementListFromPacket(int p, QByteArray pkt);
|
void setEnhancementListFromPacket(int p, QByteArray pkt);
|
||||||
bool packetFromEnhancementListNeeded(int n) const { return ((m_enhancements.size()+12) / 13) > n; };
|
bool packetFromEnhancementListNeeded(int n) const;
|
||||||
|
|
||||||
X26TripletList m_enhancements;
|
X26TripletList m_enhancements;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -26,6 +26,51 @@ X26Triplet::X26Triplet(int address, int mode, int data)
|
|||||||
m_data = data;
|
m_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool X26Triplet::isValid() const
|
||||||
|
{
|
||||||
|
return m_mode != 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::address() const
|
||||||
|
{
|
||||||
|
return m_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::mode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::modeExt() const
|
||||||
|
{
|
||||||
|
return (m_address >= 40) ? m_mode : (m_mode | 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::data() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::addressRow() const
|
||||||
|
{
|
||||||
|
return (m_address == 40) ? 24 :m_address-40;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::addressColumn() const
|
||||||
|
{
|
||||||
|
return (m_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26Triplet::isRowTriplet() const
|
||||||
|
{
|
||||||
|
return (m_address >= 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X26Triplet::setInvalid()
|
||||||
|
{
|
||||||
|
m_address = m_mode = m_data = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
void X26Triplet::setAddress(int address)
|
void X26Triplet::setAddress(int address)
|
||||||
{
|
{
|
||||||
m_address = address;
|
m_address = address;
|
||||||
@@ -51,6 +96,26 @@ void X26Triplet::setAddressColumn(int addressColumn)
|
|||||||
m_address = addressColumn;
|
m_address = addressColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int X26Triplet::objectSource() const
|
||||||
|
{
|
||||||
|
return (m_address & 0x18) >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::objectLocalDesignationCode() const
|
||||||
|
{
|
||||||
|
return (((m_address & 0x01) << 3) | (m_data >> 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::objectLocalTripletNumber() const
|
||||||
|
{
|
||||||
|
return m_data & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::objectLocalIndex() const
|
||||||
|
{
|
||||||
|
return objectLocalDesignationCode() * 13 + objectLocalTripletNumber();
|
||||||
|
}
|
||||||
|
|
||||||
void X26Triplet::setObjectLocalDesignationCode(int i)
|
void X26Triplet::setObjectLocalDesignationCode(int i)
|
||||||
{
|
{
|
||||||
m_address = (m_address & 0x38) | (i >> 3);
|
m_address = (m_address & 0x38) | (i >> 3);
|
||||||
@@ -68,6 +133,46 @@ void X26Triplet::setObjectLocalIndex(int i)
|
|||||||
m_data = (((i / 13) & 0x07) << 4) | (i % 13);
|
m_data = (((i / 13) & 0x07) << 4) | (i % 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int X26Triplet::activePositionRow() const
|
||||||
|
{
|
||||||
|
return m_activePositionRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::activePositionColumn() const
|
||||||
|
{
|
||||||
|
return m_activePositionColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::activePositionRow1p5() const
|
||||||
|
{
|
||||||
|
return m_activePositionRow1p5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26Triplet::activePositionColumn1p5() const
|
||||||
|
{
|
||||||
|
return m_activePositionColumn1p5;
|
||||||
|
}
|
||||||
|
|
||||||
|
X26Triplet::X26TripletError X26Triplet::error() const
|
||||||
|
{
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26Triplet::reservedMode() const
|
||||||
|
{
|
||||||
|
return m_reservedMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26Triplet::reservedData() const
|
||||||
|
{
|
||||||
|
return m_reservedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26Triplet::activePosition1p5Differs() const
|
||||||
|
{
|
||||||
|
return m_activePosition1p5Differs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void X26TripletList::updateInternalData()
|
void X26TripletList::updateInternalData()
|
||||||
{
|
{
|
||||||
@@ -85,7 +190,9 @@ void X26TripletList::updateInternalData()
|
|||||||
triplet->m_reservedMode = false;
|
triplet->m_reservedMode = false;
|
||||||
triplet->m_reservedData = false;
|
triplet->m_reservedData = false;
|
||||||
|
|
||||||
if (triplet->isRowTriplet()) {
|
if (!triplet->isValid())
|
||||||
|
triplet->m_error = X26Triplet::ErrorDecodingTriplet;
|
||||||
|
else if (triplet->isRowTriplet()) {
|
||||||
switch (triplet->modeExt()) {
|
switch (triplet->modeExt()) {
|
||||||
case 0x00: // Full screen colour
|
case 0x00: // Full screen colour
|
||||||
if (activePosition.isDeployed())
|
if (activePosition.isDeployed())
|
||||||
@@ -239,17 +346,16 @@ void X26TripletList::updateInternalData()
|
|||||||
case 0x2f: // G2 character
|
case 0x2f: // G2 character
|
||||||
activePosition.setColumn(triplet->addressColumn());
|
activePosition.setColumn(triplet->addressColumn());
|
||||||
|
|
||||||
if (activePosition.row() != triplet->m_activePositionRow || activePosition.column() != triplet->m_activePositionColumn)
|
triplet->m_activePosition1p5Differs = activePosition.row() != triplet->m_activePositionRow || activePosition.column() != triplet->m_activePositionColumn;
|
||||||
triplet->m_activePosition1p5Differs = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (triplet->modeExt() >= 0x30 && triplet->modeExt() <= 0x3f) {
|
if (triplet->modeExt() >= 0x30 && triplet->modeExt() <= 0x3f) {
|
||||||
// G0 diacritical mark
|
// G0 diacritical mark
|
||||||
activePosition.setColumn(triplet->addressColumn());
|
activePosition.setColumn(triplet->addressColumn());
|
||||||
|
|
||||||
if (activePosition.row() != triplet->m_activePositionRow || activePosition.column() != triplet->m_activePositionColumn)
|
triplet->m_activePosition1p5Differs = activePosition.row() != triplet->m_activePositionRow || activePosition.column() != triplet->m_activePositionColumn;
|
||||||
triplet->m_activePosition1p5Differs = true;
|
} else
|
||||||
}
|
triplet->m_activePosition1p5Differs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
triplet->m_activePositionRow1p5 = activePosition.row();
|
triplet->m_activePositionRow1p5 = activePosition.row();
|
||||||
@@ -282,6 +388,35 @@ void X26TripletList::replace(int i, const X26Triplet &value)
|
|||||||
updateInternalData();
|
updateInternalData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void X26TripletList::removeLast()
|
||||||
|
{
|
||||||
|
m_list.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
const X26Triplet &X26TripletList::at(int i) const
|
||||||
|
{
|
||||||
|
return m_list.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26TripletList::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_list.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void X26TripletList::reserve(int alloc)
|
||||||
|
{
|
||||||
|
m_list.reserve(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26TripletList::size() const
|
||||||
|
{
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<int> &X26TripletList::objects(int t) const
|
||||||
|
{
|
||||||
|
return m_objects[t];
|
||||||
|
};
|
||||||
|
|
||||||
X26TripletList::ActivePosition::ActivePosition()
|
X26TripletList::ActivePosition::ActivePosition()
|
||||||
{
|
{
|
||||||
@@ -293,6 +428,21 @@ void X26TripletList::ActivePosition::reset()
|
|||||||
m_row = m_column = -1;
|
m_row = m_column = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int X26TripletList::ActivePosition::row() const
|
||||||
|
{
|
||||||
|
return m_row; // return (m_row == -1) ? 0 : m_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
int X26TripletList::ActivePosition::column() const
|
||||||
|
{
|
||||||
|
return m_column; // return (m_column == -1) ? 0 : m_column;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X26TripletList::ActivePosition::isDeployed() const
|
||||||
|
{
|
||||||
|
return m_row != -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool X26TripletList::ActivePosition::setRow(int row)
|
bool X26TripletList::ActivePosition::setRow(int row)
|
||||||
{
|
{
|
||||||
if (row < m_row)
|
if (row < m_row)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -26,7 +26,7 @@ class X26Triplet
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// x26model.h has the Plain English descriptions of these errors
|
// x26model.h has the Plain English descriptions of these errors
|
||||||
enum X26TripletError { NoError, ActivePositionMovedUp, ActivePositionMovedLeft, InvokePointerInvalid, InvokeTypeMismatch, OriginModifierAlone };
|
enum X26TripletError { NoError, ErrorDecodingTriplet, ActivePositionMovedUp, ActivePositionMovedLeft, InvokePointerInvalid, InvokeTypeMismatch, OriginModifierAlone };
|
||||||
enum ObjectSource { InvalidObjectSource, LocalObject, POPObject, GPOPObject };
|
enum ObjectSource { InvalidObjectSource, LocalObject, POPObject, GPOPObject };
|
||||||
|
|
||||||
X26Triplet() {}
|
X26Triplet() {}
|
||||||
@@ -36,37 +36,39 @@ public:
|
|||||||
|
|
||||||
X26Triplet(int address, int mode, int data);
|
X26Triplet(int address, int mode, int data);
|
||||||
|
|
||||||
int address() const { return m_address; }
|
bool isValid() const;
|
||||||
int mode() const { return m_mode; }
|
int address() const;
|
||||||
int modeExt() const { return (m_address >= 40) ? m_mode : (m_mode | 0x20); }
|
int mode() const;
|
||||||
int data() const { return m_data; }
|
int modeExt() const;
|
||||||
int addressRow() const { return (m_address == 40) ? 24 :m_address-40; }
|
int data() const;
|
||||||
int addressColumn() const { return (m_address); }
|
int addressRow() const;
|
||||||
bool isRowTriplet() const { return (m_address >= 40); }
|
int addressColumn() const;
|
||||||
|
bool isRowTriplet() const;
|
||||||
|
|
||||||
|
void setInvalid();
|
||||||
void setAddress(int address);
|
void setAddress(int address);
|
||||||
void setMode(int mode);
|
void setMode(int mode);
|
||||||
void setData(int data);
|
void setData(int data);
|
||||||
void setAddressRow(int addressRow);
|
void setAddressRow(int addressRow);
|
||||||
void setAddressColumn(int addressColumn);
|
void setAddressColumn(int addressColumn);
|
||||||
|
|
||||||
int objectSource() const { return (m_address & 0x18) >> 3; }
|
int objectSource() const;
|
||||||
|
|
||||||
int objectLocalDesignationCode() const { return (((m_address & 0x01) << 3) | (m_data >> 4)); }
|
int objectLocalDesignationCode() const;
|
||||||
int objectLocalTripletNumber() const { return m_data & 0x0f; }
|
int objectLocalTripletNumber() const;
|
||||||
int objectLocalIndex() const { return objectLocalDesignationCode() * 13 + objectLocalTripletNumber(); }
|
int objectLocalIndex() const;
|
||||||
void setObjectLocalDesignationCode(int i);
|
void setObjectLocalDesignationCode(int i);
|
||||||
void setObjectLocalTripletNumber(int i);
|
void setObjectLocalTripletNumber(int i);
|
||||||
void setObjectLocalIndex(int i);
|
void setObjectLocalIndex(int i);
|
||||||
|
|
||||||
int activePositionRow() const { return m_activePositionRow; }
|
int activePositionRow() const;
|
||||||
int activePositionColumn() const { return m_activePositionColumn; }
|
int activePositionColumn() const;
|
||||||
int activePositionRow1p5() const { return m_activePositionRow1p5; }
|
int activePositionRow1p5() const;
|
||||||
int activePositionColumn1p5() const { return m_activePositionColumn1p5; }
|
int activePositionColumn1p5() const;
|
||||||
X26TripletError error() const { return m_error; }
|
X26TripletError error() const;
|
||||||
bool reservedMode() const { return m_reservedMode; }
|
bool reservedMode() const;
|
||||||
bool reservedData() const { return m_reservedData; }
|
bool reservedData() const;
|
||||||
bool activePosition1p5Differs() const { return m_activePosition1p5Differs; }
|
bool activePosition1p5Differs() const;
|
||||||
|
|
||||||
friend class X26TripletList;
|
friend class X26TripletList;
|
||||||
|
|
||||||
@@ -91,14 +93,13 @@ public:
|
|||||||
void insert(int i, const X26Triplet &value);
|
void insert(int i, const X26Triplet &value);
|
||||||
void removeAt(int i);
|
void removeAt(int i);
|
||||||
void replace(int i, const X26Triplet &value);
|
void replace(int i, const X26Triplet &value);
|
||||||
|
void removeLast();
|
||||||
|
const X26Triplet &at(int i) const;
|
||||||
|
bool isEmpty() const;
|
||||||
|
void reserve(int alloc);
|
||||||
|
int size() const;
|
||||||
|
|
||||||
void removeLast() { m_list.removeLast(); }
|
const QList<int> &objects(int t) const;
|
||||||
|
|
||||||
const X26Triplet &at(int i) const { return m_list.at(i); }
|
|
||||||
bool isEmpty() const { return m_list.isEmpty(); }
|
|
||||||
void reserve(int alloc) { m_list.reserve(alloc); }
|
|
||||||
int size() const { return m_list.size(); }
|
|
||||||
const QList<int> &objects(int t) const { return m_objects[t]; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateInternalData();
|
void updateInternalData();
|
||||||
@@ -111,11 +112,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
ActivePosition();
|
ActivePosition();
|
||||||
void reset();
|
void reset();
|
||||||
// int row() const { return (m_row == -1) ? 0 : m_row; }
|
int row() const;
|
||||||
// int column() const { return (m_column == -1) ? 0 : m_column; }
|
int column() const;
|
||||||
int row() const { return m_row; }
|
bool isDeployed() const;
|
||||||
int column() const { return m_column; }
|
|
||||||
bool isDeployed() const { return m_row != -1; }
|
|
||||||
bool setRow(int);
|
bool setRow(int);
|
||||||
bool setColumn(int);
|
bool setColumn(int);
|
||||||
// bool setRowAndColumn(int, int);
|
// bool setRowAndColumn(int, int);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -139,11 +139,11 @@ bool LoadTTIFormat::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash
|
|||||||
fastTextPacket[i*6+2] = (fastTextLinkRead & 0x0f0) >> 4;
|
fastTextPacket[i*6+2] = (fastTextLinkRead & 0x0f0) >> 4;
|
||||||
fastTextPacket[i*6+4] = 0x7 | ((fastTextLinkRead & 0x100) >> 5);
|
fastTextPacket[i*6+4] = 0x7 | ((fastTextLinkRead & 0x100) >> 5);
|
||||||
fastTextPacket[i*6+6] = 0x3 | ((fastTextLinkRead & 0x600) >> 7);
|
fastTextPacket[i*6+6] = 0x3 | ((fastTextLinkRead & 0x600) >> 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
loadingPage->setPacket(27, 0, fastTextPacket);
|
loadingPage->setPacket(27, 0, fastTextPacket);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (metadata != nullptr)
|
if (metadata != nullptr)
|
||||||
metadata->insert(QString("fastextAbsolute"), true);
|
metadata->insert(QString("fastextAbsolute"), true);
|
||||||
}
|
}
|
||||||
@@ -227,6 +227,9 @@ bool LoadT42Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash
|
|||||||
int foundPageNumber = -1;
|
int foundPageNumber = -1;
|
||||||
bool firstPacket0Found = false;
|
bool firstPacket0Found = false;
|
||||||
bool pageBodyPacketsFound = false;
|
bool pageBodyPacketsFound = false;
|
||||||
|
bool errorEnhancements = false;
|
||||||
|
bool errorLinks = false;
|
||||||
|
bool errorPresentation = false;
|
||||||
|
|
||||||
m_inFile = inFile;
|
m_inFile = inFile;
|
||||||
|
|
||||||
@@ -374,6 +377,7 @@ bool LoadT42Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash
|
|||||||
// Error found in at least one byte of the link
|
// Error found in at least one byte of the link
|
||||||
// Neutralise the whole link to same magazine, page FF, subcode 3F7F
|
// Neutralise the whole link to same magazine, page FF, subcode 3F7F
|
||||||
qDebug("X/27/%d link %d decoding error", readDesignationCode, i);
|
qDebug("X/27/%d link %d decoding error", readDesignationCode, i);
|
||||||
|
errorLinks = true;
|
||||||
m_inLine[b] = 0xf;
|
m_inLine[b] = 0xf;
|
||||||
m_inLine[b+1] = 0xf;
|
m_inLine[b+1] = 0xf;
|
||||||
m_inLine[b+2] = 0xf;
|
m_inLine[b+2] = 0xf;
|
||||||
@@ -416,15 +420,17 @@ bool LoadT42Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash
|
|||||||
// Error decoding Hamming 24/18
|
// Error decoding Hamming 24/18
|
||||||
qDebug("X/%d/%d triplet %d decoding error", readPacketNumber, readDesignationCode, i);
|
qDebug("X/%d/%d triplet %d decoding error", readPacketNumber, readDesignationCode, i);
|
||||||
if (readPacketNumber == 26) {
|
if (readPacketNumber == 26) {
|
||||||
// Enhancements packet, set to "dummy" Address 41, Mode 0x1e, Data 0
|
// Enhancements packet, set to invalid triplet
|
||||||
m_inLine[b] = 41;
|
m_inLine[b] = 0xff;
|
||||||
m_inLine[b+1] = 0x1e;
|
m_inLine[b+1] = 0xff;
|
||||||
m_inLine[b+2] = 0;
|
m_inLine[b+2] = 0xff;
|
||||||
|
errorEnhancements = true;
|
||||||
} else {
|
} else {
|
||||||
// Zero out whole decoded triplet, bound to make things go wrong...
|
// Zero out whole decoded triplet, bound to make things go wrong...
|
||||||
m_inLine[b] = 0x00;
|
m_inLine[b] = 0x00;
|
||||||
m_inLine[b+1] = 0x00;
|
m_inLine[b+1] = 0x00;
|
||||||
m_inLine[b+2] = 0x00;
|
m_inLine[b+2] = 0x00;
|
||||||
|
errorPresentation = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_inLine[b] = d & 0x0003f;
|
m_inLine[b] = d & 0x0003f;
|
||||||
@@ -441,7 +447,14 @@ bool LoadT42Format::load(QFile *inFile, QList<PageBase>& subPages, QVariantHash
|
|||||||
} else if (!pageBodyPacketsFound) {
|
} else if (!pageBodyPacketsFound) {
|
||||||
m_error = "X/0 found, but no page body packets were found.";
|
m_error = "X/0 found, but no page body packets were found.";
|
||||||
return false;
|
return false;
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
if (errorEnhancements)
|
||||||
|
m_warnings.append("Error decoding triplet(s) in enhancement data.");
|
||||||
|
if (errorLinks)
|
||||||
|
m_warnings.append("Error decoding FLOF links.");
|
||||||
|
if (errorPresentation)
|
||||||
|
m_warnings.append("Error decoding triplet(s) in presentation data.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
|
|||||||
QApplication::setApplicationDisplayName(QApplication::applicationName());
|
QApplication::setApplicationDisplayName(QApplication::applicationName());
|
||||||
QApplication::setOrganizationName("gkmac.co.uk");
|
QApplication::setOrganizationName("gkmac.co.uk");
|
||||||
QApplication::setOrganizationDomain("gkmac.co.uk");
|
QApplication::setOrganizationDomain("gkmac.co.uk");
|
||||||
QApplication::setApplicationVersion("0.8.1-beta");
|
QApplication::setApplicationVersion("0.8.2-beta");
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(QApplication::applicationName());
|
parser.setApplicationDescription(QApplication::applicationName());
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -539,6 +539,11 @@ void TeletextWidget::paste()
|
|||||||
m_teletextDocument->undoStack()->push(new PasteCommand(m_teletextDocument, m_pageDecode.level1CharSet(m_teletextDocument->cursorRow(), m_teletextDocument->cursorColumn())));
|
m_teletextDocument->undoStack()->push(new PasteCommand(m_teletextDocument, m_pageDecode.level1CharSet(m_teletextDocument->cursorRow(), m_teletextDocument->cursorColumn())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeletextWidget::selectAll()
|
||||||
|
{
|
||||||
|
m_teletextDocument->setSelection((int)!m_teletextDocument->rowZeroAllowed(), 0, 24, 39);
|
||||||
|
}
|
||||||
|
|
||||||
QPair<int, int> TeletextWidget::mouseToRowAndColumn(const QPoint &mousePosition)
|
QPair<int, int> TeletextWidget::mouseToRowAndColumn(const QPoint &mousePosition)
|
||||||
{
|
{
|
||||||
int row = mousePosition.y() / 10;
|
int row = mousePosition.y() / 10;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -82,6 +82,8 @@ public slots:
|
|||||||
void copy();
|
void copy();
|
||||||
void paste();
|
void paste();
|
||||||
|
|
||||||
|
void selectAll();
|
||||||
|
|
||||||
void changeSize();
|
void changeSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -191,6 +191,9 @@ void MainWindow::extractImages(QImage sceneImage[], bool smooth, bool flashExtra
|
|||||||
// Prepare widget image for extraction
|
// Prepare widget image for extraction
|
||||||
m_textScene->hideGUIElements(true);
|
m_textScene->hideGUIElements(true);
|
||||||
|
|
||||||
|
if (m_textWidget->pageRender()->renderMode() == TeletextPageRender::RenderMix)
|
||||||
|
m_textScene->setBackgroundBrush(Qt::NoBrush);
|
||||||
|
|
||||||
const int flashTiming = flashExtract ? m_textWidget->flashTiming() : 0;
|
const int flashTiming = flashExtract ? m_textWidget->flashTiming() : 0;
|
||||||
|
|
||||||
// Allocate initial image, with additional images for flashing if necessary
|
// Allocate initial image, with additional images for flashing if necessary
|
||||||
@@ -221,6 +224,9 @@ void MainWindow::extractImages(QImage sceneImage[], bool smooth, bool flashExtra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now we've extracted the image we can put the GUI things back
|
// Now we've extracted the image we can put the GUI things back
|
||||||
|
if (m_textWidget->pageRender()->renderMode() == TeletextPageRender::RenderMix)
|
||||||
|
m_textScene->setBackgroundBrush(QColor(40, 54, 96));
|
||||||
|
|
||||||
m_textScene->hideGUIElements(false);
|
m_textScene->hideGUIElements(false);
|
||||||
m_textWidget->resumeFlash();
|
m_textWidget->resumeFlash();
|
||||||
|
|
||||||
@@ -365,7 +371,7 @@ void MainWindow::about()
|
|||||||
QMessageBox::about(this, tr("About"), QString("<b>%1</b><br>"
|
QMessageBox::about(this, tr("About"), QString("<b>%1</b><br>"
|
||||||
"An open source Level 2.5 teletext page editor.<br>"
|
"An open source Level 2.5 teletext page editor.<br>"
|
||||||
"<i>Version %2</i><br><br>"
|
"<i>Version %2</i><br><br>"
|
||||||
"Copyright (C) 2020-2025 Gavin MacGregor<br><br>"
|
"Copyright (C) 2020-2026 Gavin MacGregor<br><br>"
|
||||||
"Released under the GNU General Public License version 3<br>"
|
"Released under the GNU General Public License version 3<br>"
|
||||||
"<a href=\"https://github.com/gkthemac/qteletextmaker\">https://github.com/gkthemac/qteletextmaker</a>").arg(QApplication::applicationDisplayName()).arg(QApplication::applicationVersion()));
|
"<a href=\"https://github.com/gkthemac/qteletextmaker\">https://github.com/gkthemac/qteletextmaker</a>").arg(QApplication::applicationDisplayName()).arg(QApplication::applicationVersion()));
|
||||||
}
|
}
|
||||||
@@ -637,6 +643,13 @@ void MainWindow::createActions()
|
|||||||
editMenu->addAction(pasteAct);
|
editMenu->addAction(pasteAct);
|
||||||
editToolBar->addAction(pasteAct);
|
editToolBar->addAction(pasteAct);
|
||||||
|
|
||||||
|
const QIcon selectAllIcon = QIcon::fromTheme("edit-select-all");
|
||||||
|
QAction *selectAllAct = new QAction(selectAllIcon, tr("Select &all"), this);
|
||||||
|
selectAllAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_A));
|
||||||
|
selectAllAct->setStatusTip(tr("Select the whole subpage"));
|
||||||
|
connect(selectAllAct, &QAction::triggered, m_textWidget, &TeletextWidget::selectAll);
|
||||||
|
editMenu->addAction(selectAllAct);
|
||||||
|
|
||||||
QAction *copyImageAct = editMenu->addAction(tr("Copy as image"));
|
QAction *copyImageAct = editMenu->addAction(tr("Copy as image"));
|
||||||
copyImageAct->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C));
|
copyImageAct->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C));
|
||||||
copyImageAct->setStatusTip(tr("Copy this subpage as an image to the clipboard"));
|
copyImageAct->setStatusTip(tr("Copy this subpage as an image to the clipboard"));
|
||||||
@@ -824,16 +837,23 @@ void MainWindow::createActions()
|
|||||||
QMenu *alphaColourSubMenu = insertMenu->addMenu(tr("Alphanumeric colour"));
|
QMenu *alphaColourSubMenu = insertMenu->addMenu(tr("Alphanumeric colour"));
|
||||||
QMenu *mosaicColourSubMenu = insertMenu->addMenu(tr("Mosaic colour"));
|
QMenu *mosaicColourSubMenu = insertMenu->addMenu(tr("Mosaic colour"));
|
||||||
for (int i=0; i<=7; i++) {
|
for (int i=0; i<=7; i++) {
|
||||||
const char *colours[] = { "Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White" };
|
const char *colourNames[] = { "Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White" };
|
||||||
|
const QChar azertyKeys[] = { 'P', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U' };
|
||||||
|
|
||||||
QAction *alphaColour = alphaColourSubMenu->addAction(tr(colours[i]));
|
QAction *alphaColour = alphaColourSubMenu->addAction(tr(colourNames[i]));
|
||||||
alphaColour->setShortcut(QKeySequence(QString("Esc, %1").arg(i)));
|
alphaColour->setShortcuts(QList<QKeySequence> {
|
||||||
alphaColour->setStatusTip(QString("Insert alphanumeric %1 attribute").arg(QString(colours[i]).toLower()));
|
QKeySequence(QString("Esc, %1").arg(i)),
|
||||||
|
QKeySequence(QString("Esc, %1").arg(azertyKeys[i]))
|
||||||
|
} );
|
||||||
|
alphaColour->setStatusTip(QString("Insert alphanumeric %1 attribute").arg(QString(colourNames[i]).toLower()));
|
||||||
connect(alphaColour, &QAction::triggered, [=]() { m_textWidget->setCharacter(i); });
|
connect(alphaColour, &QAction::triggered, [=]() { m_textWidget->setCharacter(i); });
|
||||||
|
|
||||||
QAction *mosaicColour = mosaicColourSubMenu->addAction(tr(colours[i]));
|
QAction *mosaicColour = mosaicColourSubMenu->addAction(tr(colourNames[i]));
|
||||||
mosaicColour->setShortcut(QKeySequence(QString("Esc, Shift+%1").arg(i)));
|
mosaicColour->setShortcuts(QList<QKeySequence> {
|
||||||
mosaicColour->setStatusTip(QString("Insert mosaic %1 attribute").arg(QString(colours[i]).toLower()));
|
QKeySequence(QString("Esc, Shift+%1").arg(i)),
|
||||||
|
QKeySequence(QString("Esc, Shift+%1").arg(azertyKeys[i]))
|
||||||
|
} );
|
||||||
|
mosaicColour->setStatusTip(QString("Insert mosaic %1 attribute").arg(QString(colourNames[i]).toLower()));
|
||||||
connect(mosaicColour, &QAction::triggered, [=]() { m_textWidget->setCharacter(i+0x10); });
|
connect(mosaicColour, &QAction::triggered, [=]() { m_textWidget->setCharacter(i+0x10); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -160,8 +160,23 @@ QByteArray SaveTTIFormat::format18BitPacket(QByteArray packet)
|
|||||||
// TTI stores the triplets 6 bits at a time like we do, without Hamming encoding
|
// TTI stores the triplets 6 bits at a time like we do, without Hamming encoding
|
||||||
// We don't touch the first byte; the caller replaces it with the designation code
|
// We don't touch the first byte; the caller replaces it with the designation code
|
||||||
// unless it's X/1-X/25 used in (G)POP pages
|
// unless it's X/1-X/25 used in (G)POP pages
|
||||||
for (int i=1; i<packet.size(); i++)
|
for (int i=1; i<packet.size(); i++) {
|
||||||
|
// Save invalid triplets as address 41, mode 0x1e, data 0
|
||||||
|
// which hopefully won't do anything when parsed as X/26 enhancements
|
||||||
|
if ((packet.at(i) & 0xff) == 0xff)
|
||||||
|
switch (i % 3) {
|
||||||
|
case 1:
|
||||||
|
packet[i] = 41;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
packet[i] = 0x1e;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
packet[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
packet[i] = packet.at(i) | 0x40;
|
packet[i] = packet.at(i) | 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@@ -322,7 +337,11 @@ QByteArray SaveT42Format::format4BitPacket(QByteArray packet)
|
|||||||
|
|
||||||
QByteArray SaveT42Format::format18BitPacket(QByteArray packet)
|
QByteArray SaveT42Format::format18BitPacket(QByteArray packet)
|
||||||
{
|
{
|
||||||
for (int c=1; c<packet.size(); c+=3) {
|
for (int c=1; c<packet.size(); c+=3)
|
||||||
|
// For invalid packets, save as all zeroes which will fail Hamming 24/18 decoding
|
||||||
|
if ((packet.at(c) & 0xff) == 0xff)
|
||||||
|
packet[c] = packet[c+1] = packet[c+2] = 0;
|
||||||
|
else {
|
||||||
unsigned int D5_D11;
|
unsigned int D5_D11;
|
||||||
unsigned int D12_D18;
|
unsigned int D12_D18;
|
||||||
unsigned int P5, P6;
|
unsigned int P5, P6;
|
||||||
@@ -440,7 +459,14 @@ bool SaveEP1Format::getWarnings(const PageBase &subPage)
|
|||||||
|
|
||||||
QByteArray SaveEP1Format::format18BitPacket(QByteArray packet)
|
QByteArray SaveEP1Format::format18BitPacket(QByteArray packet)
|
||||||
{
|
{
|
||||||
for (int c=1; c<packet.size(); c+=3) {
|
for (int c=1; c<packet.size(); c+=3)
|
||||||
|
if ((packet.at(c+1) & 0xff) == 0xff) {
|
||||||
|
// Save invalid triplets as address 41, mode 0x1e, data 0
|
||||||
|
// which hopefully won't do anything when parsed as X/26 enhancements
|
||||||
|
packet[c] = 41;
|
||||||
|
packet[c+1] = 0x1e;
|
||||||
|
packet[c+2] = 0;
|
||||||
|
} else {
|
||||||
// Shuffle triplet bits to 6 bit address, 5 bit mode, 7 bit data
|
// Shuffle triplet bits to 6 bit address, 5 bit mode, 7 bit data
|
||||||
packet[c+2] = ((packet.at(c+2) & 0x3f) << 1) | ((packet.at(c+1) & 0x20) >> 5);
|
packet[c+2] = ((packet.at(c+2) & 0x3f) << 1) | ((packet.at(c+1) & 0x20) >> 5);
|
||||||
packet[c+1] = packet.at(c+1) & 0x1f;
|
packet[c+1] = packet.at(c+1) & 0x1f;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -678,6 +678,13 @@ void X26DockWidget::updateAllCookedTripletWidgets(const QModelIndex &index)
|
|||||||
{
|
{
|
||||||
const int modeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
|
const int modeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
|
||||||
|
|
||||||
|
if (modeExt == 0xff) {
|
||||||
|
disableTripletWidgets();
|
||||||
|
m_cookedModePushButton->setEnabled(true);
|
||||||
|
m_cookedModePushButton->setText("Replace...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_cookedModePushButton->setEnabled(true);
|
m_cookedModePushButton->setEnabled(true);
|
||||||
m_cookedModePushButton->setText(m_modeTripletNames.modeName(modeExt));
|
m_cookedModePushButton->setText(m_modeTripletNames.modeName(modeExt));
|
||||||
|
|
||||||
@@ -1034,7 +1041,7 @@ void X26DockWidget::insertTriplet(int modeExt, int row)
|
|||||||
if (modeExt >= 0x20 && modeExt != 0x24 && modeExt != 0x25 && modeExt != 0x26 && modeExt != 0x2a) {
|
if (modeExt >= 0x20 && modeExt != 0x24 && modeExt != 0x25 && modeExt != 0x26 && modeExt != 0x2a) {
|
||||||
const int existingTripletModeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
|
const int existingTripletModeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
|
||||||
|
|
||||||
if (existingTripletModeExt >= 0x20 && existingTripletModeExt != 0x24 && existingTripletModeExt != 0x25 && existingTripletModeExt != 0x26 && existingTripletModeExt != 0x2a)
|
if (existingTripletModeExt >= 0x20 && existingTripletModeExt <= 0x3f && existingTripletModeExt != 0x24 && existingTripletModeExt != 0x25 && existingTripletModeExt != 0x26 && existingTripletModeExt != 0x2a)
|
||||||
newTriplet.setAddress(index.model()->data(index.model()->index(index.row(), 0), Qt::UserRole).toInt());
|
newTriplet.setAddress(index.model()->data(index.model()->index(index.row(), 0), Qt::UserRole).toInt());
|
||||||
}
|
}
|
||||||
// If we're inserting a Set Active Position or Full Row Colour triplet,
|
// If we're inserting a Set Active Position or Full Row Colour triplet,
|
||||||
@@ -1059,11 +1066,15 @@ void X26DockWidget::insertTriplet(int modeExt, int row)
|
|||||||
} else
|
} else
|
||||||
row = 0;
|
row = 0;
|
||||||
|
|
||||||
// Avoid reserved bits
|
// Avoid reserved bits or suggest sane defaults
|
||||||
switch (modeExt) {
|
switch (modeExt) {
|
||||||
case 0x07: // Address Row 0
|
case 0x07: // Address Row 0
|
||||||
newTriplet.setAddress(63); // set Address to notreserved
|
newTriplet.setAddress(63); // set Address to notreserved
|
||||||
break;
|
break;
|
||||||
|
case 0x15: // Define Active Object
|
||||||
|
case 0x16: // Define Adaptive Object
|
||||||
|
case 0x17: // Define Passive Object
|
||||||
|
newTriplet.setAddress(0x38); // Required at Levels 2.5 and 3.5
|
||||||
case 0x18: // DRCS mode
|
case 0x18: // DRCS mode
|
||||||
newTriplet.setData(0x70); // Normal DRCS at Levels 2.5 and 3.5
|
newTriplet.setData(0x70); // Normal DRCS at Levels 2.5 and 3.5
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -108,7 +108,7 @@ QVariant X26Model::data(const QModelIndex &index, int role) const
|
|||||||
else
|
else
|
||||||
return QVariant();
|
return QVariant();
|
||||||
case 1:
|
case 1:
|
||||||
if (!triplet.isRowTriplet())
|
if (triplet.isValid() && !triplet.isRowTriplet())
|
||||||
return triplet.addressColumn();
|
return triplet.addressColumn();
|
||||||
// For Set Active Position and Origin Modifier, data is the column
|
// For Set Active Position and Origin Modifier, data is the column
|
||||||
else if (triplet.modeExt() == 0x04)
|
else if (triplet.modeExt() == 0x04)
|
||||||
@@ -122,9 +122,14 @@ QVariant X26Model::data(const QModelIndex &index, int role) const
|
|||||||
QString result;
|
QString result;
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
if (index.column() == 2)
|
if (index.column() == 2) {
|
||||||
|
if (!triplet.isValid())
|
||||||
|
return "Error decoding triplet";
|
||||||
return (m_modeTripletNames.modeName(triplet.modeExt()));
|
return (m_modeTripletNames.modeName(triplet.modeExt()));
|
||||||
|
}
|
||||||
// Column 3 - describe effects of data/address triplet parameters in plain English
|
// Column 3 - describe effects of data/address triplet parameters in plain English
|
||||||
|
if (!triplet.isValid())
|
||||||
|
return QVariant();
|
||||||
switch (triplet.modeExt()) {
|
switch (triplet.modeExt()) {
|
||||||
case 0x01: // Full row colour
|
case 0x01: // Full row colour
|
||||||
case 0x07: // Address row 0
|
case 0x07: // Address row 0
|
||||||
@@ -609,12 +614,15 @@ bool X26Model::setData(const QModelIndex &index, const QVariant &value, int role
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 2: // Cooked triplet mode
|
case 2: // Cooked triplet mode
|
||||||
if (intValue < 0x20 && !triplet.isRowTriplet()) {
|
if (!triplet.isValid()) {
|
||||||
|
// Changing from invalid triplet
|
||||||
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x00, intValue < 0x20 ? 41 : 0, role));
|
||||||
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 32, role));
|
||||||
|
} else if (intValue < 0x20 && !triplet.isRowTriplet()) {
|
||||||
// Changing mode from column triplet to row triplet
|
// Changing mode from column triplet to row triplet
|
||||||
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x00, 41, role));
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x00, 41, role));
|
||||||
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0, role));
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0, role));
|
||||||
}
|
} else if (intValue >= 0x20 && triplet.isRowTriplet()) {
|
||||||
if (intValue >= 0x20 && triplet.isRowTriplet()) {
|
|
||||||
// Changing mode from row triplet to column triplet
|
// Changing mode from row triplet to column triplet
|
||||||
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x00, 0, role));
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x00, 0, role));
|
||||||
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0, role));
|
m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0, role));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
@@ -60,8 +60,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Needs to be in the same order as enum X26TripletError in x26triplets.h
|
// Needs to be in the same order as enum X26TripletError in x26triplets.h
|
||||||
const tripletErrorShow m_tripletErrors[6] {
|
const tripletErrorShow m_tripletErrors[7] {
|
||||||
{ "", 0 }, // No error
|
{ "", 0 }, // No error
|
||||||
|
{ "Error decoding triplet", 2 },
|
||||||
{ "Active Position can't move up", 0 },
|
{ "Active Position can't move up", 0 },
|
||||||
{ "Active Position can't move left within row", 1 },
|
{ "Active Position can't move left within row", 1 },
|
||||||
{ "Invocation not pointing to Object Definition", 3 },
|
{ "Invocation not pointing to Object Definition", 3 },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2025 Gavin MacGregor
|
* Copyright (C) 2020-2026 Gavin MacGregor
|
||||||
*
|
*
|
||||||
* This file is part of QTeletextMaker.
|
* This file is part of QTeletextMaker.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user