diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/itemviews/qabstractitemview.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 14 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_qws.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.h | 1 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine.cpp | 1 | ||||
-rw-r--r-- | src/gui/styles/qstylesheetstyle.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 155 | ||||
-rw-r--r-- | src/gui/widgets/qlinecontrol_p.h | 6 | ||||
-rw-r--r-- | src/gui/widgets/qlineedit.cpp | 2 |
10 files changed, 143 insertions, 61 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 52529ff..99e9aeb 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1661,6 +1661,10 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers); bool edited = edit(index, trigger, event); + //in the case the user presses on no item we might decide to clear the selection + if (d->selectionModel && !index.isValid()) + d->selectionModel->select(QModelIndex(), selectionCommand(index, event)); + setState(NoState); if (click) { diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 511c797..a3420da 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4772,7 +4772,12 @@ void QApplicationPrivate::emitLastWindowClosed() If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus. - This feature is available in Qt for Embedded Linux and Symbian only. + This feature is available in Qt for Embedded Linux, Symbian and Windows CE + only. + + \note On Windows CE this feature is disabled by default for touch device + mkspecs. To enable keypad navigation, build Qt with + QT_KEYPAD_NAVIGATION defined. \sa keypadNavigationEnabled() */ @@ -4785,7 +4790,12 @@ void QApplication::setKeypadNavigationEnabled(bool enable) Returns true if Qt is set to use keypad navigation; otherwise returns false. The default value is true on Symbian, but false on other platforms. - This feature is available in Qt for Embedded Linux and Symbian only. + This feature is available in Qt for Embedded Linux, Symbian and Windows CE + only. + + \note On Windows CE this feature is disabled by default for touch device + mkspecs. To enable keypad navigation, build Qt with + QT_KEYPAD_NAVIGATION defined. \sa setKeypadNavigationEnabled() */ diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index e3bd786..ba2e6a6 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -2202,6 +2202,8 @@ void qt_init(QApplicationPrivate *priv, int type) mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5); + priv->inputContext = 0; + int flags = 0; char *p; int argc = priv->argc; @@ -2361,6 +2363,11 @@ void qt_cleanup() delete mouseInWidget; mouseInWidget = 0; + +#if !defined(QT_NO_IM) + delete QApplicationPrivate::inputContext; + QApplicationPrivate::inputContext = 0; +#endif } diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 8e76715..b3e137d 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -535,6 +535,12 @@ void QPinchGesture::reset() QGesture::reset(); } +/*! \enum QPinchGesture::WhatChange + \value ScaleFactorChanged + \value RotationAngleChanged + \value CenterPointChanged +*/ + /*! \property QPinchGesture::whatChanged diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 284558f..bd30cad 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -731,6 +731,7 @@ private: friend class QGLContext; friend class QGLWidget; friend class QGLWindowSurface; + friend class QGLWindowSurfaceGLPaintDevice; friend class QVGWindowSurface; friend class QX11PaintEngine; friend class QWin32PaintEngine; diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index f442788..42da637 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -386,6 +386,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw \value User First user type ID \value MaxUser Last user type ID \value OpenGL2 + \value PaintBuffer */ /*! diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 3d8dec6..b1fd415 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1130,10 +1130,10 @@ void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect) const QStyleSheetBorderImageData *borderImageData = border()->borderImage(); const int *targetBorders = border()->borders; const int *sourceBorders = borderImageData->cuts; - QMargins sourceMargins(sourceBorders[TopEdge], sourceBorders[LeftEdge], - sourceBorders[BottomEdge], sourceBorders[RightEdge]); - QMargins targetMargins(targetBorders[TopEdge], targetBorders[LeftEdge], - targetBorders[BottomEdge], targetBorders[RightEdge]); + QMargins sourceMargins(sourceBorders[LeftEdge], sourceBorders[TopEdge], + sourceBorders[RightEdge], sourceBorders[BottomEdge]); + QMargins targetMargins(targetBorders[LeftEdge], targetBorders[TopEdge], + targetBorders[RightEdge], targetBorders[BottomEdge]); bool wasSmoothPixmapTransform = p->renderHints() & QPainter::SmoothPixmapTransform; p->setRenderHint(QPainter::SmoothPixmapTransform); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index b150f50..60e5296 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1589,27 +1589,54 @@ void QTextLine::setNumColumns(int numColumns, qreal alignmentWidth) #define LB_DEBUG if (0) qDebug #endif -static inline bool checkFullOtherwiseExtend(QScriptLine &line, QScriptLine &tmpData, QScriptLine &spaceData, - int glyphCount, int maxGlyphs, QFixed &minw, bool manualWrap, - QFixed softHyphenWidth = QFixed()) -{ +namespace { + + struct LineBreakHelper + { + LineBreakHelper() : glyphCount(0), maxGlyphs(0), manualWrap(false) {} + + QScriptLine tmpData; + QScriptLine spaceData; + + int glyphCount; + int maxGlyphs; + + QFixed minw; + QFixed softHyphenWidth; + QFixed rightBearing; + + bool manualWrap; + + bool checkFullOtherwiseExtend(QScriptLine &line); + }; + +inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line) +{ LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal()); - if (line.length && !manualWrap && - (line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth > line.width || glyphCount > maxGlyphs)) + + QFixed newWidth = line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + rightBearing; + if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs)) return true; + minw = qMax(minw, tmpData.textWidth); line += tmpData; line.textWidth += spaceData.textWidth; + line.length += spaceData.length; tmpData.textWidth = 0; tmpData.length = 0; spaceData.textWidth = 0; spaceData.length = 0; + return false; } +} // anonymous namespace + + static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount, - const QScriptItem ¤t, const unsigned short *logClusters, const QGlyphLayout &glyphs) + const QScriptItem ¤t, const unsigned short *logClusters, + const QGlyphLayout &glyphs) { int glyphPosition = logClusters[pos]; do { // got to the first next cluster @@ -1642,9 +1669,13 @@ void QTextLine::layout_helper(int maxGlyphs) Q_ASSERT(line.from < eng->layoutData->string.length()); + LineBreakHelper lbh; + + lbh.maxGlyphs = maxGlyphs; + QTextOption::WrapMode wrapMode = eng->option.wrapMode(); bool breakany = (wrapMode == QTextOption::WrapAnywhere); - bool manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap); + lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap); // #### binary search! int item = -1; @@ -1654,12 +1685,7 @@ void QTextLine::layout_helper(int maxGlyphs) break; } - QFixed minw = 0; - int glyphCount = 0; - LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal()); - QScriptLine tmpData; - QScriptLine spaceData; Qt::Alignment alignment = eng->option.alignment(); @@ -1668,7 +1694,10 @@ void QTextLine::layout_helper(int maxGlyphs) int end = 0; QGlyphLayout glyphs; const unsigned short *logClusters = eng->layoutData->logClustersPtr; + while (newItem < eng->layoutData->items.size()) { + lbh.rightBearing = 0; + lbh.softHyphenWidth = 0; if (newItem != item) { item = newItem; const QScriptItem ¤t = eng->layoutData->items[item]; @@ -1683,57 +1712,60 @@ void QTextLine::layout_helper(int maxGlyphs) } const QScriptItem ¤t = eng->layoutData->items[item]; - tmpData.ascent = qMax(tmpData.ascent, current.ascent); - tmpData.descent = qMax(tmpData.descent, current.descent); + lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent); + lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent); if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) { - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + if (lbh.checkFullOtherwiseExtend(line)) goto found; - QFixed x = line.x + line.textWidth + tmpData.textWidth + spaceData.textWidth; - spaceData.textWidth += eng->calculateTabWidth(item, x); - spaceData.length++; + QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth; + lbh.spaceData.textWidth += eng->calculateTabWidth(item, x); + lbh.spaceData.length++; newItem = item + 1; - ++glyphCount; - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + ++lbh.glyphCount; + if (lbh.checkFullOtherwiseExtend(line)) goto found; } else if (current.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) { // if the line consists only of the line separator make sure // we have a sane height - if (!line.length && !tmpData.length) + if (!line.length && !lbh.tmpData.length) line.setDefaultHeight(eng); if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) { - addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, + current, logClusters, glyphs); } else { - tmpData.length++; + lbh.tmpData.length++; } - line += tmpData; + line += lbh.tmpData; goto found; } else if (current.analysis.flags == QScriptAnalysis::Object) { - tmpData.length++; + lbh.tmpData.length++; QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item])); if (eng->block.docHandle()) eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format); - tmpData.textWidth += current.width; + lbh.tmpData.textWidth += current.width; newItem = item + 1; - ++glyphCount; - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + ++lbh.glyphCount; + if (lbh.checkFullOtherwiseExtend(line)) goto found; } else if (attributes[pos].whiteSpace) { while (pos < end && attributes[pos].whiteSpace) - addNextCluster(pos, end, spaceData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.spaceData, lbh.glyphCount, + current, logClusters, glyphs); - if (!manualWrap && spaceData.textWidth > line.width) { - spaceData.textWidth = line.width; // ignore spaces that fall out of the line. + if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { + lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. goto found; } } else { bool sb_or_ws = false; do { - addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, + current, logClusters, glyphs); if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != HB_NoBreak) { sb_or_ws = true; @@ -1742,9 +1774,8 @@ void QTextLine::layout_helper(int maxGlyphs) break; } } while (pos < end); - minw = qMax(tmpData.textWidth, minw); + lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw); - QFixed softHyphenWidth; if (pos && attributes[pos - 1].lineBreakType == HB_SoftHyphen) { // if we are splitting up a word because of // a soft hyphen then we ... @@ -1763,16 +1794,29 @@ void QTextLine::layout_helper(int maxGlyphs) // and thus become invisible again. // if (line.length) - softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]]; + lbh.softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]]; else if (breakany) - tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]]; + lbh.tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]]; } - if ((sb_or_ws|breakany) - && checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap, softHyphenWidth)) { + // The actual width of the text needs to take the right bearing into account. The + // right bearing is left-ward, which means that if the rightmost pixel is to the right + // of the advance of the glyph, the bearing will be negative. We flip the sign + // for the code to be more readable. Logic borrowed from qfontmetrics.cpp. + if (pos) { + QFontEngine *fontEngine = eng->fontEngine(current); + glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]]; + glyph_metrics_t gi = fontEngine->boundingBox(glyph); + lbh.rightBearing = -qRound(gi.xoff - gi.x - gi.width); + } + + if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) { if (!breakany) { - line.textWidth += softHyphenWidth; + line.textWidth += lbh.softHyphenWidth; } + + line.textWidth += lbh.rightBearing; + goto found; } } @@ -1780,45 +1824,48 @@ void QTextLine::layout_helper(int maxGlyphs) newItem = item + 1; } LB_DEBUG("reached end of line"); - checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap); -found: + lbh.checkFullOtherwiseExtend(line); + line.textWidth += lbh.rightBearing; + +found: if (line.length == 0) { LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f", - tmpData.length, tmpData.textWidth.toReal(), spaceData.length, spaceData.textWidth.toReal()); - line += tmpData; + lbh.tmpData.length, lbh.tmpData.textWidth.toReal(), + lbh.spaceData.length, lbh.spaceData.textWidth.toReal()); + line += lbh.tmpData; } LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(), - line.descent.toReal(), line.textWidth.toReal(), spaceData.width.toReal()); + line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal()); LB_DEBUG(" : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data()); - if (manualWrap) { + if (lbh.manualWrap) { eng->minWidth = qMax(eng->minWidth, line.textWidth); eng->maxWidth = qMax(eng->maxWidth, line.textWidth); } else { - eng->minWidth = qMax(eng->minWidth, minw); + eng->minWidth = qMax(eng->minWidth, lbh.minw); eng->maxWidth += line.textWidth; } if (line.textWidth > 0 && item < eng->layoutData->items.size()) - eng->maxWidth += spaceData.textWidth; + eng->maxWidth += lbh.spaceData.textWidth; if (eng->option.flags() & QTextOption::IncludeTrailingSpaces) - line.textWidth += spaceData.textWidth; - line.length += spaceData.length; - if (spaceData.length) + line.textWidth += lbh.spaceData.textWidth; + line.length += lbh.spaceData.length; + if (lbh.spaceData.length) line.hasTrailingSpaces = true; line.justified = false; line.gridfitted = false; if (eng->option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere) { - if ((maxGlyphs != INT_MAX && glyphCount > maxGlyphs) - || (maxGlyphs == INT_MAX && line.textWidth > line.width)) { + if ((lbh.maxGlyphs != INT_MAX && lbh.glyphCount > lbh.maxGlyphs) + || (lbh.maxGlyphs == INT_MAX && line.textWidth > line.width)) { eng->option.setWrapMode(QTextOption::WrapAnywhere); line.length = 0; line.textWidth = 0; - layout_helper(maxGlyphs); + layout_helper(lbh.maxGlyphs); eng->option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); } } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index a81f138..f46abf1 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -109,6 +109,7 @@ public: int width() const; int height() const; int ascent() const; + qreal naturalTextWidth() const; void setSelection(int start, int length); @@ -410,6 +411,11 @@ inline int QLineControl::width() const return qRound(m_textLayout.lineAt(0).width()) + 1; } +inline qreal QLineControl::naturalTextWidth() const +{ + return m_textLayout.lineAt(0).naturalTextWidth(); +} + inline int QLineControl::height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 3065c7f..9571860 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1808,7 +1808,7 @@ void QLineEdit::paintEvent(QPaintEvent *) // (cix). int minLB = qMax(0, -fm.minLeftBearing()); int minRB = qMax(0, -fm.minRightBearing()); - int widthUsed = d->control->width() + minRB; + int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB; if ((minLB + widthUsed) <= lineRect.width()) { // text fits in lineRect; use hscroll for alignment switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { |