mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
171 lines
5.6 KiB
C++
171 lines
5.6 KiB
C++
/*
|
|
This file is part of KDE.
|
|
|
|
Copyright (c) 2009 Thomas McGuire <mcguire@kde.org>
|
|
Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
*/
|
|
|
|
#include "textutils.h"
|
|
|
|
#include <QTextBlock>
|
|
#include <QTextCharFormat>
|
|
#include <QTextDocument>
|
|
#include <KDE/KDebug>
|
|
|
|
using namespace KPIMTextEdit;
|
|
|
|
static bool isCharFormatFormatted( const QTextCharFormat &format, const QFont &defaultFont,
|
|
const QTextCharFormat &defaultBlockFormat )
|
|
{
|
|
if ( !format.anchorHref().isEmpty() ||
|
|
format.font() != defaultFont ||
|
|
format.isAnchor() ||
|
|
format.verticalAlignment() != defaultBlockFormat.verticalAlignment() ||
|
|
format.layoutDirection() != defaultBlockFormat.layoutDirection() ||
|
|
format.underlineStyle() != defaultBlockFormat.underlineStyle() ||
|
|
format.foreground().color() != defaultBlockFormat.foreground().color() ||
|
|
format.background().color() != defaultBlockFormat.background().color() ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool isBlockFormatFormatted( const QTextBlockFormat &format,
|
|
const QTextBlockFormat &defaultFormat )
|
|
{
|
|
if ( format.alignment() != defaultFormat.alignment() ||
|
|
format.layoutDirection() != defaultFormat.layoutDirection() ||
|
|
format.indent() != defaultFormat.indent() ||
|
|
format.textIndent() != defaultFormat.textIndent() ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// @return true if the format represents a list, table, image or something like that.
|
|
static bool isSpecial( const QTextFormat &charFormat )
|
|
{
|
|
return charFormat.isFrameFormat() || charFormat.isImageFormat() ||
|
|
charFormat.isListFormat() || charFormat.isTableFormat() || charFormat.isTableCellFormat();
|
|
}
|
|
|
|
bool TextUtils::containsFormatting( const QTextDocument *document )
|
|
{
|
|
if ( !document ) {
|
|
return false;
|
|
}
|
|
|
|
QTextDocument defaultTextDocument;
|
|
const QTextCharFormat defaultCharFormat = defaultTextDocument.begin().charFormat();
|
|
const QTextBlockFormat defaultBlockFormat = defaultTextDocument.begin().blockFormat();
|
|
const QFont defaultFont = defaultTextDocument.defaultFont();
|
|
|
|
QTextBlock block = document->firstBlock();
|
|
while ( block.isValid() ) {
|
|
|
|
if ( isBlockFormatFormatted( block.blockFormat(), defaultBlockFormat ) ) {
|
|
return true;
|
|
}
|
|
|
|
if ( isSpecial( block.charFormat() ) || isSpecial( block.blockFormat() ) ||
|
|
block.textList() ) {
|
|
return true;
|
|
}
|
|
|
|
QTextBlock::iterator it = block.begin();
|
|
while ( !it.atEnd() ) {
|
|
const QTextFragment fragment = it.fragment();
|
|
const QTextCharFormat charFormat = fragment.charFormat();
|
|
if ( isSpecial( charFormat ) ) {
|
|
return true;
|
|
}
|
|
if ( isCharFormatFormatted( fragment.charFormat(), defaultFont, defaultCharFormat ) ) {
|
|
return true;
|
|
}
|
|
|
|
it++;
|
|
}
|
|
|
|
block = block.next();
|
|
}
|
|
|
|
if ( document->toHtml().contains( QLatin1String( "<hr />" ) ) ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
QString TextUtils::flowText( QString &wrappedText, const QString &indent, int maxLength )
|
|
{
|
|
if ( wrappedText.isEmpty() ) {
|
|
return indent;
|
|
}
|
|
|
|
if ( maxLength <= indent.length() ) {
|
|
kWarning() << "indent was set to a string that is longer or the same length "
|
|
<< "as maxLength, setting maxLength to indent.length() + 1";
|
|
maxLength = indent.length() + 1;
|
|
}
|
|
|
|
maxLength -= indent.length(); // take into account indent
|
|
QString result;
|
|
while ( !wrappedText.isEmpty() ) {
|
|
// first check for the next newline. if it's before maxLength, break there, and continue
|
|
int newLine = wrappedText.indexOf( QLatin1Char( '\n' ) );
|
|
if ( newLine > 0 && newLine <= maxLength ) {
|
|
result += indent + wrappedText.left( newLine + 1 );
|
|
wrappedText = wrappedText.mid( newLine + 1 );
|
|
continue;
|
|
}
|
|
// Find the next point in the wrappedText where we have to do a line break.
|
|
// Start searching at maxLength position and then walk backwards looking
|
|
// for a space.
|
|
int breakPosition;
|
|
if ( wrappedText.length() > maxLength ) {
|
|
breakPosition = maxLength;
|
|
while ( ( breakPosition >= 0 ) && ( wrappedText[breakPosition] != QLatin1Char( ' ' ) ) ) {
|
|
breakPosition--;
|
|
}
|
|
if ( breakPosition <= 0 ) {
|
|
// Couldn't break before maxLength.
|
|
breakPosition = maxLength;
|
|
}
|
|
} else {
|
|
breakPosition = wrappedText.length();
|
|
}
|
|
|
|
QString line = wrappedText.left( breakPosition );
|
|
if ( breakPosition < wrappedText.length() ) {
|
|
wrappedText = wrappedText.mid( breakPosition );
|
|
} else {
|
|
wrappedText.clear();
|
|
}
|
|
|
|
// Strip leading whitespace of new lines, since that looks strange
|
|
if ( !result.isEmpty() && line.startsWith( QLatin1Char( ' ' ) ) ) {
|
|
line = line.mid( 1 );
|
|
}
|
|
|
|
result += indent + line + QLatin1Char( '\n' );
|
|
}
|
|
|
|
return result.left( result.length() - 1 );
|
|
}
|