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_p.h" |
41 #include "hbfeaturemanager_p.h" |
41 #include "hbfeaturemanager_r.h" |
42 #endif |
42 #endif |
43 |
43 |
|
44 // #define HB_TEXT_ITEM_LOGS |
44 #define EPSILON 0.01 |
45 #define EPSILON 0.01 |
45 |
46 |
|
47 #ifdef HB_TEXT_ITEM_LOGS |
|
48 # include <QDebug> |
|
49 #endif // HB_TEXT_ITEM_LOGS |
|
50 |
46 bool HbTextItemPrivate::outlinesEnabled = false; |
51 bool HbTextItemPrivate::outlinesEnabled = false; |
47 |
52 |
48 static const QString KDefaultColorThemeName = "qtc_view_normal"; |
53 static const QString KDefaultColorThemeName = "qtc_view_normal"; |
49 const int MinimumWidth = 5; // minimum width if there is some text. |
54 const qreal MinimumWidth = 5.0; // minimum width if there is some text. |
50 const int KLayoutCacheLimit = 64; |
55 const int KLayoutCacheLimit = 64; |
51 const qreal KFadeTolerance = 1.0; |
56 const qreal KFadeTolerance = 1.0; |
52 |
57 |
53 HbTextItemPrivate::HbTextItemPrivate () : |
58 HbTextItemPrivate::HbTextItemPrivate () : |
54 mAlignment(Qt::AlignLeft | Qt::AlignVCenter), |
59 mAlignment(Qt::AlignLeft | Qt::AlignVCenter), |
77 |
84 |
78 QTextOption textOption = mTextLayout.textOption(); |
85 QTextOption textOption = mTextLayout.textOption(); |
79 textOption.setWrapMode(QTextOption::WordWrap); |
86 textOption.setWrapMode(QTextOption::WordWrap); |
80 mTextLayout.setTextOption(textOption); |
87 mTextLayout.setTextOption(textOption); |
81 mTextLayout.setCacheEnabled(true); |
88 mTextLayout.setCacheEnabled(true); |
|
89 mTextLayout.setFont(q->font()); |
82 } |
90 } |
83 |
91 |
84 void HbTextItemPrivate::clear() |
92 void HbTextItemPrivate::clear() |
85 { |
93 { |
86 // no implementation needed |
94 // no implementation needed |
87 } |
95 } |
88 |
96 |
89 bool HbTextItemPrivate::doLayout(const QString& text, const qreal lineWidth, qreal leading) |
97 bool HbTextItemPrivate::doLayout(const QString& text, const qreal lineWidth, qreal lineSpacing) |
90 { |
98 { |
91 bool textTruncated = false; |
99 bool textTruncated = false; |
92 mInvalidateShownText = false; |
|
93 |
100 |
94 mTextLayout.setText(text); |
101 mTextLayout.setText(text); |
95 mTextLayout.setFont( q_func()->font() ); |
102 |
96 |
103 qreal yLinePos = 0; |
97 qreal height = 0; |
|
98 mTextLayout.beginLayout(); |
104 mTextLayout.beginLayout(); |
99 while (1) { |
105 while (1) { |
100 QTextLine line = mTextLayout.createLine(); |
106 QTextLine line = mTextLayout.createLine(); |
101 if (!line.isValid()) |
107 if (!line.isValid()) |
102 break; |
108 break; |
103 if( ( mMaxLines > 0 ) && ( mTextLayout.lineCount() > mMaxLines ) ) { |
109 |
104 textTruncated = true; |
110 line.setLineWidth(lineWidth); |
|
111 line.setPosition(QPointF(0, yLinePos)); |
|
112 |
|
113 if( ( mMaxLines > 0 ) && ( mTextLayout.lineCount() >= mMaxLines ) ) { |
|
114 textTruncated = (line.textStart()+line.textLength() < text.length()); |
105 break; |
115 break; |
106 } |
116 } |
107 |
117 yLinePos += lineSpacing; |
108 line.setLineWidth(lineWidth); |
|
109 height += leading; |
|
110 line.setPosition(QPointF(0, height)); |
|
111 height += line.height(); |
|
112 } |
118 } |
113 mTextLayout.endLayout(); |
119 mTextLayout.endLayout(); |
114 |
120 |
115 if( textTruncated ) { |
|
116 mTextLayout.setText(text); |
|
117 mTextLayout.setFont( q_func()->font() ); |
|
118 |
|
119 qreal height = 0; |
|
120 mTextLayout.beginLayout(); |
|
121 while ( mTextLayout.lineCount() < mMaxLines ) { |
|
122 QTextLine line = mTextLayout.createLine(); |
|
123 line.setLineWidth(lineWidth); |
|
124 height += leading; |
|
125 line.setPosition(QPointF(0, height)); |
|
126 height += line.height(); |
|
127 } |
|
128 mTextLayout.endLayout(); |
|
129 } |
|
130 |
|
131 return textTruncated; |
121 return textTruncated; |
132 } |
122 } |
133 |
123 |
134 void HbTextItemPrivate::setSize(const QSizeF &newSize) |
124 void HbTextItemPrivate::rebuildTextLayout(const QSizeF &newSize) |
135 { |
125 { |
136 Q_Q(HbTextItem); |
126 QFontMetricsF fontMetrics(mTextLayout.font()); |
137 |
|
138 QFont usedFont = q->font(); |
|
139 QFontMetricsF fontMetrics(usedFont); |
|
140 |
127 |
141 const qreal lineWidth = qRound( newSize.width() + 0.5 ); // round up to integer |
128 const qreal lineWidth = qRound( newSize.width() + 0.5 ); // round up to integer |
142 |
129 |
143 updateTextOption(); |
130 updateTextOption(); |
144 |
131 |
146 if(tempText.indexOf('\n')>=0) { |
133 if(tempText.indexOf('\n')>=0) { |
147 // to prevent creation of deep copy if replace has no effect |
134 // to prevent creation of deep copy if replace has no effect |
148 tempText.replace('\n', QChar::LineSeparator); |
135 tempText.replace('\n', QChar::LineSeparator); |
149 } |
136 } |
150 |
137 |
151 // function does the layout only when needed |
|
152 mTextLayout.setFont(usedFont); |
|
153 // Need to call elidedText explicitly to enable multiple length translations. |
138 // Need to call elidedText explicitly to enable multiple length translations. |
154 tempText = fontMetrics.elidedText(tempText, Qt::ElideNone, lineWidth); |
139 tempText = fontMetrics.elidedText(tempText, Qt::ElideNone, lineWidth); |
155 bool textTruncated = doLayout(tempText, lineWidth, fontMetrics.leading()); |
140 bool textTruncated = doLayout(tempText, lineWidth, fontMetrics.lineSpacing()); |
|
141 |
156 if(mElideMode!=Qt::ElideNone && !tempText.isEmpty()) { |
142 if(mElideMode!=Qt::ElideNone && !tempText.isEmpty()) { |
157 if( ( mTextLayout.boundingRect().height() - newSize.height() > EPSILON ) || |
143 if( ( mTextLayout.boundingRect().height() - newSize.height() > EPSILON ) || |
158 ( mTextLayout.boundingRect().width() - lineWidth > EPSILON ) || |
144 ( mTextLayout.boundingRect().width() - lineWidth > EPSILON ) || |
159 textTruncated) { |
145 textTruncated) { |
160 // TODO: Multiple length translations with multiline text |
146 // TODO: Multiple length translations with multiline text |
161 doLayout(elideLayoutedText(newSize, fontMetrics), |
147 doLayout(elideLayoutedText(newSize, fontMetrics), |
162 lineWidth, |
148 lineWidth, |
163 fontMetrics.leading()); |
149 fontMetrics.lineSpacing()); |
164 } |
150 } |
165 } |
151 } |
|
152 |
166 calculateVerticalOffset(); |
153 calculateVerticalOffset(); |
167 calculateFadeRects(); |
154 calculateFadeRects(); |
168 q->update(); |
155 |
|
156 // build of text layout is completed |
|
157 mInvalidateShownText = false; |
169 } |
158 } |
170 |
159 |
171 /* |
160 /* |
172 finds index of last line before given Y coordinate |
161 finds index of last line before given Y coordinate |
173 It is a binary search. |
162 It is a binary search. |
278 } |
286 } |
279 |
287 |
280 return flags; |
288 return flags; |
281 } |
289 } |
282 |
290 |
283 bool HbTextItemPrivate::adjustSizeHint() |
291 /*! |
284 { |
292 This method check spetial case of calculating sizeHint. |
285 Q_Q( HbTextItem ); |
293 By default prefferedSize returns size of text which has lots of free space. |
286 |
294 But there can be situaltion that text has less avaible free width ther requred. |
287 mNeedToAdjustSizeHint = false; |
295 In such cases prefered hight of HbTextItem should be recaculated because wrapping |
288 |
296 of the line may requre more space in vertical direction. |
289 if ( !(q->sizePolicy().verticalPolicy()&QSizePolicy::IgnoreFlag) ) { |
297 |
290 // only calculated if the vertical sizeHint is taken into account |
298 In such case bigger hight should be cached for sizeHint calculations. |
291 |
299 */ |
292 const QFontMetricsF metrics(q->font()); |
300 bool HbTextItemPrivate::isAdjustHightNeeded(const QSizeF& newSize, |
293 |
301 const QSizeF& prefSize) |
294 if ( mMinLines > 0 && (mMinLines == mMaxLines) ) { |
302 { |
295 // if the number of lines if fixed: optimize |
303 #ifdef HB_TEXT_ITEM_LOGS |
296 const qreal newPrefHeight = ( metrics.height() + metrics.leading() ) * mMinLines - metrics.leading(); |
304 qDebug() << "isAdjustHightNeeded for: " << q_ptr->objectName() |
297 if( qAbs( mPrefHeight - newPrefHeight ) > EPSILON ) { |
305 << " text=" << mText.left(20) |
298 mPrefHeight = newPrefHeight; |
306 << " adjusted=" << mAdjustedSize |
299 return true; |
307 << " pref=" << prefSize |
300 } |
308 << mTextLayout.font(); |
301 return false; |
309 #endif // HB_TEXT_ITEM_LOGS |
302 } |
310 |
303 |
311 // first check if wrapping of text is not active |
304 QSizeF currSize = q->size(); |
312 QTextOption::WrapMode wrapMode = mTextLayout.textOption().wrapMode(); |
305 // do the heavy calculation |
313 if (wrapMode==QTextOption::NoWrap |
306 QRectF desiredRect = metrics.boundingRect( QRectF( 0, 0 , currSize.width(), QWIDGETSIZE_MAX ), textFlagsFromTextOption(), mText ); |
314 || wrapMode==QTextOption::ManualWrap) { |
307 |
315 return false; |
308 if( qAbs( desiredRect.height() - mPrefHeight ) > EPSILON ) { |
316 } |
309 mPrefHeight = desiredRect.height(); |
317 |
310 return true; |
318 // check if line count is fixed |
311 } |
319 if (mMaxLines == mMinLines) { |
312 } |
320 return false; |
313 |
321 } |
314 return false; |
322 |
|
323 // check if preffered height is defined by user |
|
324 // so check if preff height is same as value returned by sizeHint |
|
325 if (!qFuzzyCompare(prefSize.height(), mAdjustedSize.height())) { |
|
326 return false; |
|
327 } |
|
328 |
|
329 // check if adjusted size has been already calculated |
|
330 // new width is bigger then last estimated range of same height |
|
331 if ((mMaxWidthForAdjust>=newSize.width() |
|
332 // new width is smaller then last estimated range of same height |
|
333 && newSize.width()>=mMinWidthForAdjust)) { |
|
334 return false; |
|
335 } |
|
336 |
|
337 if (!mAdjustedSize.isValid()) { |
|
338 // this means that preferred size is set outside of class by setPreferredSize |
|
339 // so sizeHint(Qt::Preferredsize) was not called and size adjustment is useless |
|
340 return false; |
|
341 } |
|
342 |
|
343 // if preconditions are met test if current hight is enough |
|
344 const QFontMetricsF metrics(mTextLayout.font()); |
|
345 |
|
346 // heavy calculation: check if text fits in current size and cache result |
|
347 QSizeF newAdjust = metrics.boundingRect(QRectF(0, 0, newSize.width(), QWIDGETSIZE_MAX), |
|
348 textFlagsFromTextOption(), |
|
349 mText).size(); |
|
350 |
|
351 if (qFuzzyCompare(newAdjust.height(), mAdjustedSize.height())) { |
|
352 // height is same as last time update range of same height |
|
353 mMaxWidthForAdjust = qMax(mMaxWidthForAdjust, newSize.width()); |
|
354 mMinWidthForAdjust = qMin(mMinWidthForAdjust, newSize.width()); |
|
355 |
|
356 // and don't update geometry |
|
357 return false; |
|
358 } |
|
359 |
|
360 // new height was calculated create new range for which |
|
361 // current mAdjustedSize.height is valid |
|
362 mMaxWidthForAdjust = newSize.width(); |
|
363 mMinWidthForAdjust = newAdjust.width(); |
|
364 |
|
365 // store new hieght use don't change width |
|
366 mAdjustedSize.setHeight(newAdjust.height()); |
|
367 Q_ASSERT_X(mAdjustedSize.width()>=newAdjust.width(), |
|
368 "HbTextItemPrivate::isAdjustHightNeeded", |
|
369 QString("Fail for string: \"%1\"").arg(mText).toAscii().data()); |
|
370 |
|
371 if (respectSizeLimits(mAdjustedSize)==prefSize) { |
|
372 // updateGeometry has no effect |
|
373 return false; |
|
374 } |
|
375 |
|
376 // all conditions for calling updateGeometry are meet |
|
377 return true; |
|
378 } |
|
379 |
|
380 void HbTextItemPrivate::clearAdjustedSizeCache() |
|
381 { |
|
382 // clear cache of size |
|
383 mMinWidthForAdjust = -1; |
|
384 mMaxWidthForAdjust = -1; |
|
385 mAdjustedSize.setHeight(-1); |
|
386 } |
|
387 |
|
388 QSizeF HbTextItemPrivate::calculatePrefferedSize(const QSizeF& constraint) const |
|
389 { |
|
390 const QFontMetricsF metrics(mTextLayout.font()); |
|
391 |
|
392 if (mAdjustedSize.isValid() && |
|
393 (constraint.height()<0 || qFuzzyCompare(constraint.height(), mAdjustedSize.height())) && |
|
394 (constraint.width()<0 || qFuzzyCompare(constraint.width(), mAdjustedSize.width()))) { |
|
395 // return cached value, see more in: |
|
396 // - HbTextItemPrivate::isAdjustHightNeeded |
|
397 // - HbTextItem::resizeEvent |
|
398 return mAdjustedSize; |
|
399 } |
|
400 |
|
401 QSizeF maxSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); |
|
402 if(constraint.width()>0) { |
|
403 maxSize.setWidth(constraint.width()); |
|
404 } |
|
405 if(constraint.height()>0) { |
|
406 maxSize.setHeight(constraint.height()); |
|
407 } |
|
408 |
|
409 QSizeF size = metrics.boundingRect(QRectF(QPointF(),maxSize), |
|
410 textFlagsFromTextOption(), |
|
411 mText).size(); |
|
412 |
|
413 mAdjustedSize = size; |
|
414 mDefaultHeight = size.height(); |
|
415 mMinWidthForAdjust = size.width(); |
|
416 mMaxWidthForAdjust = QWIDGETSIZE_MAX; |
|
417 |
|
418 return size; |
315 } |
419 } |
316 |
420 |
317 bool HbTextItemPrivate::fadeNeeded(const QRectF& contentRect) const |
421 bool HbTextItemPrivate::fadeNeeded(const QRectF& contentRect) const |
318 { |
422 { |
319 return (mFadeLengthX!=0 || mFadeLengthY!=0) |
423 return (mFadeLengthX!=0 || mFadeLengthY!=0) |
530 |
634 |
531 const int n = mTextLayout.lineCount(); |
635 const int n = mTextLayout.lineCount(); |
532 |
636 |
533 // #define SEE_FADE_RECTANGLES |
637 // #define SEE_FADE_RECTANGLES |
534 #ifdef SEE_FADE_RECTANGLES |
638 #ifdef SEE_FADE_RECTANGLES |
535 painter->setClipRect(mFadeToRect); |
|
536 painter->setBrush(QBrush(QColor(215, 0, 0, 30))); |
639 painter->setBrush(QBrush(QColor(215, 0, 0, 30))); |
537 painter->drawRect(mFadeToRect); |
640 painter->drawRect(mFadeToRect); |
538 painter->setBrush(QBrush(QColor(0, 0, 200, 30))); |
641 painter->setBrush(QBrush(QColor(0, 0, 200, 30))); |
539 painter->drawRect(mFadeFromRect.adjusted(0,0,-1,-1)); |
642 painter->drawRect(mFadeFromRect.adjusted(0,0,-1,-1)); |
540 #endif // SEE_FADE_RECTANGLES |
643 #endif // SEE_FADE_RECTANGLES |
870 } |
977 } |
871 } |
978 } |
872 #endif //HB_TEXT_MEASUREMENT_UTILITY |
979 #endif //HB_TEXT_MEASUREMENT_UTILITY |
873 |
980 |
874 if (d->mText != txt) { |
981 if (d->mText != txt) { |
875 d->mInvalidateShownText = true; |
982 d->scheduleTextBuild(); |
876 prepareGeometryChange(); |
983 prepareGeometryChange(); |
877 d->mText = txt; |
984 d->mText = txt; |
878 d->mTextLayout.setCacheEnabled(KLayoutCacheLimit >= d->mText.length()); |
985 d->mTextLayout.setCacheEnabled(KLayoutCacheLimit >= d->mText.length()); |
879 bool onlyHorizontalSizeHintChanged = false; |
986 d->clearAdjustedSizeCache(); |
880 if ( d->mMinLines > 0 && (d->mMinLines == d->mMaxLines) ) { |
|
881 onlyHorizontalSizeHintChanged = true; |
|
882 } |
|
883 if ( (sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag) && onlyHorizontalSizeHintChanged ) { |
|
884 // suppress updateGeometry() and use the same geometry |
|
885 d->setSize( size() ); |
|
886 } else { |
|
887 updateGeometry(); |
|
888 } |
|
889 update(); |
987 update(); |
|
988 |
|
989 // check if call of updateGeometry can be ignored |
|
990 // don't call it when minimum and maximum lines are equal (height is fixed) or ... |
|
991 if ((d->mMinLines == d->mMaxLines) |
|
992 // or when preferred height is ignored |
|
993 || (sizePolicy().verticalPolicy()&QSizePolicy::IgnoreFlag)) { |
|
994 |
|
995 // and when preferred width is ignored or ... |
|
996 if (sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag |
|
997 // or when preferred width is defined from outside |
|
998 || !qFuzzyCompare(preferredWidth(), d->mAdjustedSize.width())) { |
|
999 // TODO: looking for better solution since preferredWidth() can cause call of sizeHint |
|
1000 |
|
1001 // in those cases skip updateGeometry |
|
1002 return; |
|
1003 } |
|
1004 } |
|
1005 updateGeometry(); |
890 } |
1006 } |
891 } |
1007 } |
892 |
1008 |
893 /*! |
1009 /*! |
894 Sets the text color into \a color. |
1010 Sets the text color into \a color. |
1041 QSizeF HbTextItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
1166 QSizeF HbTextItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
1042 { |
1167 { |
1043 Q_D(const HbTextItem); |
1168 Q_D(const HbTextItem); |
1044 |
1169 |
1045 QSizeF size(0,0); |
1170 QSizeF size(0,0); |
|
1171 |
|
1172 // TODO: Temporary work-around - font change event are not always received |
|
1173 // so updating font here (this is needed because of sizeHint adjustments). |
|
1174 if (d->mTextLayout.font()!=font()) { |
|
1175 #ifdef HB_TEXT_ITEM_LOGS |
|
1176 qWarning() << "Font change was not recieved on time: work-around is active" |
|
1177 << objectName() |
|
1178 << " test: " << d->mText.left(20) |
|
1179 << " oldFont:" << d->mTextLayout.font() |
|
1180 << " newFont:" << font(); |
|
1181 #endif // HB_TEXT_ITEM_LOGS |
|
1182 |
|
1183 const_cast<HbTextItemPrivate *>(d)->mTextLayout.setFont(font()); |
|
1184 const_cast<HbTextItemPrivate *>(d)->clearAdjustedSizeCache(); |
|
1185 } |
1046 |
1186 |
1047 Qt::Orientations effectiveOrientations(0); |
1187 Qt::Orientations effectiveOrientations(0); |
1048 if ( !(sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag) ) { |
1188 if ( !(sizePolicy().horizontalPolicy()&QSizePolicy::IgnoreFlag) ) { |
1049 effectiveOrientations |= Qt::Horizontal; |
1189 effectiveOrientations |= Qt::Horizontal; |
1050 } |
1190 } |
1054 } |
1194 } |
1055 |
1195 |
1056 if ( !effectiveOrientations ) { |
1196 if ( !effectiveOrientations ) { |
1057 // if the whole sizeHint is ignored, return ASAP with default values (0<50<QMAX) |
1197 // if the whole sizeHint is ignored, return ASAP with default values (0<50<QMAX) |
1058 return HbWidgetBase::sizeHint( which, constraint ); |
1198 return HbWidgetBase::sizeHint( which, constraint ); |
1059 } |
|
1060 |
|
1061 const QFontMetricsF metrics(font()); |
|
1062 QSizeF maxSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); |
|
1063 |
|
1064 if(constraint.width()>0) { |
|
1065 maxSize.setWidth(constraint.width()); |
|
1066 } |
|
1067 if(constraint.height()>0) { |
|
1068 maxSize.setHeight(constraint.height()); |
|
1069 } |
1199 } |
1070 |
1200 |
1071 switch(which) { |
1201 switch(which) { |
1072 case Qt::MinimumSize: |
1202 case Qt::MinimumSize: |
1073 { |
1203 { |
1074 if ( !d->mText.isEmpty() ) { |
1204 if ( !d->mText.isEmpty() ) { |
1075 size.setWidth( MinimumWidth ); // just to show something -- should not matter in read use-case |
1205 size.setWidth(MinimumWidth); // just to show something -- should not matter in read use-case |
1076 |
1206 size = d->respectSizeLimits(size); |
1077 if( d->mMinLines > 1 ) { |
|
1078 size.setHeight( ( metrics.height() + metrics.leading() ) * d->mMinLines - metrics.leading() ); |
|
1079 } else { |
|
1080 size.setHeight( metrics.height() ); |
|
1081 } |
|
1082 } |
1207 } |
1083 |
|
1084 break; |
1208 break; |
1085 } |
1209 } |
1086 |
1210 |
1087 case Qt::PreferredSize: |
1211 case Qt::PreferredSize: |
1088 { |
1212 { |
1089 if ( !(effectiveOrientations&Qt::Horizontal) && d->mMinLines > 0 && (d->mMinLines == d->mMaxLines) ) { |
1213 if ( !effectiveOrientations.testFlag(Qt::Horizontal) |
|
1214 && (d->mMinLines == d->mMaxLines) ) { |
1090 //optimize single line if the horizontal sizeHint is ignored |
1215 //optimize single line if the horizontal sizeHint is ignored |
1091 size.setHeight( ( metrics.height() + metrics.leading() ) * d->mMinLines - metrics.leading() ); |
1216 size = d->respectSizeLimits(size); |
1092 break; |
1217 break; |
1093 } |
1218 } |
1094 |
1219 |
1095 // do the heavy calculation |
1220 size = d->calculatePrefferedSize(constraint); |
1096 size = metrics.boundingRect(QRectF(QPointF(),maxSize), |
1221 size = d->respectSizeLimits(size); |
1097 d->textFlagsFromTextOption(), |
|
1098 d->mText).size(); |
|
1099 |
|
1100 |
|
1101 if( ( constraint.width() < 0 ) && ( constraint.height() < 0 ) ) { |
|
1102 |
|
1103 if( ( d->mNeedToAdjustSizeHint ) || ( d->oldSize != size ) ) { |
|
1104 const_cast<HbTextItemPrivate*>(d)->adjustSizeHint(); |
|
1105 } |
|
1106 |
|
1107 qreal pref = d->mPrefHeight; |
|
1108 |
|
1109 if( d->mMaxLines > 0 ) { |
|
1110 qreal maxLimit = ( metrics.height() + metrics.leading() ) * d->mMaxLines - metrics.leading(); |
|
1111 if( maxLimit < pref ) { |
|
1112 pref = maxLimit; |
|
1113 } |
|
1114 |
|
1115 } |
|
1116 |
|
1117 const_cast<HbTextItemPrivate*>(d)->oldSize = size; |
|
1118 size.setHeight( pref ); |
|
1119 } |
|
1120 |
|
1121 break; |
1222 break; |
1122 } |
1223 } |
1123 |
1224 |
1124 default: |
1225 default: |
1125 size = HbWidgetBase::sizeHint( which, constraint ); |
1226 size = HbWidgetBase::sizeHint(which, constraint); |
1126 } |
1227 } |
1127 |
1228 |
1128 return size; |
1229 return size; |
1129 } |
1230 } |
1130 |
1231 |
1138 // Listens theme changed event so that item size hint is |
1239 // Listens theme changed event so that item size hint is |
1139 |
1240 |
1140 switch(event->type()) { |
1241 switch(event->type()) { |
1141 case QEvent::LayoutDirectionChange: { |
1242 case QEvent::LayoutDirectionChange: { |
1142 Q_D(HbTextItem); |
1243 Q_D(HbTextItem); |
1143 d->mInvalidateShownText = true; |
1244 d->scheduleTextBuild(); |
1144 updateGeometry(); |
|
1145 } |
1245 } |
1146 break; |
1246 break; |
1147 |
1247 |
1148 case QEvent::FontChange: { |
1248 case QEvent::FontChange: { |
1149 Q_D(HbTextItem); |
1249 Q_D(HbTextItem); |
1150 d->mInvalidateShownText = true; |
1250 |
1151 prepareGeometryChange(); |
1251 if (!d->mTextLayout.font().isCopyOf(font())) { |
1152 updateGeometry(); |
1252 |
|
1253 #ifdef HB_TEXT_ITEM_LOGS |
|
1254 qDebug() << "fontChangeEvent: " << objectName() |
|
1255 << " text: " << text().left(20) |
|
1256 << " font: " << font(); |
|
1257 #endif // HB_TEXT_ITEM_LOGS |
|
1258 |
|
1259 d->mTextLayout.setFont(font()); |
|
1260 d->clearAdjustedSizeCache(); |
|
1261 d->scheduleTextBuild(); |
|
1262 prepareGeometryChange(); |
|
1263 updateGeometry(); |
|
1264 } else { |
|
1265 // ignoring event since it has no effect |
|
1266 return; |
|
1267 } |
1153 } |
1268 } |
1154 break; |
1269 break; |
1155 |
1270 |
1156 default: |
1271 default: |
1157 // comparing event->type() with dynamic values: |
1272 // comparing event->type() with dynamic values: |
1315 void HbTextItem::setMaximumLines( int maxLines ) |
1441 void HbTextItem::setMaximumLines( int maxLines ) |
1316 { |
1442 { |
1317 Q_D( HbTextItem ); |
1443 Q_D( HbTextItem ); |
1318 d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMax, true); |
1444 d->setApiProtectionFlag(HbWidgetBasePrivate::AC_TextLinesMax, true); |
1319 |
1445 |
|
1446 maxLines = qMax(maxLines, 0); |
|
1447 |
1320 if( maxLines != d->mMaxLines ) { |
1448 if( maxLines != d->mMaxLines ) { |
1321 if( ( d->mMinLines > 0 ) && ( maxLines > 0 ) && ( maxLines < d->mMinLines ) ){ |
1449 if ((maxLines > 0) && (maxLines < d->mMinLines)){ |
1322 d->mMinLines = maxLines; |
1450 d->mMinLines = maxLines; |
1323 } |
1451 } |
1324 |
|
1325 d->mMaxLines = maxLines; |
1452 d->mMaxLines = maxLines; |
|
1453 |
|
1454 d->scheduleTextBuild(); |
|
1455 prepareGeometryChange(); |
|
1456 update(); |
|
1457 |
1326 updateGeometry(); |
1458 updateGeometry(); |
1327 #ifdef HB_TEXT_MEASUREMENT_UTILITY |
1459 #ifdef HB_TEXT_MEASUREMENT_UTILITY |
1328 if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) { |
1460 if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) { |
1329 setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines ); |
1461 setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, d->mMaxLines ); |
1330 } |
1462 } |