Compare commits
9 Commits
0.5.4-alph
...
0.5.5-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06e0b401ca | ||
|
|
bc8780608c | ||
|
|
536c231941 | ||
|
|
4faed597c0 | ||
|
|
75816e7750 | ||
|
|
8b655afb2d | ||
|
|
abf649d2ab | ||
|
|
a8f2152c92 | ||
|
|
9d05126e8f |
@@ -14,13 +14,15 @@ Features
|
||||
- Configurable zoom.
|
||||
- View teletext pages in 4:3, 16:9 pillar-box and 16:9 stretch aspect ratios.
|
||||
|
||||
Although designed on and developed for Linux, the Qt 5 libraries are cross platform so a Windows executable can be built. A Windows executable can be found within the "Releases" link, compiled on a Linux host using [MXE](https://github.com/mxe/mxe) based on [these instructions](https://blog.8bitbuddhism.com/2018/08/22/cross-compiling-windows-applications-with-mxe/). After MXE is installed `make qtbase` should be enough to build QTeletextMaker.
|
||||
Although designed on and developed for Linux, the Qt 5 libraries are cross platform so a Windows executable can be built. A Windows executable can be found within the "Releases" link, compiled on a Linux host using [MXE](https://github.com/mxe/mxe) based on [these instructions](https://blog.8bitbuddhism.com/2018/08/22/cross-compiling-windows-applications-with-mxe/). After MXE is installed `make qtbase` should build and install the required dependencies to build QTeletextMaker.
|
||||
|
||||
## Building
|
||||
### Linux
|
||||
Install the QtCore, QtGui and QtWidgets libraries and build headers, along with the qmake tool. Then type `qmake5 && make -j3` in a terminal, you can replace -j3 with the number of processor cores used for the compile process.
|
||||
Install the QtCore, QtGui and QtWidgets libraries and build headers, along with the qmake tool. Depending on how qmake is installed, type `qmake && make -j3` or `qmake5 && make -j3` in a terminal to build, you can replace -j3 with the number of processor cores used for the compile process.
|
||||
|
||||
The above will place the qteletextmaker executable in the same directory as the source, type `./qteletextmaker` in the terminal to launch. Optionally, type `make install` afterwards to place the executable into /usr/local/bin.
|
||||
The above should place the qteletextmaker executable in the same directory as the source, type `./qteletextmaker` in the terminal to launch. Some Qt installs may place the executable into a "release" directory.
|
||||
|
||||
Optionally, type `make install` afterwards to place the executable into /usr/local/bin.
|
||||
|
||||
## Current limitations
|
||||
The following X/26 enhancement triplets are not rendered by the editor, although the list is fully aware of them.
|
||||
|
||||
@@ -68,7 +68,13 @@ void TeletextPageDecode::setLevel(int level)
|
||||
{
|
||||
if (level == m_level)
|
||||
return;
|
||||
|
||||
m_level = level;
|
||||
|
||||
for (int r=0; r<25; r++)
|
||||
for (int c=0; c<72; c++)
|
||||
m_refresh[r][c] = true;
|
||||
|
||||
decodePage();
|
||||
}
|
||||
|
||||
|
||||
19
document.cpp
19
document.cpp
@@ -94,6 +94,25 @@ bool TeletextDocument::isEmpty() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeletextDocument::clear()
|
||||
{
|
||||
LevelOnePage *blankSubPage = new LevelOnePage;
|
||||
|
||||
m_subPages.insert(m_subPages.begin(), blankSubPage);
|
||||
|
||||
emit aboutToChangeSubPage();
|
||||
m_currentSubPageIndex = 0;
|
||||
m_clutModel->setSubPage(m_subPages[0]);
|
||||
emit subPageSelected();
|
||||
cancelSelection();
|
||||
m_undoStack->clear();
|
||||
|
||||
for (int i=m_subPages.size()-1; i>0; i--) {
|
||||
delete(m_subPages[i]);
|
||||
m_subPages.erase(m_subPages.begin()+i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void TeletextDocument::setPageFunction(PageFunctionEnum newPageFunction)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
~TeletextDocument();
|
||||
|
||||
bool isEmpty() const;
|
||||
void clear();
|
||||
|
||||
PageFunctionEnum pageFunction() const { return m_pageFunction; }
|
||||
// void setPageFunction(PageFunctionEnum);
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "levelonepage.h"
|
||||
|
||||
#include "x26triplets.h"
|
||||
|
||||
LevelOnePage::LevelOnePage()
|
||||
{
|
||||
m_enhancements.reserve(maxEnhancements());
|
||||
@@ -403,17 +405,21 @@ bool LevelOnePage::isPaletteDefault(int fromColour, int toColour) const
|
||||
|
||||
int LevelOnePage::levelRequired() const
|
||||
{
|
||||
// X/28/4 present i.e. CLUTs 0 or 1 redefined - Level 3.5
|
||||
if (!isPaletteDefault(0, 15))
|
||||
return 3;
|
||||
|
||||
// TODO Check for X/28/1 for DCLUT for mode 1-3 DRCS characters - return 3
|
||||
|
||||
// Assume Level 2.5 if any X/28 page enhancements are present, otherwise assume Level 1
|
||||
int levelSeen = (!isPaletteDefault(16,31) || m_leftSidePanelDisplayed || m_rightSidePanelDisplayed || m_defaultScreenColour !=0 || m_defaultRowColour !=0 || m_blackBackgroundSubst || m_colourTableRemap !=0 || m_defaultCharSet != 0 || m_secondCharSet != 0xf) ? 2 : 0;
|
||||
|
||||
// If there's no X/26 triplets, exit here as Level 1 or 2.5
|
||||
if (m_enhancements.isEmpty())
|
||||
return levelSeen;
|
||||
|
||||
for (int i=0; i<m_enhancements.size(); i++) {
|
||||
// Font style - Level 3.5 only triplet
|
||||
if (m_enhancements.at(i).modeExt() == 0x2e) // Font style
|
||||
return 3;
|
||||
|
||||
@@ -426,9 +432,10 @@ int LevelOnePage::levelRequired() const
|
||||
case 0x22: // G3 character @ Level 1.5
|
||||
case 0x2f: // G2 character
|
||||
case 0x30 ... 0x3f: // G0 character with diacritical
|
||||
levelSeen = qMax(levelSeen, 1);
|
||||
levelSeen = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (levelSeen < 2)
|
||||
switch (m_enhancements.at(i).modeExt()) {
|
||||
// Check for Level 2.5 triplets
|
||||
@@ -436,25 +443,26 @@ int LevelOnePage::levelRequired() const
|
||||
case 0x01: // Full row colour
|
||||
case 0x10 ... 0x13: // Origin Modifer and Object Invocation
|
||||
case 0x15 ... 0x17: // Object Definition
|
||||
// Check if Object Definition is required only at Level 3.5
|
||||
if ((m_enhancements.at(i).address() & 0x18) == 0x10)
|
||||
return 3;
|
||||
else
|
||||
levelSeen = qMax(levelSeen, 2);
|
||||
break;
|
||||
case 0x18: // DRCS Mode
|
||||
// Check if DRCS is required only at Level 3.5
|
||||
if ((m_enhancements.at(i).data() & 0x30) == 0x20)
|
||||
return 3;
|
||||
else
|
||||
levelSeen = qMax(levelSeen, 2);
|
||||
break;
|
||||
case 0x20: // Foreground colour
|
||||
case 0x21: // G1 character
|
||||
case 0x23: // Background colour
|
||||
case 0x27 ... 0x29: // Flash functions, G0 and G2 charset designation, G0 character @ Level 2.5
|
||||
case 0x2b ... 0x2d: // G3 character @ Level 2.5, display attributes, DRCS character
|
||||
levelSeen = qMax(levelSeen, 2);
|
||||
levelSeen = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (levelSeen == 2)
|
||||
switch (m_enhancements.at(i).modeExt()) {
|
||||
// Check for triplets with "required at Level 3.5 only" parameters
|
||||
case 0x15 ... 0x17: // Object Definition
|
||||
if ((m_enhancements.at(i).address() & 0x18) == 0x10)
|
||||
return 3;
|
||||
break;
|
||||
case 0x18: // DRCS Mode
|
||||
if ((m_enhancements.at(i).data() & 0x30) == 0x20)
|
||||
return 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
2
main.cpp
2
main.cpp
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
|
||||
QApplication::setApplicationDisplayName(QApplication::applicationName());
|
||||
QApplication::setOrganizationName("gkmac.co.uk");
|
||||
QApplication::setOrganizationDomain("gkmac.co.uk");
|
||||
QApplication::setApplicationVersion("0.5.4-alpha");
|
||||
QApplication::setApplicationVersion("0.5.5-alpha");
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(QApplication::applicationName());
|
||||
parser.addHelpOption();
|
||||
|
||||
@@ -250,8 +250,8 @@ void TeletextWidget::keyPressEvent(QKeyEvent *event)
|
||||
if (event->key() < 0x01000000) {
|
||||
// A character-typing key was pressed
|
||||
// Try to keymap it, if not keymapped then plain ASCII code (may be) returned
|
||||
char mappedKeyPress = keymapping[m_pageDecode.level1CharSet(m_teletextDocument->cursorRow(), m_teletextDocument->cursorColumn())].value(event->text().at(0), *qPrintable(event->text()));
|
||||
if (mappedKeyPress < 0x20)
|
||||
char mappedKeyPress = keymapping[m_pageDecode.level1CharSet(m_teletextDocument->cursorRow(), m_teletextDocument->cursorColumn())].value(event->text().at(0), *qPrintable(event->text().at(0)));
|
||||
if (mappedKeyPress >= 0x00 && mappedKeyPress <= 0x1f)
|
||||
return;
|
||||
// If outside ASCII map then the character can't be represented by current Level 1 character set
|
||||
// Map it to block character so it doesn't need to be inserted-between later on
|
||||
@@ -386,7 +386,7 @@ void TeletextWidget::keyPressEvent(QKeyEvent *event)
|
||||
case Qt::Key_PageDown:
|
||||
m_teletextDocument->selectSubPagePrevious();
|
||||
break;
|
||||
case Qt::Key_F5:
|
||||
case Qt::Key_F6:
|
||||
m_pageDecode.decodePage();
|
||||
m_pageRender.renderPage(true);
|
||||
update();
|
||||
|
||||
@@ -149,6 +149,34 @@ bool MainWindow::saveAs()
|
||||
return saveFile(fileName);
|
||||
}
|
||||
|
||||
void MainWindow::reload()
|
||||
{
|
||||
if (m_isUntitled)
|
||||
return;
|
||||
|
||||
if (!m_textWidget->document()->undoStack()->isClean()) {
|
||||
const QMessageBox::StandardButton ret = QMessageBox::warning(this, QApplication::applicationDisplayName(), tr("The document \"%1\" has been modified.\nDo you want to discard your changes?").arg(QFileInfo(m_curFile).fileName()), QMessageBox::Discard | QMessageBox::Cancel);
|
||||
|
||||
if (ret != QMessageBox::Discard)
|
||||
return;
|
||||
} else {
|
||||
const QMessageBox::StandardButton ret = QMessageBox::warning(this, QApplication::applicationDisplayName(), tr("Do you want to reload the document \"%1\" from disk?").arg(QFileInfo(m_curFile).fileName()), QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (ret != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
int subPageIndex = m_textWidget->document()->currentSubPageIndex();
|
||||
|
||||
m_textWidget->document()->clear();
|
||||
loadFile(m_curFile);
|
||||
|
||||
if (subPageIndex >= m_textWidget->document()->numberOfSubPages())
|
||||
subPageIndex = m_textWidget->document()->numberOfSubPages()-1;
|
||||
|
||||
m_textWidget->document()->selectSubPageIndex(subPageIndex, true);
|
||||
}
|
||||
|
||||
void MainWindow::exportPNG()
|
||||
{
|
||||
QString exportFileName = QFileDialog::getSaveFileName(this, tr("Export PNG"), QString(), "PNG image (*.png)");
|
||||
@@ -328,6 +356,11 @@ void MainWindow::createActions()
|
||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||
saveAsAct->setStatusTip(tr("Save the document under a new name"));
|
||||
|
||||
const QIcon reloadIcon = QIcon::fromTheme("document-revert");
|
||||
QAction *reloadAct = fileMenu->addAction(reloadIcon, tr("Reload"), this, &MainWindow::reload);
|
||||
reloadAct->setShortcuts(QKeySequence::Refresh);
|
||||
reloadAct->setStatusTip(tr("Reload the document from disk"));
|
||||
|
||||
fileMenu->addSeparator();
|
||||
|
||||
QMenu *recentMenu = fileMenu->addMenu(tr("Recent"));
|
||||
|
||||
@@ -59,6 +59,7 @@ private slots:
|
||||
void open();
|
||||
bool save();
|
||||
bool saveAs();
|
||||
void reload();
|
||||
void exportT42();
|
||||
void exportZXNet();
|
||||
void exportEditTF();
|
||||
|
||||
@@ -354,7 +354,9 @@ void TeletextPageRender::renderPage(bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if (!force || m_decoder->cellFlashMode(r, c) == 0)
|
||||
if (force && m_decoder->cellFlashMode(r, c) != 0)
|
||||
m_decoder->setRefresh(r, c, true);
|
||||
else
|
||||
m_decoder->setRefresh(r, c, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,6 +623,8 @@ X26DockWidget::X26DockWidget(TeletextWidget *parent): QDockWidget(parent)
|
||||
|
||||
x26Layout->addLayout(insertDeleteLayout);
|
||||
|
||||
disableTripletWidgets();
|
||||
|
||||
x26Widget->setLayout(x26Layout);
|
||||
this->setWidget(x26Widget);
|
||||
|
||||
@@ -674,14 +676,48 @@ void X26DockWidget::rowSelected(const QModelIndex ¤t, const QModelIndex &p
|
||||
{
|
||||
Q_UNUSED(previous);
|
||||
|
||||
updateAllRawTripletSpinBoxes(current);
|
||||
updateAllCookedTripletWidgets(current);
|
||||
if (current.isValid()) {
|
||||
updateAllRawTripletSpinBoxes(current);
|
||||
updateAllCookedTripletWidgets(current);
|
||||
} else
|
||||
disableTripletWidgets();
|
||||
}
|
||||
|
||||
void X26DockWidget::disableTripletWidgets()
|
||||
{
|
||||
m_rawTripletAddressSpinBox->setEnabled(false);
|
||||
m_rawTripletDataSpinBox->setEnabled(false);
|
||||
m_rawTripletModeSpinBox->setEnabled(false);
|
||||
m_rawTripletAddressSpinBox->blockSignals(true);
|
||||
m_rawTripletModeSpinBox->blockSignals(true);
|
||||
m_rawTripletDataSpinBox->blockSignals(true);
|
||||
m_rawTripletAddressSpinBox->setValue(0);
|
||||
m_rawTripletModeSpinBox->setValue(0);
|
||||
m_rawTripletDataSpinBox->setValue(0);
|
||||
m_rawTripletAddressSpinBox->blockSignals(false);
|
||||
m_rawTripletModeSpinBox->blockSignals(false);
|
||||
m_rawTripletDataSpinBox->blockSignals(false);
|
||||
|
||||
m_cookedRowSpinBox->setEnabled(false);
|
||||
m_cookedColumnSpinBox->setEnabled(false);
|
||||
m_cookedRowSpinBox->blockSignals(true);
|
||||
m_cookedColumnSpinBox->blockSignals(true);
|
||||
m_cookedRowSpinBox->setValue(1);
|
||||
m_cookedColumnSpinBox->setValue(0);
|
||||
m_cookedRowSpinBox->blockSignals(false);
|
||||
m_cookedColumnSpinBox->blockSignals(false);
|
||||
|
||||
m_cookedModePushButton->setEnabled(false);
|
||||
m_cookedModePushButton->setText(QString());
|
||||
|
||||
m_tripletParameterStackedLayout->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void X26DockWidget::updateAllCookedTripletWidgets(const QModelIndex &index)
|
||||
{
|
||||
const int modeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
|
||||
|
||||
m_cookedModePushButton->setEnabled(true);
|
||||
m_cookedModePushButton->setText(m_x26Model->modeTripletName(modeExt));
|
||||
|
||||
switch (modeExt) {
|
||||
|
||||
@@ -117,6 +117,9 @@ private:
|
||||
QPushButton *m_insertBeforePushButton, *m_insertAfterPushButton, *m_insertCopyPushButton, *m_deletePushButton;
|
||||
|
||||
TeletextWidget *m_parentMainWidget;
|
||||
|
||||
void disableTripletWidgets();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
16
x26model.cpp
16
x26model.cpp
@@ -65,11 +65,19 @@ QVariant X26Model::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
|
||||
// Error colours from KDE Plasma Breeze (light) theme
|
||||
if (role == Qt::ForegroundRole && triplet.error() != X26Triplet::NoError && index.column() == m_tripletErrors[triplet.error()].columnHighlight)
|
||||
return QColor(252, 252, 252);
|
||||
if (role == Qt::ForegroundRole) {
|
||||
if (triplet.error() != X26Triplet::NoError && index.column() == m_tripletErrors[triplet.error()].columnHighlight)
|
||||
return QColor(252, 252, 252);
|
||||
else if ((index.column() == 2 && triplet.reservedMode()) || (index.column() == 3 && triplet.reservedData()))
|
||||
return QColor(35, 38, 39);
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole && triplet.error() != X26Triplet::NoError && index.column() == m_tripletErrors[triplet.error()].columnHighlight)
|
||||
return QColor(218, 68, 63);
|
||||
if (role == Qt::BackgroundRole) {
|
||||
if (triplet.error() != X26Triplet::NoError && index.column() == m_tripletErrors[triplet.error()].columnHighlight)
|
||||
return QColor(218, 68, 63);
|
||||
else if ((index.column() == 2 && triplet.reservedMode()) || (index.column() == 3 && triplet.reservedData()))
|
||||
return QColor(246, 116, 0);
|
||||
}
|
||||
|
||||
if (role == Qt::ToolTipRole && triplet.error() != X26Triplet::NoError)
|
||||
return m_tripletErrors[triplet.error()].message;
|
||||
|
||||
@@ -77,30 +77,45 @@ void X26TripletList::updateInternalData()
|
||||
for (int i=0; i < m_list.size(); i++) {
|
||||
triplet = &m_list[i];
|
||||
triplet->m_error = X26Triplet::NoError;
|
||||
triplet->m_reservedMode = false;
|
||||
triplet->m_reservedData = false;
|
||||
|
||||
if (triplet->isRowTriplet()) {
|
||||
switch (triplet->modeExt()) {
|
||||
case 0x00: // Full screen colour
|
||||
if (activePosition.isDeployed())
|
||||
// TODO more specific error needed
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedUp;
|
||||
if (triplet->m_data & 0x60)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x01: // Full row colour
|
||||
if (!activePosition.setRow(triplet->addressRow()))
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedUp;
|
||||
if ((triplet->m_data & 0x60) != 0x00 && (triplet->m_data & 0x60) != 0x60)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x04: // Set Active Position;
|
||||
if (!activePosition.setRow(triplet->addressRow()))
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedUp;
|
||||
else if (triplet->data() >= 40 || !activePosition.setColumn(triplet->data()))
|
||||
else if (triplet->data() >= 40)
|
||||
// FIXME data column highlighted?
|
||||
triplet->m_reservedData = true;
|
||||
else if (!activePosition.setColumn(triplet->data()))
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedLeft;
|
||||
break;
|
||||
case 0x07: // Address row 0
|
||||
if (activePosition.isDeployed())
|
||||
if (triplet->m_address != 63)
|
||||
// FIXME data column highlighted?
|
||||
triplet->m_reservedData = true;
|
||||
else if (activePosition.isDeployed())
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedUp;
|
||||
else {
|
||||
activePosition.setRow(0);
|
||||
activePosition.setColumn(8);
|
||||
}
|
||||
if ((triplet->m_data & 0x60) != 0x00 && (triplet->m_data & 0x60) != 0x60)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x10: // Origin Modifier
|
||||
if (i == m_list.size()-1 ||
|
||||
@@ -125,11 +140,45 @@ void X26TripletList::updateInternalData()
|
||||
// otherwise the object won't appear
|
||||
triplet->setObjectLocalIndex(i);
|
||||
break;
|
||||
case 0x18: // DRCS mode
|
||||
if ((triplet->m_data & 0x30) == 0x00)
|
||||
triplet->m_reservedData = true;
|
||||
case 0x1f: // Termination marker
|
||||
case 0x08 ... 0x0d: // PDC
|
||||
break;
|
||||
default:
|
||||
triplet->m_reservedMode = true;
|
||||
};
|
||||
// Column triplet: make sure that PDC and reserved triplets don't affect the Active Position
|
||||
} else if (triplet->modeExt() != 0x24 && triplet->modeExt() != 0x25 && triplet->modeExt() != 0x26 && triplet->modeExt() != 0x2a)
|
||||
if (!activePosition.setColumn(triplet->addressColumn()))
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedLeft;
|
||||
// Column triplet: all triplets modes except PDC and reserved move the Active Position
|
||||
} else if (triplet->modeExt() == 0x24 || triplet->modeExt() == 0x25 || triplet->modeExt() == 0x2a)
|
||||
triplet->m_reservedMode = true;
|
||||
else if (triplet->modeExt() != 0x26 && !activePosition.setColumn(triplet->addressColumn()))
|
||||
triplet->m_error = X26Triplet::ActivePositionMovedLeft;
|
||||
else
|
||||
switch (triplet->modeExt()) {
|
||||
case 0x20: // Foreground colour
|
||||
case 0x23: // Foreground colour
|
||||
if (triplet->m_data & 0x60)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x21: // G1 mosaic character
|
||||
case 0x22: // G3 mosaic character at level 1.5
|
||||
case 0x29: // G0 character
|
||||
case 0x2b: // G3 mosaic character at level >=2.5
|
||||
case 0x2f ... 0x3f: // G2 character or G0 diacritical mark
|
||||
if (triplet->m_data < 0x20)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x27: // Additional flash functions
|
||||
if (triplet->m_data >= 0x18)
|
||||
triplet->m_reservedData = true;
|
||||
break;
|
||||
case 0x2d: // DRCS character
|
||||
if ((triplet->m_data & 0x3f) >= 48)
|
||||
// Should really be an error?
|
||||
triplet->m_reservedData = true;
|
||||
}
|
||||
|
||||
triplet->m_activePositionRow = activePosition.row();
|
||||
triplet->m_activePositionColumn = activePosition.column();
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ public:
|
||||
int activePositionRow() const { return m_activePositionRow; }
|
||||
int activePositionColumn() const { return m_activePositionColumn; }
|
||||
X26TripletError error() const { return m_error; }
|
||||
bool reservedMode() const { return m_reservedMode; }
|
||||
bool reservedData() const { return m_reservedData; }
|
||||
|
||||
friend class X26TripletList;
|
||||
|
||||
@@ -70,6 +72,8 @@ private:
|
||||
int m_activePositionRow = -1;
|
||||
int m_activePositionColumn = -1;
|
||||
X26TripletError m_error = NoError;
|
||||
bool m_reservedMode = false;
|
||||
bool m_reservedData = false;
|
||||
};
|
||||
|
||||
class X26TripletList
|
||||
|
||||
Reference in New Issue
Block a user