diff --git a/hamming.h b/hamming.h new file mode 100644 index 0000000..6d272c1 --- /dev/null +++ b/hamming.h @@ -0,0 +1,179 @@ +#ifndef HAMMING_H +#define HAMMING_H + +// Hamming 8/4 decoding table +// decoded_value = hamming_8_4_decode[encoded_value] +// 0xff - double bit error that can't be corrected +const unsigned char hamming_8_4_decode[256] = { + 0x01, 0xff, 0x01, 0x01, 0xff, 0x00, 0x01, 0xff, + 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, + 0xff, 0x00, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00, + 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff, + 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07, + 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x07, + 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff, + 0x06, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, + 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09, + 0x02, 0x02, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, + 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff, + 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03, + 0x04, 0xff, 0xff, 0x05, 0x04, 0x04, 0x04, 0xff, + 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, + 0xff, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, 0x05, + 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, + 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09, + 0x0a, 0xff, 0xff, 0x0b, 0x0a, 0x0a, 0x0a, 0xff, + 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff, + 0xff, 0x0b, 0x0b, 0x0b, 0x0a, 0xff, 0xff, 0x0b, + 0x0c, 0x0c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff, + 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, + 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x0d, 0x0d, + 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, + 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x09, + 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, + 0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09, + 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff, + 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09, + 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, + 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff, + 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e +}; + +const unsigned char hamming_24_18_parities[3][256] = { + { // Parities of first byte + 0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20, + 0x24, 0x05, 0x06, 0x27, 0x07, 0x26, 0x25, 0x04, + 0x25, 0x04, 0x07, 0x26, 0x06, 0x27, 0x24, 0x05, + 0x01, 0x20, 0x23, 0x02, 0x22, 0x03, 0x00, 0x21, + 0x26, 0x07, 0x04, 0x25, 0x05, 0x24, 0x27, 0x06, + 0x02, 0x23, 0x20, 0x01, 0x21, 0x00, 0x03, 0x22, + 0x03, 0x22, 0x21, 0x00, 0x20, 0x01, 0x02, 0x23, + 0x27, 0x06, 0x05, 0x24, 0x04, 0x25, 0x26, 0x07, + 0x27, 0x06, 0x05, 0x24, 0x04, 0x25, 0x26, 0x07, + 0x03, 0x22, 0x21, 0x00, 0x20, 0x01, 0x02, 0x23, + 0x02, 0x23, 0x20, 0x01, 0x21, 0x00, 0x03, 0x22, + 0x26, 0x07, 0x04, 0x25, 0x05, 0x24, 0x27, 0x06, + 0x01, 0x20, 0x23, 0x02, 0x22, 0x03, 0x00, 0x21, + 0x25, 0x04, 0x07, 0x26, 0x06, 0x27, 0x24, 0x05, + 0x24, 0x05, 0x06, 0x27, 0x07, 0x26, 0x25, 0x04, + 0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20, + 0x28, 0x09, 0x0a, 0x2b, 0x0b, 0x2a, 0x29, 0x08, + 0x0c, 0x2d, 0x2e, 0x0f, 0x2f, 0x0e, 0x0d, 0x2c, + 0x0d, 0x2c, 0x2f, 0x0e, 0x2e, 0x0f, 0x0c, 0x2d, + 0x29, 0x08, 0x0b, 0x2a, 0x0a, 0x2b, 0x28, 0x09, + 0x0e, 0x2f, 0x2c, 0x0d, 0x2d, 0x0c, 0x0f, 0x2e, + 0x2a, 0x0b, 0x08, 0x29, 0x09, 0x28, 0x2b, 0x0a, + 0x2b, 0x0a, 0x09, 0x28, 0x08, 0x29, 0x2a, 0x0b, + 0x0f, 0x2e, 0x2d, 0x0c, 0x2c, 0x0d, 0x0e, 0x2f, + 0x0f, 0x2e, 0x2d, 0x0c, 0x2c, 0x0d, 0x0e, 0x2f, + 0x2b, 0x0a, 0x09, 0x28, 0x08, 0x29, 0x2a, 0x0b, + 0x2a, 0x0b, 0x08, 0x29, 0x09, 0x28, 0x2b, 0x0a, + 0x0e, 0x2f, 0x2c, 0x0d, 0x2d, 0x0c, 0x0f, 0x2e, + 0x29, 0x08, 0x0b, 0x2a, 0x0a, 0x2b, 0x28, 0x09, + 0x0d, 0x2c, 0x2f, 0x0e, 0x2e, 0x0f, 0x0c, 0x2d, + 0x0c, 0x2d, 0x2e, 0x0f, 0x2f, 0x0e, 0x0d, 0x2c, + 0x28, 0x09, 0x0a, 0x2b, 0x0b, 0x2a, 0x29, 0x08 + }, + { // Parities of second byte + 0x00, 0x29, 0x2a, 0x03, 0x2b, 0x02, 0x01, 0x28, + 0x2c, 0x05, 0x06, 0x2f, 0x07, 0x2e, 0x2d, 0x04, + 0x2d, 0x04, 0x07, 0x2e, 0x06, 0x2f, 0x2c, 0x05, + 0x01, 0x28, 0x2b, 0x02, 0x2a, 0x03, 0x00, 0x29, + 0x2e, 0x07, 0x04, 0x2d, 0x05, 0x2c, 0x2f, 0x06, + 0x02, 0x2b, 0x28, 0x01, 0x29, 0x00, 0x03, 0x2a, + 0x03, 0x2a, 0x29, 0x00, 0x28, 0x01, 0x02, 0x2b, + 0x2f, 0x06, 0x05, 0x2c, 0x04, 0x2d, 0x2e, 0x07, + 0x2f, 0x06, 0x05, 0x2c, 0x04, 0x2d, 0x2e, 0x07, + 0x03, 0x2a, 0x29, 0x00, 0x28, 0x01, 0x02, 0x2b, + 0x02, 0x2b, 0x28, 0x01, 0x29, 0x00, 0x03, 0x2a, + 0x2e, 0x07, 0x04, 0x2d, 0x05, 0x2c, 0x2f, 0x06, + 0x01, 0x28, 0x2b, 0x02, 0x2a, 0x03, 0x00, 0x29, + 0x2d, 0x04, 0x07, 0x2e, 0x06, 0x2f, 0x2c, 0x05, + 0x2c, 0x05, 0x06, 0x2f, 0x07, 0x2e, 0x2d, 0x04, + 0x00, 0x29, 0x2a, 0x03, 0x2b, 0x02, 0x01, 0x28, + 0x30, 0x19, 0x1a, 0x33, 0x1b, 0x32, 0x31, 0x18, + 0x1c, 0x35, 0x36, 0x1f, 0x37, 0x1e, 0x1d, 0x34, + 0x1d, 0x34, 0x37, 0x1e, 0x36, 0x1f, 0x1c, 0x35, + 0x31, 0x18, 0x1b, 0x32, 0x1a, 0x33, 0x30, 0x19, + 0x1e, 0x37, 0x34, 0x1d, 0x35, 0x1c, 0x1f, 0x36, + 0x32, 0x1b, 0x18, 0x31, 0x19, 0x30, 0x33, 0x1a, + 0x33, 0x1a, 0x19, 0x30, 0x18, 0x31, 0x32, 0x1b, + 0x1f, 0x36, 0x35, 0x1c, 0x34, 0x1d, 0x1e, 0x37, + 0x1f, 0x36, 0x35, 0x1c, 0x34, 0x1d, 0x1e, 0x37, + 0x33, 0x1a, 0x19, 0x30, 0x18, 0x31, 0x32, 0x1b, + 0x32, 0x1b, 0x18, 0x31, 0x19, 0x30, 0x33, 0x1a, + 0x1e, 0x37, 0x34, 0x1d, 0x35, 0x1c, 0x1f, 0x36, + 0x31, 0x18, 0x1b, 0x32, 0x1a, 0x33, 0x30, 0x19, + 0x1d, 0x34, 0x37, 0x1e, 0x36, 0x1f, 0x1c, 0x35, + 0x1c, 0x35, 0x36, 0x1f, 0x37, 0x1e, 0x1d, 0x34, + 0x30, 0x19, 0x1a, 0x33, 0x1b, 0x32, 0x31, 0x18 + }, + { // Parities of third byte + 0x3f, 0x0e, 0x0d, 0x3c, 0x0c, 0x3d, 0x3e, 0x0f, + 0x0b, 0x3a, 0x39, 0x08, 0x38, 0x09, 0x0a, 0x3b, + 0x0a, 0x3b, 0x38, 0x09, 0x39, 0x08, 0x0b, 0x3a, + 0x3e, 0x0f, 0x0c, 0x3d, 0x0d, 0x3c, 0x3f, 0x0e, + 0x09, 0x38, 0x3b, 0x0a, 0x3a, 0x0b, 0x08, 0x39, + 0x3d, 0x0c, 0x0f, 0x3e, 0x0e, 0x3f, 0x3c, 0x0d, + 0x3c, 0x0d, 0x0e, 0x3f, 0x0f, 0x3e, 0x3d, 0x0c, + 0x08, 0x39, 0x3a, 0x0b, 0x3b, 0x0a, 0x09, 0x38, + 0x08, 0x39, 0x3a, 0x0b, 0x3b, 0x0a, 0x09, 0x38, + 0x3c, 0x0d, 0x0e, 0x3f, 0x0f, 0x3e, 0x3d, 0x0c, + 0x3d, 0x0c, 0x0f, 0x3e, 0x0e, 0x3f, 0x3c, 0x0d, + 0x09, 0x38, 0x3b, 0x0a, 0x3a, 0x0b, 0x08, 0x39, + 0x3e, 0x0f, 0x0c, 0x3d, 0x0d, 0x3c, 0x3f, 0x0e, + 0x0a, 0x3b, 0x38, 0x09, 0x39, 0x08, 0x0b, 0x3a, + 0x0b, 0x3a, 0x39, 0x08, 0x38, 0x09, 0x0a, 0x3b, + 0x3f, 0x0e, 0x0d, 0x3c, 0x0c, 0x3d, 0x3e, 0x0f, + 0x1f, 0x2e, 0x2d, 0x1c, 0x2c, 0x1d, 0x1e, 0x2f, + 0x2b, 0x1a, 0x19, 0x28, 0x18, 0x29, 0x2a, 0x1b, + 0x2a, 0x1b, 0x18, 0x29, 0x19, 0x28, 0x2b, 0x1a, + 0x1e, 0x2f, 0x2c, 0x1d, 0x2d, 0x1c, 0x1f, 0x2e, + 0x29, 0x18, 0x1b, 0x2a, 0x1a, 0x2b, 0x28, 0x19, + 0x1d, 0x2c, 0x2f, 0x1e, 0x2e, 0x1f, 0x1c, 0x2d, + 0x1c, 0x2d, 0x2e, 0x1f, 0x2f, 0x1e, 0x1d, 0x2c, + 0x28, 0x19, 0x1a, 0x2b, 0x1b, 0x2a, 0x29, 0x18, + 0x28, 0x19, 0x1a, 0x2b, 0x1b, 0x2a, 0x29, 0x18, + 0x1c, 0x2d, 0x2e, 0x1f, 0x2f, 0x1e, 0x1d, 0x2c, + 0x1d, 0x2c, 0x2f, 0x1e, 0x2e, 0x1f, 0x1c, 0x2d, + 0x29, 0x18, 0x1b, 0x2a, 0x1a, 0x2b, 0x28, 0x19, + 0x1e, 0x2f, 0x2c, 0x1d, 0x2d, 0x1c, 0x1f, 0x2e, + 0x2a, 0x1b, 0x18, 0x29, 0x19, 0x28, 0x2b, 0x1a, + 0x2b, 0x1a, 0x19, 0x28, 0x18, 0x29, 0x2a, 0x1b, + 0x1f, 0x2e, 0x2d, 0x1c, 0x2c, 0x1d, 0x1e, 0x2f + } +}; + +static const unsigned char hamming_24_18_decode_d1_d4[64] = { + 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, + 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07, + 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, + 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07, + 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f +}; + +// Mapping from parity checks in hamming_24_18_parities to incorrect bit +// 0x80000000 - double bit error that can't be corrected +static const unsigned int hamming_24_18_decode_correct [64] = { + 0x00000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000002, 0x00000004, 0x00000008, + 0x00000000, 0x00000010, 0x00000020, 0x00000040, + 0x00000080, 0x00000100, 0x00000200, 0x00000400, + 0x00000000, 0x00000800, 0x00001000, 0x00002000, + 0x00004000, 0x00008000, 0x00010000, 0x00020000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000 +}; + +#endif diff --git a/loadsave.cpp b/loadsave.cpp index e46ceb6..02a31d7 100644 --- a/loadsave.cpp +++ b/loadsave.cpp @@ -26,6 +26,7 @@ #include #include "document.h" +#include "hamming.h" #include "levelonepage.h" #include "pagebase.h" @@ -166,6 +167,195 @@ void loadTTI(QFile *inFile, TeletextDocument *document) } } +void importT42(QFile *inFile, TeletextDocument *document) +{ + unsigned char inLine[42]; + int readMagazineNumber, readPacketNumber; + int foundMagazineNumber = -1; + int foundPageNumber = -1; + bool firstPacket0Found = false; + bool pageBodyPacketsFound = false; + + for (;;) { + if (inFile->read((char *)inLine, 42) != 42) + // Reached end of .t42 file, or less than 42 bytes left + break; + + // Magazine and packet numbers + inLine[0] = hamming_8_4_decode[inLine[0]]; + inLine[1] = hamming_8_4_decode[inLine[1]]; + if (inLine[0] == 0xff || inLine[1] == 0xff) + // Error decoding magazine or packet number + continue; + readMagazineNumber = inLine[0] & 0x07; + readPacketNumber = (inLine[0] >> 3) | (inLine[1] << 1); + + if (readPacketNumber == 0) { + // Hamming decode page number, subcodes and control bits + for (int i=2; i<10; i++) + inLine[i] = hamming_8_4_decode[inLine[i]]; + // See if the page number is valid + if (inLine[2] == 0xff || inLine[3] == 0xff) + // Error decoding page number + continue; + + const int readPageNumber = (inLine[3] << 4) | inLine[2]; + + if (readPageNumber == 0xff) + // Time filling header + continue; + + // A second or subsequent X/0 has been found + if (firstPacket0Found) { + if (readMagazineNumber != foundMagazineNumber) + // Packet from different magazine broadcast in parallel mode + continue; + if ((readPageNumber == foundPageNumber) && pageBodyPacketsFound) + // X/0 with same page number found after page body packets loaded - assume end of page + break; + if (readPageNumber != foundPageNumber) { + // More than one page in .t42 file - end of current page reached + qDebug("More than one page in .t42 file"); + break; + } + // Could get here if X/0 with same page number was found with no body packets inbetween + continue; + } else { + // First X/0 found + foundMagazineNumber = readMagazineNumber; + foundPageNumber = readPageNumber; + firstPacket0Found = true; + + document->setPageNumber((foundMagazineNumber << 8) | foundPageNumber); + + document->subPage(0)->setControlBit(PageBase::C4ErasePage, inLine[5] & 0x08); + document->subPage(0)->setControlBit(PageBase::C5Newsflash, inLine[7] & 0x04); + document->subPage(0)->setControlBit(PageBase::C6Subtitle, inLine[7] & 0x08); + for (int i=0; i<4; i++) + document->subPage(0)->setControlBit(PageBase::C7SuppressHeader+i, inLine[8] & (1 << i)); + document->subPage(0)->setControlBit(PageBase::C11SerialMagazine, inLine[9] & 0x01); + document->subPage(0)->setControlBit(PageBase::C12NOS, inLine[9] & 0x08); + document->subPage(0)->setControlBit(PageBase::C13NOS, inLine[9] & 0x04); + document->subPage(0)->setControlBit(PageBase::C14NOS, inLine[9] & 0x02); + + continue; + } + } + + // No X/0 has been found yet, keep looking for one + if (!firstPacket0Found) + continue; + + // Disregard whole-magazine packets + if (readPacketNumber > 28) + continue; + + // We get here when a page-body packet belonging to the found X/0 header was found + pageBodyPacketsFound = true; + + // At the moment this only loads a Level One Page properly + // because it assumes X/1 to X/25 is odd partity + if (readPacketNumber < 25) { + for (int i=2; i<42; i++) + // TODO - obey odd parity? + inLine[i] &= 0x7f; + document->subPage(0)->setPacket(readPacketNumber, QByteArray((const char *)&inLine[2], 40)); + continue; + } + + // X/26, X/27 or X/28 + int readDesignationCode = hamming_8_4_decode[inLine[2]]; + + if (readDesignationCode == 0xff) + // Error decoding designation code + continue; + + if (readPacketNumber == 27 && readDesignationCode < 4) { + // X/27/0 to X/27/3 for Editorial Linking + // Decode Hamming 8/4 on each of the six links, checking for errors on the way + for (int i=0; i<6; i++) { + bool decodingError = false; + const int b = 3 + i*6; // First byte of this link + + for (int j=0; j<6; j++) { + inLine[b+j] = hamming_8_4_decode[inLine[b+j]]; + if (inLine[b+j] == 0xff) { + decodingError = true; + break; + } + } + + if (decodingError) { + // Error found in at least one byte of the link + // Neutralise the whole link to same magazine, page FF, subcode 3F7F + qDebug("X/27/%d link %d decoding error", readDesignationCode, i); + inLine[b] = 0xf; + inLine[b+1] = 0xf; + inLine[b+2] = 0xf; + inLine[b+3] = 0x7; + inLine[b+4] = 0xf; + inLine[b+5] = 0x3; + } + } + document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&inLine[2], 40)); + + continue; + } + + // X/26, or X/27/4 to X/27/15, or X/28 + // Decode Hamming 24/18 + for (int i=0; i<13; i++) { + const int b = 3 + i*3; // First byte of triplet + + const int p0 = inLine[b]; + const int p1 = inLine[b+1]; + const int p2 = inLine[b+2]; + + unsigned int D1_D4; + unsigned int D5_D11; + unsigned int D12_D18; + unsigned int ABCDEF; + int32_t d; + + D1_D4 = hamming_24_18_decode_d1_d4[p0 >> 2]; + D5_D11 = p1 & 0x7f; + D12_D18 = p2 & 0x7f; + + d = D1_D4 | (D5_D11 << 4) | (D12_D18 << 11); + + ABCDEF = (hamming_24_18_parities[0][p0] ^ hamming_24_18_parities[1][p1] ^ hamming_24_18_parities[2][p2]); + + d ^= (int)hamming_24_18_decode_correct[ABCDEF]; + + if ((d & 0x80000000) == 0x80000000) { + // Error decoding Hamming 24/18 + qDebug("X/%d/%d triplet %d decoding error", readPacketNumber, readDesignationCode, i); + if (readPacketNumber == 26) { + // Enhancements packet, set to "dummy" Address 41, Mode 0x1e, Data 0 + inLine[b] = 41; + inLine[b+1] = 0x1e; + inLine[b+2] = 0; + } else { + // Zero out whole decoded triplet, bound to make things go wrong... + inLine[b] = 0x00; + inLine[b+1] = 0x00; + inLine[b+2] = 0x00; + } + } else { + inLine[b] = d & 0x0003f; + inLine[b+1] = (d & 0x00fc0) >> 6; + inLine[b+2] = d >> 12; + } + } + document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&inLine[2], 40)); + } + + if (!firstPacket0Found) + qDebug("No X/0 found"); + else if (!pageBodyPacketsFound) + qDebug("X/0 found, but no page body packets were found"); +} + // Used by saveTTI and HashString int controlBitsToPS(PageBase *subPage) { diff --git a/loadsave.h b/loadsave.h index b3d7d29..29aa29a 100644 --- a/loadsave.h +++ b/loadsave.h @@ -30,7 +30,8 @@ #include "levelonepage.h" #include "pagebase.h" -void loadTTI(QFile *inFile, TeletextDocument *document); +void loadTTI(QFile *, TeletextDocument *); +void importT42(QFile *, TeletextDocument *); int controlBitsToPS(PageBase *); diff --git a/mainwindow.cpp b/mainwindow.cpp index 294567b..dabc4e1 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -844,14 +844,27 @@ void MainWindow::loadFile(const QString &fileName) int levelSeen; QFile file(fileName); - if (!file.open(QFile::ReadOnly | QFile::Text)) { + const QFileInfo fileInfo(file); + QIODevice::OpenMode fileOpenMode; + + if (fileInfo.suffix() == "t42") + fileOpenMode = QFile::ReadOnly; + else + fileOpenMode = QFile::ReadOnly | QFile::Text; + + if (!file.open(fileOpenMode)) { QMessageBox::warning(this, tr("QTeletextMaker"), tr("Cannot read file %1:\n%2.").arg(QDir::toNativeSeparators(fileName), file.errorString())); setCurrentFile(QString()); return; } QApplication::setOverrideCursor(Qt::WaitCursor); - loadTTI(&file, m_textWidget->document()); + + if (fileInfo.suffix() == "t42") + importT42(&file, m_textWidget->document()); + else + loadTTI(&file, m_textWidget->document()); + levelSeen = m_textWidget->document()->levelRequired(); m_levelRadioButton[levelSeen]->toggle(); m_textWidget->pageRender()->setRenderLevel(levelSeen); diff --git a/qteletextmaker.pro b/qteletextmaker.pro index c0b01ed..d720c71 100644 --- a/qteletextmaker.pro +++ b/qteletextmaker.pro @@ -2,6 +2,7 @@ QT += widgets requires(qtConfig(filedialog)) HEADERS = document.h \ + hamming.h \ keymap.h \ levelonecommands.h \ levelonepage.h \ @@ -37,6 +38,8 @@ SOURCES = document.cpp \ x26triplets.cpp RESOURCES = qteletextmaker.qrc +CONFIG += debug + # install target.path = /usr/local/bin INSTALLS += target