diff --git a/x26model.cpp b/x26model.cpp index 7bed1eb..82b516c 100644 --- a/x26model.cpp +++ b/x26model.cpp @@ -64,6 +64,16 @@ QVariant X26Model::data(const QModelIndex &index, int role) const return QVariant(); } + // 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::BackgroundRole && triplet.error() != X26Triplet::NoError && index.column() == m_tripletErrors[triplet.error()].columnHighlight) + return QColor(218, 68, 63); + + if (role == Qt::ToolTipRole && triplet.error() != X26Triplet::NoError) + return m_tripletErrors[triplet.error()].message; + if (role == Qt::DisplayRole || role == Qt::EditRole) switch (index.column()) { case 0: @@ -94,7 +104,7 @@ QVariant X26Model::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { if (index.column() == 2) - return (modeTripletName[triplet.modeExt()]); + return (m_modeTripletName[triplet.modeExt()]); // Column 3 - describe effects of data/address triplet parameters in plain English switch (triplet.modeExt()) { case 0x01: // Full row colour diff --git a/x26model.h b/x26model.h index bf4eee8..99e511c 100644 --- a/x26model.h +++ b/x26model.h @@ -51,87 +51,98 @@ private: TeletextWidget *m_parentMainWidget; bool m_listLoaded; TeletextFontBitmap m_fontBitmap; -}; -static const QString modeTripletName[64] { - // Row triplet modes - "Full screen colour", - "Full row colour", - "Reserved 0x02", - "Reserved 0x03", + const QString m_modeTripletName[64] { + // Row triplet modes + "Full screen colour", + "Full row colour", + "Reserved 0x02", + "Reserved 0x03", - "Set Active Position", - "Reserved 0x05", - "Reserved 0x06", - "Address row 0", + "Set Active Position", + "Reserved 0x05", + "Reserved 0x06", + "Address row 0", - "PDC origin, source", - "PDC month and day", - "PDC cursor and start hour", - "PDC cursor and end hour", + "PDC origin, source", + "PDC month and day", + "PDC cursor and start hour", + "PDC cursor and end hour", - "PDC cursor local offset", - "PDC series ID and code", - "Reserved 0x0e", - "Reserved 0x0f", + "PDC cursor local offset", + "PDC series ID and code", + "Reserved 0x0e", + "Reserved 0x0f", - "Origin modifier", - "Invoke active object", - "Invoke adaptive object", - "Invoke passive object", + "Origin modifier", + "Invoke active object", + "Invoke adaptive object", + "Invoke passive object", - "Reserved 0x14", - "Define active object", - "Define adaptive object", - "Define passive object", + "Reserved 0x14", + "Define active object", + "Define adaptive object", + "Define passive object", - "DRCS mode", - "Reserved 0x19", - "Reserved 0x1a", - "Reserved 0x1b", + "DRCS mode", + "Reserved 0x19", + "Reserved 0x1a", + "Reserved 0x1b", - "Reserved 0x1c", - "Reserved 0x1d", - "Reserved 0x1e", - "Termination marker", + "Reserved 0x1c", + "Reserved 0x1d", + "Reserved 0x1e", + "Termination marker", - // Column triplet modes - "Foreground colour", - "G1 character", - "G3 character, level 1.5", - "Background colour", + // Column triplet modes + "Foreground colour", + "G1 character", + "G3 character, level 1.5", + "Background colour", - "Reserved 0x04", - "Reserved 0x05", - "PDC cursor, start end min", - "Additional flash functions", + "Reserved 0x04", + "Reserved 0x05", + "PDC cursor, start end min", + "Additional flash functions", - "Modified G0/G2 character set", - "G0 character", - "Reserved 0x0a", - "G3 character, level 2.5", + "Modified G0/G2 character set", + "G0 character", + "Reserved 0x0a", + "G3 character, level 2.5", - "Display attributes", - "DRCS character", - "Font style", - "G2 character", + "Display attributes", + "DRCS character", + "Font style", + "G2 character", - "G0 character no diacritical", - "G0 character diacritical 1", - "G0 character diacritical 2", - "G0 character diacritical 3", - "G0 character diacritical 4", - "G0 character diacritical 5", - "G0 character diacritical 6", - "G0 character diacritical 7", - "G0 character diacritical 8", - "G0 character diacritical 9", - "G0 character diacritical A", - "G0 character diacritical B", - "G0 character diacritical C", - "G0 character diacritical D", - "G0 character diacritical E", - "G0 character diacritical F" + "G0 character no diacritical", + "G0 character diacritical 1", + "G0 character diacritical 2", + "G0 character diacritical 3", + "G0 character diacritical 4", + "G0 character diacritical 5", + "G0 character diacritical 6", + "G0 character diacritical 7", + "G0 character diacritical 8", + "G0 character diacritical 9", + "G0 character diacritical A", + "G0 character diacritical B", + "G0 character diacritical C", + "G0 character diacritical D", + "G0 character diacritical E", + "G0 character diacritical F" + }; + + struct tripletErrorShow { + QString message; + int columnHighlight; + }; + + const tripletErrorShow m_tripletErrors[3] { + { "", 0 }, // No error + { "Active Position can't move up", 0 }, + { "Active Position can't move left within row", 1 } + }; }; #endif diff --git a/x26triplets.cpp b/x26triplets.cpp index fcad995..286277a 100644 --- a/x26triplets.cpp +++ b/x26triplets.cpp @@ -52,22 +52,117 @@ void X26Triplet::setAddressColumn(int addressColumn) } +void X26TripletList::updateInternalData(int r) +{ + ActivePosition activePosition; + X26Triplet *triplet; + + if (r != 0) { + activePosition.setRow(m_list[r-1].m_activePositionRow); + activePosition.setColumn(m_list[r-1].m_activePositionColumn); + } + + for (int i = r; i < m_list.size(); i++) { + triplet = &m_list[i]; + triplet->m_error = X26Triplet::NoError; + if (triplet->isRowTriplet()) { + switch (m_list.at(i).modeExt()) { + case 0x00: // Full screen colour + if (activePosition.isDeployed()) + // TODO more specific error needed + triplet->m_error = X26Triplet::ActivePositionMovedUp; + break; + case 0x01: // Full row colour + if (!activePosition.setRow(triplet->addressRow())) + triplet->m_error = X26Triplet::ActivePositionMovedUp; + 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())) + triplet->m_error = X26Triplet::ActivePositionMovedLeft; + break; + case 0x07: // Address row 0 + if (activePosition.isDeployed()) + triplet->m_error = X26Triplet::ActivePositionMovedUp; + else { + activePosition.setRow(0); + activePosition.setColumn(8); + } + break; + case 0x15 ... 0x17: // Define Object + activePosition.reset(); + }; + // 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; + triplet->m_activePositionRow = activePosition.row(); + triplet->m_activePositionColumn = activePosition.column(); + } +} + void X26TripletList::append(const X26Triplet &value) { m_list.append(value); + updateInternalData(m_list.size()-1); } void X26TripletList::insert(int i, const X26Triplet &value) { m_list.insert(i, value); + updateInternalData(i); } void X26TripletList::removeAt(int i) { m_list.removeAt(i); + if (m_list.size() != 0 && i < m_list.size()) + updateInternalData(i); } void X26TripletList::replace(int i, const X26Triplet &value) { m_list.replace(i, value); + updateInternalData(i); } + + +X26TripletList::ActivePosition::ActivePosition() +{ + m_row = m_column = -1; +} + +void X26TripletList::ActivePosition::reset() +{ + m_row = m_column = -1; +} + +bool X26TripletList::ActivePosition::setRow(int row) +{ + if (row < m_row) + return false; + if (row > m_row) { + m_row = row; + m_column = -1; + } + return true; +} + +bool X26TripletList::ActivePosition::setColumn(int column) +{ + if (column < m_column) + return false; + if (m_row == -1 and column >= 0) + m_row = 0; + m_column = column; + return true; +} +/* +bool X26TripletList::ActivePosition::setRowAndColumn(int newRow, int newColumn) +{ + if (!setRow(newRow)) + return false; + return setColumn(newColumn); +} +*/ diff --git a/x26triplets.h b/x26triplets.h index 422ca0e..fd1a625 100644 --- a/x26triplets.h +++ b/x26triplets.h @@ -25,6 +25,8 @@ class X26Triplet { public: + enum X26TripletError { NoError, ActivePositionMovedUp, ActivePositionMovedLeft }; + X26Triplet() {} // X26Triplet(const X26Triplet &other); @@ -46,8 +48,17 @@ public: void setAddressRow(int); void setAddressColumn(int); + int activePositionRow() const { return m_activePositionRow; } + int activePositionColumn() const { return m_activePositionColumn; } + X26TripletError error() const { return m_error; } + + friend class X26TripletList; + private: int m_address, m_mode, m_data; + int m_activePositionRow = -1; + int m_activePositionColumn = -1; + X26TripletError m_error = NoError; }; class X26TripletList @@ -66,7 +77,27 @@ public: int size() const { return m_list.size(); } private: + void updateInternalData(int); + QList m_list; + + class ActivePosition + { + public: + ActivePosition(); + void reset(); +// int row() const { return (m_row == -1) ? 0 : m_row; } +// int column() const { return (m_column == -1) ? 0 : m_column; } + int row() const { return m_row; } + int column() const { return m_column; } + bool isDeployed() const { return m_row != -1; } + bool setRow(int); + bool setColumn(int); +// bool setRowAndColumn(int, int); + + private: + int m_row, m_column; + }; }; #endif