src/hbcore/primitives/hbtextitem.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    35 #include <QPainter>
    35 #include <QPainter>
    36 #include <QTextOption>
    36 #include <QTextOption>
    37 #include <QApplication>
    37 #include <QApplication>
    38 
    38 
    39 #ifdef HB_TEXT_MEASUREMENT_UTILITY
    39 #ifdef HB_TEXT_MEASUREMENT_UTILITY
    40 #include "hbtextmeasurementutility_p.h"
    40 #include "hbtextmeasurementutility_r.h"
    41 #include "hbfeaturemanager_r.h"
    41 #include "hbtextmeasurementutility_r_p.h"
    42 #endif
    42 #endif
    43 
    43 
    44 // #define HB_TEXT_ITEM_LOGS
       
    45 #define EPSILON 0.01
    44 #define EPSILON 0.01
    46 
    45 
    47 #ifdef HB_TEXT_ITEM_LOGS
    46 // #define HB_DEBUG_TEXT_ITEM_LOGS
    48 #   include <QDebug>
    47 #ifdef HB_DEBUG_TEXT_ITEM_LOGS
    49 const int KMaxLogedTextLength = 30;
    48     #include <QDebug>
    50 #endif // HB_TEXT_ITEM_LOGS
    49 
       
    50     #define HB_TEXT_ITEM_LOG(args) qDebug() << "HbTextItem::" << __FUNCTION__ \
       
    51             << "(" << __LINE__ << ")"\
       
    52             << ", objectName:" << this->objectName() \
       
    53             << ", text: " << this->text().left(30) \
       
    54             << " " << args;
       
    55     #define HB_TEXT_ITEM_PRIV_LOG(args) qDebug() << "HbTextItemPrivate::" << __FUNCTION__ \
       
    56             << "(" << __LINE__ << ")"\
       
    57             << ", objectName:" << q_ptr->objectName() \
       
    58             << ", text: " << this->mText.left(30) \
       
    59             << " " << args;
       
    60 #else
       
    61     #define HB_TEXT_ITEM_LOG(args)
       
    62     #define HB_TEXT_ITEM_PRIV_LOG(args)
       
    63 #endif // HB_DEBUG_TEXT_ITEM_LOGS
    51 
    64 
    52 bool HbTextItemPrivate::outlinesEnabled = false;
    65 bool HbTextItemPrivate::outlinesEnabled = false;
    53 
    66 
    54 static const QString KDefaultColorThemeName = "qtc_view_normal";
    67 static const QString KDefaultColorThemeName = "qtc_view_normal";
    55 const qreal MinimumWidth = 5.0; // minimum width if there is some text.
    68 const qreal MinimumWidth = 5.0; // minimum width if there is some text.
    67     mMinLines(1),
    80     mMinLines(1),
    68     mMaxLines(0),
    81     mMaxLines(0),
    69     mMinWidthForAdjust(-1),
    82     mMinWidthForAdjust(-1),
    70     mMaxWidthForAdjust(-1),
    83     mMaxWidthForAdjust(-1),
    71     mDefaultHeight(-1),
    84     mDefaultHeight(-1),
       
    85     mHasMultiTrans(false),
    72     mUpdateColor(true),
    86     mUpdateColor(true),
    73     mEventPosted(false)
    87     mEventPosted(false),
       
    88     inConstructor(1)
    74 {
    89 {
    75 }
    90 }
    76 
    91 
    77 void HbTextItemPrivate::init(QGraphicsItem *)
    92 void HbTextItemPrivate::init(QGraphicsItem *)
    78 {
    93 {
    79     Q_Q(HbTextItem);
    94     Q_Q(HbTextItem);
    80 
    95     inConstructor = 1;
    81     q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    96     q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    82     q->setFlag(QGraphicsItem::ItemClipsToShape, false);
    97     q->setFlag(QGraphicsItem::ItemClipsToShape, false);
    83     q->setFlag(QGraphicsItem::ItemIsSelectable, false);
    98     q->setFlag(QGraphicsItem::ItemIsSelectable, false);
    84     q->setFlag(QGraphicsItem::ItemIsFocusable,  false);
    99     q->setFlag(QGraphicsItem::ItemIsFocusable,  false);
    85 
   100 
    86     QTextOption textOption = mTextLayout.textOption();
   101     QTextOption textOption = mTextLayout.textOption();
    87     textOption.setWrapMode(QTextOption::WordWrap);
   102     textOption.setWrapMode(QTextOption::WordWrap);
    88     mTextLayout.setTextOption(textOption);
   103     mTextLayout.setTextOption(textOption);
    89     mTextLayout.setCacheEnabled(true);
   104     mTextLayout.setCacheEnabled(true);
    90     mTextLayout.setFont(q->font());
   105     mTextLayout.setFont(q->font());
       
   106     inConstructor = 0;
    91 }
   107 }
    92 
   108 
    93 void HbTextItemPrivate::clear()
   109 void HbTextItemPrivate::clear()
    94 {
   110 {
    95     // no implementation needed
   111     // no implementation needed
   134     if(tempText.indexOf('\n')>=0) {
   150     if(tempText.indexOf('\n')>=0) {
   135         // to prevent creation of deep copy if replace has no effect
   151         // to prevent creation of deep copy if replace has no effect
   136         tempText.replace('\n', QChar::LineSeparator);
   152         tempText.replace('\n', QChar::LineSeparator);
   137     }
   153     }
   138 
   154 
   139 	// Need to call elidedText explicitly to enable multiple length translations.
   155     // Need to call elidedText explicitly to enable multiple length translations.
   140     tempText = fontMetrics.elidedText(tempText, Qt::ElideNone, lineWidth);
   156     tempText = fontMetrics.elidedText(tempText, Qt::ElideNone, lineWidth);
   141     bool textTruncated = doLayout(tempText, lineWidth, fontMetrics.lineSpacing());
   157     bool textTruncated = doLayout(tempText, lineWidth, fontMetrics.lineSpacing());
   142 
   158 
   143     if(mElideMode!=Qt::ElideNone && !tempText.isEmpty()) {
   159     if(mElideMode!=Qt::ElideNone && !tempText.isEmpty()) {
   144         if( ( mTextLayout.boundingRect().height() - newSize.height() > EPSILON ) ||
   160         if( ( mTextLayout.boundingRect().height() - newSize.height() > EPSILON ) ||
   150                      fontMetrics.lineSpacing());
   166                      fontMetrics.lineSpacing());
   151         }
   167         }
   152     }
   168     }
   153 
   169 
   154     calculateVerticalOffset();
   170     calculateVerticalOffset();
       
   171     mBoundingRect = layoutBoundingRect();
   155     calculateFadeRects();
   172     calculateFadeRects();
   156 
   173 
   157     // build of text layout is completed
   174     // build of text layout is completed
   158     mInvalidateShownText = false;
   175     mInvalidateShownText = false;
   159 }
   176 }
   215     if(!elidedText.isEmpty() && !elidedText.endsWith(QChar::LineSeparator)) {
   232     if(!elidedText.isEmpty() && !elidedText.endsWith(QChar::LineSeparator)) {
   216         // needed to prevent to move "..." to line before last line
   233         // needed to prevent to move "..." to line before last line
   217         elidedText.append(QChar::LineSeparator);
   234         elidedText.append(QChar::LineSeparator);
   218     }
   235     }
   219 
   236 
   220     int n = lastLine.textLength();
   237     int n = lastLine.textLength()-1;
   221     if(textToElide.at(lastLine.textStart()+n-1)!=QChar::LineSeparator) {
   238     if(textToElide.at(lastLine.textStart()+n)!=QChar::LineSeparator) {
   222         n = -1;
   239         n = -1;
   223     }
   240     }
   224     elidedText.append(metrics.elidedText(textToElide.mid(lastLine.textStart(), n),
   241     elidedText.append(metrics.elidedText(textToElide.mid(lastLine.textStart(), n),
   225                                          mElideMode, size.width(),textFlagsFromTextOption()));
   242                                          mElideMode, size.width(),textFlagsFromTextOption()));
   226 
   243 
   301 bool HbTextItemPrivate::isAdjustHightNeeded(qreal newWidth,
   318 bool HbTextItemPrivate::isAdjustHightNeeded(qreal newWidth,
   302                                             qreal prefHeight,
   319                                             qreal prefHeight,
   303                                             qreal minHeight,
   320                                             qreal minHeight,
   304                                             qreal maxHeight)
   321                                             qreal maxHeight)
   305 {
   322 {
   306 #ifdef HB_TEXT_ITEM_LOGS
       
   307     qDebug() << "isAdjustHightNeeded for: " << q_ptr->objectName()
       
   308             << " text=" << mText.left(KMaxLogedTextLength)
       
   309             << " adjusted=" << mAdjustedSize
       
   310             << " prefHeight=" << prefHeight
       
   311             << " minHeight=" << minHeight
       
   312             << " lastConstraint=" << mLastConstraint
       
   313             << " " << mTextLayout.font();
       
   314 #endif // HB_TEXT_ITEM_LOGS
       
   315 
       
   316     // first check if wrapping of text is not active
   323     // first check if wrapping of text is not active
   317     QTextOption::WrapMode wrapMode = mTextLayout.textOption().wrapMode();
   324     QTextOption::WrapMode wrapMode = mTextLayout.textOption().wrapMode();
   318     if (wrapMode==QTextOption::NoWrap
   325     if (wrapMode==QTextOption::NoWrap
   319         || wrapMode==QTextOption::ManualWrap) {
   326         || wrapMode==QTextOption::ManualWrap) {
   320         return false;
   327         return false;
   327 
   334 
   328     // check if line count is fixed
   335     // check if line count is fixed
   329     if (mMaxLines == mMinLines) {
   336     if (mMaxLines == mMinLines) {
   330         return false;
   337         return false;
   331     }
   338     }
       
   339 
       
   340     HB_TEXT_ITEM_PRIV_LOG("adjusted=" << mAdjustedSize
       
   341             << " prefHeight=" << prefHeight
       
   342             << " minHeight=" << minHeight
       
   343             << " lastConstraint=" << mLastConstraint
       
   344             << " " << mTextLayout.font())
   332 
   345 
   333     // check if adjusted size has been already calculated
   346     // check if adjusted size has been already calculated
   334     // new width is bigger then last estimated range of same height
   347     // new width is bigger then last estimated range of same height
   335     if ((mMaxWidthForAdjust>=newWidth
   348     if ((mMaxWidthForAdjust>=newWidth
   336          // new width is smaller then last estimated range of same height
   349          // new width is smaller then last estimated range of same height
   345     }
   358     }
   346 
   359 
   347     // if preconditions are met test if current hight is enough
   360     // if preconditions are met test if current hight is enough
   348     const QFontMetricsF metrics(mTextLayout.font());
   361     const QFontMetricsF metrics(mTextLayout.font());
   349 
   362 
       
   363     QString txt(mText);
       
   364     if (mHasMultiTrans) {
       
   365         // it has to be like that since same aproach is used  in rebuildTextLayout
       
   366         // so to be consistent is sizeHInt and what is shown this has to be done
       
   367         txt = metrics.elidedText(mText, Qt::ElideNone, newWidth);
       
   368     }
   350     // heavy calculation: check if text fits in current size and cache result
   369     // heavy calculation: check if text fits in current size and cache result
   351     QSizeF newAdjust = metrics.boundingRect(QRectF(0, 0, newWidth, QWIDGETSIZE_MAX),
   370     QSizeF newAdjust = metrics.boundingRect(QRectF(0, 0, newWidth, QWIDGETSIZE_MAX),
   352                                             textFlagsFromTextOption(),
   371                                             textFlagsFromTextOption(),
   353                                             mText).size();
   372                                             txt).size();
   354 
   373 
   355     if (qFuzzyCompare(newAdjust.height(), mAdjustedSize.height())) {
   374     if (qFuzzyCompare(newAdjust.height(), mAdjustedSize.height())) {
   356         // height is same as last time update range of same height
   375         // height is same as last time update range of same height
   357         mMaxWidthForAdjust = qMax(mMaxWidthForAdjust, newWidth);
   376         mMaxWidthForAdjust = qMax(mMaxWidthForAdjust, newWidth);
   358         mMinWidthForAdjust = qMin(mMinWidthForAdjust, newWidth);
   377         mMinWidthForAdjust = qMin(mMinWidthForAdjust, newWidth);
   383 
   402 
   384     // all conditions for calling updateGeometry are meet
   403     // all conditions for calling updateGeometry are meet
   385     return true;
   404     return true;
   386 }
   405 }
   387 
   406 
       
   407 bool HbTextItemPrivate::isAdjustWidthNeeded(qreal newWidth)
       
   408 {
       
   409     if (!mHasMultiTrans) {
       
   410         return false;
       
   411     }
       
   412 
       
   413     if (mLastConstraint.width()>0) {
       
   414         return false;
       
   415     }    // check if adjusted size has been already calculated
       
   416     // new width is bigger then last estimated range of same height
       
   417 
       
   418     if (!mAdjustedSize.isValid()) {
       
   419         // this means that preferred size is set outside of class by setPreferredSize
       
   420         // so sizeHint(Qt::Preferredsize) was not called and size adjustment is useless
       
   421         return false;
       
   422     }
       
   423 
       
   424     HB_TEXT_ITEM_PRIV_LOG("oldadjusted=" << mAdjustedSize
       
   425             << " newWidth=" << newWidth
       
   426             << " lastConstraint=" << mLastConstraint)
       
   427 
       
   428     if ((mMaxWidthForAdjust>=newWidth
       
   429          // new width is smaller then last estimated range of same height
       
   430          && newWidth>=mMinWidthForAdjust)) {
       
   431         return false;
       
   432     }
       
   433 
       
   434     QFontMetricsF metrics(q_ptr->font());
       
   435 
       
   436     // heavy calculation: check if text fits in current size and cache result
       
   437     // note that no wrapping is used here since full width of text is needed to return
       
   438     // proper preferred sizeHint
       
   439     QSizeF newAdjust = metrics.boundingRect(QRectF(0, 0, newWidth, QWIDGETSIZE_MAX),
       
   440                                             0,
       
   441                                             mText).size();
       
   442 
       
   443     if (qFuzzyCompare(newAdjust.width(), mAdjustedSize.width())) {
       
   444         return false;
       
   445     }
       
   446 
       
   447     if (mAdjustedSize.width()<newAdjust.width()
       
   448         && newAdjust.width()>newWidth) {
       
   449         qWarning("Provided multiple translation: \"%s\", "
       
   450                  "has wrong order of possible translations. "
       
   451                  "This could lead to infinitive loop of LayoutRequest events.",
       
   452                  mText.toLatin1().data());
       
   453 
       
   454         return false;
       
   455     }
       
   456     mAdjustedSize = newAdjust;
       
   457 
       
   458     mMaxWidthForAdjust = mMinWidthForAdjust = newAdjust.width();
       
   459     // it must be like this since it is unknown if there will be next resize or not
       
   460     // size hint width is changed so change of width can occur and wrapping can be active
       
   461 
       
   462     HB_TEXT_ITEM_PRIV_LOG("newAdjusted=" << mAdjustedSize
       
   463             << " newWidth=" << newWidth)
       
   464 
       
   465     return true;
       
   466 }
       
   467 
   388 void HbTextItemPrivate::clearAdjustedSizeCache()
   468 void HbTextItemPrivate::clearAdjustedSizeCache()
   389 {
   469 {
   390     // clear cache of size
   470     // clear cache of size
   391     mMinWidthForAdjust = -1;
   471     mMinWidthForAdjust = -1;
   392     mMaxWidthForAdjust = -1;
   472     mMaxWidthForAdjust = -1;
   400     if (mAdjustedSize.isValid() && constraint == mLastConstraint) {
   480     if (mAdjustedSize.isValid() && constraint == mLastConstraint) {
   401         // return cached value, see more in:
   481         // return cached value, see more in:
   402         //      - HbTextItemPrivate::isAdjustHightNeeded
   482         //      - HbTextItemPrivate::isAdjustHightNeeded
   403         //      - HbTextItem::resizeEvent
   483         //      - HbTextItem::resizeEvent
   404 
   484 
   405 #ifdef HB_TEXT_ITEM_LOGS
   485         HB_TEXT_ITEM_PRIV_LOG("mAdjustedSize: " << mAdjustedSize
   406         qDebug() << "HbTextItemPrivate::calculatePrefferedSize: returning cached value: " << mAdjustedSize
   486                 << " font:" << mTextLayout.font())
   407                 << " font:" << mTextLayout.font()
   487 
   408                 << " text:" << mText.left(KMaxLogedTextLength);
       
   409 #endif
       
   410         return mAdjustedSize;
   488         return mAdjustedSize;
   411     }
   489     }
   412     mLastConstraint = constraint;
   490     mLastConstraint = constraint;
   413 
   491 
   414     QSizeF maxSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
   492     QSizeF maxSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
   417     }
   495     }
   418     if(constraint.height()>0) {
   496     if(constraint.height()>0) {
   419         maxSize.setHeight(constraint.height());
   497         maxSize.setHeight(constraint.height());
   420     }
   498     }
   421 
   499 
       
   500     QString txt(mText);
       
   501     if (constraint.width()>0 && mHasMultiTrans) {
       
   502         // it has to be like that since same aproach is used  in rebuildTextLayout
       
   503         // so to be consistent is sizeHInt and what is shown this has to be done
       
   504         txt = metrics.elidedText(mText, Qt::ElideNone, constraint.width());
       
   505     }
   422     QSizeF size = metrics.boundingRect(QRectF(QPointF(),maxSize),
   506     QSizeF size = metrics.boundingRect(QRectF(QPointF(),maxSize),
   423                                        textFlagsFromTextOption(),
   507                                        textFlagsFromTextOption(),
   424                                        mText).size();
   508                                        txt).size();
   425 
   509 
   426     mAdjustedSize = size;
   510     mAdjustedSize = size;
   427     mDefaultHeight = size.height();
   511     mDefaultHeight = size.height();
   428     mMinWidthForAdjust = size.width();
   512     mMinWidthForAdjust = size.width();
   429     mMaxWidthForAdjust = maxSize.width();
   513     mMaxWidthForAdjust = maxSize.width();
   430 
   514 
   431 #ifdef HB_TEXT_ITEM_LOGS
   515     HB_TEXT_ITEM_PRIV_LOG("returnSize: " << mAdjustedSize
   432         qDebug() << "HbTextItemPrivate::calculatePrefferedSize:"
       
   433                 << " text: " << mText.left(KMaxLogedTextLength)
       
   434                 << " returnSize: " << mAdjustedSize
       
   435                 << " constraint: "  << constraint
   516                 << " constraint: "  << constraint
   436                 << " font: " << mTextLayout.font();
   517                 << " font: " << mTextLayout.font());
   437 #endif
   518 
   438     return size;
   519     return size;
   439 }
   520 }
   440 
   521 
   441 bool HbTextItemPrivate::fadeNeeded(const QRectF& contentRect) const
   522 bool HbTextItemPrivate::fadeNeeded(const QRectF& contentRect) const
   442 {
   523 {
       
   524     QRectF textRect = mBoundingRect.translated(mOffsetPos);
       
   525     textRect.adjust(KFadeTolerance,
       
   526                     KFadeTolerance,
       
   527                     -KFadeTolerance,
       
   528                     -KFadeTolerance);
   443     return (mFadeLengthX!=0 || mFadeLengthY!=0)
   529     return (mFadeLengthX!=0 || mFadeLengthY!=0)
   444             && !contentRect.contains(
   530             && !contentRect.contains(textRect);
   445                     layoutBoundingRect().adjusted(KFadeTolerance,
       
   446                                                   KFadeTolerance,
       
   447                                                   -KFadeTolerance,
       
   448                                                   -KFadeTolerance));
       
   449 }
   531 }
   450 
   532 
   451 void HbTextItemPrivate::setupGradient(QLinearGradient *gradient, QColor color)
   533 void HbTextItemPrivate::setupGradient(QLinearGradient *gradient, QColor color)
   452 {
   534 {
   453     gradient->setColorAt(1.0, color);
   535     gradient->setColorAt(1.0, color);
   511     This work-around is needed since there is a problem with pen transformations
   593     This work-around is needed since there is a problem with pen transformations
   512     in hardware Open VG renderer. This problem occurs only on s60 hardware.
   594     in hardware Open VG renderer. This problem occurs only on s60 hardware.
   513     On platforms: Linux, Windows and S60 emulator there is no such problem.
   595     On platforms: Linux, Windows and S60 emulator there is no such problem.
   514     Below flag detects platform which have this problem to activate work-around.
   596     Below flag detects platform which have this problem to activate work-around.
   515  */
   597  */
   516 #if defined(Q_WS_S60) && defined(Q_BIG_ENDIAN)
   598 #if defined(Q_OS_SYMBIAN) && defined(Q_BIG_ENDIAN)
   517 #   warning Work-around is active in fade effect of HbTextItem (see comment)
   599 //#   warning Work-around is active in fade effect of HbTextItem (see comment)
   518 #   define HB_FADE_EFFECT_WORKAROUND_ON_PHONE
   600 #   define HB_FADE_EFFECT_WORKAROUND_ON_PHONE
   519 #endif
   601 #endif
   520 inline void HbTextItemPrivate::setPainterPen(QPainter *painter,
   602 inline void HbTextItemPrivate::setPainterPen(QPainter *painter,
   521                          const QPen& pen,
   603                          const QPen& pen,
   522                          const QPointF& lineBegin)
   604                          const QPointF& lineBegin)
   832     }
   914     }
   833 }
   915 }
   834 
   916 
   835 QRectF HbTextItemPrivate::layoutBoundingRect () const
   917 QRectF HbTextItemPrivate::layoutBoundingRect () const
   836 {
   918 {
   837     QRectF result;
   919     QRectF result; // (mTextLayout.boundingRect());
   838     for (int i=0, n=mTextLayout.lineCount(); i<n; ++i) {
   920     for (int i=0, n=mTextLayout.lineCount(); i<n; ++i) {
   839         result = result.unite(
   921         result = result.unite(
   840                 mTextLayout.lineAt(i).naturalTextRect());
   922                 mTextLayout.lineAt(i).naturalTextRect());
   841     }
   923     }
   842 
   924 
       
   925     return result;
       
   926 }
       
   927 
       
   928 QRectF HbTextItemPrivate::boundingRect (const QRectF& contentsRect) const
       
   929 {
       
   930     QRectF result(mBoundingRect);
   843     result.translate(mOffsetPos);
   931     result.translate(mOffsetPos);
   844 
       
   845     return result;
       
   846 }
       
   847 
       
   848 QRectF HbTextItemPrivate::boundingRect (const QRectF& contentsRect) const
       
   849 {
       
   850     QRectF result(layoutBoundingRect());
       
   851 
   932 
   852     if (mPaintFaded) {
   933     if (mPaintFaded) {
   853         result = result.intersected(mFadeToRect);
   934         result = result.intersected(mFadeToRect);
   854     }
   935     }
   855 
   936 
   897 HbTextItem::HbTextItem (const QString &text, QGraphicsItem *parent) :
   978 HbTextItem::HbTextItem (const QString &text, QGraphicsItem *parent) :
   898     HbWidgetBase(*new HbTextItemPrivate, parent)
   979     HbWidgetBase(*new HbTextItemPrivate, parent)
   899 {
   980 {
   900     Q_D(HbTextItem);
   981     Q_D(HbTextItem);
   901     d->init(parent);
   982     d->init(parent);
       
   983     d->inConstructor = 1;
   902     setText(text);
   984     setText(text);
       
   985     d->inConstructor = 0;
   903 }
   986 }
   904 
   987 
   905 /*
   988 /*
   906     Constructor for internal use only
   989     Constructor for internal use only
   907  */
   990  */
   982 
  1065 
   983     QString txt( text );
  1066     QString txt( text );
   984 
  1067 
   985 #ifdef HB_TEXT_MEASUREMENT_UTILITY
  1068 #ifdef HB_TEXT_MEASUREMENT_UTILITY
   986 
  1069 
   987     if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) {
  1070     if (HbTextMeasurementUtility::instance()->locTestMode()) {
   988         if (text.endsWith(QChar(LOC_TEST_END))) {
  1071         if (text.endsWith(QChar(LOC_TEST_END))) {
   989             int index = text.indexOf(QChar(LOC_TEST_START));
  1072             int index = text.indexOf(QChar(LOC_TEST_START));
   990             setProperty( HbTextMeasurementUtilityNameSpace::textIdPropertyName,  text.mid(index + 1, text.indexOf(QChar(LOC_TEST_END)) - index - 1) );
  1073             setProperty( HbTextMeasurementUtilityNameSpace::textIdPropertyName,  text.mid(index + 1, text.indexOf(QChar(LOC_TEST_END)) - index - 1) );
   991             setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines );
  1074             setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines );
   992             txt = text.left(index);
  1075             txt = text.left(index);
   999     if (d->mText != txt) {
  1082     if (d->mText != txt) {
  1000         d->scheduleTextBuild();
  1083         d->scheduleTextBuild();
  1001         prepareGeometryChange();
  1084         prepareGeometryChange();
  1002         d->mText = txt;
  1085         d->mText = txt;
  1003         d->mTextLayout.setCacheEnabled(KLayoutCacheLimit >= d->mText.length());
  1086         d->mTextLayout.setCacheEnabled(KLayoutCacheLimit >= d->mText.length());
       
  1087         d->mHasMultiTrans = (txt.indexOf('\x9c')>=0);
  1004         d->clearAdjustedSizeCache();
  1088         d->clearAdjustedSizeCache();
  1005         update();
  1089         update();
  1006 
  1090 
  1007         // check if call of updateGeometry can be ignored
  1091         // check if call of updateGeometry can be ignored
  1008         // don't call it when minimum and maximum lines are equal (height is fixed) or ...
  1092         // don't call it when minimum and maximum lines are equal (height is fixed) or ...
  1014 
  1098 
  1015             // and when preferred width is ignored
  1099             // and when preferred width is ignored
  1016             if (sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag
  1100             if (sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag
  1017                 // or was preferred width set from outside of this class?
  1101                 // or was preferred width set from outside of this class?
  1018                 || d->mLastConstraint.width()>0) {
  1102                 || d->mLastConstraint.width()>0) {
  1019 #ifdef HB_TEXT_ITEM_LOGS
  1103 
  1020                 qDebug() << "HbTextItem::setText: skiping updateGeometry for: "
  1104                 HB_TEXT_ITEM_LOG("skiping updateGeometry!")
  1021                         << objectName() << " text:" << d->mText.left(KMaxLogedTextLength);
  1105 
  1022 #endif
       
  1023                 // in those cases skip updateGeometry
  1106                 // in those cases skip updateGeometry
  1024                 return;
  1107                 return;
  1025             }
  1108             }
  1026         }
  1109         }
  1027         updateGeometry();
  1110         updateGeometry();
  1065     \sa HbTextItem::alignment()
  1148     \sa HbTextItem::alignment()
  1066  */
  1149  */
  1067 void HbTextItem::setAlignment (Qt::Alignment alignment)
  1150 void HbTextItem::setAlignment (Qt::Alignment alignment)
  1068 {
  1151 {
  1069     Q_D(HbTextItem);
  1152     Q_D(HbTextItem);
  1070 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextAlign, true);
  1153     d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextAlign, true);
  1071     alignment &= Qt::AlignVertical_Mask | Qt::AlignHorizontal_Mask;
  1154     alignment = d->combineAlignment(alignment, d->mAlignment);
  1072     if (d->mAlignment != alignment) {
  1155     if (d->mAlignment != alignment) {
  1073         prepareGeometryChange();
  1156         prepareGeometryChange();
  1074         d->mAlignment = alignment;
  1157         d->mAlignment = alignment;
  1075         d->updateTextOption();
  1158         d->updateTextOption();
  1076         d->calculateVerticalOffset();
  1159         d->calculateVerticalOffset();
       
  1160         d->mBoundingRect = d->layoutBoundingRect();
  1077 
  1161 
  1078         update();
  1162         update();
  1079     }
  1163     }
  1080 }
  1164 }
  1081 
  1165 
  1087     \sa HbTextItem::elideMode()
  1171     \sa HbTextItem::elideMode()
  1088  */
  1172  */
  1089 void HbTextItem::setElideMode (Qt::TextElideMode elideMode)
  1173 void HbTextItem::setElideMode (Qt::TextElideMode elideMode)
  1090 {
  1174 {
  1091     Q_D(HbTextItem);
  1175     Q_D(HbTextItem);
       
  1176     d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextElideMode, true);
  1092     if (elideMode != d->mElideMode) {
  1177     if (elideMode != d->mElideMode) {
  1093         d->mElideMode = elideMode;
  1178         d->mElideMode = elideMode;
  1094         d->scheduleTextBuild();
  1179         d->scheduleTextBuild();
  1095         prepareGeometryChange();
  1180         prepareGeometryChange();
  1096         update();
  1181         update();
  1161     if (parentLayoutItem() && parentLayoutItem()->isLayout()) {
  1246     if (parentLayoutItem() && parentLayoutItem()->isLayout()) {
  1162         // rect.size can't be used here since size can be limited inside of
  1247         // rect.size can't be used here since size can be limited inside of
  1163         // called method HbWidgetBase::setGeometry(rect) so size is used which
  1248         // called method HbWidgetBase::setGeometry(rect) so size is used which
  1164         // holds current size
  1249         // holds current size
  1165         Q_D(HbTextItem);
  1250         Q_D(HbTextItem);
       
  1251         if (d->isAdjustWidthNeeded(size().width())) {
       
  1252             updateGeometry();
       
  1253             HB_TEXT_ITEM_LOG("isAdjustWidthNeeded - updateGeometry was called");
       
  1254             return;
       
  1255         }
       
  1256 
  1166         if (d->isAdjustHightNeeded(size().width(),
  1257         if (d->isAdjustHightNeeded(size().width(),
  1167                                    preferredHeight(),
  1258                                    preferredHeight(),
  1168                                    minimumHeight(),
  1259                                    minimumHeight(),
  1169                                    maximumHeight())) {
  1260                                    maximumHeight())) {
  1170             updateGeometry();            
  1261             updateGeometry();
  1171 #ifdef HB_TEXT_ITEM_LOGS
  1262             HB_TEXT_ITEM_LOG("isAdjustHightNeeded - updateGeometry was called");
  1172             qDebug() << "isAdjustHightNeeded returned true - updateGeometry was called";
  1263             return;
  1173 #endif // HB_TEXT_ITEM_LOGS
       
  1174         }
  1264         }
  1175     }
  1265     }
  1176 }
  1266 }
  1177 
  1267 
  1178 /*!
  1268 /*!
  1200     QSizeF size(0,0);
  1290     QSizeF size(0,0);
  1201 
  1291 
  1202     // TODO: Temporary work-around - font change event are not always received
  1292     // TODO: Temporary work-around - font change event are not always received
  1203     // so updating font here (this is needed because of sizeHint adjustments).
  1293     // so updating font here (this is needed because of sizeHint adjustments).
  1204     if (d->mTextLayout.font()!=font()) {
  1294     if (d->mTextLayout.font()!=font()) {
  1205 #ifdef HB_TEXT_ITEM_LOGS
  1295         HB_TEXT_ITEM_LOG("Font change was not recieved on time: work-around is active"
  1206         qWarning() << "Font change was not recieved on time: work-around is active"
       
  1207                 << objectName()
       
  1208                 << " test: " << d->mText.left(KMaxLogedTextLength)
       
  1209                 << " oldFont:" << d->mTextLayout.font()
  1296                 << " oldFont:" << d->mTextLayout.font()
  1210                 << " newFont:" << font();
  1297                 << " newFont:" << font())
  1211 #endif // HB_TEXT_ITEM_LOGS
       
  1212 
  1298 
  1213         const_cast<HbTextItemPrivate *>(d)->mTextLayout.setFont(font());
  1299         const_cast<HbTextItemPrivate *>(d)->mTextLayout.setFont(font());
  1214         const_cast<HbTextItemPrivate *>(d)->clearAdjustedSizeCache();
  1300         const_cast<HbTextItemPrivate *>(d)->clearAdjustedSizeCache();
  1215     }
  1301     }
  1216 
  1302 
  1264 
  1350 
  1265     Detects: font changes, layout direction changes and theme changes.
  1351     Detects: font changes, layout direction changes and theme changes.
  1266  */
  1352  */
  1267 void HbTextItem::changeEvent(QEvent *event)
  1353 void HbTextItem::changeEvent(QEvent *event)
  1268 {
  1354 {
  1269     // Listens theme changed event so that item size hint is
       
  1270 
       
  1271     switch(event->type()) {
  1355     switch(event->type()) {
  1272     case QEvent::LayoutDirectionChange: {
  1356     case QEvent::LayoutDirectionChange: {
  1273             Q_D(HbTextItem);
  1357             Q_D(HbTextItem);
  1274             d->scheduleTextBuild();
  1358             d->scheduleTextBuild();
       
  1359             prepareGeometryChange();
  1275         }
  1360         }
  1276         break;
  1361         break;
  1277 
  1362 
  1278     case QEvent::FontChange: {
  1363     case QEvent::FontChange: {
  1279             Q_D(HbTextItem);
  1364             Q_D(HbTextItem);
  1280 
  1365 
  1281             if (!d->mTextLayout.font().isCopyOf(font())) {
  1366             if (!d->mTextLayout.font().isCopyOf(font())) {
  1282 
  1367                 HB_TEXT_ITEM_LOG(" font: " << font());
  1283 #ifdef HB_TEXT_ITEM_LOGS
       
  1284                 qDebug() << "fontChangeEvent: " << objectName()
       
  1285                         << " text: " << text().left(KMaxLogedTextLength)
       
  1286                         << " font: " << font();
       
  1287 #endif // HB_TEXT_ITEM_LOGS
       
  1288 
  1368 
  1289                 d->mTextLayout.setFont(font());
  1369                 d->mTextLayout.setFont(font());
  1290                 d->clearAdjustedSizeCache();
  1370                 d->clearAdjustedSizeCache();
  1291                 d->scheduleTextBuild();
  1371                 d->scheduleTextBuild();
  1292                 prepareGeometryChange();
  1372                 prepareGeometryChange();
  1333     \sa QTextOption::setWrapMode
  1413     \sa QTextOption::setWrapMode
  1334  */
  1414  */
  1335 void HbTextItem::setTextWrapping(Hb::TextWrapping mode)
  1415 void HbTextItem::setTextWrapping(Hb::TextWrapping mode)
  1336 {
  1416 {
  1337     Q_D(HbTextItem);
  1417     Q_D(HbTextItem);
  1338 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextWrapMode, true);
  1418     d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextWrapMode, true);
  1339     QTextOption::WrapMode textWrapMode = static_cast<QTextOption::WrapMode>(mode);
  1419     QTextOption::WrapMode textWrapMode = static_cast<QTextOption::WrapMode>(mode);
  1340 
  1420 
  1341     QTextOption textOption = d->mTextLayout.textOption();
  1421     QTextOption textOption = d->mTextLayout.textOption();
  1342     if(textOption.wrapMode()!=textWrapMode) {
  1422     if(textOption.wrapMode()!=textWrapMode) {
  1343         textOption.setWrapMode(textWrapMode);
  1423         textOption.setWrapMode(textWrapMode);
  1440 void HbTextItem::setMinimumLines( int minLines )
  1520 void HbTextItem::setMinimumLines( int minLines )
  1441 {
  1521 {
  1442     Q_D( HbTextItem );
  1522     Q_D( HbTextItem );
  1443     minLines = qMax(minLines, 1); // zero or nagative values are meanless and are restoring 1
  1523     minLines = qMax(minLines, 1); // zero or nagative values are meanless and are restoring 1
  1444 
  1524 
  1445 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMin, true);
  1525     d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMin, true);
  1446 
  1526 
  1447     if( minLines != d->mMinLines ) {
  1527     if( minLines != d->mMinLines ) {
  1448         if( ( d->mMaxLines > 0 ) && ( minLines > d->mMaxLines ) ) {
  1528         if( ( d->mMaxLines > 0 ) && ( minLines > d->mMaxLines ) ) {
  1449             d->mMaxLines = minLines;
  1529             d->mMaxLines = minLines;
  1450         }
  1530         }
  1469     \sa HbTextItem::minimumLines()
  1549     \sa HbTextItem::minimumLines()
  1470  */
  1550  */
  1471 void HbTextItem::setMaximumLines( int maxLines )
  1551 void HbTextItem::setMaximumLines( int maxLines )
  1472 {
  1552 {
  1473     Q_D( HbTextItem );
  1553     Q_D( HbTextItem );
  1474 	d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMax, true);
  1554     d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMax, true);
  1475 
  1555 
  1476     maxLines = qMax(maxLines, 0);
  1556     maxLines = qMax(maxLines, 0);
  1477 
  1557 
  1478     if( maxLines != d->mMaxLines ) {
  1558     if( maxLines != d->mMaxLines ) {
  1479         if ((maxLines > 0) && (maxLines < d->mMinLines)){
  1559         if ((maxLines > 0) && (maxLines < d->mMinLines)){
  1485         prepareGeometryChange();
  1565         prepareGeometryChange();
  1486         update();
  1566         update();
  1487 
  1567 
  1488         updateGeometry();
  1568         updateGeometry();
  1489 #ifdef HB_TEXT_MEASUREMENT_UTILITY
  1569 #ifdef HB_TEXT_MEASUREMENT_UTILITY
  1490         if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) {
  1570         if (HbTextMeasurementUtility::instance()->locTestMode()) {
  1491             setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines );
  1571             setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines );
  1492         }
  1572         }
  1493 #endif
  1573 #endif
  1494     }
  1574     }
  1495 }
  1575 }
  1582 {
  1662 {
  1583     Q_D( HbTextItem );
  1663     Q_D( HbTextItem );
  1584     d->setFadeLengths(lengths.x(), lengths.y());
  1664     d->setFadeLengths(lengths.x(), lengths.y());
  1585 }
  1665 }
  1586 
  1666 
       
  1667 /*!
       
  1668     \reimp
       
  1669  */
       
  1670 void HbTextItem::updateGeometry()
       
  1671 {
       
  1672     Q_D( HbTextItem );
       
  1673     if (d->inConstructor) {
       
  1674         return;
       
  1675     }
       
  1676     HbWidgetBase::updateGeometry();
       
  1677 }
       
  1678 
  1587 // end of file
  1679 // end of file