~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/QIRichLabel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 *
 
3
 * VBox frontends: Qt GUI ("VirtualBox"):
 
4
 * innotek Qt extensions: QIRichLabel class implementation
 
5
 */
 
6
 
 
7
/*
 
8
 * Copyright (C) 2006-2007 innotek GmbH
 
9
 *
 
10
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
11
 * available from http://www.virtualbox.org. This file is free software;
 
12
 * you can redistribute it and/or modify it under the terms of the GNU
 
13
 * General Public License as published by the Free Software Foundation,
 
14
 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
 
15
 * distribution. VirtualBox OSE is distributed in the hope that it will
 
16
 * be useful, but WITHOUT ANY WARRANTY of any kind.
 
17
 */
 
18
 
 
19
/*
 
20
 * This class is based on the original QLabel implementation.
 
21
 */
 
22
 
 
23
#include "QIRichLabel.h"
 
24
 
 
25
#include <qpainter.h>
 
26
#include <qaccel.h>
 
27
#include <qmovie.h>
 
28
#include <qimage.h>
 
29
#include <qpicture.h>
 
30
#include <qapplication.h>
 
31
#include <qsimplerichtext.h>
 
32
#include <qstylesheet.h>
 
33
#include <qstyle.h>
 
34
#include <qregexp.h>
 
35
#include <qfocusdata.h>
 
36
#include <qtooltip.h>
 
37
#include <qpopupmenu.h>
 
38
#include <qaction.h>
 
39
#include <qclipboard.h>
 
40
#include <qcursor.h>
 
41
 
 
42
class QLabelPrivate
 
43
{
 
44
public:
 
45
   QLabelPrivate()
 
46
      :img (0), pix (0), valid_hints (-1)
 
47
   {}
 
48
   QImage* img; // for scaled contents
 
49
   QPixmap* pix; // for scaled contents
 
50
   QSize sh;
 
51
   QSize msh;
 
52
   int valid_hints; // stores the frameWidth() for the stored size hint, -1 otherwise
 
53
};
 
54
 
 
55
 
 
56
QIRichLabel::QIRichLabel (QWidget *parent, const char *name, WFlags f)
 
57
: QFrame (parent, name, f | WMouseNoMask)
 
58
{
 
59
   init();
 
60
}
 
61
 
 
62
 
 
63
QIRichLabel::QIRichLabel (const QString &text, QWidget *parent, const char *name,
 
64
                          WFlags f)
 
65
                          : QFrame (parent, name, f | WMouseNoMask)
 
66
{
 
67
   init();
 
68
   setText (text);
 
69
}
 
70
 
 
71
 
 
72
QIRichLabel::QIRichLabel (QWidget *buddy,  const QString &text,
 
73
                          QWidget *parent, const char *name, WFlags f)
 
74
                          : QFrame (parent, name, f | WMouseNoMask)
 
75
{
 
76
   init();
 
77
   setBuddy (buddy);
 
78
   setText (text);
 
79
}
 
80
 
 
81
 
 
82
QIRichLabel::~QIRichLabel()
 
83
{
 
84
   clearContents();
 
85
   delete d;
 
86
}
 
87
 
 
88
 
 
89
void QIRichLabel::init()
 
90
{
 
91
   mMaxHeightMode = false;
 
92
   baseheight = 0;
 
93
   lpixmap = 0;
 
94
   lmovie = 0;
 
95
   lbuddy = 0;
 
96
   accel = 0;
 
97
   lpixmap = 0;
 
98
   lpicture = 0;
 
99
   align = AlignAuto | AlignVCenter | ExpandTabs;
 
100
   extraMargin = -1;
 
101
   autoresize = FALSE;
 
102
   scaledcontents = FALSE;
 
103
   textformat = Qt::AutoText;
 
104
   doc = 0;
 
105
 
 
106
   d = new QLabelPrivate;
 
107
 
 
108
   QAction *copyAction = new QAction (this, "copyAction");
 
109
   connect (copyAction, SIGNAL (activated()),
 
110
      this, SLOT (putToClipBoard()));
 
111
   copyAction->setMenuText (tr ("Copy to clipboard"));
 
112
 
 
113
   popupMenu = new QPopupMenu (this, "contextMenu");
 
114
   copyAction->addTo (popupMenu);
 
115
 
 
116
   setMouseTracking (true);
 
117
}
 
118
 
 
119
 
 
120
void QIRichLabel::setFixedHeight (int aHeight)
 
121
{
 
122
    baseheight = aHeight;
 
123
    QFrame::setFixedHeight (baseheight);
 
124
}
 
125
 
 
126
 
 
127
void QIRichLabel::setText (const QString &text)
 
128
{
 
129
   if (ltext == text)
 
130
      return;
 
131
   QSize osh = sizeHint();
 
132
   bool hadRichtext = doc != 0;
 
133
 
 
134
   clearContents();
 
135
   ltext = text;
 
136
 
 
137
   bool useRichText = (textformat == RichText ||
 
138
      ((textformat == AutoText) && QStyleSheet::mightBeRichText (ltext)));
 
139
 
 
140
   // ### Setting accelerators for rich text labels will not work.
 
141
   // Eg. <b>&gt;Hello</b> will return ALT+G which is clearly
 
142
   // not intended.
 
143
   if (!useRichText) {
 
144
      int p = QAccel::shortcutKey (ltext);
 
145
      if (p) {
 
146
         if (!accel)
 
147
            accel = new QAccel (this, "accel label accel");
 
148
         accel->connectItem (accel->insertItem (p),
 
149
            this, SLOT (acceleratorSlot()));
 
150
      }
 
151
   }
 
152
 
 
153
   if (useRichText) {
 
154
      if (!hadRichtext)
 
155
         align |= WordBreak;
 
156
      QString t = ltext;
 
157
      if (align & AlignRight)
 
158
         t.prepend ("<div align=\"right\">");
 
159
      else if (align & AlignHCenter)
 
160
         t.prepend ("<div align=\"center\">");
 
161
      if ((align & WordBreak) == 0)
 
162
         t.prepend ("<nobr>");
 
163
      doc = new QSimpleRichText (compressText(0), font());
 
164
   }
 
165
 
 
166
   updateLabel (osh);
 
167
 
 
168
   if (mMaxHeightMode && (int)baseheight < heightForWidth (width()))
 
169
   {
 
170
       baseheight = heightForWidth (width());
 
171
       QFrame::setFixedHeight (baseheight);
 
172
   }
 
173
}
 
174
 
 
175
 
 
176
void QIRichLabel::clear()
 
177
{
 
178
   setText (QString::fromLatin1 (""));
 
179
}
 
180
 
 
181
 
 
182
void QIRichLabel::setPixmap (const QPixmap &pixmap)
 
183
{
 
184
   QSize osh = sizeHint();
 
185
 
 
186
   if (!lpixmap || lpixmap->serialNumber() != pixmap.serialNumber()) {
 
187
      clearContents();
 
188
      lpixmap = new QPixmap (pixmap);
 
189
   }
 
190
 
 
191
   if (lpixmap->depth() == 1 && !lpixmap->mask())
 
192
      lpixmap->setMask (*((QBitmap *)lpixmap));
 
193
 
 
194
   updateLabel (osh);
 
195
}
 
196
 
 
197
 
 
198
void QIRichLabel::setPicture (const QPicture &picture)
 
199
{
 
200
   QSize osh = sizeHint();
 
201
   clearContents();
 
202
   lpicture = new QPicture (picture);
 
203
 
 
204
   updateLabel (osh);
 
205
}
 
206
 
 
207
 
 
208
void QIRichLabel::setNum (int num)
 
209
{
 
210
   QString str;
 
211
   str.setNum (num);
 
212
   setText (str);
 
213
}
 
214
 
 
215
 
 
216
void QIRichLabel::setNum (double num)
 
217
{
 
218
   QString str;
 
219
   str.setNum (num);
 
220
   setText (str);
 
221
}
 
222
 
 
223
 
 
224
void QIRichLabel::setAlignment (int alignment)
 
225
{
 
226
   if (alignment == align)
 
227
      return;
 
228
   QSize osh = sizeHint();
 
229
 
 
230
   if (lbuddy)
 
231
      align = alignment | ShowPrefix;
 
232
   else
 
233
      align = alignment;
 
234
 
 
235
   QString t = ltext;
 
236
   if (!t.isNull()) {
 
237
      ltext = QString::null;
 
238
      setText (t);
 
239
   }
 
240
 
 
241
   updateLabel (osh);
 
242
}
 
243
 
 
244
 
 
245
void QIRichLabel::setIndent (int indent)
 
246
{
 
247
   extraMargin = indent;
 
248
   updateLabel (QSize (-1, -1));
 
249
}
 
250
 
 
251
 
 
252
void QIRichLabel::setAutoResize (bool enable)
 
253
{
 
254
   if ((bool)autoresize != enable) {
 
255
      autoresize = enable;
 
256
      if (autoresize)
 
257
         adjustSize();           // calls resize which repaints
 
258
   }
 
259
}
 
260
 
 
261
 
 
262
void QIRichLabel::setMaxHeightMode (bool aEnabled)
 
263
{
 
264
    mMaxHeightMode = aEnabled;
 
265
}
 
266
 
 
267
 
 
268
QSize QIRichLabel::sizeForWidth (int w) const
 
269
{
 
270
   QRect br;
 
271
   QPixmap *pix = pixmap();
 
272
   QPicture *pic = picture();
 
273
   QMovie *mov = movie();
 
274
 
 
275
   int hextra = 2 * frameWidth();
 
276
   int vextra = hextra;
 
277
   QFontMetrics fm (fontMetrics());
 
278
   int xw = fm.width ('x');
 
279
   if (!mov && !pix && !pic) {
 
280
      int m = indent();
 
281
      if (m < 0 && hextra) // no indent, but we do have a frame
 
282
         m = xw / 2 - margin();
 
283
      if (m >= 0) {
 
284
         int horizAlign = QApplication::horizontalAlignment( align );
 
285
         if ((horizAlign & AlignLeft) || (horizAlign & AlignRight))
 
286
            hextra += m;
 
287
         if ((align & AlignTop) || (align & AlignBottom))
 
288
            vextra += m;
 
289
      }
 
290
   }
 
291
 
 
292
   if (pix)
 
293
      br = pix->rect();
 
294
   else if (pic)
 
295
      br = pic->boundingRect();
 
296
   else if ( mov )
 
297
      br = mov->framePixmap().rect();
 
298
   else if (doc) {
 
299
      int focusIndent = hasFocus() ? 3 : 0;
 
300
      int oldW = doc->width();
 
301
      if ( align & WordBreak ) {
 
302
         if (w < 0)
 
303
            doc->adjustSize();
 
304
         else
 
305
            doc->setWidth (w-hextra - 2*focusIndent);
 
306
      }
 
307
      br = QRect (0, 0, doc->widthUsed(), doc->height());
 
308
      doc->setWidth (oldW);
 
309
   }
 
310
   else {
 
311
      bool tryWidth = (w < 0) && (align & WordBreak);
 
312
      if (tryWidth)
 
313
         w = xw * 80;
 
314
      else if (w < 0)
 
315
         w = 2000;
 
316
      w -= hextra;
 
317
      br = fm.boundingRect (0, 0, w ,2000, alignment(), text());
 
318
      if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
 
319
         br = fm.boundingRect (0, 0, w/2, 2000, alignment(), text());
 
320
      if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
 
321
         br = fm.boundingRect (0, 0, w/4, 2000, alignment(), text());
 
322
   }
 
323
   int wid = br.width() + hextra;
 
324
   int hei = br.height() + vextra;
 
325
 
 
326
   return QSize (wid, hei);
 
327
}
 
328
 
 
329
 
 
330
int QIRichLabel::heightForWidth (int w) const
 
331
{
 
332
   if (
 
333
      doc ||
 
334
      (align & WordBreak))
 
335
      return sizeForWidth (w).height();
 
336
   return QWidget::heightForWidth(w);
 
337
}
 
338
 
 
339
 
 
340
QSize QIRichLabel::sizeHint() const
 
341
{
 
342
   if ( d->valid_hints != frameWidth() )
 
343
      (void) QIRichLabel::minimumSizeHint();
 
344
   return d->sh;
 
345
}
 
346
 
 
347
 
 
348
QSize QIRichLabel::minimumSizeHint() const
 
349
{
 
350
   if ( d->valid_hints == frameWidth() )
 
351
      return d->msh;
 
352
 
 
353
   constPolish();
 
354
   d->valid_hints = frameWidth();
 
355
   d->sh = sizeForWidth (-1);
 
356
   QSize sz (-1, -1);
 
357
 
 
358
   if (
 
359
      !doc &&
 
360
      (align & WordBreak) == 0) {
 
361
      sz = d->sh;
 
362
   } else {
 
363
      // think about caching these for performance
 
364
      sz.rwidth() = sizeForWidth (0).width();
 
365
      sz.rheight() = sizeForWidth (QWIDGETSIZE_MAX).height();
 
366
      if (d->sh.height() < sz.height())
 
367
         sz.rheight() = d->sh.height();
 
368
   }
 
369
   if (sizePolicy().horData() == QSizePolicy::Ignored)
 
370
      sz.rwidth() = -1;
 
371
   if (sizePolicy().verData() == QSizePolicy::Ignored)
 
372
      sz.rheight() = -1;
 
373
   d->msh = sz;
 
374
   return sz;
 
375
}
 
376
 
 
377
 
 
378
void QIRichLabel::mouseMoveEvent (QMouseEvent *aEvent)
 
379
{
 
380
    if (!doc) return;
 
381
 
 
382
    QString link = doc->anchorAt (aEvent->pos());
 
383
    if (!link.isEmpty()) /* Mouse cursor above link */
 
384
        setCursor (QCursor (Qt::PointingHandCursor));
 
385
    else /* Mouse cursor above non-link */
 
386
        setCursor (QCursor (Qt::ArrowCursor));
 
387
}
 
388
 
 
389
 
 
390
void QIRichLabel::mousePressEvent (QMouseEvent *aEvent)
 
391
{
 
392
    if (!doc) return;
 
393
 
 
394
    QString link = doc->anchorAt (aEvent->pos());
 
395
    /* Check for mouse left button clicked on the link */
 
396
    if (!link.isEmpty() && aEvent->button() == LeftButton)
 
397
        emit clickedOnLink (link);
 
398
}
 
399
 
 
400
 
 
401
void QIRichLabel::resizeEvent (QResizeEvent *e)
 
402
{
 
403
   QFrame::resizeEvent (e);
 
404
 
 
405
   static const bool doc = FALSE;
 
406
 
 
407
   // optimize for standard labels
 
408
   if (frameShape() == NoFrame && (align & WordBreak) == 0 && !doc &&
 
409
       (e->oldSize().width() >= e->size().width() && (align & AlignLeft) == AlignLeft)
 
410
       && (e->oldSize().height() >= e->size().height() && (align & AlignTop) == AlignTop)) {
 
411
      setWFlags (WResizeNoErase);
 
412
      return;
 
413
   }
 
414
 
 
415
   clearWFlags (WResizeNoErase);
 
416
   QRect cr = contentsRect();
 
417
   if ( !lpixmap ||  !cr.isValid() ||
 
418
      // masked pixmaps can only reduce flicker when being top/left
 
419
      // aligned and when we do not perform scaled contents
 
420
      (lpixmap->hasAlpha() && (scaledcontents || ((align & (AlignLeft|AlignTop)) != (AlignLeft|AlignTop)))))
 
421
      return;
 
422
 
 
423
   setWFlags (WResizeNoErase);
 
424
 
 
425
   if (!scaledcontents) {
 
426
      // don't we all love QFrame? Reduce pixmap flicker
 
427
      QRegion reg = QRect (QPoint(0, 0), e->size());
 
428
      reg = reg.subtract (cr);
 
429
      int x = cr.x();
 
430
      int y = cr.y();
 
431
      int w = lpixmap->width();
 
432
      int h = lpixmap->height();
 
433
      if ((align & Qt::AlignVCenter) == Qt::AlignVCenter)
 
434
         y += cr.height()/2 - h/2;
 
435
      else if ((align & Qt::AlignBottom) == Qt::AlignBottom)
 
436
         y += cr.height() - h;
 
437
      if ((align & Qt::AlignRight) == Qt::AlignRight )
 
438
         x += cr.width() - w;
 
439
      else if ((align & Qt::AlignHCenter) == Qt::AlignHCenter )
 
440
         x += cr.width()/2 - w/2;
 
441
      if (x > cr.x())
 
442
         reg = reg.unite (QRect (cr.x(), cr.y(), x - cr.x(), cr.height()));
 
443
      if (y > cr.y())
 
444
         reg = reg.unite (QRect (cr.x(), cr.y(), cr.width(), y - cr.y()));
 
445
 
 
446
      if (x + w < cr.right())
 
447
         reg = reg.unite (QRect (x + w, cr.y(),  cr.right() - x - w, cr.height()));
 
448
      if (y + h < cr.bottom())
 
449
         reg = reg.unite (QRect (cr.x(), y +  h, cr.width(), cr.bottom() - y - h));
 
450
 
 
451
      erase (reg);
 
452
   }
 
453
}
 
454
 
 
455
 
 
456
void QIRichLabel::focusInEvent (QFocusEvent *aEvent)
 
457
{
 
458
   QFrame::focusInEvent (aEvent);
 
459
   repaint();
 
460
}
 
461
 
 
462
 
 
463
void QIRichLabel::keyPressEvent (QKeyEvent *aEvent)
 
464
{
 
465
   switch (aEvent->key())
 
466
   {
 
467
   case Qt::Key_Up:
 
468
      focusData()->home();
 
469
      focusData()->prev()->setFocus();
 
470
      break;
 
471
   case Qt::Key_Down:
 
472
      focusData()->home();
 
473
      focusData()->next()->setFocus();
 
474
      break;
 
475
   default:
 
476
      aEvent->ignore();
 
477
   }
 
478
}
 
479
 
 
480
 
 
481
void QIRichLabel::contextMenuEvent (QContextMenuEvent *aEvent)
 
482
{
 
483
    popupBuffer = doc->anchorAt (aEvent->pos());
 
484
    if (hasFocus() || !popupBuffer.isEmpty())
 
485
        popupMenu->popup (aEvent->globalPos());
 
486
}
 
487
 
 
488
 
 
489
void QIRichLabel::putToClipBoard()
 
490
{
 
491
    QString toClipBoard = ltext;
 
492
 
 
493
    if (popupBuffer.isEmpty())
 
494
        toClipBoard.remove (QRegExp ("<[^>]*>"));
 
495
    else
 
496
        toClipBoard = popupBuffer;
 
497
 
 
498
    QApplication::clipboard()->setText (toClipBoard);
 
499
}
 
500
 
 
501
 
 
502
QString QIRichLabel::compressText (int aPaneWidth) const
 
503
{
 
504
    QString allText = ltext;
 
505
 
 
506
    if (aPaneWidth == -1) aPaneWidth = width();
 
507
    int indentSize = fontMetrics().width ("x...x") + frameWidth() * 2;
 
508
 
 
509
    QStringList strList = QStringList::split ("<br>", allText);
 
510
    for (QStringList::Iterator it = strList.begin(); it != strList.end(); ++it)
 
511
    {
 
512
        QString oneString = *it;
 
513
        int oldSize = fontMetrics().width (oneString);
 
514
 
 
515
        int start = 0;
 
516
        int finish = 0;
 
517
        int position = 0;
 
518
        int textWidth = 0;
 
519
        do {
 
520
            QString filteredString = oneString;
 
521
            filteredString.remove (QRegExp (QString ("<[^>]+>")));
 
522
            textWidth = fontMetrics().width (filteredString);
 
523
            if (textWidth + indentSize > aPaneWidth)
 
524
            {
 
525
                QRegExp regStart ("(<compact(\\s+elipsis=\"(start|middle|end)\")?>)");
 
526
                QRegExp regFinish ("</compact>");
 
527
                start  = regStart.search (oneString);
 
528
                finish = regFinish.search (oneString);
 
529
                if (start == -1 || finish == -1 || finish < start)
 
530
                   break;
 
531
 
 
532
                if (regStart.cap(3) == "start")
 
533
                    position = start + regStart.cap(1).length();
 
534
                else if (regStart.cap(3) == "middle" || regStart.cap(3).isEmpty())
 
535
                    position = start + regStart.cap(1).length() +
 
536
                               (finish-start-regStart.cap(1).length())/2;
 
537
                else if (regStart.cap(3) == "end")
 
538
                    position = finish - 1;
 
539
                else
 
540
                    break;
 
541
 
 
542
                if (position == finish ||
 
543
                    position == start + (int) regStart.cap(1).length() - 1)
 
544
                   break;
 
545
                oneString.remove (position, 1);
 
546
            }
 
547
        } while (textWidth + indentSize > aPaneWidth);
 
548
        if (position) oneString.insert (position, "...");
 
549
 
 
550
        int newSize = fontMetrics().width (oneString);
 
551
        if (newSize < oldSize) *it = oneString;
 
552
    }
 
553
    QString result = strList.join ("<br>");
 
554
    return result;
 
555
}
 
556
 
 
557
 
 
558
void QIRichLabel::drawContents (QPainter *p)
 
559
{
 
560
   QRect cr = contentsRect();
 
561
 
 
562
   QPixmap *pix = pixmap();
 
563
   QPicture *pic = picture();
 
564
   QMovie *mov = movie();
 
565
 
 
566
   if (!mov && !pix && !pic) {
 
567
      int m = indent();
 
568
      if (m < 0 && frameWidth()) // no indent, but we do have a frame
 
569
         m = fontMetrics().width ('x') / 2 - margin();
 
570
      if (m > 0) {
 
571
         int hAlign = QApplication::horizontalAlignment (align);
 
572
         if (hAlign & AlignLeft)
 
573
            cr.setLeft (cr.left() + m);
 
574
         if (hAlign & AlignRight)
 
575
            cr.setRight (cr.right() - m);
 
576
         if (align & AlignTop)
 
577
            cr.setTop (cr.top() + m);
 
578
         if (align & AlignBottom)
 
579
            cr.setBottom (cr.bottom() - m);
 
580
      }
 
581
   }
 
582
 
 
583
   if (mov) {
 
584
      // ### should add movie to qDrawItem
 
585
      QRect r = style().itemRect (p, cr, align, isEnabled(), &(mov->framePixmap()),
 
586
         QString::null);
 
587
      // ### could resize movie frame at this point
 
588
      p->drawPixmap (r.x(), r.y(), mov->framePixmap());
 
589
   }
 
590
   else
 
591
      if (doc) {
 
592
         delete doc;
 
593
         QToolTip::remove (this);
 
594
         QString filteredText = compressText();
 
595
         doc = new QSimpleRichText (filteredText, font());
 
596
         /* focus indent */
 
597
         int focusIndent = hasFocus() ? 3 : 0;
 
598
         doc->setWidth (p, cr.width() - 2*focusIndent);
 
599
         int rh = doc->height();
 
600
         int yo = 0;
 
601
         if (align & AlignVCenter)
 
602
            yo = (cr.height()-rh)/2;
 
603
         else if (align & AlignBottom)
 
604
            yo = cr.height()-rh;
 
605
         if (! isEnabled() &&
 
606
            style().styleHint (QStyle::SH_EtchDisabledText, this)) {
 
607
            QColorGroup cg = colorGroup();
 
608
            cg.setColor (QColorGroup::Text, cg.light());
 
609
            doc->draw (p, cr.x()+1, cr.y()+yo+1, cr, cg, 0);
 
610
         }
 
611
 
 
612
         // QSimpleRichText always draws with QColorGroup::Text as with
 
613
         // background mode PaletteBase. QIRichLabel typically has
 
614
         // background mode PaletteBackground, so we create a temporary
 
615
         // color group with the text color adjusted.
 
616
         QColorGroup cg = colorGroup();
 
617
         QBrush paper;
 
618
         if (isEnabled())
 
619
         {
 
620
            if (hasFocus())
 
621
            {
 
622
               const QColorGroup &standartGroup = QApplication::palette().active();
 
623
               cg.setColor (QColorGroup::Text,
 
624
                  standartGroup.color (QColorGroup::HighlightedText));
 
625
               paper.setColor (standartGroup.color (QColorGroup::Highlight));
 
626
               paper.setStyle (QBrush::SolidPattern);
 
627
            }
 
628
            else
 
629
               cg.setColor (QColorGroup::Text, paletteForegroundColor());
 
630
         }
 
631
 
 
632
         doc->draw (p, cr.x()+focusIndent, cr.y()+yo, cr, cg, &paper);
 
633
         if (hasFocus())
 
634
            style().drawPrimitive (QStyle::PE_FocusRect, p, cr, cg,
 
635
            QStyle::Style_FocusAtBorder,
 
636
            cg.highlight());
 
637
 
 
638
         if (filteredText != ltext)
 
639
            QToolTip::add (this, QString ("&nbsp;&nbsp;%1").arg (ltext));
 
640
      } else
 
641
         if ( pic ) {
 
642
            QRect br = pic->boundingRect();
 
643
            int rw = br.width();
 
644
            int rh = br.height();
 
645
            if ( scaledcontents ) {
 
646
               p->save();
 
647
               p->translate (cr.x(), cr.y());
 
648
               p->scale ((double)cr.width()/rw, (double)cr.height()/rh);
 
649
               p->drawPicture (-br.x(), -br.y(), *pic);
 
650
               p->restore();
 
651
            } else {
 
652
               int xo = 0;
 
653
               int yo = 0;
 
654
               if (align & AlignVCenter)
 
655
                  yo = (cr.height()-rh)/2;
 
656
               else if (align & AlignBottom)
 
657
                  yo = cr.height()-rh;
 
658
               if (align & AlignRight)
 
659
                  xo = cr.width()-rw;
 
660
               else if (align & AlignHCenter)
 
661
                  xo = (cr.width()-rw)/2;
 
662
               p->drawPicture (cr.x()+xo-br.x(), cr.y()+yo-br.y(), *pic);
 
663
            }
 
664
         } else
 
665
         {
 
666
            if (scaledcontents && pix) {
 
667
               if (!d->img)
 
668
                  d->img = new QImage (lpixmap->convertToImage());
 
669
 
 
670
               if (!d->pix)
 
671
                  d->pix = new QPixmap;
 
672
               if (d->pix->size() != cr.size())
 
673
                  d->pix->convertFromImage (d->img->smoothScale (cr.width(), cr.height()));
 
674
               pix = d->pix;
 
675
            }
 
676
            int alignment = align;
 
677
            if ((align & ShowPrefix) && !style().styleHint(QStyle::SH_UnderlineAccelerator, this))
 
678
               alignment |= NoAccel;
 
679
            // ordinary text or pixmap label
 
680
            style().drawItem ( p, cr, alignment, colorGroup(), isEnabled(),
 
681
               pix, ltext );
 
682
         }
 
683
}
 
684
 
 
685
 
 
686
void QIRichLabel::updateLabel (QSize oldSizeHint)
 
687
{
 
688
   d->valid_hints = -1;
 
689
   QSizePolicy policy = sizePolicy();
 
690
   bool wordBreak = align & WordBreak;
 
691
   policy.setHeightForWidth (wordBreak);
 
692
   if (policy != sizePolicy())
 
693
      setSizePolicy (policy);
 
694
   if (sizeHint() != oldSizeHint)
 
695
      updateGeometry();
 
696
   if (autoresize) {
 
697
      adjustSize();
 
698
      update (contentsRect());
 
699
   } else {
 
700
      update (contentsRect());
 
701
   }
 
702
}
 
703
 
 
704
 
 
705
void QIRichLabel::acceleratorSlot()
 
706
{
 
707
   if (!lbuddy)
 
708
      return;
 
709
   QWidget * w = lbuddy;
 
710
   while (w->focusProxy())
 
711
      w = w->focusProxy();
 
712
   if (!w->hasFocus() &&
 
713
       w->isEnabled() &&
 
714
       w->isVisible() &&
 
715
       w->focusPolicy() != NoFocus) {
 
716
      QFocusEvent::setReason (QFocusEvent::Shortcut);
 
717
      w->setFocus();
 
718
      QFocusEvent::resetReason();
 
719
   }
 
720
}
 
721
 
 
722
 
 
723
void QIRichLabel::buddyDied()
 
724
{
 
725
   lbuddy = 0;
 
726
}
 
727
 
 
728
 
 
729
void QIRichLabel::setBuddy (QWidget *buddy)
 
730
{
 
731
   if (buddy)
 
732
      setAlignment (alignment() | ShowPrefix);
 
733
   else
 
734
      setAlignment (alignment() & ~ShowPrefix);
 
735
 
 
736
   if (lbuddy)
 
737
      disconnect (lbuddy, SIGNAL (destroyed()), this, SLOT (buddyDied()));
 
738
 
 
739
   lbuddy = buddy;
 
740
 
 
741
   if (!lbuddy)
 
742
      return;
 
743
 
 
744
   if (!( textformat == RichText || (textformat == AutoText &&
 
745
      QStyleSheet::mightBeRichText(ltext))))
 
746
   {
 
747
      int p = QAccel::shortcutKey (ltext);
 
748
      if (p) {
 
749
         if (!accel)
 
750
            accel = new QAccel (this, "accel label accel");
 
751
         accel->connectItem (accel->insertItem (p),
 
752
            this, SLOT (acceleratorSlot()));
 
753
      }
 
754
   }
 
755
 
 
756
   connect (lbuddy, SIGNAL (destroyed()), this, SLOT (buddyDied()));
 
757
}
 
758
 
 
759
 
 
760
QWidget * QIRichLabel::buddy() const
 
761
{
 
762
   return lbuddy;
 
763
}
 
764
 
 
765
 
 
766
void QIRichLabel::movieUpdated (const QRect &rect)
 
767
{
 
768
   QMovie *mov = movie();
 
769
   if (mov && !mov->isNull()) {
 
770
      QRect r = contentsRect();
 
771
      r = style().itemRect (0, r, align, isEnabled(), &(mov->framePixmap()),
 
772
         QString::null);
 
773
      r.moveBy (rect.x(), rect.y());
 
774
      r.setWidth (QMIN (r.width(), rect.width()));
 
775
      r.setHeight (QMIN (r.height(), rect.height()));
 
776
      repaint (r, mov->framePixmap().mask() != 0);
 
777
   }
 
778
}
 
779
 
 
780
 
 
781
void QIRichLabel::movieResized (const QSize &size)
 
782
{
 
783
   d->valid_hints = -1;
 
784
   if (autoresize)
 
785
      adjustSize();
 
786
   movieUpdated (QRect (QPoint(0,0), size));
 
787
   updateGeometry();
 
788
}
 
789
 
 
790
 
 
791
void QIRichLabel::setMovie (const QMovie &movie)
 
792
{
 
793
   QSize osh = sizeHint();
 
794
   clearContents();
 
795
 
 
796
   lmovie = new QMovie (movie);
 
797
   lmovie->connectResize (this, SLOT (movieResized (const QSize&)));
 
798
   lmovie->connectUpdate (this, SLOT (movieUpdated (const QRect&)));
 
799
 
 
800
   if (!lmovie->running())   // Assume that if the movie is running,
 
801
      updateLabel (osh); // resize/update signals will come soon enough
 
802
}
 
803
 
 
804
 
 
805
void QIRichLabel::clearContents()
 
806
{
 
807
   delete doc;
 
808
   doc = 0;
 
809
 
 
810
   delete lpixmap;
 
811
   lpixmap = 0;
 
812
 
 
813
   delete lpicture;
 
814
   lpicture = 0;
 
815
 
 
816
   delete d->img;
 
817
   d->img = 0;
 
818
 
 
819
   delete d->pix;
 
820
   d->pix = 0;
 
821
 
 
822
   ltext = QString::null;
 
823
 
 
824
   if (accel)
 
825
      accel->clear();
 
826
 
 
827
   if (lmovie) {
 
828
      lmovie->disconnectResize (this, SLOT (movieResized (const QSize&)));
 
829
      lmovie->disconnectUpdate (this, SLOT (movieUpdated (const QRect&)));
 
830
      delete lmovie;
 
831
      lmovie = 0;
 
832
   }
 
833
}
 
834
 
 
835
 
 
836
QMovie* QIRichLabel::movie() const
 
837
{
 
838
   return lmovie;
 
839
}
 
840
 
 
841
 
 
842
Qt::TextFormat QIRichLabel::textFormat() const
 
843
{
 
844
   return textformat;
 
845
}
 
846
 
 
847
void QIRichLabel::setTextFormat( Qt::TextFormat format )
 
848
{
 
849
   if (format != textformat) {
 
850
      textformat = format;
 
851
      QString t = ltext;
 
852
      if (!t.isNull()) {
 
853
         ltext = QString::null;
 
854
         setText (t);
 
855
      }
 
856
   }
 
857
}
 
858
 
 
859
 
 
860
void QIRichLabel::fontChange (const QFont&)
 
861
{
 
862
   if (!ltext.isEmpty()) {
 
863
      if (doc)
 
864
         doc->setDefaultFont (font());
 
865
 
 
866
      updateLabel (QSize (-1, -1));
 
867
   }
 
868
}
 
869
 
 
870
 
 
871
bool QIRichLabel::hasScaledContents() const
 
872
{
 
873
   return scaledcontents;
 
874
}
 
875
 
 
876
 
 
877
void QIRichLabel::setScaledContents (bool enable)
 
878
{
 
879
   if ((bool)scaledcontents == enable)
 
880
      return;
 
881
   scaledcontents = enable;
 
882
   if (!enable) {
 
883
      delete d->img;
 
884
      d->img = 0;
 
885
      delete d->pix;
 
886
      d->pix = 0;
 
887
   }
 
888
   update (contentsRect());
 
889
}
 
890
 
 
891
 
 
892
void QIRichLabel::setFont (const QFont &f)
 
893
{
 
894
   QFrame::setFont (f);
 
895
}