summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp4
-rw-r--r--src/gui/kernel/qapplication.cpp14
-rw-r--r--src/gui/kernel/qapplication_qws.cpp7
-rw-r--r--src/gui/kernel/qstandardgestures.cpp6
-rw-r--r--src/gui/kernel/qwidget.h1
-rw-r--r--src/gui/painting/qpaintengine.cpp1
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp8
-rw-r--r--src/gui/text/qtextlayout.cpp155
-rw-r--r--src/gui/widgets/qlinecontrol_p.h6
-rw-r--r--src/gui/widgets/qlineedit.cpp2
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 &current, const unsigned short *logClusters, const QGlyphLayout &glyphs)
+ const QScriptItem &current, 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 &current = eng->layoutData->items[item];
@@ -1683,57 +1712,60 @@ void QTextLine::layout_helper(int maxGlyphs)
}
const QScriptItem &current = 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)) {