source: vendor/trolltech/current/src/kernel/qsimplerichtext.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1/****************************************************************************
2** $Id: qsimplerichtext.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of the QSimpleRichText class
5**
6** Created : 990101
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qsimplerichtext.h"
39
40#ifndef QT_NO_RICHTEXT
41#include "qrichtext_p.h"
42#include "qapplication.h"
43
44class QSimpleRichTextData
45{
46public:
47 QTextDocument *doc;
48 QFont font;
49 int cachedWidth;
50 bool cachedWidthWithPainter;
51 void adjustSize(QPainter *p = 0);
52};
53
54// Pull this private function in from qglobal.cpp
55extern unsigned int qt_int_sqrt( unsigned int n );
56
57void QSimpleRichTextData::adjustSize(QPainter *p) {
58 QFontMetrics fm( font );
59 int mw = fm.width( 'x' ) * 80;
60 int w = mw;
61 doc->doLayout(p, w);
62 if ( doc->widthUsed() != 0 ) {
63 w = qt_int_sqrt( 5 * doc->height() * doc->widthUsed() / 3 );
64 doc->doLayout(p, QMIN(w, mw));
65
66 if ( w*3 < 5*doc->height() ) {
67 w = qt_int_sqrt( 2 * doc->height() * doc->widthUsed() );
68 doc->doLayout(p, QMIN(w, mw));
69 }
70 }
71 cachedWidth = doc->width();
72 cachedWidthWithPainter = FALSE;
73}
74
75/*!
76 \class QSimpleRichText qsimplerichtext.h
77 \brief The QSimpleRichText class provides a small displayable piece of rich text.
78
79 \ingroup text
80 \mainclass
81
82 This class encapsulates simple rich text usage in which a string
83 is interpreted as rich text and can be drawn. This is particularly
84 useful if you want to display some rich text in a custom widget. A
85 QStyleSheet is needed to interpret the tags and format the rich
86 text. Qt provides a default HTML-like style sheet, but you may
87 define custom style sheets.
88
89 Once created, the rich text object can be queried for its width(),
90 height(), and the actual width used (see widthUsed()). Most
91 importantly, it can be drawn on any given QPainter with draw().
92 QSimpleRichText can also be used to implement hypertext or active
93 text facilities by using anchorAt(). A hit test through inText()
94 makes it possible to use simple rich text for text objects in
95 editable drawing canvases.
96
97 Once constructed from a string the contents cannot be changed,
98 only resized. If the contents change, just throw the rich text
99 object away and make a new one with the new contents.
100
101 For large documents use QTextEdit or QTextBrowser. For very small
102 items of rich text you can use a QLabel.
103
104 If you are using QSimpleRichText to print in high resolution you
105 should call setWidth(QPainter, int) so that the content will be
106 laid out properly on the page.
107*/
108
109/*!
110 Constructs a QSimpleRichText from the rich text string \a text and
111 the font \a fnt.
112
113 The font is used as a basis for the text rendering. When using
114 rich text rendering on a widget \e w, you would normally specify
115 the widget's font, for example:
116
117 \code
118 QSimpleRichText myrichtext( contents, mywidget->font() );
119 \endcode
120
121 \a context is the optional context of the rich text object. This
122 becomes important if \a text contains relative references, for
123 example within image tags. QSimpleRichText always uses the default
124 mime source factory (see \l{QMimeSourceFactory::defaultFactory()})
125 to resolve those references. The context will then be used to
126 calculate the absolute path. See
127 QMimeSourceFactory::makeAbsolute() for details.
128
129 The \a sheet is an optional style sheet. If it is 0, the default
130 style sheet will be used (see \l{QStyleSheet::defaultSheet()}).
131*/
132
133QSimpleRichText::QSimpleRichText( const QString& text, const QFont& fnt,
134 const QString& context, const QStyleSheet* sheet )
135{
136 d = new QSimpleRichTextData;
137 d->cachedWidth = -1;
138 d->cachedWidthWithPainter = FALSE;
139 d->font = fnt;
140 d->doc = new QTextDocument( 0 );
141 d->doc->setTextFormat( Qt::RichText );
142 d->doc->setLeftMargin( 0 );
143 d->doc->setRightMargin( 0 );
144 d->doc->setFormatter( new QTextFormatterBreakWords );
145 d->doc->setStyleSheet( (QStyleSheet*)sheet );
146 d->doc->setDefaultFormat( fnt, QColor() );
147 d->doc->setText( text, context );
148}
149
150
151/*!
152 Constructs a QSimpleRichText from the rich text string \a text and
153 the font \a fnt.
154
155 This is a slightly more complex constructor for QSimpleRichText
156 that takes an additional mime source factory \a factory, a page
157 break parameter \a pageBreak and a bool \a linkUnderline. \a
158 linkColor is only provided for compatibility, but has no effect,
159 as QColorGroup's QColorGroup::link() color is used now.
160
161 \a context is the optional context of the rich text object. This
162 becomes important if \a text contains relative references, for
163 example within image tags. QSimpleRichText always uses the default
164 mime source factory (see \l{QMimeSourceFactory::defaultFactory()})
165 to resolve those references. The context will then be used to
166 calculate the absolute path. See
167 QMimeSourceFactory::makeAbsolute() for details.
168
169 The \a sheet is an optional style sheet. If it is 0, the default
170 style sheet will be used (see \l{QStyleSheet::defaultSheet()}).
171
172 This constructor is useful for creating a QSimpleRichText object
173 suitable for printing. Set \a pageBreak to be the height of the
174 contents area of the pages.
175*/
176
177QSimpleRichText::QSimpleRichText( const QString& text, const QFont& fnt,
178 const QString& context, const QStyleSheet* sheet,
179 const QMimeSourceFactory* factory, int pageBreak,
180 const QColor& /*linkColor*/, bool linkUnderline )
181{
182 d = new QSimpleRichTextData;
183 d->cachedWidth = -1;
184 d->cachedWidthWithPainter = FALSE;
185 d->font = fnt;
186 d->doc = new QTextDocument( 0 );
187 d->doc->setTextFormat( Qt::RichText );
188 d->doc->setFormatter( new QTextFormatterBreakWords );
189 d->doc->setStyleSheet( (QStyleSheet*)sheet );
190 d->doc->setDefaultFormat( fnt, QColor() );
191 d->doc->flow()->setPageSize( pageBreak );
192 d->doc->setPageBreakEnabled( TRUE );
193#ifndef QT_NO_MIME
194 d->doc->setMimeSourceFactory( (QMimeSourceFactory*)factory );
195#endif
196 d->doc->setUnderlineLinks( linkUnderline );
197 d->doc->setText( text, context );
198}
199
200/*!
201 Destroys the rich text object, freeing memory.
202*/
203
204QSimpleRichText::~QSimpleRichText()
205{
206 delete d->doc;
207 delete d;
208}
209
210/*!
211 \overload
212
213 Sets the width of the rich text object to \a w pixels.
214
215 \sa height(), adjustSize()
216*/
217
218void QSimpleRichText::setWidth( int w )
219{
220 if ( w == d->cachedWidth && !d->cachedWidthWithPainter )
221 return;
222 d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() );
223 d->cachedWidth = w;
224 d->cachedWidthWithPainter = FALSE;
225 d->doc->doLayout( 0, w );
226}
227
228/*!
229 Sets the width of the rich text object to \a w pixels,
230 recalculating the layout as if it were to be drawn with painter \a
231 p.
232
233 Passing a painter is useful when you intend drawing on devices
234 other than the screen, for example a QPrinter.
235
236 \sa height(), adjustSize()
237*/
238
239void QSimpleRichText::setWidth( QPainter *p, int w )
240{
241 if ( w == d->cachedWidth && d->cachedWidthWithPainter )
242 return;
243 d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() ||
244 p && p->device() &&
245 p->device()->devType() == QInternal::Printer );
246 p->save();
247 d->cachedWidth = w;
248 d->cachedWidthWithPainter = TRUE;
249 d->doc->doLayout( p, w );
250 p->restore();
251}
252
253/*!
254 Returns the set width of the rich text object in pixels.
255
256 \sa widthUsed()
257*/
258
259int QSimpleRichText::width() const
260{
261 if ( d->cachedWidth < 0 )
262 d->adjustSize();
263 return d->doc->width();
264}
265
266/*!
267 Returns the width in pixels that is actually used by the rich text
268 object. This can be smaller or wider than the set width.
269
270 It may be wider, for example, if the text contains images or
271 non-breakable words that are already wider than the available
272 space. It's smaller when the object only consists of lines that do
273 not fill the width completely.
274
275 \sa width()
276*/
277
278int QSimpleRichText::widthUsed() const
279{
280 if ( d->cachedWidth < 0 )
281 d->adjustSize();
282 return d->doc->widthUsed();
283}
284
285/*!
286 Returns the height of the rich text object in pixels.
287
288 \sa setWidth()
289*/
290
291int QSimpleRichText::height() const
292{
293 if ( d->cachedWidth < 0 )
294 d->adjustSize();
295 return d->doc->height();
296}
297
298/*!
299 Adjusts the richt text object to a reasonable size.
300
301 \sa setWidth()
302*/
303
304void QSimpleRichText::adjustSize()
305{
306 d->adjustSize();
307}
308
309/*!
310 Draws the formatted text with painter \a p, at position (\a x, \a
311 y), clipped to \a clipRect. The clipping rectangle is given in the
312 rich text object's coordinates translated by (\a x, \a y). Passing
313 an null rectangle results in no clipping. Colors from the color
314 group \a cg are used as needed, and if not 0, \a *paper is used as
315 the background brush.
316
317 Note that the display code is highly optimized to reduce flicker,
318 so passing a brush for \a paper is preferable to simply clearing
319 the area to be painted and then calling this without a brush.
320*/
321
322void QSimpleRichText::draw( QPainter *p, int x, int y, const QRect& clipRect,
323 const QColorGroup& cg, const QBrush* paper ) const
324{
325 p->save();
326 if ( d->cachedWidth < 0 )
327 d->adjustSize(p);
328
329 QRect r = clipRect;
330 if ( !r.isNull() )
331 r.moveBy( -x, -y );
332
333 if ( paper )
334 d->doc->setPaper( new QBrush( *paper ) );
335 QColorGroup g = cg;
336 if ( d->doc->paper() )
337 g.setBrush( QColorGroup::Base, *d->doc->paper() );
338
339 if ( !clipRect.isNull() )
340 p->setClipRect( clipRect, QPainter::CoordPainter );
341 p->translate( x, y );
342 d->doc->draw( p, r, g, paper );
343 p->translate( -x, -y );
344 p->restore();
345}
346
347
348/*! \fn void QSimpleRichText::draw( QPainter *p, int x, int y, const QRegion& clipRegion,
349 const QColorGroup& cg, const QBrush* paper ) const
350
351 \obsolete
352
353 Use the version with clipRect instead. The region version has
354 problems with larger documents on some platforms (on X11 regions
355 internally are represented with 16bit coordinates).
356*/
357
358
359
360/*!
361 Returns the context of the rich text object. If no context has
362 been specified in the constructor, a null string is returned. The
363 context is the path to use to look up relative links, such as
364 image tags and anchor references.
365*/
366
367QString QSimpleRichText::context() const
368{
369 return d->doc->context();
370}
371
372/*!
373 Returns the anchor at the requested position, \a pos. An empty
374 string is returned if no anchor is specified for this position.
375*/
376
377QString QSimpleRichText::anchorAt( const QPoint& pos ) const
378{
379 if ( d->cachedWidth < 0 )
380 d->adjustSize();
381 QTextCursor c( d->doc );
382 c.place( pos, d->doc->firstParagraph(), TRUE );
383 return c.paragraph()->at( c.index() )->anchorHref();
384}
385
386/*!
387 Returns TRUE if \a pos is within a text line of the rich text
388 object; otherwise returns FALSE.
389*/
390
391bool QSimpleRichText::inText( const QPoint& pos ) const
392{
393 if ( d->cachedWidth < 0 )
394 d->adjustSize();
395 if ( pos.y() > d->doc->height() )
396 return FALSE;
397 QTextCursor c( d->doc );
398 c.place( pos, d->doc->firstParagraph() );
399 return c.totalOffsetX() + c.paragraph()->at( c.index() )->x +
400 c.paragraph()->at( c.index() )->format()->width( c.paragraph()->at( c.index() )->c ) > pos.x();
401}
402
403/*!
404 Sets the default font for the rich text object to \a f
405*/
406
407void QSimpleRichText::setDefaultFont( const QFont &f )
408{
409 if ( d->font == f )
410 return;
411 d->font = f;
412 d->cachedWidth = -1;
413 d->cachedWidthWithPainter = FALSE;
414 d->doc->setDefaultFormat( f, QColor() );
415 d->doc->setText( d->doc->originalText(), d->doc->context() );
416}
417
418#endif //QT_NO_RICHTEXT
Note: See TracBrowser for help on using the repository browser.