23#include <QTextDocument>
33 mBlocks.append( block );
44 document.
reserve( lines.size() );
45 for (
const QString &line : lines )
55#define TAB_REPLACEMENT_MARKER " ignore_me_i_am_a_tab "
61 document.
reserve( lines.size() );
63 for (
const QString &l : std::as_const( lines ) )
70 QTextDocument sourceDoc;
81 const thread_local QRegularExpression sRxPixelsToPtFix( QStringLiteral(
"(word-spacing|line-height|margin-top|margin-bottom|margin-left|margin-right):\\s*(-?\\d+(?:\\.\\d+)?)(?![%\\d])([a-zA-Z]*)" ) );
82 line.replace( sRxPixelsToPtFix, QStringLiteral(
"\\1: \\2px" ) );
83 const thread_local QRegularExpression sRxMarginPixelsToPtFix( QStringLiteral(
"margin:\\s*(-?\\d+(?:\\.\\d+)?)([a-zA-Z]*)\\s*(-?\\d+(?:\\.\\d+)?)([a-zA-Z]*)\\s*(-?\\d+(?:\\.\\d+)?)([a-zA-Z]*)\\s*(-?\\d+(?:\\.\\d+)?)([a-zA-Z]*)" ) );
84 line.replace( sRxMarginPixelsToPtFix, QStringLiteral(
"margin: \\1px \\3px \\5px \\7px" ) );
88 line.prepend( QStringLiteral(
"<style>p, h1, h2, h3, h4, h5, h6 { margin: 0pt; }</style>" ) );
90 sourceDoc.setHtml( line );
92 QTextBlock sourceBlock = sourceDoc.firstBlock();
96 const int headingLevel = sourceBlock.blockFormat().headingLevel();
98 if ( headingLevel > 0 )
100 switch ( headingLevel )
125 auto it = sourceBlock.begin();
128 while ( !it.atEnd() )
130 const QTextFragment fragment = it.fragment();
131 if ( fragment.isValid() )
134 const QString fragmentText = fragment.text();
135 if ( fragmentText.contains( QStringLiteral(
"\u2028" ) ) )
138 const QStringList
splitLines = fragmentText.split( QStringLiteral(
"\u2028" ), Qt::SplitBehaviorFlags::SkipEmptyParts );
140 for (
const QString &splitLine : std::as_const(
splitLines ) )
147 previousFormat = &document.
at( document.
size() - 1 ).
at( 0 ).characterFormat();
157 if ( previousFormat )
160 newFormat.overrideWith( *previousFormat );
167 for (
const QString &part : tabSplit )
169 if ( !part.isEmpty() )
172 block.
append( splitFragment );
174 if ( index != tabSplit.size() - 1 )
184 splitFragment.
setText( splitLine );
188 if ( previousFormat )
191 newFormat.overrideWith( *previousFormat );
195 block.
append( splitFragment );
215 for (
const QString &part : tabSplit )
217 if ( !part.isEmpty() )
220 block.
append( tmpFragment );
222 if ( index != tabSplit.size() - 1 )
236 block.
append( tmpFragment );
242 if ( !block.
empty() )
245 sourceBlock = sourceBlock.next();
246 if ( !sourceBlock.isValid() )
265 if ( doc.
size() > 0 )
272 mBlocks.append( block );
277 mBlocks.push_back( block );
282 mBlocks.insert( index, block );
287 mBlocks.insert( index, block );
292 mBlocks.reserve( count );
297 return mBlocks.at( i );
307 return mBlocks.size();
312 QStringList textLines;
313 textLines.reserve( mBlocks.size() );
319 line.append( fragment.text() );
328 const QVector< QgsTextBlock > prevBlocks = mBlocks;
330 mBlocks.reserve( prevBlocks.size() );
337 QStringList thisParts;
338 if ( !wrapCharacter.isEmpty() && wrapCharacter != QLatin1String(
"\n" ) )
341 const QStringList lines = fragment.text().split( wrapCharacter );
342 for (
const QString &line : lines )
344 thisParts.append( line.split(
'\n' ) );
349 thisParts = fragment.text().split(
'\n' );
353 if ( autoWrapLength != 0 )
355 QStringList autoWrappedLines;
356 autoWrappedLines.reserve( thisParts.count() );
357 for (
const QString &line : std::as_const( thisParts ) )
359 autoWrappedLines.append(
QgsStringUtils::wordWrap( line, autoWrapLength, useMaxLineLengthWhenAutoWrapping ).split(
'\n' ) );
361 thisParts = autoWrappedLines;
364 if ( thisParts.empty() )
366 else if ( thisParts.size() == 1 )
367 destinationBlock.
append( fragment );
370 if ( !thisParts.at( 0 ).isEmpty() )
373 append( destinationBlock );
374 destinationBlock.
clear();
375 for (
int i = 1 ; i < thisParts.size() - 1; ++i )
381 destinationBlock.
append(
QgsTextFragment( thisParts.at( thisParts.size() - 1 ), fragment.characterFormat() ) );
384 append( destinationBlock );
392 block.applyCapitalization( capitalization );
397QVector< QgsTextBlock >::const_iterator QgsTextDocument::begin()
const
399 return mBlocks.begin();
402QVector< QgsTextBlock >::const_iterator QgsTextDocument::end()
const
404 return mBlocks.end();
Capitalization
String capitalization options.
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
Stores information relating to individual block formatting.
Represents a block of text consisting of one or more QgsTextFragment objects.
void clear()
Clears the block, removing all its contents.
static QgsTextBlock fromPlainText(const QString &text, const QgsTextCharacterFormat &format=QgsTextCharacterFormat())
Constructor for QgsTextBlock consisting of a plain text, and optional character format.
void setBlockFormat(const QgsTextBlockFormat &format)
Sets the block format for the fragment.
void append(const QgsTextFragment &fragment)
Appends a fragment to the block.
bool empty() const
Returns true if the block is empty.
Stores information relating to individual character formatting.
void overrideWith(const QgsTextCharacterFormat &other)
Override all the default/unset properties of the current character format with the settings from anot...
void setFontPercentageSize(double size)
Sets the font percentage size (as fraction of inherited font size).
Represents a document consisting of one or more QgsTextBlock objects.
void splitLines(const QString &wrapCharacter, int autoWrapLength=0, bool useMaxLineLengthWhenAutoWrapping=true)
Splits lines of text in the document to separate lines, using a specified wrap character (wrapCharact...
QgsTextBlock & operator[](int index)
Returns the block at the specified index.
const QgsTextBlock & at(int index) const
Returns the block at the specified index.
void reserve(int count)
Reserves the specified count of blocks for optimised block appending.
QStringList toPlainText() const
Returns a list of plain text lines of text representing the document.
int size() const
Returns the number of blocks in the document.
static QgsTextDocument fromHtml(const QStringList &lines)
Constructor for QgsTextDocument consisting of a set of HTML formatted lines.
static QgsTextDocument fromPlainText(const QStringList &lines)
Constructor for QgsTextDocument consisting of a set of plain text lines.
void append(const QgsTextBlock &block)
Appends a block to the document.
void insert(int index, const QgsTextBlock &block)
Inserts a block into the document, at the specified index.
static QgsTextDocument fromTextAndFormat(const QStringList &lines, const QgsTextFormat &format)
Constructor for QgsTextDocument consisting of a set of lines, respecting settings from a text format.
void applyCapitalization(Qgis::Capitalization capitalization)
Applies a capitalization style to the document's text.
Container for all settings relating to text rendering.
Qgis::Capitalization capitalization() const
Returns the text capitalization style.
bool allowHtmlFormatting() const
Returns true if text should be treated as a HTML document and HTML tags should be used for formatting...
Stores a fragment of document along with formatting overrides to be used when rendering the fragment.
void setText(const QString &text)
Sets the text content of the fragment.
void setCharacterFormat(const QgsTextCharacterFormat &format)
Sets the character format for the fragment.
const QgsTextCharacterFormat & characterFormat() const
Returns the character formatting for the fragment.
#define TAB_REPLACEMENT_MARKER