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