summaryrefslogtreecommitdiffstats
path: root/src/kernel/qsimplerichtext.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /src/kernel/qsimplerichtext.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'src/kernel/qsimplerichtext.cpp')
-rw-r--r--src/kernel/qsimplerichtext.cpp421
1 files changed, 421 insertions, 0 deletions
diff --git a/src/kernel/qsimplerichtext.cpp b/src/kernel/qsimplerichtext.cpp
new file mode 100644
index 0000000..9712b90
--- /dev/null
+++ b/src/kernel/qsimplerichtext.cpp
@@ -0,0 +1,421 @@
+/****************************************************************************
+**
+** Implementation of the QSimpleRichText class
+**
+** Created : 990101
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qsimplerichtext.h"
+
+#ifndef QT_NO_RICHTEXT
+#include "qrichtext_p.h"
+#include "qapplication.h"
+
+class QSimpleRichTextData
+{
+public:
+ QTextDocument *doc;
+ QFont font;
+ int cachedWidth;
+ bool cachedWidthWithPainter;
+ void adjustSize(QPainter *p = 0);
+};
+
+// Pull this private function in from qglobal.cpp
+extern unsigned int qt_int_sqrt( unsigned int n );
+
+void QSimpleRichTextData::adjustSize(QPainter *p) {
+ QFontMetrics fm( font );
+ int mw = fm.width( 'x' ) * 80;
+ int w = mw;
+ doc->doLayout(p, w);
+ if ( doc->widthUsed() != 0 ) {
+ w = qt_int_sqrt( 5 * doc->height() * doc->widthUsed() / 3 );
+ doc->doLayout(p, QMIN(w, mw));
+
+ if ( w*3 < 5*doc->height() ) {
+ w = qt_int_sqrt( 2 * doc->height() * doc->widthUsed() );
+ doc->doLayout(p, QMIN(w, mw));
+ }
+ }
+ cachedWidth = doc->width();
+ cachedWidthWithPainter = FALSE;
+}
+
+/*!
+ \class QSimpleRichText qsimplerichtext.h
+ \brief The QSimpleRichText class provides a small displayable piece of rich text.
+
+ \ingroup text
+ \mainclass
+
+ This class encapsulates simple rich text usage in which a string
+ is interpreted as rich text and can be drawn. This is particularly
+ useful if you want to display some rich text in a custom widget. A
+ QStyleSheet is needed to interpret the tags and format the rich
+ text. Qt provides a default HTML-like style sheet, but you may
+ define custom style sheets.
+
+ Once created, the rich text object can be queried for its width(),
+ height(), and the actual width used (see widthUsed()). Most
+ importantly, it can be drawn on any given QPainter with draw().
+ QSimpleRichText can also be used to implement hypertext or active
+ text facilities by using anchorAt(). A hit test through inText()
+ makes it possible to use simple rich text for text objects in
+ editable drawing canvases.
+
+ Once constructed from a string the contents cannot be changed,
+ only resized. If the contents change, just throw the rich text
+ object away and make a new one with the new contents.
+
+ For large documents use QTextEdit or QTextBrowser. For very small
+ items of rich text you can use a QLabel.
+
+ If you are using QSimpleRichText to print in high resolution you
+ should call setWidth(QPainter, int) so that the content will be
+ laid out properly on the page.
+*/
+
+/*!
+ Constructs a QSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ The font is used as a basis for the text rendering. When using
+ rich text rendering on a widget \e w, you would normally specify
+ the widget's font, for example:
+
+ \code
+ QSimpleRichText myrichtext( contents, mywidget->font() );
+ \endcode
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text contains relative references, for
+ example within image tags. QSimpleRichText always uses the default
+ mime source factory (see \l{QMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ QMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{QStyleSheet::defaultSheet()}).
+*/
+
+QSimpleRichText::QSimpleRichText( const QString& text, const QFont& fnt,
+ const QString& context, const QStyleSheet* sheet )
+{
+ d = new QSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->font = fnt;
+ d->doc = new QTextDocument( 0 );
+ d->doc->setTextFormat( Qt::RichText );
+ d->doc->setLeftMargin( 0 );
+ d->doc->setRightMargin( 0 );
+ d->doc->setFormatter( new QTextFormatterBreakWords );
+ d->doc->setStyleSheet( (QStyleSheet*)sheet );
+ d->doc->setDefaultFormat( fnt, QColor() );
+ d->doc->setText( text, context );
+}
+
+
+/*!
+ Constructs a QSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ This is a slightly more complex constructor for QSimpleRichText
+ that takes an additional mime source factory \a factory, a page
+ break parameter \a pageBreak and a bool \a linkUnderline. \a
+ linkColor is only provided for compatibility, but has no effect,
+ as QColorGroup's QColorGroup::link() color is used now.
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text contains relative references, for
+ example within image tags. QSimpleRichText always uses the default
+ mime source factory (see \l{QMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ QMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{QStyleSheet::defaultSheet()}).
+
+ This constructor is useful for creating a QSimpleRichText object
+ suitable for printing. Set \a pageBreak to be the height of the
+ contents area of the pages.
+*/
+
+QSimpleRichText::QSimpleRichText( const QString& text, const QFont& fnt,
+ const QString& context, const QStyleSheet* sheet,
+ const QMimeSourceFactory* factory, int pageBreak,
+ const QColor& /*linkColor*/, bool linkUnderline )
+{
+ d = new QSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->font = fnt;
+ d->doc = new QTextDocument( 0 );
+ d->doc->setTextFormat( Qt::RichText );
+ d->doc->setFormatter( new QTextFormatterBreakWords );
+ d->doc->setStyleSheet( (QStyleSheet*)sheet );
+ d->doc->setDefaultFormat( fnt, QColor() );
+ d->doc->flow()->setPageSize( pageBreak );
+ d->doc->setPageBreakEnabled( TRUE );
+#ifndef QT_NO_MIME
+ d->doc->setMimeSourceFactory( (QMimeSourceFactory*)factory );
+#endif
+ d->doc->setUnderlineLinks( linkUnderline );
+ d->doc->setText( text, context );
+}
+
+/*!
+ Destroys the rich text object, freeing memory.
+*/
+
+QSimpleRichText::~QSimpleRichText()
+{
+ delete d->doc;
+ delete d;
+}
+
+/*!
+ \overload
+
+ Sets the width of the rich text object to \a w pixels.
+
+ \sa height(), adjustSize()
+*/
+
+void QSimpleRichText::setWidth( int w )
+{
+ if ( w == d->cachedWidth && !d->cachedWidthWithPainter )
+ return;
+ d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() );
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = FALSE;
+ d->doc->doLayout( 0, w );
+}
+
+/*!
+ Sets the width of the rich text object to \a w pixels,
+ recalculating the layout as if it were to be drawn with painter \a
+ p.
+
+ Passing a painter is useful when you intend drawing on devices
+ other than the screen, for example a QPrinter.
+
+ \sa height(), adjustSize()
+*/
+
+void QSimpleRichText::setWidth( QPainter *p, int w )
+{
+ if ( w == d->cachedWidth && d->cachedWidthWithPainter )
+ return;
+ d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() ||
+ p && p->device() &&
+ p->device()->devType() == QInternal::Printer );
+ p->save();
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = TRUE;
+ d->doc->doLayout( p, w );
+ p->restore();
+}
+
+/*!
+ Returns the set width of the rich text object in pixels.
+
+ \sa widthUsed()
+*/
+
+int QSimpleRichText::width() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->width();
+}
+
+/*!
+ Returns the width in pixels that is actually used by the rich text
+ object. This can be smaller or wider than the set width.
+
+ It may be wider, for example, if the text contains images or
+ non-breakable words that are already wider than the available
+ space. It's smaller when the object only consists of lines that do
+ not fill the width completely.
+
+ \sa width()
+*/
+
+int QSimpleRichText::widthUsed() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->widthUsed();
+}
+
+/*!
+ Returns the height of the rich text object in pixels.
+
+ \sa setWidth()
+*/
+
+int QSimpleRichText::height() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->height();
+}
+
+/*!
+ Adjusts the richt text object to a reasonable size.
+
+ \sa setWidth()
+*/
+
+void QSimpleRichText::adjustSize()
+{
+ d->adjustSize();
+}
+
+/*!
+ Draws the formatted text with painter \a p, at position (\a x, \a
+ y), clipped to \a clipRect. The clipping rectangle is given in the
+ rich text object's coordinates translated by (\a x, \a y). Passing
+ an null rectangle results in no clipping. Colors from the color
+ group \a cg are used as needed, and if not 0, \a *paper is used as
+ the background brush.
+
+ Note that the display code is highly optimized to reduce flicker,
+ so passing a brush for \a paper is preferable to simply clearing
+ the area to be painted and then calling this without a brush.
+*/
+
+void QSimpleRichText::draw( QPainter *p, int x, int y, const QRect& clipRect,
+ const QColorGroup& cg, const QBrush* paper ) const
+{
+ p->save();
+ if ( d->cachedWidth < 0 )
+ d->adjustSize(p);
+
+ QRect r = clipRect;
+ if ( !r.isNull() )
+ r.moveBy( -x, -y );
+
+ if ( paper )
+ d->doc->setPaper( new QBrush( *paper ) );
+ QColorGroup g = cg;
+ if ( d->doc->paper() )
+ g.setBrush( QColorGroup::Base, *d->doc->paper() );
+
+ if ( !clipRect.isNull() )
+ p->setClipRect( clipRect, QPainter::CoordPainter );
+ p->translate( x, y );
+ d->doc->draw( p, r, g, paper );
+ p->translate( -x, -y );
+ p->restore();
+}
+
+
+/*! \fn void QSimpleRichText::draw( QPainter *p, int x, int y, const QRegion& clipRegion,
+ const QColorGroup& cg, const QBrush* paper ) const
+
+ \obsolete
+
+ Use the version with clipRect instead. The region version has
+ problems with larger documents on some platforms (on X11 regions
+ internally are represented with 16bit coordinates).
+*/
+
+
+
+/*!
+ Returns the context of the rich text object. If no context has
+ been specified in the constructor, a null string is returned. The
+ context is the path to use to look up relative links, such as
+ image tags and anchor references.
+*/
+
+QString QSimpleRichText::context() const
+{
+ return d->doc->context();
+}
+
+/*!
+ Returns the anchor at the requested position, \a pos. An empty
+ string is returned if no anchor is specified for this position.
+*/
+
+QString QSimpleRichText::anchorAt( const QPoint& pos ) const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ QTextCursor c( d->doc );
+ c.place( pos, d->doc->firstParagraph(), TRUE );
+ return c.paragraph()->at( c.index() )->anchorHref();
+}
+
+/*!
+ Returns TRUE if \a pos is within a text line of the rich text
+ object; otherwise returns FALSE.
+*/
+
+bool QSimpleRichText::inText( const QPoint& pos ) const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ if ( pos.y() > d->doc->height() )
+ return FALSE;
+ QTextCursor c( d->doc );
+ c.place( pos, d->doc->firstParagraph() );
+ return c.totalOffsetX() + c.paragraph()->at( c.index() )->x +
+ c.paragraph()->at( c.index() )->format()->width( c.paragraph()->at( c.index() )->c ) > pos.x();
+}
+
+/*!
+ Sets the default font for the rich text object to \a f
+*/
+
+void QSimpleRichText::setDefaultFont( const QFont &f )
+{
+ if ( d->font == f )
+ return;
+ d->font = f;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->doc->setDefaultFormat( f, QColor() );
+ d->doc->setText( d->doc->originalText(), d->doc->context() );
+}
+
+#endif //QT_NO_RICHTEXT