Add exporting of single page .t42 files, wrt #2
This commit is contained in:
83
hamming.h
83
hamming.h
@@ -1,6 +1,13 @@
|
|||||||
#ifndef HAMMING_H
|
#ifndef HAMMING_H
|
||||||
#define HAMMING_H
|
#define HAMMING_H
|
||||||
|
|
||||||
|
// Hamming 8/4 encoding table
|
||||||
|
// encoded_value = hamming_8_4_encode[value_to_encode]
|
||||||
|
const unsigned char hamming_8_4_encode[16] = {
|
||||||
|
0x15, 0x02, 0x49, 0x5e, 0x64, 0x73, 0x38, 0x2f,
|
||||||
|
0xd0, 0xc7, 0x8c, 0x9b, 0xa1, 0xb6, 0xfd, 0xea
|
||||||
|
};
|
||||||
|
|
||||||
// Hamming 8/4 decoding table
|
// Hamming 8/4 decoding table
|
||||||
// decoded_value = hamming_8_4_decode[encoded_value]
|
// decoded_value = hamming_8_4_decode[encoded_value]
|
||||||
// 0xff - double bit error that can't be corrected
|
// 0xff - double bit error that can't be corrected
|
||||||
@@ -39,6 +46,82 @@ const unsigned char hamming_8_4_decode[256] = {
|
|||||||
0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e
|
0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned char hamming_24_18_forward[2][256] = {
|
||||||
|
{
|
||||||
|
0x8b, 0x8c, 0x92, 0x95, 0xa1, 0xa6, 0xb8, 0xbf,
|
||||||
|
0xc0, 0xc7, 0xd9, 0xde, 0xea, 0xed, 0xf3, 0xf4,
|
||||||
|
0x0a, 0x0d, 0x13, 0x14, 0x20, 0x27, 0x39, 0x3e,
|
||||||
|
0x41, 0x46, 0x58, 0x5f, 0x6b, 0x6c, 0x72, 0x75,
|
||||||
|
0x09, 0x0e, 0x10, 0x17, 0x23, 0x24, 0x3a, 0x3d,
|
||||||
|
0x42, 0x45, 0x5b, 0x5c, 0x68, 0x6f, 0x71, 0x76,
|
||||||
|
0x88, 0x8f, 0x91, 0x96, 0xa2, 0xa5, 0xbb, 0xbc,
|
||||||
|
0xc3, 0xc4, 0xda, 0xdd, 0xe9, 0xee, 0xf0, 0xf7,
|
||||||
|
0x08, 0x0f, 0x11, 0x16, 0x22, 0x25, 0x3b, 0x3c,
|
||||||
|
0x43, 0x44, 0x5a, 0x5d, 0x69, 0x6e, 0x70, 0x77,
|
||||||
|
0x89, 0x8e, 0x90, 0x97, 0xa3, 0xa4, 0xba, 0xbd,
|
||||||
|
0xc2, 0xc5, 0xdb, 0xdc, 0xe8, 0xef, 0xf1, 0xf6,
|
||||||
|
0x8a, 0x8d, 0x93, 0x94, 0xa0, 0xa7, 0xb9, 0xbe,
|
||||||
|
0xc1, 0xc6, 0xd8, 0xdf, 0xeb, 0xec, 0xf2, 0xf5,
|
||||||
|
0x0b, 0x0c, 0x12, 0x15, 0x21, 0x26, 0x38, 0x3f,
|
||||||
|
0x40, 0x47, 0x59, 0x5e, 0x6a, 0x6d, 0x73, 0x74,
|
||||||
|
0x03, 0x04, 0x1a, 0x1d, 0x29, 0x2e, 0x30, 0x37,
|
||||||
|
0x48, 0x4f, 0x51, 0x56, 0x62, 0x65, 0x7b, 0x7c,
|
||||||
|
0x82, 0x85, 0x9b, 0x9c, 0xa8, 0xaf, 0xb1, 0xb6,
|
||||||
|
0xc9, 0xce, 0xd0, 0xd7, 0xe3, 0xe4, 0xfa, 0xfd,
|
||||||
|
0x81, 0x86, 0x98, 0x9f, 0xab, 0xac, 0xb2, 0xb5,
|
||||||
|
0xca, 0xcd, 0xd3, 0xd4, 0xe0, 0xe7, 0xf9, 0xfe,
|
||||||
|
0x00, 0x07, 0x19, 0x1e, 0x2a, 0x2d, 0x33, 0x34,
|
||||||
|
0x4b, 0x4c, 0x52, 0x55, 0x61, 0x66, 0x78, 0x7f,
|
||||||
|
0x80, 0x87, 0x99, 0x9e, 0xaa, 0xad, 0xb3, 0xb4,
|
||||||
|
0xcb, 0xcc, 0xd2, 0xd5, 0xe1, 0xe6, 0xf8, 0xff,
|
||||||
|
0x01, 0x06, 0x18, 0x1f, 0x2b, 0x2c, 0x32, 0x35,
|
||||||
|
0x4a, 0x4d, 0x53, 0x54, 0x60, 0x67, 0x79, 0x7e,
|
||||||
|
0x02, 0x05, 0x1b, 0x1c, 0x28, 0x2f, 0x31, 0x36,
|
||||||
|
0x49, 0x4e, 0x50, 0x57, 0x63, 0x64, 0x7a, 0x7d,
|
||||||
|
0x83, 0x84, 0x9a, 0x9d, 0xa9, 0xae, 0xb0, 0xb7,
|
||||||
|
0xc8, 0xcf, 0xd1, 0xd6, 0xe2, 0xe5, 0xfb, 0xfc
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x00, 0x89, 0x8a, 0x03, 0x8b, 0x02, 0x01, 0x88,
|
||||||
|
0x01, 0x88, 0x8b, 0x02, 0x8a, 0x03, 0x00, 0x89,
|
||||||
|
0x02, 0x8b, 0x88, 0x01, 0x89, 0x00, 0x03, 0x8a,
|
||||||
|
0x03, 0x8a, 0x89, 0x00, 0x88, 0x01, 0x02, 0x8b,
|
||||||
|
0x03, 0x8a, 0x89, 0x00, 0x88, 0x01, 0x02, 0x8b,
|
||||||
|
0x02, 0x8b, 0x88, 0x01, 0x89, 0x00, 0x03, 0x8a,
|
||||||
|
0x01, 0x88, 0x8b, 0x02, 0x8a, 0x03, 0x00, 0x89,
|
||||||
|
0x00, 0x89, 0x8a, 0x03, 0x8b, 0x02, 0x01, 0x88,
|
||||||
|
0x08, 0x81, 0x82, 0x0b, 0x83, 0x0a, 0x09, 0x80,
|
||||||
|
0x09, 0x80, 0x83, 0x0a, 0x82, 0x0b, 0x08, 0x81,
|
||||||
|
0x0a, 0x83, 0x80, 0x09, 0x81, 0x08, 0x0b, 0x82,
|
||||||
|
0x0b, 0x82, 0x81, 0x08, 0x80, 0x09, 0x0a, 0x83,
|
||||||
|
0x0b, 0x82, 0x81, 0x08, 0x80, 0x09, 0x0a, 0x83,
|
||||||
|
0x0a, 0x83, 0x80, 0x09, 0x81, 0x08, 0x0b, 0x82,
|
||||||
|
0x09, 0x80, 0x83, 0x0a, 0x82, 0x0b, 0x08, 0x81,
|
||||||
|
0x08, 0x81, 0x82, 0x0b, 0x83, 0x0a, 0x09, 0x80,
|
||||||
|
0x09, 0x80, 0x83, 0x0a, 0x82, 0x0b, 0x08, 0x81,
|
||||||
|
0x08, 0x81, 0x82, 0x0b, 0x83, 0x0a, 0x09, 0x80,
|
||||||
|
0x0b, 0x82, 0x81, 0x08, 0x80, 0x09, 0x0a, 0x83,
|
||||||
|
0x0a, 0x83, 0x80, 0x09, 0x81, 0x08, 0x0b, 0x82,
|
||||||
|
0x0a, 0x83, 0x80, 0x09, 0x81, 0x08, 0x0b, 0x82,
|
||||||
|
0x0b, 0x82, 0x81, 0x08, 0x80, 0x09, 0x0a, 0x83,
|
||||||
|
0x08, 0x81, 0x82, 0x0b, 0x83, 0x0a, 0x09, 0x80,
|
||||||
|
0x09, 0x80, 0x83, 0x0a, 0x82, 0x0b, 0x08, 0x81,
|
||||||
|
0x01, 0x88, 0x8b, 0x02, 0x8a, 0x03, 0x00, 0x89,
|
||||||
|
0x00, 0x89, 0x8a, 0x03, 0x8b, 0x02, 0x01, 0x88,
|
||||||
|
0x03, 0x8a, 0x89, 0x00, 0x88, 0x01, 0x02, 0x8b,
|
||||||
|
0x02, 0x8b, 0x88, 0x01, 0x89, 0x00, 0x03, 0x8a,
|
||||||
|
0x02, 0x8b, 0x88, 0x01, 0x89, 0x00, 0x03, 0x8a,
|
||||||
|
0x03, 0x8a, 0x89, 0x00, 0x88, 0x01, 0x02, 0x8b,
|
||||||
|
0x00, 0x89, 0x8a, 0x03, 0x8b, 0x02, 0x01, 0x88,
|
||||||
|
0x01, 0x88, 0x8b, 0x02, 0x8a, 0x03, 0x00, 0x89
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char hamming_24_18_forward_2[4] = {
|
||||||
|
0x00, 0x0a, 0x0b, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const unsigned char hamming_24_18_parities[3][256] = {
|
const unsigned char hamming_24_18_parities[3][256] = {
|
||||||
{ // Parities of first byte
|
{ // Parities of first byte
|
||||||
0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20,
|
0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20,
|
||||||
|
|||||||
133
loadsave.cpp
133
loadsave.cpp
@@ -20,6 +20,7 @@
|
|||||||
#include "loadsave.h"
|
#include "loadsave.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QDataStream>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QSaveFile>
|
#include <QSaveFile>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -531,6 +532,138 @@ void saveTTI(QSaveFile &file, const TeletextDocument &document)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exportT42File(QSaveFile &file, const TeletextDocument &document)
|
||||||
|
{
|
||||||
|
const PageBase &subPage = *document.currentSubPage();
|
||||||
|
|
||||||
|
QDataStream outStream(&file);
|
||||||
|
// Displayable row header we export as spaces, hence the (odd parity valid) 0x20 init value
|
||||||
|
QByteArray outLine(42, 0x20);
|
||||||
|
int magazineNumber = (document.pageNumber() & 0xf00) >> 8;
|
||||||
|
|
||||||
|
auto write7bitPacket=[&](int packetNumber)
|
||||||
|
{
|
||||||
|
if (subPage.packetExists(packetNumber)) {
|
||||||
|
outLine[0] = hamming_8_4_encode[magazineNumber | ((packetNumber & 0x01) << 3)];
|
||||||
|
outLine[1] = hamming_8_4_encode[packetNumber >> 1];
|
||||||
|
outLine.replace(2, 40, subPage.packet(packetNumber));
|
||||||
|
|
||||||
|
// Odd parity encoding
|
||||||
|
for (int c=0; c<outLine.size(); c++) {
|
||||||
|
char p = outLine.at(c);
|
||||||
|
|
||||||
|
// Recursively divide integer into two equal halves and take their XOR until only 1 bit is left
|
||||||
|
p ^= p >> 4;
|
||||||
|
p ^= p >> 2;
|
||||||
|
p ^= p >> 1;
|
||||||
|
// If last bit left is 0 then it started with an even number of bits, so do the odd parity
|
||||||
|
if (!(p & 1))
|
||||||
|
outLine[c] = outLine.at(c) | 0x80;
|
||||||
|
}
|
||||||
|
outStream.writeRawData(outLine.constData(), 42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto writeHamming8_4Packet=[&](int packetNumber, int designationCode=0)
|
||||||
|
{
|
||||||
|
if (subPage.packetExists(packetNumber, designationCode)) {
|
||||||
|
outLine[0] = hamming_8_4_encode[magazineNumber | ((packetNumber & 0x01) << 3)];
|
||||||
|
outLine[1] = hamming_8_4_encode[packetNumber >> 1];
|
||||||
|
outLine.replace(2, 40, subPage.packet(packetNumber, designationCode));
|
||||||
|
outLine[2] = hamming_8_4_encode[designationCode];
|
||||||
|
|
||||||
|
for (int c=3; c<outLine.size(); c++)
|
||||||
|
outLine[c] = hamming_8_4_encode[(int)outLine.at(c)];
|
||||||
|
|
||||||
|
outStream.writeRawData(outLine.constData(), 42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto writeHamming24_18Packet=[&](int packetNumber, int designationCode=0)
|
||||||
|
{
|
||||||
|
if (subPage.packetExists(packetNumber, designationCode)) {
|
||||||
|
outLine[0] = hamming_8_4_encode[magazineNumber | ((packetNumber & 0x01) << 3)];
|
||||||
|
outLine[1] = hamming_8_4_encode[packetNumber >> 1];
|
||||||
|
outLine.replace(2, 40, subPage.packet(packetNumber, designationCode));
|
||||||
|
outLine[2] = hamming_8_4_encode[designationCode];
|
||||||
|
|
||||||
|
for (int c=3; c<outLine.size(); c+=3) {
|
||||||
|
unsigned int D5_D11;
|
||||||
|
unsigned int D12_D18;
|
||||||
|
unsigned int P5, P6;
|
||||||
|
unsigned int Byte_0;
|
||||||
|
|
||||||
|
const unsigned int toEncode = outLine[c] | (outLine[c+1] << 6) | (outLine[c+2] << 12);
|
||||||
|
|
||||||
|
Byte_0 = (hamming_24_18_forward[0][(toEncode >> 0) & 0xff] ^ hamming_24_18_forward[1][(toEncode >> 8) & 0xff] ^ hamming_24_18_forward_2[(toEncode >> 16) & 0x03]);
|
||||||
|
outLine[c] = Byte_0;
|
||||||
|
|
||||||
|
D5_D11 = (toEncode >> 4) & 0x7f;
|
||||||
|
D12_D18 = (toEncode >> 11) & 0x7f;
|
||||||
|
|
||||||
|
P5 = 0x80 & ~(hamming_24_18_parities[0][D12_D18] << 2);
|
||||||
|
outLine[c+1] = D5_D11 | P5;
|
||||||
|
|
||||||
|
P6 = 0x80 & ((hamming_24_18_parities[0][Byte_0] ^ hamming_24_18_parities[0][D5_D11]) << 2);
|
||||||
|
outLine[c+2] = D12_D18 | P6;
|
||||||
|
}
|
||||||
|
|
||||||
|
outStream.writeRawData(outLine.constData(), 42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (magazineNumber == 8)
|
||||||
|
magazineNumber = 0;
|
||||||
|
|
||||||
|
// Write X/0 separately as it features both Hamming 8/4 and 7-bit odd parity within
|
||||||
|
outLine[0] = magazineNumber & 0x07;
|
||||||
|
outLine[1] = 0; // Packet number 0
|
||||||
|
outLine[2] = document.pageNumber() & 0x00f;
|
||||||
|
outLine[3] = (document.pageNumber() & 0x0f0) >> 4;
|
||||||
|
outLine[4] = 0; // Subcode S1 - always export as 0
|
||||||
|
outLine[5] = subPage.controlBit(PageBase::C4ErasePage) << 3;
|
||||||
|
outLine[6] = 0; // Subcode S3 - always export as 0
|
||||||
|
outLine[7] = (subPage.controlBit(PageBase::C5Newsflash) << 2) | (subPage.controlBit(PageBase::C6Subtitle) << 3);
|
||||||
|
outLine[8] = subPage.controlBit(PageBase::C7SuppressHeader) | (subPage.controlBit(PageBase::C8Update) << 2) | (subPage.controlBit(PageBase::C9InterruptedSequence) << 2) | (subPage.controlBit(PageBase::C10InhibitDisplay) << 3);
|
||||||
|
outLine[9] = subPage.controlBit(PageBase::C11SerialMagazine) | (subPage.controlBit(PageBase::C14NOS) << 2) | (subPage.controlBit(PageBase::C13NOS) << 2) | (subPage.controlBit(PageBase::C12NOS) << 3);
|
||||||
|
|
||||||
|
for (int i=0; i<10; i++)
|
||||||
|
outLine[i] = hamming_8_4_encode[(int)outLine.at(i)];
|
||||||
|
|
||||||
|
// If we allow text in the row header, we'd odd-parity encode it here
|
||||||
|
|
||||||
|
outStream.writeRawData(outLine.constData(), 42);
|
||||||
|
|
||||||
|
// After X/0, X/27 then X/28 always come next
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
writeHamming8_4Packet(27, i);
|
||||||
|
for (int i=4; i<16; i++)
|
||||||
|
writeHamming24_18Packet(27, i);
|
||||||
|
for (int i=0; i<16; i++)
|
||||||
|
writeHamming24_18Packet(28, i);
|
||||||
|
|
||||||
|
if (document.packetCoding() == TeletextDocument::Coding7bit) {
|
||||||
|
// For 7 bit coding i.e. Level One Pages, X/26 are written before X/1 to X/25
|
||||||
|
for (int i=0; i<16; i++)
|
||||||
|
writeHamming24_18Packet(26, i);
|
||||||
|
for (int i=1; i<=24; i++)
|
||||||
|
write7bitPacket(i);
|
||||||
|
} else {
|
||||||
|
// For others (especially (G)POP pages) X/1 to X/25 are written before X/26
|
||||||
|
if (document.packetCoding() == TeletextDocument::Coding18bit)
|
||||||
|
for (int i=1; i<=25; i++)
|
||||||
|
writeHamming24_18Packet(i);
|
||||||
|
else if (document.packetCoding() == TeletextDocument::Coding4bit)
|
||||||
|
for (int i=1; i<=25; i++)
|
||||||
|
writeHamming8_4Packet(i);
|
||||||
|
else
|
||||||
|
qDebug("Exported broken file as page coding is not supported");
|
||||||
|
for (int i=0; i<16; i++)
|
||||||
|
writeHamming24_18Packet(26, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray rowPacketAlways(PageBase *subPage, int packetNumber)
|
QByteArray rowPacketAlways(PageBase *subPage, int packetNumber)
|
||||||
{
|
{
|
||||||
if (subPage->packetExists(packetNumber))
|
if (subPage->packetExists(packetNumber))
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ void importT42(QFile *, TeletextDocument *);
|
|||||||
int controlBitsToPS(PageBase *);
|
int controlBitsToPS(PageBase *);
|
||||||
|
|
||||||
void saveTTI(QSaveFile &, const TeletextDocument &);
|
void saveTTI(QSaveFile &, const TeletextDocument &);
|
||||||
|
void exportT42File(QSaveFile &, const TeletextDocument &);
|
||||||
|
|
||||||
QByteArray rowPacketAlways(PageBase *, int);
|
QByteArray rowPacketAlways(PageBase *, int);
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,17 @@ static inline bool hasTTISuffix(const QString &filename)
|
|||||||
return filename.endsWith(".tti", Qt::CaseInsensitive) || filename.endsWith(".ttix", Qt::CaseInsensitive);
|
return filename.endsWith(".tti", Qt::CaseInsensitive) || filename.endsWith(".ttix", Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void changeSuffixFromTTI(QString &filename, const QString &newSuffix)
|
||||||
|
{
|
||||||
|
if (filename.endsWith(".tti", Qt::CaseInsensitive)) {
|
||||||
|
filename.chop(4);
|
||||||
|
filename.append("." + newSuffix);
|
||||||
|
} else if (filename.endsWith(".ttix", Qt::CaseInsensitive)) {
|
||||||
|
filename.chop(5);
|
||||||
|
filename.append("." + newSuffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MainWindow::save()
|
bool MainWindow::save()
|
||||||
{
|
{
|
||||||
// If imported from non-.tti, force "Save As" so we don't clobber the original imported file
|
// If imported from non-.tti, force "Save As" so we don't clobber the original imported file
|
||||||
@@ -324,9 +335,9 @@ void MainWindow::createActions()
|
|||||||
|
|
||||||
setRecentFilesVisible(MainWindow::hasRecentFiles());
|
setRecentFilesVisible(MainWindow::hasRecentFiles());
|
||||||
|
|
||||||
QAction *exportPNGAct = fileMenu->addAction(tr("Export subpage as PNG..."));
|
QAction *exportT42Act = fileMenu->addAction(tr("Export subpage as t42..."));
|
||||||
exportPNGAct->setStatusTip("Export a PNG image of this subpage");
|
exportT42Act->setStatusTip("Export this subpage as a t42 file");
|
||||||
connect(exportPNGAct, &QAction::triggered, this, &MainWindow::exportPNG);
|
connect(exportT42Act, &QAction::triggered, this, &MainWindow::exportT42);
|
||||||
|
|
||||||
QMenu *exportHashStringSubMenu = fileMenu->addMenu(tr("Export subpage to online editor"));
|
QMenu *exportHashStringSubMenu = fileMenu->addMenu(tr("Export subpage to online editor"));
|
||||||
|
|
||||||
@@ -338,6 +349,10 @@ void MainWindow::createActions()
|
|||||||
exportEditTFAct->setStatusTip("Export and open this subpage in the edit.tf online editor");
|
exportEditTFAct->setStatusTip("Export and open this subpage in the edit.tf online editor");
|
||||||
connect(exportEditTFAct, &QAction::triggered, this, &MainWindow::exportEditTF);
|
connect(exportEditTFAct, &QAction::triggered, this, &MainWindow::exportEditTF);
|
||||||
|
|
||||||
|
QAction *exportPNGAct = fileMenu->addAction(tr("Export subpage as PNG..."));
|
||||||
|
exportPNGAct->setStatusTip("Export a PNG image of this subpage");
|
||||||
|
connect(exportPNGAct, &QAction::triggered, this, &MainWindow::exportPNG);
|
||||||
|
|
||||||
fileMenu->addSeparator();
|
fileMenu->addSeparator();
|
||||||
|
|
||||||
QAction *closeAct = fileMenu->addAction(tr("&Close"), this, &QWidget::close);
|
QAction *closeAct = fileMenu->addAction(tr("&Close"), this, &QWidget::close);
|
||||||
@@ -991,6 +1006,31 @@ bool MainWindow::saveFile(const QString &fileName)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::exportT42()
|
||||||
|
{
|
||||||
|
QString errorMessage;
|
||||||
|
QString exportFileName = m_curFile;
|
||||||
|
|
||||||
|
changeSuffixFromTTI(exportFileName, "t42");
|
||||||
|
|
||||||
|
exportFileName = QFileDialog::getSaveFileName(this, tr("Export t42"), exportFileName, "t42 stream (*.t42)");
|
||||||
|
if (exportFileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
QSaveFile file(exportFileName);
|
||||||
|
if (file.open(QFile::WriteOnly)) {
|
||||||
|
exportT42File(file, *m_textWidget->document());
|
||||||
|
if (!file.commit())
|
||||||
|
errorMessage = tr("Cannot write file %1:\n%2.").arg(QDir::toNativeSeparators(exportFileName), file.errorString());
|
||||||
|
} else
|
||||||
|
errorMessage = tr("Cannot open file %1 for writing:\n%2.").arg(QDir::toNativeSeparators(exportFileName), file.errorString());
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
|
||||||
|
if (!errorMessage.isEmpty())
|
||||||
|
QMessageBox::warning(this, tr("QTeletextMaker"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::setCurrentFile(const QString &fileName)
|
void MainWindow::setCurrentFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
static int sequenceNumber = 1;
|
static int sequenceNumber = 1;
|
||||||
|
|||||||
@@ -58,9 +58,10 @@ private slots:
|
|||||||
void open();
|
void open();
|
||||||
bool save();
|
bool save();
|
||||||
bool saveAs();
|
bool saveAs();
|
||||||
void exportPNG();
|
void exportT42();
|
||||||
void exportZXNet();
|
void exportZXNet();
|
||||||
void exportEditTF();
|
void exportEditTF();
|
||||||
|
void exportPNG();
|
||||||
void updateRecentFileActions();
|
void updateRecentFileActions();
|
||||||
void openRecentFile();
|
void openRecentFile();
|
||||||
void about();
|
void about();
|
||||||
|
|||||||
Reference in New Issue
Block a user