diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/AbstractRtfOutput.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/AbstractRtfOutput.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/AbstractRtfOutput.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/AbstractRtfOutput.h @@ -256,6 +256,7 @@ void addUserProp( const QString &propertyName, const QVariant &propertyValue ); // TODO: consider adding default implementation for this + virtual void appendText( const QByteArray &text ) = 0; virtual void appendText( const QString &text ) = 0; virtual void insertPar() = 0; virtual void insertTab() = 0; @@ -291,7 +292,7 @@ virtual void setTextDirectionLeftToRight() = 0; virtual void setTextDirectionRightToLeft() = 0; virtual void resetCharacterProperties() = 0; - virtual void createImage( const QImage &image, const QTextImageFormat &format) = 0; + virtual void createImage( const QByteArray &data, const QTextImageFormat &format) = 0; virtual void setPageHeight( const int pageHeight ) = 0; virtual void setPageWidth( const int pageWidth ) = 0; virtual void setSpaceBefore( const int value ) = 0; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.h @@ -34,8 +34,8 @@ virtual ~ColorTableDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); private: void resetCurrentColor(); diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/ColorTableDestination.cpp @@ -31,7 +31,7 @@ ColorTableDestination::~ColorTableDestination() {} - void ColorTableDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void ColorTableDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "red" ) { m_currentColor.setRed( value ); @@ -44,7 +44,7 @@ } } - void ColorTableDestination::handlePlainText( const QString &plainText ) + void ColorTableDestination::handlePlainText( const QByteArray &plainText ) { if ( plainText == ";" ) { m_output->appendToColourTable( m_currentColor ); diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.h @@ -42,9 +42,9 @@ QString name() const; - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/Destination.cpp @@ -40,11 +40,11 @@ return m_name; } - void Destination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void Destination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { }; - void Destination::handlePlainText( const QString &plainText ) + void Destination::handlePlainText( const QByteArray &plainText ) { qCDebug(lcRtf) << "plain text:" << plainText << "in" << m_name; }; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.h @@ -34,12 +34,13 @@ virtual ~DocumentDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); protected: int m_charactersToSkip; + int m_unicodeSkip; }; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/DocumentDestination.cpp @@ -24,15 +24,15 @@ namespace RtfReader { DocumentDestination::DocumentDestination( Reader *reader, AbstractRtfOutput *output, const QString &name ) : - Destination( reader, output, name ), m_charactersToSkip( 0 ) + Destination( reader, output, name ), m_charactersToSkip( 0 ), m_unicodeSkip( 1 ) { } DocumentDestination::~DocumentDestination() { } - void DocumentDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void DocumentDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "par" ) { @@ -120,10 +120,14 @@ } else if ( controlWord == "strike" ) { m_output->setFontStrikeout( ! hasValue || ( hasValue && value != 0 ) ); } else if ( ( controlWord == "u" ) && hasValue ) { - m_output->appendText( QChar( value ) ); - m_charactersToSkip = 1; /* TODO: this should be driven by \uc, default to 1 */ + m_output->appendText( QString( 1, QChar( value ) ) ); + m_charactersToSkip = m_unicodeSkip; + } else if ( controlWord == "uc" && hasValue ) { + m_unicodeSkip = value; } else if ( ( controlWord == "\'" ) && hasValue ) { qCDebug(lcRtf) << "special character value:" << value; + } else if ( controlWord == "line" ) { + m_output->appendText( QString( "\n" ) ); } else if ( controlWord == "*" ) { // handled elsewhere } else { @@ -135,15 +139,15 @@ } } - void DocumentDestination::handlePlainText( const QString &plainText ) + void DocumentDestination::handlePlainText( const QByteArray &plainText ) { if ( m_charactersToSkip > 0 ) { qCDebug(lcRtf) << "skipping" << m_charactersToSkip << "of" << plainText; if ( m_charactersToSkip >= plainText.size() ) { m_charactersToSkip -= plainText.size(); return; } else if ( plainText.size() > m_charactersToSkip ) { - QString partiallySkippedText( plainText ); + QByteArray partiallySkippedText( plainText ); partiallySkippedText.remove( 0, m_charactersToSkip ); m_output->appendText( partiallySkippedText ); m_charactersToSkip = 0; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.h @@ -35,8 +35,8 @@ virtual ~FontTableDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); protected: diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableDestination.cpp @@ -20,6 +20,37 @@ #include "rtfreader.h" #include "rtfdebug.h" +namespace { +struct CharsetEntry { int id; const char *name; }; + +static constexpr CharsetEntry charsetToCodec[] = { + { 0, "Windows-1252" }, // ANSI + { 1, "Windows-1252" }, // Default + { 2, nullptr }, // Symbol, + { 3, nullptr }, // Invalid, + { 77, "Macintosh" }, // Mac + { 128, "Shift-JIS" }, // Shift Jis + { 129, "CP949" }, // Hangul + { 130, nullptr }, // Johab + { 134, "GB2312" }, // GB2312 + { 136, "Big5" }, // Big5 + { 161, "Windows-1253" }, // Greek + { 162, "Windows-1254" }, // Turkish + { 163, "Windows-1258" }, // Vietnamese + { 177, "Windows-1255" }, // Hebrew + { 178, "Windows-1256" }, // Arabic + { 179, nullptr }, // Arabic Traditional + { 180, nullptr }, // Arabic user + { 181, nullptr }, // Hebrew user + { 186, "Windows-1257" }, // Baltic + { 204, "Windows-1251" }, // Russian + { 222, "CP847" }, // Thai + { 238, "Windows-1250" }, // Eastern European + { 254, "IBM437" }, // PC 437 +}; + +} + namespace RtfReader { FontTableDestination::FontTableDestination( Reader *reader, AbstractRtfOutput *output, const QString &name ) : @@ -31,7 +62,7 @@ { } - void FontTableDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void FontTableDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "f" ) { m_currentFontTableIndex = value; @@ -54,13 +85,18 @@ } else if ( controlWord == "fprq" ) { m_fontTableEntry.setFontPitch( static_cast(value) ); } else if ( controlWord == "fcharset" ) { - // TODO: need to figure out how to sanely handle this + for (const auto &entry : charsetToCodec) { + if (entry.id == value) { + m_fontTableEntry.setCodec(QTextCodec::codecForName(entry.name)); + break; + } + } } else { qCDebug(lcRtf) << "unhandled fonttbl control word:" << controlWord << "(" << value << ")"; } } - void FontTableDestination::handlePlainText( const QString &plainText ) + void FontTableDestination::handlePlainText( const QByteArray &plainText ) { if ( plainText == ";" ) { m_output->insertFontTableEntry( m_fontTableEntry, m_currentFontTableIndex ); diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableEntry.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableEntry.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableEntry.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/FontTableEntry.h @@ -18,6 +18,9 @@ #ifndef RTFREADER_FONTTABLEENTRY_H #define RTFREADER_FONTTABLEENTRY_H #include "rtfreader_export.h" + +#include + namespace RtfReader { enum FontFamily { Nil, Roman, Swiss, Modern, Script, Decor, Tech, Bidi }; @@ -48,10 +51,17 @@ void setFontName( const QString &fontName ) { m_fontName = fontName; } + QTextCodec *codec() const + { return m_codec; } + + void setCodec(QTextCodec *codec) + { m_codec = codec; } + protected: enum FontFamily m_fontFamily; enum FontPitch m_fontPitch; QString m_fontName; + QTextCodec *m_codec = nullptr; }; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.h @@ -34,8 +34,8 @@ virtual ~IgnoredDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); }; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/IgnoredDestination.cpp @@ -30,11 +30,11 @@ { } - void IgnoredDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void IgnoredDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { } - void IgnoredDestination::handlePlainText( const QString &plainText ) + void IgnoredDestination::handlePlainText( const QByteArray &plainText ) { } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.h @@ -34,8 +34,8 @@ virtual ~InfoDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); private: diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoDestination.cpp @@ -30,7 +30,7 @@ InfoDestination::~InfoDestination() {} - void InfoDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void InfoDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( ( controlWord == "edmins" ) && hasValue ) { m_output->setTotalEditingTime( value ); @@ -53,7 +53,7 @@ } } - void InfoDestination::handlePlainText( const QString &plainText ) + void InfoDestination::handlePlainText( const QByteArray &plainText ) { qCDebug(lcRtf) << "unexpected text in InfoDestination:" << plainText; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.h @@ -34,8 +34,8 @@ virtual ~InfoTimeDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination() = 0; protected: diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/InfoTimeDestination.cpp @@ -31,7 +31,7 @@ { } - void InfoTimeDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void InfoTimeDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "yr" ) { m_year = value; @@ -48,7 +48,7 @@ } } - void InfoTimeDestination::handlePlainText( const QString &plainText ) + void InfoTimeDestination::handlePlainText( const QByteArray &plainText ) { qCDebug(lcRtf) << "unexpected text in InfoTimeDestination:" << plainText; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.h @@ -34,8 +34,8 @@ virtual ~PcdataDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination() = 0; protected: diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/PcdataDestination.cpp @@ -31,12 +31,12 @@ { } - void PcdataDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void PcdataDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { qCDebug(lcRtf) << "unexpected control word in" << m_name << ": " << controlWord; } - void PcdataDestination::handlePlainText( const QString &plainText ) + void PcdataDestination::handlePlainText( const QByteArray &plainText ) { m_pcdata = plainText; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.h @@ -34,16 +34,21 @@ virtual ~PictDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); private: // The hexadecimal version of the data for the image that is currently being built - QByteArray m_pictHexData; + QByteArray m_pictData; // The format information for the current image QTextImageFormat m_imageFormat; + const char *m_format = nullptr; + qreal m_xScale = 1.; + qreal m_yScale = 1.; + qreal m_goalWidth = 0.; + qreal m_goalHeight = 0.; }; } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/PictDestination.cpp @@ -19,6 +19,10 @@ #include "rtfreader.h" #include "rtfdebug.h" +#include +#include +#include +#include namespace RtfReader { @@ -31,22 +35,29 @@ { } - void PictDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void PictDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "jpegblip" ) { - // handle this later + qCDebug(lcRtf) << "JPEG"; + m_format = "jpg"; + } else if ( controlWord == "pngblip" ) { + qCDebug(lcRtf) << "PNG"; + m_format = "png"; + } else if ( controlWord == "dibitmap" ) { + qCDebug(lcRtf) << "BMP"; + m_format = "bmp"; } else if ( controlWord == "wmetafile" ) { qCDebug(lcRtf) << "todo: get WMF data"; } else if ( controlWord == "picw" ) { qCDebug(lcRtf) << "pict width: " << value; - m_imageFormat.setWidth( value ); } else if ( controlWord == "pich" ) { qCDebug(lcRtf) << "pict height: " << value; - m_imageFormat.setHeight( value ); } else if ( controlWord == "picscalex" ) { qCDebug(lcRtf) << "X scale: " << value; + m_xScale = value / 100.; } else if ( controlWord == "picscaley" ) { qCDebug(lcRtf) << "Y scale: " << value; + m_yScale = value / 100.; } else if ( controlWord == "piccropl" ) { qCDebug(lcRtf) << "Left crop:" << value; } else if ( controlWord == "piccropr" ) { @@ -57,21 +68,45 @@ qCDebug(lcRtf) << "Bottom crop:" << value; } else if ( controlWord == "pichgoal" ) { qCDebug(lcRtf) << "Goal Height:" << value; + m_goalHeight = value * 96 / 1440.; } else if ( controlWord == "picwgoal" ) { qCDebug(lcRtf) << "Goal Width:" << value; + m_goalWidth = value * 96 / 1440.; } else { qCDebug(lcRtf) << "unexpected control word in pict:" << controlWord; } } - void PictDestination::handlePlainText( const QString &plainText ) + void PictDestination::handlePlainText( const QByteArray &plainText ) { - m_pictHexData += plainText.toLatin1(); + m_pictData += QByteArray::fromHex( plainText ); } void PictDestination::aboutToEndDestination() { - QImage image = QImage::fromData( QByteArray::fromHex( m_pictHexData ) ); - m_output->createImage(image, m_imageFormat); + if ( m_format ) { + static int counter = 0; + + if ( m_goalWidth == 0 || m_goalHeight == 0 ) { + QBuffer buffer(&m_pictData); + buffer.open(QIODevice::ReadOnly); + QImageReader reader(&buffer); + QSize size = reader.size(); + if ( m_goalWidth == 0 ) { + m_goalWidth = size.width(); + } + if ( m_goalHeight == 0 ) { + m_goalHeight = size.height(); + } + } + + m_imageFormat.setName( QStringLiteral("rtfparser://%1.%2").arg( ++counter ).arg( QString::fromUtf8( m_format) ) ); + m_imageFormat.setWidth( m_goalWidth * m_xScale ); + m_imageFormat.setHeight( m_goalHeight * m_yScale ); + + m_output->createImage(m_pictData, m_imageFormat); + } else { + qCWarning(lcRtf) << "Embedded picture in unknown format"; + } } } diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.h @@ -35,8 +35,8 @@ virtual ~StyleSheetDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); virtual void aboutToEndDestination(); protected: diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/StyleSheetDestination.cpp @@ -34,7 +34,7 @@ { } - void StyleSheetDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void StyleSheetDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "ql" ) { m_style.setTextAlignment( LeftAligned); @@ -61,7 +61,7 @@ } } - void StyleSheetDestination::handlePlainText( const QString &plainText ) + void StyleSheetDestination::handlePlainText( const QByteArray &plainText ) { if ( plainText == ";" ) { m_output->insertStyleSheetTableEntry( m_currentStyleHandleNumber, m_style ); diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.h @@ -43,6 +43,7 @@ virtual void endGroup(); + virtual void appendText( const QByteArray &text ); virtual void appendText( const QString &text ); virtual void insertPar(); @@ -103,7 +104,7 @@ virtual void setLeftIndent( const int twips ); virtual void setRightIndent( const int twips ); - virtual void createImage( const QImage &image, const QTextImageFormat &format ); + virtual void createImage( const QByteArray &data, const QTextImageFormat &format ); virtual void setPageHeight( const int pageHeight ); virtual void setPageWidth( const int pageWidth ); @@ -128,6 +129,7 @@ QHash m_stylesheetTable; QTextDocument *m_document; + QTextCodec *m_codec = nullptr; /** Convenience routine to convert a size in twips into pixels diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/TextDocumentRtfOutput.cpp @@ -18,6 +18,7 @@ #include "TextDocumentRtfOutput.h" #include "rtfdebug.h" +#include #include #include #include @@ -56,9 +57,15 @@ m_cursor->setCharFormat( m_textCharFormatStack.top() ); } - void TextDocumentRtfOutput::appendText( const QString &text ) + void TextDocumentRtfOutput::appendText( const QByteArray &text ) { - m_cursor->insertText( text ); + static const QRegularExpression controlCharacters(QStringLiteral("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]")); + m_cursor->insertText( (m_codec ? m_codec->toUnicode(text) : QString::fromLatin1(text)).remove(controlCharacters) ); + } + + void TextDocumentRtfOutput::appendText(const QString &str) + { + m_cursor->insertText(str); } void TextDocumentRtfOutput::insertPar() @@ -193,6 +200,7 @@ qCDebug(lcRtf) << "selecting font:" << fontEntry.fontName(); m_textCharFormatStack.top().setFontFamily( fontEntry.fontName() ); m_cursor->setCharFormat( m_textCharFormatStack.top() ); + m_codec = fontEntry.codec(); m_haveSetFont = true; } @@ -314,16 +322,10 @@ m_cursor->setCharFormat( m_textCharFormatStack.top() ); } - void TextDocumentRtfOutput::createImage( const QImage &image, const QTextImageFormat &format ) + void TextDocumentRtfOutput::createImage( const QByteArray &data, const QTextImageFormat &format ) { -#if 0 - QString imageUuid = QString( "rtfparser://" ) + QUuid::createUuid().toString(); - m_document->addResource( QTextDocument::ImageResource, QUrl( imageUuid ), QVariant( image )); - format.setName( imageUuid ); + m_document->addResource( QTextDocument::ImageResource, QUrl( format.name() ), data ); m_cursor->insertImage( format ); -#else - m_cursor->insertImage( image.scaled( format.width(), format.height() ) ); -#endif } void TextDocumentRtfOutput::setPageHeight( const int pageHeight ) diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/Token.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/Token.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/Token.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/Token.h @@ -32,7 +32,7 @@ public: /* TODO: convert to getters / setters */ void dump() const; TokenType type; - QString name; + QByteArray name; bool hasParameter; QString parameter; QByteArray binaryData; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/Tokenizer.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/Tokenizer.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/Tokenizer.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/Tokenizer.cpp @@ -53,7 +53,7 @@ hexDigits.append( QChar( lowNibbleHexDigit ) ); uint codepoint = hexDigits.toUInt(0, 16); token->type = Plain; - token->name = QChar( codepoint ); + token->name = QByteArray( 1, codepoint ); } } else if ( token->name == "\\" ) { token->type = Plain; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.h b/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.h --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.h +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.h @@ -35,8 +35,8 @@ virtual ~UserPropsDestination(); - virtual void handleControlWord( const QString &controlWord, bool hasValue, const int value ); - virtual void handlePlainText( const QString &plainText ); + virtual void handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ); + virtual void handlePlainText( const QByteArray &plainText ); private: bool m_nextPlainTextIsPropertyName; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/UserPropsDestination.cpp @@ -31,7 +31,7 @@ UserPropsDestination::~UserPropsDestination() {} - void UserPropsDestination::handleControlWord( const QString &controlWord, bool hasValue, const int value ) + void UserPropsDestination::handleControlWord( const QByteArray &controlWord, bool hasValue, const int value ) { if ( controlWord == "propname" ) { m_nextPlainTextIsPropertyName = true; @@ -56,7 +56,7 @@ } } - void UserPropsDestination::handlePlainText( const QString &plainText ) + void UserPropsDestination::handlePlainText( const QByteArray &plainText ) { if ( m_nextPlainTextIsPropertyName ) { m_propertyName = plainText; diff --git a/filters/words/rtf/import/3rdparty/rtf-qt/src/rtfreader.cpp b/filters/words/rtf/import/3rdparty/rtf-qt/src/rtfreader.cpp --- a/filters/words/rtf/import/3rdparty/rtf-qt/src/rtfreader.cpp +++ b/filters/words/rtf/import/3rdparty/rtf-qt/src/rtfreader.cpp @@ -314,6 +314,7 @@ break; case Binary: qCDebug(lcRtf) << "binary data:" << token.name; + break; default: qCDebug(lcRtf) << "Unexpected token Type"; }