Moved FastText links from document to subpages
This paves the way for different FastText links per subpage. Will also be some help when we come to splitting out document loading and saving.
This commit is contained in:
55
document.cpp
55
document.cpp
@@ -29,8 +29,6 @@ TeletextDocument::TeletextDocument()
|
|||||||
{
|
{
|
||||||
m_pageNumber = 0x198;
|
m_pageNumber = 0x198;
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
for (int i=0; i<6; i++)
|
|
||||||
m_fastTextLink[i] = 0x8ff;
|
|
||||||
m_empty = true;
|
m_empty = true;
|
||||||
m_subPages.push_back(new LevelOnePage);
|
m_subPages.push_back(new LevelOnePage);
|
||||||
m_subPages[0]->setPageNumber(m_pageNumber);
|
m_subPages[0]->setPageNumber(m_pageNumber);
|
||||||
@@ -114,8 +112,14 @@ void TeletextDocument::loadDocument(QFile *inFile)
|
|||||||
if (flLine.count(',') == 5)
|
if (flLine.count(',') == 5)
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
fastTextLinkRead = flLine.section(',', i, i).toInt(&fastTextLinkOk, 16);
|
fastTextLinkRead = flLine.section(',', i, i).toInt(&fastTextLinkOk, 16);
|
||||||
if (fastTextLinkOk)
|
if (fastTextLinkOk) {
|
||||||
m_fastTextLink[i] = fastTextLinkRead == 0 ? 0x8ff : fastTextLinkRead;
|
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,"))
|
if (inLine.startsWith("OL,"))
|
||||||
@@ -141,10 +145,16 @@ void TeletextDocument::saveDocument(QTextStream *outStream)
|
|||||||
|
|
||||||
for (auto &subPage : m_subPages) {
|
for (auto &subPage : m_subPages) {
|
||||||
subPage->savePage(outStream, m_pageNumber, subPageNumber++);
|
subPage->savePage(outStream, m_pageNumber, subPageNumber++);
|
||||||
if (m_fastTextLink[0] != 0x8ff) {
|
if (subPage->fastTextLinkPageNumber(0) != 0x8ff) {
|
||||||
*outStream << "FL,";
|
*outStream << "FL,";
|
||||||
for (int i=0; i<6; i++) {
|
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)
|
if (i<5)
|
||||||
*outStream << ',';
|
*outStream << ',';
|
||||||
}
|
}
|
||||||
@@ -203,17 +213,18 @@ void TeletextDocument::deleteSubPage(int subPageToDelete)
|
|||||||
m_subPages.erase(m_subPages.begin()+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...
|
// The LineEdit should check if a valid hex number was entered, but just in case...
|
||||||
bool newPageNumberOk;
|
bool pageNumberOk;
|
||||||
int newPageNumberRead = newPageNumberString.toInt(&newPageNumberOk, 16);
|
int pageNumberRead = pageNumberString.toInt(&pageNumberOk, 16);
|
||||||
if ((!newPageNumberOk) || newPageNumberRead < 0x100 || newPageNumberRead > 0x8fe)
|
if ((!pageNumberOk) || pageNumberRead < 0x100 || pageNumberRead > 0x8fe)
|
||||||
return;
|
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 oldMagazine = (m_pageNumber & 0xf00);
|
||||||
int newMagazine = (newPageNumberRead & 0xf00);
|
int newMagazine = (pageNumberRead & 0xf00);
|
||||||
// Fix magazine 0 to 8
|
// Fix magazine 0 to 8
|
||||||
if (oldMagazine == 0x800)
|
if (oldMagazine == 0x800)
|
||||||
oldMagazine = 0x000;
|
oldMagazine = 0x000;
|
||||||
@@ -221,13 +232,16 @@ void TeletextDocument::setPageNumber(QString newPageNumberString)
|
|||||||
newMagazine = 0x000;
|
newMagazine = 0x000;
|
||||||
int magazineFlip = oldMagazine ^ newMagazine;
|
int magazineFlip = oldMagazine ^ newMagazine;
|
||||||
|
|
||||||
m_pageNumber = newPageNumberRead;
|
m_pageNumber = pageNumberRead;
|
||||||
|
|
||||||
for (auto &subPage : m_subPages) {
|
for (auto &subPage : m_subPages) {
|
||||||
subPage->setPageNumber(newPageNumberRead);
|
subPage->setPageNumber(pageNumberRead);
|
||||||
if (magazineFlip)
|
if (magazineFlip) {
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
subPage->setFastTextLinkPageNumber(i, subPage->fastTextLinkPageNumber(i) ^ magazineFlip);
|
||||||
for (int i=0; i<8; i++)
|
for (int i=0; i<8; i++)
|
||||||
subPage->setComposeLinkPageNumber(i, subPage->composeLinkPageNumber(i) ^ magazineFlip);
|
subPage->setComposeLinkPageNumber(i, subPage->composeLinkPageNumber(i) ^ magazineFlip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,15 +250,10 @@ void TeletextDocument::setDescription(QString newDescription)
|
|||||||
m_description = 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...
|
for (auto &subPage : m_subPages)
|
||||||
bool newPageNumberOk;
|
subPage->setFastTextLinkPageNumber(linkNumber, pageNumber);
|
||||||
int newPageNumberRead = newPageNumberString.toInt(&newPageNumberOk, 16);
|
|
||||||
if ((!newPageNumberOk) || newPageNumberRead < 0x100 || newPageNumberRead > 0x8ff)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_fastTextLink[linkNumber] = newPageNumberRead;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::cursorUp()
|
void TeletextDocument::cursorUp()
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ public:
|
|||||||
void setPageNumber(QString);
|
void setPageNumber(QString);
|
||||||
QString description() const { return m_description; }
|
QString description() const { return m_description; }
|
||||||
void setDescription(QString);
|
void setDescription(QString);
|
||||||
int fastTextLink(int linkNumber) const { return m_fastTextLink[linkNumber]; }
|
void setFastTextLinkPageNumberOnAllSubPages(int, int);
|
||||||
void setFastTextLink(int, QString);
|
|
||||||
QUndoStack *undoStack() const { return m_undoStack; }
|
QUndoStack *undoStack() const { return m_undoStack; }
|
||||||
int cursorRow() const { return m_cursorRow; }
|
int cursorRow() const { return m_cursorRow; }
|
||||||
int cursorColumn() const { return m_cursorColumn; }
|
int cursorColumn() const { return m_cursorColumn; }
|
||||||
@@ -84,7 +83,6 @@ private:
|
|||||||
QString m_description;
|
QString m_description;
|
||||||
bool m_empty;
|
bool m_empty;
|
||||||
int m_pageNumber, m_currentSubPageIndex;
|
int m_pageNumber, m_currentSubPageIndex;
|
||||||
int m_fastTextLink[6];
|
|
||||||
std::vector<LevelOnePage *> m_subPages;
|
std::vector<LevelOnePage *> m_subPages;
|
||||||
QUndoStack *m_undoStack;
|
QUndoStack *m_undoStack;
|
||||||
int m_cursorRow, m_cursorColumn, m_selectionTopRow, m_selectionBottomRow, m_selectionLeftColumn, m_selectionRightColumn;
|
int m_cursorRow, m_cursorColumn, m_selectionTopRow, m_selectionBottomRow, m_selectionLeftColumn, m_selectionRightColumn;
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ void LevelOnePage::clearPage()
|
|||||||
setControlBit(i, false);
|
setControlBit(i, false);
|
||||||
m_composeLink[i] = { (i<4) ? i : 0, false, i>=4, 0x0ff, 0x0000 };
|
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_subPageNumber = 0x0000; */
|
||||||
m_cycleValue = 8;
|
m_cycleValue = 8;
|
||||||
@@ -124,7 +126,20 @@ QByteArray LevelOnePage::packet(int packetNumber, int designationCode)
|
|||||||
return result;
|
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)) {
|
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) {
|
||||||
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) {
|
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;
|
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)) {
|
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) {
|
||||||
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) {
|
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)
|
if (packetNumber == 26)
|
||||||
return ((localEnhance.size()+12) / 13) > designationCode;
|
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)) {
|
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) {
|
||||||
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) {
|
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::setSidePanelColumns(int newSidePanelColumns) { m_sidePanelColumns = newSidePanelColumns; }
|
||||||
void LevelOnePage::setSidePanelStatusL25(bool newSidePanelStatusL25) { m_sidePanelStatusL25 = newSidePanelStatusL25; }
|
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)
|
void LevelOnePage::setComposeLinkFunction(int linkNumber, int newFunction)
|
||||||
{
|
{
|
||||||
m_composeLink[linkNumber].function = newFunction;
|
m_composeLink[linkNumber].function = newFunction;
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ public:
|
|||||||
void setSidePanelColumns(int);
|
void setSidePanelColumns(int);
|
||||||
bool sidePanelStatusL25() const { return m_sidePanelStatusL25; }
|
bool sidePanelStatusL25() const { return m_sidePanelStatusL25; }
|
||||||
void setSidePanelStatusL25(bool);
|
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; }
|
int composeLinkFunction(int linkNumber) const { return m_composeLink[linkNumber].function; }
|
||||||
void setComposeLinkFunction(int, int);
|
void setComposeLinkFunction(int, int);
|
||||||
bool composeLinkLevel2p5(int linkNumber) const { return m_composeLink[linkNumber].level2p5; }
|
bool composeLinkLevel2p5(int linkNumber) const { return m_composeLink[linkNumber].level2p5; }
|
||||||
@@ -112,6 +114,10 @@ private:
|
|||||||
int m_defaultScreenColour, m_defaultRowColour, m_colourTableRemap, m_sidePanelColumns;
|
int m_defaultScreenColour, m_defaultRowColour, m_colourTableRemap, m_sidePanelColumns;
|
||||||
bool m_blackBackgroundSubst, m_leftSidePanelDisplayed, m_rightSidePanelDisplayed, m_sidePanelStatusL25;
|
bool m_blackBackgroundSubst, m_leftSidePanelDisplayed, m_rightSidePanelDisplayed, m_sidePanelStatusL25;
|
||||||
int m_CLUT[32];
|
int m_CLUT[32];
|
||||||
|
struct fastTextLink {
|
||||||
|
int pageNumber;
|
||||||
|
int subPageNumber;
|
||||||
|
} m_fastTextLink[6];
|
||||||
struct composeLink {
|
struct composeLink {
|
||||||
int function;
|
int function;
|
||||||
bool level2p5, level3p5;
|
bool level2p5, level3p5;
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ PageOptionsDockWidget::PageOptionsDockWidget(TeletextWidget *parent): QDockWidge
|
|||||||
m_fastTextEdit[i]->setInputMask("DHH");
|
m_fastTextEdit[i]->setInputMask("DHH");
|
||||||
//TODO restrict first digit of page number to 1-8
|
//TODO restrict first digit of page number to 1-8
|
||||||
fastTextLayout->addWidget(m_fastTextEdit[i], 1, i, 1, 1);
|
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);
|
pageOptionsLayout->addLayout(fastTextLayout);
|
||||||
@@ -161,8 +161,13 @@ void PageOptionsDockWidget::updateWidgets()
|
|||||||
m_pageDescriptionEdit->setText(m_parentMainWidget->document()->description());
|
m_pageDescriptionEdit->setText(m_parentMainWidget->document()->description());
|
||||||
m_pageDescriptionEdit->blockSignals(false);
|
m_pageDescriptionEdit->blockSignals(false);
|
||||||
for (int i=0; i<6; i++) {
|
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]->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_fastTextEdit[i]->blockSignals(false);
|
||||||
}
|
}
|
||||||
m_cycleValueSpinBox->blockSignals(true);
|
m_cycleValueSpinBox->blockSignals(true);
|
||||||
@@ -192,6 +197,23 @@ void PageOptionsDockWidget::updateWidgets()
|
|||||||
m_secondNOSCombo->blockSignals(false);
|
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()
|
void PageOptionsDockWidget::updateDefaultNOSOptions()
|
||||||
{
|
{
|
||||||
while (m_defaultNOSCombo->count() > 0)
|
while (m_defaultNOSCombo->count() > 0)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ private:
|
|||||||
QLineEdit *m_fastTextEdit[6];
|
QLineEdit *m_fastTextEdit[6];
|
||||||
|
|
||||||
void addRegionList(QComboBox *);
|
void addRegionList(QComboBox *);
|
||||||
|
void setFastTextLinkPageNumber(int, const QString &);
|
||||||
void setDefaultRegion();
|
void setDefaultRegion();
|
||||||
void setDefaultNOS();
|
void setDefaultNOS();
|
||||||
void setSecondRegion();
|
void setSecondRegion();
|
||||||
|
|||||||
Reference in New Issue
Block a user