src/hbcore/primitives/hbrichtextitem.cpp
changeset 21 4633027730f5
parent 1 f7ac710697a9
child 23 e6ad4ef83b23
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
    35 #include <QTextBlock>
    35 #include <QTextBlock>
    36 #include <QTextLayout>
    36 #include <QTextLayout>
    37 #include <QPainter>
    37 #include <QPainter>
    38 #include <QAbstractTextDocumentLayout>
    38 #include <QAbstractTextDocumentLayout>
    39 #include <QApplication>
    39 #include <QApplication>
    40 
    40 #include <QWidget>
    41 const int KMinimumLetersToShow = 4;
    41 
       
    42 const qreal KMinimumRichTextWidth = 6.0;
    42 
    43 
    43 static const QString KDefaultColorThemeName = "qtc_view_normal";
    44 static const QString KDefaultColorThemeName = "qtc_view_normal";
    44 
    45 
    45 HbRichTextItemPrivate::HbRichTextItemPrivate() :
    46 HbRichTextItemPrivate::HbRichTextItemPrivate() :
    46     mAlignment(Qt::AlignLeft|Qt::AlignVCenter),
    47         mTextOption(Qt::AlignLeft|Qt::AlignVCenter),
    47     mTextOption(mAlignment),
    48         mRtf(0)
    48     mDontPrint(false),
       
    49     mDontClip(false),
       
    50     mRtf(0)
       
    51 {
    49 {
    52 }
    50 }
    53 
    51 
    54 HbRichTextItemPrivate::~HbRichTextItemPrivate()
    52 HbRichTextItemPrivate::~HbRichTextItemPrivate()
    55 {
    53 {
    60  */
    58  */
    61 void HbRichTextItemPrivate::init()
    59 void HbRichTextItemPrivate::init()
    62 {
    60 {
    63     Q_Q(HbRichTextItem);
    61     Q_Q(HbRichTextItem);
    64 
    62 
    65     q->setFlag(QGraphicsItem::ItemClipsToShape, !mDontClip);
    63     q->setFlag(QGraphicsItem::ItemClipsToShape, true);
    66     q->setFlag(QGraphicsItem::ItemIsSelectable, false);
    64     q->setFlag(QGraphicsItem::ItemIsSelectable, false);
    67     q->setFlag(QGraphicsItem::ItemIsFocusable,  false);
    65     q->setFlag(QGraphicsItem::ItemIsFocusable,  false);
    68 
    66 
    69     mRtf = new QTextDocument(q);
    67     mRtf = new QTextDocument(q);
    70     mRtf->setDocumentMargin(0.0); // no margins needed
    68     mRtf->setDocumentMargin(0.0); // no margins needed
    75     mRtf->setDefaultFont(q->font());
    73     mRtf->setDefaultFont(q->font());
    76 }
    74 }
    77 
    75 
    78 void HbRichTextItemPrivate::clear()
    76 void HbRichTextItemPrivate::clear()
    79 {
    77 {
    80     delete mRtf;
    78 }
    81 }
    79 
    82 
    80 void HbRichTextItemPrivate::setDocumentWidth(qreal newWidth)
    83 int HbRichTextItemPrivate::textFlagsFromTextOption() const
    81 {
    84 {
    82     if (!qFuzzyCompare(mRtf->textWidth(), newWidth)) {
    85     int flags = (int)mAlignment;
    83         mRtf->setTextWidth(newWidth);
    86 
       
    87     switch(mTextOption.wrapMode()) {
       
    88     case QTextOption::NoWrap:
       
    89         flags |= Qt::TextSingleLine;
       
    90         break;
       
    91     case QTextOption::WordWrap:
       
    92         flags |=Qt::TextWordWrap;
       
    93         break;
       
    94     case QTextOption::ManualWrap:
       
    95         break;
       
    96     case QTextOption::WrapAnywhere:
       
    97         flags |=Qt::TextWrapAnywhere;
       
    98         break;
       
    99     case QTextOption::WrapAtWordBoundaryOrAnywhere:
       
   100         flags |=Qt::TextWordWrap | Qt::TextWrapAnywhere;
       
   101         break;
       
   102     }
       
   103 
       
   104     if(mDontClip)  flags |= Qt::TextDontClip;
       
   105     if(mDontPrint) flags |= Qt::TextDontPrint;
       
   106 
       
   107     return flags;
       
   108 }
       
   109 
       
   110 bool HbRichTextItemPrivate::setLayoutDirection(Qt::LayoutDirection newDirection)
       
   111 {
       
   112     Qt::Alignment oldAlign = mTextOption.alignment();
       
   113     Qt::Alignment alignment = QStyle::visualAlignment(newDirection, mAlignment);
       
   114     mTextOption.setAlignment(alignment);
       
   115     mTextOption.setTextDirection(newDirection);
       
   116     mRtf->setDefaultTextOption(mTextOption);
       
   117 
       
   118     return alignment!=oldAlign;
       
   119 }
       
   120 
       
   121 void HbRichTextItemPrivate::setSize(const QSizeF &newSize)
       
   122 {
       
   123     if(mRtf->size()!=newSize) {
       
   124         Q_Q(HbRichTextItem);
       
   125         mRtf->setTextWidth(newSize.width());
       
   126         calculateOffset();
    84         calculateOffset();
   127         q->update();
       
   128     }
    85     }
   129 }
    86 }
   130 
    87 
   131 // #define HB_RICH_TEXT_ITEM_ALWAS_SHOW_FIRST_LINE
    88 // #define HB_RICH_TEXT_ITEM_ALWAS_SHOW_FIRST_LINE
   132 void HbRichTextItemPrivate::calculateOffset()
    89 void HbRichTextItemPrivate::calculateOffset()
   133 {
    90 {
   134     Q_Q(HbRichTextItem);
    91     Q_Q(HbRichTextItem);
   135 
    92 
   136     qreal diff;
    93     qreal diff;
   137     if(mAlignment.testFlag(Qt::AlignTop)) {
    94     Qt::Alignment align = mTextOption.alignment();
       
    95     if (align.testFlag(Qt::AlignTop)) {
   138         diff = 0.0;
    96         diff = 0.0;
   139     } else {
    97     } else {
   140         diff = q->geometry().height() - mRtf->size().height();
    98         diff = q->geometry().height() - mRtf->size().height();
   141         if(!mAlignment.testFlag(Qt::AlignBottom)) {
    99         if (!align.testFlag(Qt::AlignBottom)) {
   142             // default align Qt::AlignVCenter if no flags are set
   100             // default align Qt::AlignVCenter if no flags are set
   143             diff*=0.5;
   101             diff*=0.5;
   144         }
   102         }
   145     }
   103     }
   146 #ifdef HB_RICH_TEXT_ITEM_ALWAS_SHOW_FIRST_LINE
   104 #ifdef HB_RICH_TEXT_ITEM_ALWAS_SHOW_FIRST_LINE
   147     diff = qMax(diff, (qreal)0.0);
   105     diff = qMax(diff, (qreal)0.0);
   148 #endif
   106 #endif
   149 
   107 
   150     if(diff!=mOffset.y()) {
   108     if (diff!=mOffset.y()) {
   151         mOffset.setY(diff);
   109         mOffset.setY(diff);
   152         q->prepareGeometryChange();
   110         q->prepareGeometryChange();
   153     }
   111     }
       
   112 }
       
   113 
       
   114 QSizeF HbRichTextItemPrivate::minimumSizeHint(const QSizeF &/*constraint*/) const
       
   115 {
       
   116     QSizeF result(KMinimumRichTextWidth, 0);
       
   117 
       
   118     QTextBlock textBlock = mRtf->begin();
       
   119     if (textBlock.isValid() && textBlock.layout()->lineCount() > 0) {
       
   120         QTextLine line = textBlock.layout()->lineAt(0);
       
   121         result.setHeight(line.height());
       
   122     } else {
       
   123         QFontMetricsF metrics(mRtf->defaultFont());
       
   124         result.setHeight(metrics.height());
       
   125     }
       
   126 
       
   127     qreal doubleDocMargin = mRtf->documentMargin() * (qreal)2.0;
       
   128     result.rheight() += doubleDocMargin;
       
   129     result.rwidth() += doubleDocMargin;
       
   130 
       
   131     return result;
       
   132 }
       
   133 
       
   134 void HbRichTextItemPrivate::clearPrefSizeCache()
       
   135 {
       
   136     mPrefSize.setWidth(-1);
       
   137     mMinWidthForAdjust = QWIDGETSIZE_MAX;
       
   138     mMaxWidthForAdjust = -1;
       
   139 }
       
   140 
       
   141 QSizeF HbRichTextItemPrivate::preferredSizeHint(const QSizeF &constraint) const
       
   142 {
       
   143     if (mPrefSizeConstraint==constraint && mPrefSize.isValid()) {
       
   144         return mPrefSize;
       
   145     }
       
   146     mPrefSizeConstraint=constraint;
       
   147 
       
   148     QSizeF result;
       
   149 
       
   150     if (constraint.width()<=0) {
       
   151         mRtf->setTextWidth(QWIDGETSIZE_MAX);
       
   152     } else {
       
   153         QTextOption::WrapMode wrapMode = mTextOption.wrapMode();
       
   154         // optimization when there is no automatic wrap there is no reason
       
   155         // to setTextWidth with width constraint (width measure is not needed)
       
   156         if (wrapMode!=QTextOption::NoWrap
       
   157             && wrapMode!=QTextOption::ManualWrap) {
       
   158             mRtf->setTextWidth(constraint.width());
       
   159         }
       
   160     }
       
   161     result = mRtf->size();
       
   162     mMaxWidthForAdjust = result.width();
       
   163     result.setWidth(mRtf->idealWidth());
       
   164     mMinWidthForAdjust = result.width();
       
   165     mDefaultPrefHeight = result.height();
       
   166     mPrefSize = result;
       
   167 
       
   168     return result;
       
   169 }
       
   170 
       
   171 bool HbRichTextItemPrivate::isAdjustHeightNeeded(qreal newWidth,
       
   172                                                  qreal prefHeight,
       
   173                                                  qreal minHeight,
       
   174                                                  qreal maxHeight)
       
   175 {
       
   176     // first check if wrapping of text is not active
       
   177     QTextOption::WrapMode wrapMode = mTextOption.wrapMode();
       
   178     if (wrapMode==QTextOption::NoWrap
       
   179         || wrapMode==QTextOption::ManualWrap) {
       
   180         return false;
       
   181     }
       
   182 
       
   183     // preferred height was set from outside of this class so there is mo reason to adjust it
       
   184     if (mPrefSizeConstraint.height()>0) {
       
   185         return false;
       
   186     }
       
   187 
       
   188     // check if adjusted size has been already calculated
       
   189     // new width is bigger than last estimated range of same height
       
   190     if ((mMaxWidthForAdjust>=newWidth
       
   191          // new width is smaller than last estimated range of same height
       
   192          && newWidth>=mMinWidthForAdjust)) {
       
   193         return false;
       
   194     }
       
   195 
       
   196     if (!mPrefSize.isValid()) {
       
   197         // this means that preferred size is set outside of class by setPreferredSize
       
   198         // so sizeHint(Qt::Preferredsize) was not called and size adjustment is useless
       
   199         return false;
       
   200     }
       
   201 
       
   202     // new text width was set in setGeometry here it is not needed
       
   203     Q_ASSERT_X(qFuzzyCompare(mRtf->textWidth(), newWidth),
       
   204                "HbRichTextItemPrivate::isAdjustHeightNeeded",
       
   205                QString("mRtf->textWidth()=%1, newWidth=%2")
       
   206                     .arg(mRtf->textWidth())
       
   207                     .arg(newWidth).toAscii().data());
       
   208 
       
   209     // if preconditions are met test if current height is enough
       
   210     QSizeF newAdjust = mRtf->size();
       
   211 
       
   212     if (qFuzzyCompare(newAdjust.height(), mPrefSize.height())) {
       
   213         // height is same as last time update range of same height
       
   214         mMaxWidthForAdjust = qMax(mMaxWidthForAdjust, newWidth);
       
   215         mMinWidthForAdjust = qMin(mMinWidthForAdjust, newWidth);
       
   216         return false;
       
   217     }
       
   218 
       
   219     // new height was calculated create new range for which
       
   220     // current mPrefSize.height is valid
       
   221     mMaxWidthForAdjust = newWidth;
       
   222     mMinWidthForAdjust = mRtf->idealWidth();
       
   223 
       
   224     // store new height, don't change width
       
   225     mPrefSize.setHeight(newAdjust.height());
       
   226 
       
   227     Q_ASSERT_X(mPrefSizeConstraint.width()>0 || mPrefSize.width()>=mMinWidthForAdjust,
       
   228                "HbRichTextItemPrivate::isAdjustHeightNeeded",
       
   229                QString("Fail for (%1<%2) string: \"%3\"")
       
   230                .arg(mPrefSize.width())
       
   231                .arg(mMinWidthForAdjust)
       
   232                .arg(mText).toAscii().data());
       
   233 
       
   234     if (qFuzzyCompare(qBound(minHeight, mPrefSize.height(), maxHeight),
       
   235                       prefHeight)) {
       
   236         // updateGeometry has no effect
       
   237         return false;
       
   238     }
       
   239 
       
   240     // all conditions for calling updateGeometry are meet
       
   241     return true;
       
   242 }
       
   243 
       
   244 /*
       
   245     returns true if updateGeometry is needed
       
   246  */
       
   247 bool HbRichTextItemPrivate::restoreDefaultHeightHint()
       
   248 {
       
   249     if (mPrefSizeConstraint.height()>0) {
       
   250         return false;
       
   251     }
       
   252 
       
   253     if (mPrefSizeConstraint.width()>0) {
       
   254         clearPrefSizeCache();
       
   255         return true;
       
   256     }
       
   257 
       
   258     if (mPrefSize.height()==mDefaultPrefHeight) {
       
   259         return true;
       
   260     }
       
   261 
       
   262     mPrefSize.setHeight(mDefaultPrefHeight);
       
   263     mMinWidthForAdjust = mPrefSize.width();
       
   264     mMaxWidthForAdjust = QWIDGETSIZE_MAX;
       
   265     return true;
   154 }
   266 }
   155 
   267 
   156 /*!
   268 /*!
   157   @proto
   269   @proto
   158   @hbcore
   270   @hbcore
   168 /*!
   280 /*!
   169     Constructor for the class.
   281     Constructor for the class.
   170  */
   282  */
   171 
   283 
   172 HbRichTextItem::HbRichTextItem(QGraphicsItem *parent) :
   284 HbRichTextItem::HbRichTextItem(QGraphicsItem *parent) :
   173     HbWidgetBase(*new HbRichTextItemPrivate, parent)
   285         HbWidgetBase(*new HbRichTextItemPrivate, parent)
   174 {
   286 {
   175     Q_D(HbRichTextItem);
   287     Q_D(HbRichTextItem);
   176     d->init();
   288     d->init();
   177 }
   289 }
   178 
   290 
   179 /*!
   291 /*!
   180     Constructor which set content using \a html format.
   292     Constructor which set content using \a html format.
   181  */
   293  */
   182 HbRichTextItem::HbRichTextItem(const QString &html, QGraphicsItem *parent) :
   294 HbRichTextItem::HbRichTextItem(const QString &html, QGraphicsItem *parent) :
   183     HbWidgetBase(*new HbRichTextItemPrivate, parent)
   295         HbWidgetBase(*new HbRichTextItemPrivate, parent)
   184 {
   296 {
   185     Q_D(HbRichTextItem);
   297     Q_D(HbRichTextItem);
   186     d->init();
   298     d->init();
   187     setText(html);
   299     setText(html);
   188 }
   300 }
   189 
   301 
   190 /*
   302 /*
   191     Constructor for internal use only
   303     Constructor for internal use only
   192  */
   304  */
   193 HbRichTextItem::HbRichTextItem(HbRichTextItemPrivate &dd, QGraphicsItem *parent) :
   305 HbRichTextItem::HbRichTextItem(HbRichTextItemPrivate &dd, QGraphicsItem *parent) :
   194     HbWidgetBase(dd, parent)
   306         HbWidgetBase(dd, parent)
   195 {
   307 {
   196     Q_D(HbRichTextItem);
   308     Q_D(HbRichTextItem);
   197     d->init();
   309     d->init();
   198 }
   310 }
   199 
   311 
   215 {
   327 {
   216     Q_D(HbRichTextItem);
   328     Q_D(HbRichTextItem);
   217     if (d->mText != text) {
   329     if (d->mText != text) {
   218         d->mText = text;
   330         d->mText = text;
   219         d->mRtf->setHtml(text);
   331         d->mRtf->setHtml(text);
       
   332         d->clearPrefSizeCache();
   220         updateGeometry();
   333         updateGeometry();
   221     }
   334     }
   222 }
   335 }
   223 
   336 
   224 /*!
   337 /*!
   227     \sa HbRichTextItem::setText()
   340     \sa HbRichTextItem::setText()
   228  */
   341  */
   229 
   342 
   230 QString HbRichTextItem::text() const
   343 QString HbRichTextItem::text() const
   231 {
   344 {
   232     Q_D( const HbRichTextItem );
   345     Q_D(const HbRichTextItem);
   233     return d->mText;
   346     return d->mText;
   234 }
   347 }
   235 
   348 
   236 /*!
   349 /*!
   237     Sets \a alignment for the text from Qt::Alignment enumeration.
   350     Sets \a alignment for the text from Qt::Alignment enumeration.
   238 
   351 
   239     \sa HbRichTextItem::alignment()
   352     \sa HbRichTextItem::alignment()
   240  */
   353  */
   241 void HbRichTextItem::setAlignment(Qt::Alignment alignment)
   354 void HbRichTextItem::setAlignment(Qt::Alignment alignment)
   242 {
   355 {
   243     Q_D( HbRichTextItem );
   356     Q_D(HbRichTextItem);
   244 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextAlign, true);
   357 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextAlign, true);
   245     alignment &= Qt::AlignVertical_Mask | Qt::AlignHorizontal_Mask;
   358     alignment &= Qt::AlignVertical_Mask | Qt::AlignHorizontal_Mask;
   246     if( d->mAlignment!=alignment ) {
   359     if (d->mTextOption.alignment()!=alignment) {
   247         prepareGeometryChange();
   360         prepareGeometryChange();
   248         d->mAlignment = alignment;
   361         d->mTextOption.setAlignment(alignment);
       
   362         d->mRtf->setDefaultTextOption(d->mTextOption);
   249         d->calculateOffset();
   363         d->calculateOffset();
   250         if(d->setLayoutDirection(layoutDirection())) {
   364         update();
   251             update();
       
   252         }
       
   253     }
   365     }
   254 }
   366 }
   255 
   367 
   256 /*!
   368 /*!
   257     Returns alignment for the text from Qt::Alignment enumeration.
   369     Returns alignment for the text from Qt::Alignment enumeration.
   258 
   370 
   259     \sa HbRichTextItem::setAlignment()
   371     \sa HbRichTextItem::setAlignment()
   260  */
   372  */
   261 Qt::Alignment HbRichTextItem::alignment() const
   373 Qt::Alignment HbRichTextItem::alignment() const
   262 {
   374 {
   263     Q_D( const HbRichTextItem );
   375     Q_D(const HbRichTextItem);
   264     return d->mAlignment;
   376     return d->mTextOption.alignment();
   265 }
   377 }
   266 
   378 
   267 /*!
   379 /*!
   268     \reimp
   380     \reimp
   269  */
   381  */
   270 void HbRichTextItem::paint(QPainter *painter, 
   382 void HbRichTextItem::paint(QPainter *painter, 
   271                             const QStyleOptionGraphicsItem *option, 
   383                            const QStyleOptionGraphicsItem *option,
   272                             QWidget *widget)
   384                            QWidget *widget)
   273 {
   385 {
   274     Q_UNUSED(option);
   386     Q_UNUSED(option);
   275     Q_UNUSED(widget);
   387     Q_UNUSED(widget);
   276 
   388 
   277     Q_D(HbRichTextItem);
   389     Q_D(HbRichTextItem);
   278 
   390 
   279     // Save painter's state
   391     // Save painter's state
   280     QRegion oldClipRegion = painter->clipRegion();
   392     QRegion oldClipRegion = painter->clipRegion();
   281     QTransform oldTransform = painter->transform();
   393     QTransform oldTransform = painter->transform();
   282 
   394 
   283     if(!d->mDontPrint) {
   395     painter->translate(d->mOffset);
   284         if(!d->mDontClip) {
   396     QAbstractTextDocumentLayout::PaintContext context;
   285             painter->setClipRect(contentsRect(), Qt::IntersectClip);
   397     context.palette.setColor(QPalette::Text, textDefaultColor());
   286         }
   398     d->mRtf->documentLayout()->draw(painter, context);
   287         painter->translate(d->mOffset);
       
   288         QAbstractTextDocumentLayout::PaintContext context;
       
   289         context.palette.setColor(QPalette::Text, textDefaultColor());
       
   290         d->mRtf->documentLayout()->draw(painter, context);
       
   291     }
       
   292 
   399 
   293     // Restore painter's state
   400     // Restore painter's state
   294     painter->setClipRegion(oldClipRegion);
   401     painter->setClipRegion(oldClipRegion);
   295     painter->setTransform(oldTransform);
   402     painter->setTransform(oldTransform);
   296 }
   403 }
   304 {
   411 {
   305     Q_D(HbRichTextItem);
   412     Q_D(HbRichTextItem);
   306 
   413 
   307     HbWidgetBase::setGeometry(rect);
   414     HbWidgetBase::setGeometry(rect);
   308 
   415 
   309     if(rect.isValid()) {
   416     // this call is needed since there is possible scenario
   310         d->setSize(rect.size());
   417     // when size was not changed after updateGeometry and sizeHint calls
       
   418     d->setDocumentWidth(size().width());
       
   419 
       
   420     if (parentLayoutItem() && parentLayoutItem()->isLayout()) {
       
   421         // rect.size can't be used here since size can be limited inside of
       
   422         // called method HbWidgetBase::setGeometry(rect) so size is used which
       
   423         // holds current size
       
   424         if (d->isAdjustHeightNeeded(size().width(),
       
   425                                     preferredHeight(),
       
   426                                     minimumHeight(),
       
   427                                     maximumHeight())) {
       
   428             updateGeometry();
       
   429             return;
       
   430         }
   311     }
   431     }
   312 }
   432 }
   313 
   433 
   314 /*!
   434 /*!
   315     \reimp
   435     \reimp
   316  */
   436  */
   317 QRectF HbRichTextItem::boundingRect () const
   437 QRectF HbRichTextItem::boundingRect () const
   318 {
   438 {
   319     Q_D(const HbRichTextItem);
   439     Q_D(const HbRichTextItem);
   320 
   440 
   321     QRectF result(d->mOffset, d->mRtf->size());
   441     QRectF result(d->mRtf->documentLayout()->frameBoundingRect(d->mRtf->rootFrame()));
   322 
   442     result.translate(d->mOffset);
   323     if(!d->mDontClip) {
   443 
       
   444     if (flags().testFlag(QGraphicsItem::ItemClipsToShape)) {
   324         // clip
   445         // clip
   325         result = result.intersect(QRectF(QPointF(),
   446         result = result.intersect(contentsRect());
   326                                           size()));
       
   327     }
   447     }
   328     return result;
   448     return result;
   329 }
   449 }
   330 
   450 
   331 /*!
   451 /*!
   332     \reimp
   452     \reimp
   333     Relayouts text according to new size.
   453     Relayouts text according to new size.
   334  */
   454  */
   335 void HbRichTextItem::resizeEvent(QGraphicsSceneResizeEvent *event)
   455 void HbRichTextItem::resizeEvent(QGraphicsSceneResizeEvent * /*event*/)
   336 {
   456 {
   337     Q_D(HbRichTextItem);
   457     Q_D(HbRichTextItem);
   338 
   458 
   339     d->setSize(event->newSize());
   459     d->setDocumentWidth(size().width());
       
   460     d->calculateOffset();
   340 }
   461 }
   341 
   462 
   342 /*!
   463 /*!
   343     \reimp
   464     \reimp
   344     This impelementation detects layout direction changes, font changes and theme changes.
   465     This implementation detects layout direction changes, font changes and theme changes.
   345  */
   466  */
   346 void HbRichTextItem::changeEvent(QEvent *event)
   467 void HbRichTextItem::changeEvent(QEvent *event)
   347 {
   468 {
   348     Q_D(HbRichTextItem);
   469     Q_D(HbRichTextItem);
   349 
   470 
   350     switch(event->type()) {
   471     switch(event->type()) {
   351     case QEvent::LayoutDirectionChange: {
   472     case QEvent::LayoutDirectionChange: {
   352             prepareGeometryChange();
   473             prepareGeometryChange();
   353             d->setLayoutDirection(layoutDirection());
   474             d->mTextOption.setTextDirection(layoutDirection());
       
   475             d->mRtf->setDefaultTextOption(d->mTextOption);
   354             update();
   476             update();
   355         }
   477         }
   356         break;
   478         break;
   357 
   479 
   358     case QEvent::FontChange: {
   480     case QEvent::FontChange: {
   359             d->mRtf->setDefaultFont(font());
   481             d->mRtf->setDefaultFont(font());
       
   482             d->clearPrefSizeCache();
   360             updateGeometry();
   483             updateGeometry();
   361         }
   484         }
   362         break;
   485         break;
   363 
   486 
   364     default:
   487     default:
   365         // Listens theme changed event so that item size hint is
   488         // Listens theme changed event so that item size hint is
   366         // update when physical font is changed.
   489         // update when physical font is changed.
   367         if (event->type() == HbEvent::ThemeChanged) {
   490         if (event->type() == HbEvent::ThemeChanged) {
   368             Q_D(HbRichTextItem);
   491             Q_D(HbRichTextItem);
   369             d->mDefaultColor = QColor();
   492             d->mDefaultColor = QColor();
   370             if(!d->mColor.isValid()) { 
   493             if (!d->mColor.isValid()) {
   371                 update();
   494                 update();
   372             }
   495             }
   373         }
   496         }
   374     }
   497     }
   375     HbWidgetBase::changeEvent(event);
   498     HbWidgetBase::changeEvent(event);
   385 {
   508 {
   386     Q_D(const HbRichTextItem);
   509     Q_D(const HbRichTextItem);
   387     QSizeF result;
   510     QSizeF result;
   388     switch(which) {
   511     switch(which) {
   389     case Qt::MinimumSize: {
   512     case Qt::MinimumSize: {
   390             QTextBlock textBlock = d->mRtf->begin();
   513             result = d->minimumSizeHint(constraint);
   391             if(textBlock.isValid() && textBlock.layout()->lineCount() > 0) {
       
   392                 QTextLine line = textBlock.layout()->lineAt(0);
       
   393                 result.setHeight(line.height());
       
   394                 int cursorPos(KMinimumLetersToShow);
       
   395                 result.setWidth( line.cursorToX(&cursorPos) );
       
   396 
       
   397                 qreal doubleDocMargin = d->mRtf->documentMargin() * (qreal)2.0;
       
   398                 result.rheight() += doubleDocMargin;
       
   399                 result.rwidth() += doubleDocMargin;
       
   400             } else {
       
   401                 result = HbWidgetBase::sizeHint(which, constraint);
       
   402             }
       
   403         }
   514         }
   404         break;
   515         break;
   405 
   516 
   406     case Qt::PreferredSize: {
   517     case Qt::PreferredSize: {
   407             if(constraint.width()<=0) {
   518             result = d->preferredSizeHint(constraint);
   408                 d->mRtf->adjustSize();
       
   409             } else {
       
   410                 d->mRtf->setTextWidth(constraint.width());
       
   411             }
       
   412             result = d->mRtf->size();
       
   413         }
   519         }
   414         break;
   520         break;
   415 
   521 
   416     default:
   522     default:
   417         result = HbWidgetBase::sizeHint(which, constraint);
   523         result = HbWidgetBase::sizeHint(which, constraint);
   430 {
   536 {
   431     Q_D(HbRichTextItem);
   537     Q_D(HbRichTextItem);
   432 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextWrapMode, true);
   538 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextWrapMode, true);
   433     QTextOption::WrapMode textWrapMode = static_cast<QTextOption::WrapMode>(mode);
   539     QTextOption::WrapMode textWrapMode = static_cast<QTextOption::WrapMode>(mode);
   434 
   540 
   435     if(d->mTextOption.wrapMode()!=textWrapMode) {
   541     if (d->mTextOption.wrapMode()!=textWrapMode) {
   436         prepareGeometryChange();
   542         prepareGeometryChange();
   437         d->mTextOption.setWrapMode(textWrapMode);
   543         d->mTextOption.setWrapMode(textWrapMode);
   438         d->mRtf->setDefaultTextOption(d->mTextOption);
   544         d->mRtf->setDefaultTextOption(d->mTextOption);
   439         updateGeometry();
   545         d->calculateOffset();
       
   546         if (d->restoreDefaultHeightHint()) {
       
   547             updateGeometry();
       
   548         }
   440     }
   549     }
   441 }
   550 }
   442 
   551 
   443 /*!
   552 /*!
   444  * @proto
   553  * @proto
   462  *
   571  *
   463  * \sa setTextDefaultColor()
   572  * \sa setTextDefaultColor()
   464  */
   573  */
   465 QColor HbRichTextItem::textDefaultColor() const
   574 QColor HbRichTextItem::textDefaultColor() const
   466 {
   575 {
   467     Q_D( const HbRichTextItem );
   576     Q_D(const HbRichTextItem);
   468 
   577 
   469     if (d->mColor.isValid()) { // Means user has set text color
   578     if (d->mColor.isValid()) { // Means user has set text color
   470         return d->mColor;
   579         return d->mColor;
   471     } 
   580     } 
   472     if (!d->mDefaultColor.isValid()) {
   581     if (!d->mDefaultColor.isValid()) {
   511 /*!
   620 /*!
   512  * Shows (default) or hides text. Size hint remains unchanged (same as when text is visible).
   621  * Shows (default) or hides text. Size hint remains unchanged (same as when text is visible).
   513  */
   622  */
   514 void HbRichTextItem::setTextVisible(bool isVisible)
   623 void HbRichTextItem::setTextVisible(bool isVisible)
   515 {
   624 {
   516     Q_D(HbRichTextItem);
   625     setVisible(isVisible);
   517     if( d->mDontPrint == isVisible ) {
       
   518         d->mDontPrint = !isVisible;
       
   519         update();
       
   520     }
       
   521 }
   626 }
   522 
   627 
   523 /*!
   628 /*!
   524  * Returns if text is visible.
   629  * Returns if text is visible.
   525  */
   630  */
   526 bool HbRichTextItem::isTextVisible() const
   631 bool HbRichTextItem::isTextVisible() const
   527 {
   632 {
   528     Q_D(const HbRichTextItem);
   633     return isVisible();
   529     return !d->mDontPrint;
       
   530 }
   634 }
   531 
   635 
   532 /*!
   636 /*!
   533  * Enables (default) or disables text clipping when item geometry is too small.
   637  * Enables (default) or disables text clipping when item geometry is too small.
   534  */
   638  */
   535 void HbRichTextItem::setTextClip(bool cliping)
   639 void HbRichTextItem::setTextClip(bool clipping)
   536 {
   640 {
   537     Q_D(HbRichTextItem);
   641     setFlag(QGraphicsItem::ItemClipsToShape, clipping);
   538     if( d->mDontClip == cliping ) {
       
   539         prepareGeometryChange();
       
   540         d->mDontClip = !cliping;
       
   541         setFlag(QGraphicsItem::ItemClipsToShape, cliping);
       
   542         update();
       
   543     }
       
   544 }
   642 }
   545 
   643 
   546 /*!
   644 /*!
   547  * Returns true if text is clipped when item geometry is too small.
   645  * Returns true if text is clipped when item geometry is too small.
   548  */
   646  */
   549 bool HbRichTextItem::isTextClip() const
   647 bool HbRichTextItem::isTextClip() const
   550 {
   648 {
   551     Q_D(const HbRichTextItem);
   649     return flags().testFlag(ItemClipsToShape);
   552     return !d->mDontClip;
       
   553 }
   650 }
   554 
   651 
   555 // end of file
   652 // end of file