summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/egl/egl.pri1
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp19
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.h1
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp477
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h22
-rw-r--r--src/gui/graphicsview/qsimplex_p.cpp9
-rw-r--r--src/gui/graphicsview/qsimplex_p.h2
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp12
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h1
-rw-r--r--src/gui/itemviews/qtableview.cpp28
-rw-r--r--src/gui/kernel/qapplication_s60.cpp15
-rw-r--r--src/gui/kernel/qcursor_s60.cpp10
-rw-r--r--src/gui/kernel/qdnd_s60.cpp10
-rw-r--r--src/gui/kernel/qt_s60_p.h2
-rw-r--r--src/gui/kernel/qtooltip.cpp6
-rw-r--r--src/gui/kernel/qwidget_s60.cpp3
-rw-r--r--src/gui/painting/painting.pri1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp6
-rw-r--r--src/gui/painting/qrasterizer.cpp4
-rw-r--r--src/gui/styles/qstyle.cpp6
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp31
-rw-r--r--src/gui/text/qfontengine.cpp77
23 files changed, 514 insertions, 231 deletions
diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri
index 22c8bd7..ba991bd 100644
--- a/src/gui/egl/egl.pri
+++ b/src/gui/egl/egl.pri
@@ -26,3 +26,4 @@ for(p, QMAKE_LIBDIR_EGL) {
!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
!isEmpty(QMAKE_LIBS_EGL): LIBS_PRIVATE += $$QMAKE_LIBS_EGL
+!isEmpty(QMAKE_LFLAGS_EGL): LIBS += $$QMAKE_LFLAGS_EGL
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index 5897ae4..78b6b53 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -194,7 +194,7 @@ QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint
QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
{
Q_D(QGraphicsAnchorLayout);
- QGraphicsAnchor *a = d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ QGraphicsAnchor *a = d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
invalidate();
return a;
}
@@ -246,12 +246,12 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
// Horizontal anchor
Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
- d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
// Vertical anchor
firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
- d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
invalidate();
}
@@ -288,6 +288,18 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
}
/*!
+ Returns true if there are no arrangement that satisfies all constraints.
+ Otherwise returns false.
+
+ \sa addAnchor()
+*/
+bool QGraphicsAnchorLayout::hasConflicts() const
+{
+ Q_D(const QGraphicsAnchorLayout);
+ return d->hasConflicts();
+}
+
+/*!
Sets the default horizontal spacing for the anchor layout to \a spacing.
\sa horizontalSpacing(), setVerticalSpacing(), setSpacing()
@@ -422,7 +434,6 @@ void QGraphicsAnchorLayout::invalidate()
*/
QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
- Q_UNUSED(which);
Q_UNUSED(constraint);
Q_D(const QGraphicsAnchorLayout);
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h
index d9a87ba..44074d1 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.h
@@ -93,6 +93,7 @@ public:
QGraphicsLayoutItem *secondItem,
Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical);
+ bool hasConflicts() const;
void setHorizontalSpacing(qreal spacing);
void setVerticalSpacing(qreal spacing);
void setSpacing(qreal spacing);
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index a37ec96..7041d58 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -59,7 +59,7 @@ QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
{
- layoutPrivate->deleteAnchorData(data);
+ layoutPrivate->removeAnchor(data->from, data->to);
}
void QGraphicsAnchorPrivate::setSpacing(qreal value)
@@ -95,23 +95,50 @@ qreal QGraphicsAnchorPrivate::spacing() const
void AnchorData::refreshSizeHints(qreal effectiveSpacing)
{
if (!isLayoutAnchor && from->m_item == to->m_item) {
- bool hasCenter = false;
QGraphicsLayoutItem *item = from->m_item;
- if (QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge)
- == QGraphicsAnchorLayoutPrivate::Horizontal) {
- minSize = item->minimumWidth();
- prefSize = item->preferredWidth();
- maxSize = item->maximumWidth();
- hasCenter = (from->m_edge == Qt::AnchorHorizontalCenter
- || to->m_edge == Qt::AnchorHorizontalCenter);
+ const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge);
+ const Qt::AnchorPoint centerEdge = QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient);
+
+ QSizePolicy::Policy policy;
+ qreal minSizeHint, prefSizeHint, maxSizeHint;
+ if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) {
+ policy = item->sizePolicy().horizontalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width();
} else {
- minSize = item->minimumHeight();
- prefSize = item->preferredHeight();
- maxSize = item->maximumHeight();
- hasCenter = (from->m_edge == Qt::AnchorVerticalCenter
- || to->m_edge == Qt::AnchorVerticalCenter);
+ policy = item->sizePolicy().verticalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height();
}
+ // minSize, prefSize and maxSize are initialized
+ // with item's preferred Size: this is QSizePolicy::Fixed.
+ //
+ // Then we check each flag to find the resultant QSizePolicy,
+ // according to the following table:
+ //
+ // constant value
+ // QSizePolicy::Fixed 0
+ // QSizePolicy::Minimum GrowFlag
+ // QSizePolicy::Maximum ShrinkFlag
+ // QSizePolicy::Preferred GrowFlag | ShrinkFlag
+ // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag
+ prefSize = prefSizeHint;
+ minSize = prefSize;
+ maxSize = prefSize;
+
+ if (policy & QSizePolicy::GrowFlag)
+ maxSize = maxSizeHint;
+
+ if (policy & QSizePolicy::ShrinkFlag)
+ minSize = minSizeHint;
+
+ if (policy & QSizePolicy::IgnoreFlag)
+ prefSize = minSize;
+
+ bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge);
if (hasCenter) {
minSize /= 2;
@@ -332,6 +359,7 @@ QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
for (int i = 0; i < NOrientations; ++i) {
spacings[i] = -1;
graphSimplified[i] = false;
+ graphHasConflicts[i] = false;
}
}
@@ -790,7 +818,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
// Horizontal
AnchorData *data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
- addAnchor(layout, Qt::AnchorLeft, layout,
+ addAnchor_helper(layout, Qt::AnchorLeft, layout,
Qt::AnchorRight, data);
data->skipInPreferred = 1;
@@ -800,7 +828,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
// Vertical
data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
- addAnchor(layout, Qt::AnchorTop, layout,
+ addAnchor_helper(layout, Qt::AnchorTop, layout,
Qt::AnchorBottom, data);
data->skipInPreferred = 1;
@@ -816,8 +844,10 @@ void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
Q_ASSERT(internalVertex(q, Qt::AnchorHorizontalCenter) == NULL);
Q_ASSERT(internalVertex(q, Qt::AnchorVerticalCenter) == NULL);
- removeAnchor(q, Qt::AnchorLeft, q, Qt::AnchorRight);
- removeAnchor(q, Qt::AnchorTop, q, Qt::AnchorBottom);
+ removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
+ internalVertex(q, Qt::AnchorRight));
+ removeAnchor_helper(internalVertex(q, Qt::AnchorTop),
+ internalVertex(q, Qt::AnchorBottom));
}
void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
@@ -826,22 +856,18 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
items.append(item);
- // Horizontal
- int minimumSize = item->minimumWidth();
- int preferredSize = item->preferredWidth();
- int maximumSize = item->maximumWidth();
+ QSizeF minSize = item->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF prefSize = item->effectiveSizeHint(Qt::PreferredSize);
+ QSizeF maxSize = item->effectiveSizeHint(Qt::MaximumSize);
- AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, Qt::AnchorLeft, item,
+ // Horizontal
+ AnchorData *data = new AnchorData(minSize.width(), prefSize.width(), maxSize.width());
+ addAnchor_helper(item, Qt::AnchorLeft, item,
Qt::AnchorRight, data);
// Vertical
- minimumSize = item->minimumHeight();
- preferredSize = item->preferredHeight();
- maximumSize = item->maximumHeight();
-
- data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, Qt::AnchorTop, item,
+ data = new AnchorData(minSize.height(), prefSize.height(), maxSize.height());
+ addAnchor_helper(item, Qt::AnchorTop, item,
Qt::AnchorBottom, data);
}
@@ -897,23 +923,23 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
// Create new anchors
AnchorData *oldData = graph[orientation].edgeData(first, last);
- int minimumSize = oldData->minSize / 2;
- int preferredSize = oldData->prefSize / 2;
- int maximumSize = oldData->maxSize / 2;
+ qreal minimumSize = oldData->minSize / 2;
+ qreal preferredSize = oldData->prefSize / 2;
+ qreal maximumSize = oldData->maxSize / 2;
QSimplexConstraint *c = new QSimplexConstraint;
AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
c->variables.insert(data, 1.0);
- addAnchor(item, firstEdge, item, centerEdge, data);
+ addAnchor_helper(item, firstEdge, item, centerEdge, data);
data = new AnchorData(minimumSize, preferredSize, maximumSize);
c->variables.insert(data, -1.0);
- addAnchor(item, centerEdge, item, lastEdge, data);
+ addAnchor_helper(item, centerEdge, item, lastEdge, data);
itemCenterConstraints[orientation].append(c);
// Remove old one
- removeAnchor(item, firstEdge, item, lastEdge);
+ removeAnchor_helper(first, last);
}
void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
@@ -971,16 +997,16 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
// Create the new anchor that should substitute the left-center-right anchors.
AnchorData *oldData = g.edgeData(first, center);
- int minimumSize = oldData->minSize * 2;
- int preferredSize = oldData->prefSize * 2;
- int maximumSize = oldData->maxSize * 2;
+ qreal minimumSize = oldData->minSize * 2;
+ qreal preferredSize = oldData->prefSize * 2;
+ qreal maximumSize = oldData->maxSize * 2;
AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, firstEdge, item, lastEdge, data);
+ addAnchor_helper(item, firstEdge, item, lastEdge, data);
// Remove old anchors
- removeAnchor(item, firstEdge, item, centerEdge);
- removeAnchor(item, centerEdge, item, lastEdge);
+ removeAnchor_helper(first, center);
+ removeAnchor_helper(center, internalVertex(item, lastEdge));
} else {
// this is only called from removeAnchors()
@@ -989,13 +1015,13 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
for (int i = 0; i < adjacents.count(); ++i) {
AnchorVertex *v = adjacents.at(i);
if (v->m_item != item) {
- removeAnchor(item, centerEdge, v->m_item, v->m_edge);
+ removeAnchor_helper(center, internalVertex(v->m_item, v->m_edge));
}
}
// when all non-internal anchors is removed it will automatically merge the
// center anchor into a left-right (or top-bottom) anchor. We must also delete that.
// by this time, the center vertex is deleted and merged into a non-centered internal anchor
- removeAnchor(item, firstEdge, item, lastEdge);
+ removeAnchor_helper(first, internalVertex(item, lastEdge));
}
}
@@ -1039,7 +1065,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *
* Helper function that is called from the anchor functions in the public API.
* If \a spacing is 0, it will pick up the spacing defined by the style.
*/
-QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem,
+QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -1112,18 +1138,18 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *first
} else {
data = new AnchorData(0); // spacing should be 0
}
- addAnchor(firstItem, firstEdge, secondItem, secondEdge, data);
+ addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
} else if (*spacing >= 0) {
data = new AnchorData(*spacing);
- addAnchor(firstItem, firstEdge, secondItem, secondEdge, data);
+ addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
} else {
data = new AnchorData(-*spacing);
- addAnchor(secondItem, secondEdge, firstItem, firstEdge, data);
+ addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data);
}
return acquireGraphicsAnchor(data);
}
-void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
+void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -1142,8 +1168,9 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
// Remove previous anchor
// ### Could we update the existing edgeData rather than creating a new one?
- if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2))
- removeAnchor(firstItem, firstEdge, secondItem, secondEdge);
+ if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) {
+ removeAnchor_helper(v1, v2);
+ }
// Create a bi-directional edge in the sense it can be transversed both
// from v1 or v2. "data" however is shared between the two references
@@ -1178,15 +1205,82 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi
return graphicsAnchor;
}
-void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge)
+/*!
+ * \internal
+ *
+ * Implements the high level "removeAnchor" feature. Called by
+ * the QAnchorData destructor.
+ */
+void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
+ AnchorVertex *secondVertex)
{
- removeAnchor_helper(internalVertex(firstItem, firstEdge),
- internalVertex(secondItem, secondEdge));
+ Q_Q(QGraphicsAnchorLayout);
+
+ // Actually delete the anchor
+ removeAnchor_helper(firstVertex, secondVertex);
+
+ QGraphicsLayoutItem *firstItem = firstVertex->m_item;
+ QGraphicsLayoutItem *secondItem = secondVertex->m_item;
+
+ // Checking if the item stays in the layout or not
+ bool keepFirstItem = false;
+ bool keepSecondItem = false;
+
+ QPair<AnchorVertex *, int> v;
+ int refcount = -1;
+
+ if (firstItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(firstItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepFirstItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepFirstItem = true;
+
+ if (secondItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(secondItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepSecondItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepSecondItem = true;
+
+ if (!keepFirstItem)
+ q->removeAt(items.indexOf(firstItem));
+
+ if (!keepSecondItem)
+ q->removeAt(items.indexOf(secondItem));
+
+ // Removing anchors invalidates the layout
+ q->invalidate();
}
+/*
+ \internal
+
+ Implements the low level "removeAnchor" feature. Called by
+ private methods.
+*/
void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
{
Q_ASSERT(v1 && v2);
@@ -1207,17 +1301,6 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorV
\internal
Only called from outside. (calls invalidate())
*/
-void QGraphicsAnchorLayoutPrivate::deleteAnchorData(AnchorData *data)
-{
- Q_Q(QGraphicsAnchorLayout);
- removeAnchor_helper(data->from, data->to);
- q->invalidate();
-}
-
-/*!
- \internal
- Only called from outside. (calls invalidate())
-*/
void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *anchorSize)
{
Q_Q(QGraphicsAnchorLayout);
@@ -1225,12 +1308,35 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *
// search recursively through all composite anchors
Q_ASSERT(data);
restoreSimplifiedGraph(edgeOrientation(data->from->m_edge));
+
+ QGraphicsLayoutItem *firstItem = data->from->m_item;
+ QGraphicsLayoutItem *secondItem = data->to->m_item;
+ Qt::AnchorPoint firstEdge = data->from->m_edge;
+ Qt::AnchorPoint secondEdge = data->to->m_edge;
+
+ // Use heuristics to find out what the user meant with this anchor.
+ correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
+ if (data->from->m_item != firstItem)
+ qSwap(data->from, data->to);
+
if (anchorSize) {
- data->setFixedSize(*anchorSize);
+ // ### The current implementation makes "setAnchorSize" behavior
+ // dependent on the argument order for cases where we have
+ // no heuristic. Ie. two widgets, same anchor point.
+
+ // We cannot have negative sizes inside the graph. This would cause
+ // the simplex solver to fail because all simplex variables are
+ // positive by definition.
+ // "negative spacing" is handled by inverting the standard item order.
+ if (*anchorSize >= 0) {
+ data->setFixedSize(*anchorSize);
+ } else {
+ data->setFixedSize(-*anchorSize);
+ qSwap(data->from, data->to);
+ }
} else {
data->unsetSize();
}
-
q->invalidate();
}
@@ -1360,25 +1466,23 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi
{
Q_Q(QGraphicsAnchorLayout);
- Qt::AnchorPoint effectiveFirst = firstEdge;
- Qt::AnchorPoint effectiveSecond = secondEdge;
-
- if (firstItem == q)
- effectiveFirst = QGraphicsAnchorLayoutPrivate::oppositeEdge(firstEdge);
- if (secondItem == q)
- effectiveSecond = QGraphicsAnchorLayoutPrivate::oppositeEdge(secondEdge);
-
- if (effectiveFirst < effectiveSecond) {
-
- // ### DEBUG
- /* printf("Swapping Anchor from %s %d --to--> %s %d\n",
- firstItem->isLayout() ? "<layout>" :
- qPrintable(static_cast<QGraphicsWidget *>(firstItem)->data(0).toString()),
- firstEdge,
- secondItem->isLayout() ? "<layout>" :
- qPrintable(static_cast<QGraphicsWidget *>(secondItem)->data(0).toString()),
- secondEdge);
- */
+ if ((firstItem != q) && (secondItem != q)) {
+ // If connection is between widgets (not the layout itself)
+ // Ensure that "right-edges" sit to the left of "left-edges".
+ if (firstEdge < secondEdge) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if (firstItem == q) {
+ // If connection involves the right or bottom of a layout, ensure
+ // the layout is the second item.
+ if ((firstEdge == Qt::AnchorRight) || (firstEdge == Qt::AnchorBottom)) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if ((secondEdge != Qt::AnchorRight) && (secondEdge != Qt::AnchorBottom)) {
+ // If connection involves the left, center or top of layout, ensure
+ // the layout is the first item.
qSwap(firstItem, secondItem);
qSwap(firstEdge, secondEdge);
}
@@ -1507,6 +1611,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
GraphPath trunkPath = graphPaths[orientation].value(v);
+ bool feasible = true;
if (!trunkConstraints.isEmpty()) {
#if 0
qDebug("Simplex used for trunk of %s",
@@ -1514,33 +1619,37 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
#endif
// Solve min and max size hints for trunk
- QPair<qreal, qreal> minMax = solveMinMax(trunkConstraints, trunkPath);
- sizeHints[orientation][Qt::MinimumSize] = minMax.first;
- sizeHints[orientation][Qt::MaximumSize] = minMax.second;
+ qreal min, max;
+ feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max);
// Solve for preferred. The objective function is calculated from the constraints
// and variables internally.
- solvePreferred(trunkConstraints);
+ feasible &= solvePreferred(trunkConstraints);
- // Propagate the new sizes down the simplified graph, ie. tell the
- // group anchors to set their children anchors sizes.
+ if (feasible) {
+ // Propagate the new sizes down the simplified graph, ie. tell the
+ // group anchors to set their children anchors sizes.
- // ### we calculated variables already a few times, can't we reuse that?
- QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
+ // ### we calculated variables already a few times, can't we reuse that?
+ QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
- for (int i = 0; i < trunkVariables.count(); ++i)
- trunkVariables.at(i)->updateChildrenSizes();
+ for (int i = 0; i < trunkVariables.count(); ++i)
+ trunkVariables.at(i)->updateChildrenSizes();
+
+ // Calculate and set the preferred size for the layout from the edge sizes that
+ // were calculated above.
+ qreal pref(0.0);
+ foreach (const AnchorData *ad, trunkPath.positives) {
+ pref += ad->sizeAtPreferred;
+ }
+ foreach (const AnchorData *ad, trunkPath.negatives) {
+ pref -= ad->sizeAtPreferred;
+ }
+ sizeHints[orientation][Qt::MinimumSize] = min;
+ sizeHints[orientation][Qt::PreferredSize] = pref;
+ sizeHints[orientation][Qt::MaximumSize] = max;
- // Calculate and set the preferred size for the layout from the edge sizes that
- // were calculated above.
- qreal pref(0.0);
- foreach (const AnchorData *ad, trunkPath.positives) {
- pref += ad->sizeAtPreferred;
- }
- foreach (const AnchorData *ad, trunkPath.negatives) {
- pref -= ad->sizeAtPreferred;
}
- sizeHints[orientation][Qt::PreferredSize] = pref;
} else {
#if 0
qDebug("Simplex NOT used for trunk of %s",
@@ -1574,29 +1683,34 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// layout.
// Solve the other only for preferred, skip trunk
- for (int i = 1; i < parts.count(); ++i) {
- QList<QSimplexConstraint *> partConstraints = parts[i];
- QList<AnchorData *> partVariables = getVariables(partConstraints);
- Q_ASSERT(!partVariables.isEmpty());
-
- sizeHintConstraints = constraintsFromSizeHints(partVariables);
- partConstraints += sizeHintConstraints;
- solvePreferred(partConstraints);
-
- // Propagate size at preferred to other sizes. Semi-floats
- // always will be in their sizeAtPreferred.
- for (int j = 0; j < partVariables.count(); ++j) {
- AnchorData *ad = partVariables[j];
- Q_ASSERT(ad);
- ad->sizeAtMinimum = ad->sizeAtPreferred;
- ad->sizeAtMaximum = ad->sizeAtPreferred;
- ad->updateChildrenSizes();
- }
+ if (feasible) {
+ for (int i = 1; i < parts.count(); ++i) {
+ QList<QSimplexConstraint *> partConstraints = parts[i];
+ QList<AnchorData *> partVariables = getVariables(partConstraints);
+ Q_ASSERT(!partVariables.isEmpty());
+
+ sizeHintConstraints = constraintsFromSizeHints(partVariables);
+ partConstraints += sizeHintConstraints;
+ feasible &= solvePreferred(partConstraints);
+ if (!feasible)
+ break;
+
+ // Propagate size at preferred to other sizes. Semi-floats
+ // always will be in their sizeAtPreferred.
+ for (int j = 0; j < partVariables.count(); ++j) {
+ AnchorData *ad = partVariables[j];
+ Q_ASSERT(ad);
+ ad->sizeAtMinimum = ad->sizeAtPreferred;
+ ad->sizeAtMaximum = ad->sizeAtPreferred;
+ ad->updateChildrenSizes();
+ }
- // Delete the constraints, we won't use them anymore.
- qDeleteAll(sizeHintConstraints);
- sizeHintConstraints.clear();
+ // Delete the constraints, we won't use them anymore.
+ qDeleteAll(sizeHintConstraints);
+ sizeHintConstraints.clear();
+ }
}
+ graphHasConflicts[orientation] = !feasible;
// Clean up our data structures. They are not needed anymore since
// distribution uses just interpolation.
@@ -2061,47 +2175,48 @@ void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges(
interpolateEdge(prev, data->m_edges.last(), orientation);
}
-QPair<qreal, qreal>
-QGraphicsAnchorLayoutPrivate::solveMinMax(QList<QSimplexConstraint *> constraints,
- GraphPath path)
+bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList<QSimplexConstraint *> constraints,
+ GraphPath path, qreal *min, qreal *max)
{
QSimplex simplex;
- simplex.setConstraints(constraints);
-
- // Obtain the objective constraint
- QSimplexConstraint objective;
- QSet<AnchorData *>::const_iterator iter;
- for (iter = path.positives.constBegin(); iter != path.positives.constEnd(); ++iter)
- objective.variables.insert(*iter, 1.0);
-
- for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter)
- objective.variables.insert(*iter, -1.0);
-
- simplex.setObjective(&objective);
-
- // Calculate minimum values
- qreal min = simplex.solveMin();
-
- // Save sizeAtMinimum results
- QList<QSimplexVariable *> variables = simplex.constraintsVariables();
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- ad->sizeAtMinimum = ad->result;
- }
+ bool feasible = simplex.setConstraints(constraints);
+ if (feasible) {
+ // Obtain the objective constraint
+ QSimplexConstraint objective;
+ QSet<AnchorData *>::const_iterator iter;
+ for (iter = path.positives.constBegin(); iter != path.positives.constEnd(); ++iter)
+ objective.variables.insert(*iter, 1.0);
+
+ for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter)
+ objective.variables.insert(*iter, -1.0);
+
+ simplex.setObjective(&objective);
+
+ // Calculate minimum values
+ *min = simplex.solveMin();
+
+ // Save sizeAtMinimum results
+ QList<QSimplexVariable *> variables = simplex.constraintsVariables();
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = static_cast<AnchorData *>(variables[i]);
+ Q_ASSERT(ad->result >= ad->minSize || qFuzzyCompare(ad->result, ad->minSize));
+ ad->sizeAtMinimum = ad->result;
+ }
- // Calculate maximum values
- qreal max = simplex.solveMax();
+ // Calculate maximum values
+ *max = simplex.solveMax();
- // Save sizeAtMaximum results
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- ad->sizeAtMaximum = ad->result;
+ // Save sizeAtMaximum results
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = static_cast<AnchorData *>(variables[i]);
+ Q_ASSERT(ad->result <= ad->maxSize || qFuzzyCompare(ad->result, ad->maxSize));
+ ad->sizeAtMaximum = ad->result;
+ }
}
-
- return qMakePair<qreal, qreal>(min, max);
+ return feasible;
}
-void QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> constraints)
+bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> constraints)
{
QList<AnchorData *> variables = getVariables(constraints);
QList<QSimplexConstraint *> preferredConstraints;
@@ -2148,25 +2263,35 @@ void QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co
QSimplex *simplex = new QSimplex;
- simplex->setConstraints(constraints + preferredConstraints);
- simplex->setObjective(&objective);
-
- // Calculate minimum values
- simplex->solveMin();
+ bool feasible = simplex->setConstraints(constraints + preferredConstraints);
+ if (feasible) {
+ simplex->setObjective(&objective);
- // Save sizeAtPreferred results
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- ad->sizeAtPreferred = ad->result;
- }
+ // Calculate minimum values
+ simplex->solveMin();
- // Make sure we delete the simplex solver -before- we delete the
- // constraints used by it.
- delete simplex;
+ // Save sizeAtPreferred results
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = static_cast<AnchorData *>(variables[i]);
+ ad->sizeAtPreferred = ad->result;
+ }
+ // Make sure we delete the simplex solver -before- we delete the
+ // constraints used by it.
+ delete simplex;
+ }
// Delete constraints and variables we created.
qDeleteAll(preferredConstraints);
qDeleteAll(preferredVariables);
+
+ return feasible;
+}
+
+bool QGraphicsAnchorLayoutPrivate::hasConflicts() const
+{
+ QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate*>(this);
+ that->calculateGraphs();
+ return graphHasConflicts[0] || graphHasConflicts[1];
}
#ifdef QT_DEBUG
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index f701c3f..4e1bcd4 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -403,15 +403,15 @@ public:
return data->graphicsAnchor;
}
- // helper function used by the 4 API functions
- QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem,
+ // function used by the 4 API functions
+ QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
qreal *spacing = 0);
- // Anchor Manipulation methods
- void addAnchor(QGraphicsLayoutItem *firstItem,
+ // Helper for Anchor Manipulation methods
+ void addAnchor_helper(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -420,12 +420,8 @@ public:
QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
- void removeAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge);
+ void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex);
void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2);
- void deleteAnchorData(AnchorData *data);
void setAnchorSize(AnchorData *data, const qreal *anchorSize);
void anchorSize(const AnchorData *data,
qreal *minSize = 0,
@@ -482,9 +478,10 @@ public:
Orientation orientation);
// Linear Programming solver methods
- QPair<qreal, qreal> solveMinMax(QList<QSimplexConstraint *> constraints,
- GraphPath path);
- void solvePreferred(QList<QSimplexConstraint *> constraints);
+ bool solveMinMax(QList<QSimplexConstraint *> constraints,
+ GraphPath path, qreal *min, qreal *max);
+ bool solvePreferred(QList<QSimplexConstraint *> constraints);
+ bool hasConflicts() const;
#ifdef QT_DEBUG
void dumpGraph();
@@ -518,6 +515,7 @@ public:
// ###
bool graphSimplified[2];
+ bool graphHasConflicts[2];
uint calculateGraphCacheDirty : 1;
};
diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp
index 3bd6b5a..e3a991e 100644
--- a/src/gui/graphicsview/qsimplex_p.cpp
+++ b/src/gui/graphicsview/qsimplex_p.cpp
@@ -84,12 +84,12 @@ void QSimplex::clearDataStructures()
objective = 0;
}
-void QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
+bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
{
clearDataStructures();
if (newConstraints.isEmpty())
- return;
+ return true; // we are ok with no constraints
constraints = newConstraints;
// Set Variables direct mapping
@@ -153,7 +153,7 @@ void QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
matrix = (qreal *)malloc(sizeof(qreal) * columns * rows);
if (!matrix) {
qWarning() << "QSimplex: Unable to allocate memory!";
- return;
+ return false;
}
for (int i = columns * rows - 1; i >= 0; --i)
matrix[i] = 0.0;
@@ -198,11 +198,12 @@ void QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
if (valueAt(0, columns - 1) != 0.0) {
qWarning() << "QSimplex: No feasible solution!";
clearDataStructures();
- return;
+ return false;
}
// Remove artificial variables
clearColumns(firstArtificial, columns - 2);
+ return true;
}
void QSimplex::solveMaxHelper()
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h
index 805ef4a..54b080d 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/gui/graphicsview/qsimplex_p.h
@@ -107,7 +107,7 @@ public:
qreal solveMax();
QList<QSimplexVariable *> constraintsVariables();
- void setConstraints(const QList<QSimplexConstraint *> constraints);
+ bool setConstraints(const QList<QSimplexConstraint *> constraints);
void setObjective(QSimplexConstraint *objective);
void dumpMatrix();
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 9d977a5..757ded9 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -69,6 +69,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
: model(QAbstractItemModelPrivate::staticEmptyModel()),
itemDelegate(0),
selectionModel(0),
+ ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
selectionMode(QAbstractItemView::ExtendedSelection),
selectionBehavior(QAbstractItemView::SelectItems),
currentlyCommittingEditor(0),
@@ -1589,6 +1590,11 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
d->autoScroll = autoScroll;
QRect rect(d->pressedPosition - offset, pos);
+ if (command.testFlag(QItemSelectionModel::Toggle)) {
+ command &= ~QItemSelectionModel::Toggle;
+ d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
+ command |= d->ctrlDragSelectionFlag;
+ }
setSelection(rect, command);
// signal handlers may change the model
@@ -1659,6 +1665,10 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
setState(DragSelectingState);
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ if (command.testFlag(QItemSelectionModel::Toggle)) {
+ command &= ~QItemSelectionModel::Toggle;
+ command |= d->ctrlDragSelectionFlag;
+ }
// Do the normalize ourselves, since QRect::normalized() is flawed
QRect selectionRect = QRect(topLeft, bottomRight);
@@ -1699,6 +1709,8 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
bool edited = edit(index, trigger, event);
+ d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
+
//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));
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 725d0a9..6b1ec8e 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -342,6 +342,7 @@ public:
QMap<int, QPointer<QAbstractItemDelegate> > rowDelegates;
QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
QPointer<QItemSelectionModel> selectionModel;
+ QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
QAbstractItemView::SelectionMode selectionMode;
QAbstractItemView::SelectionBehavior selectionBehavior;
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 684da3f..f1ffaa6 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -2519,9 +2519,21 @@ void QTableViewPrivate::selectRow(int row, bool anchor)
QModelIndex index = model->index(row, column, root);
QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- if ((!(command & QItemSelectionModel::Current) && anchor)
+ if ((anchor && !(command & QItemSelectionModel::Current))
|| (q->selectionMode() == QTableView::SingleSelection))
rowSectionAnchor = row;
+
+ if (q->selectionMode() != QTableView::SingleSelection
+ && command.testFlag(QItemSelectionModel::Toggle)) {
+ if (anchor)
+ ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows().contains(index)
+ ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
+ command &= ~QItemSelectionModel::Toggle;
+ command |= ctrlDragSelectionFlag;
+ if (!anchor)
+ command |= QItemSelectionModel::Current;
+ }
+
QModelIndex tl = model->index(qMin(rowSectionAnchor, row), 0, root);
QModelIndex br = model->index(qMax(rowSectionAnchor, row), model->columnCount(root) - 1, root);
if (verticalHeader->sectionsMoved() && tl.row() != br.row())
@@ -2545,9 +2557,21 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
QModelIndex index = model->index(row, column, root);
QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- if ((!(command & QItemSelectionModel::Current) && anchor)
+ if ((anchor && !(command & QItemSelectionModel::Current))
|| (q->selectionMode() == QTableView::SingleSelection))
columnSectionAnchor = column;
+
+ if (q->selectionMode() != QTableView::SingleSelection
+ && command.testFlag(QItemSelectionModel::Toggle)) {
+ if (anchor)
+ ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
+ ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
+ command &= ~QItemSelectionModel::Toggle;
+ command |= ctrlDragSelectionFlag;
+ if (!anchor)
+ command |= QItemSelectionModel::Current;
+ }
+
QModelIndex tl = model->index(0, qMin(columnSectionAnchor, column), root);
QModelIndex br = model->index(model->rowCount(root) - 1,
qMax(columnSectionAnchor, column), root);
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index fd889fc..6a381f5 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -439,7 +439,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
}
}
S60->lastCursorPos = globalPos;
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
if (S60->brokenPointerCursors)
qt_symbian_move_cursor_sprite();
#endif
@@ -855,7 +855,6 @@ void qt_init(QApplicationPrivate * /* priv */, int)
//Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
const TInt KMachineUidSamsungI8510 = 0x2000C51E;
- const TInt KMachineUidSamsungI550 = 0x2000A678;
TInt machineUID;
TInt mouse;
TInt touch;
@@ -888,6 +887,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
}
+#ifndef QT_NO_CURSOR
//Check if window server pointer cursors are supported or not
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
//In generic binary, use the HAL and OS version
@@ -912,6 +912,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
#endif
S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
}
+#endif
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
@@ -1275,7 +1276,7 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
}
break;
case EEventFocusGained:
- RDebug::Printf("focus gained %x", control);
+#ifndef QT_NO_CURSOR
//re-enable mouse interaction
if (S60->mouseInteractionEnabled) {
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
@@ -1285,9 +1286,10 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
#endif
S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
}
+#endif
break;
case EEventFocusLost:
- RDebug::Printf("focus lost %x", control);
+#ifndef QT_NO_CURSOR
//disable mouse as may be moving to application that does not support it
if (S60->mouseInteractionEnabled) {
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
@@ -1297,6 +1299,7 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
#endif
S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
}
+#endif
break;
default:
break;
@@ -1534,7 +1537,9 @@ void QApplication::restoreOverrideCursor()
QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
while (iter.hasNext()) {
CCoeControl *ctrl = iter.next();
- ctrl->DrawableWindow()->ClearPointerCursor();
+ if(ctrl->OwnsWindow()) {
+ ctrl->DrawableWindow()->ClearPointerCursor();
+ }
}
if (w)
qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index 757eaa8..0d8283d 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -52,8 +52,10 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_CURSOR
static QCursor cursorSprite;
-static int cursorSpriteVisible;
+static int cursorSpriteVisible;
+#endif
//pos and setpos are required whether cursors are configured or not.
QPoint QCursor::pos()
@@ -520,8 +522,10 @@ void qt_symbian_setGlobalCursor(const QCursor &cursor)
while(iter.hasNext())
{
CCoeControl *ctrl = iter.next();
- RWindowTreeNode *node = ctrl->DrawableWindow();
- qt_symbian_setWindowGroupCursor(cursor, *node);
+ if(ctrl->OwnsWindow()) {
+ RWindowTreeNode *node = ctrl->DrawableWindow();
+ qt_symbian_setWindowGroupCursor(cursor, *node);
+ }
}
}
}
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index 2456185..3d6ecd2 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -214,11 +214,13 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
case QEvent::MouseButtonRelease:
{
qApp->removeEventFilter(this);
+#ifndef QT_NO_CURSOR
if (restoreCursor) {
QApplication::restoreOverrideCursor();
willDrop = false;
restoreCursor = false;
}
+#endif
if (object && object->target()) {
QMouseEvent *me = (QMouseEvent *)e;
@@ -267,7 +269,9 @@ Qt::DropAction QDragManager::drag(QDrag *o)
updatePixmap();
updateCursor();
+#ifndef QT_NO_CURSOR
qt_symbian_set_cursor_visible(true); //force cursor on even for touch phone
+#endif
object->d_func()->target = 0;
@@ -282,10 +286,12 @@ Qt::DropAction QDragManager::drag(QDrag *o)
delete eventLoop;
eventLoop = 0;
+#ifndef QT_NO_CURSOR
qt_symbian_set_cursor_visible(false);
overrideCursor = QCursor(); //deref the cursor data
qt_symbian_dnd_dragging = false;
+#endif
return global_accepted_action;
}
@@ -306,10 +312,12 @@ void QDragManager::cancel(bool deleteSource)
drag_object = object = 0;
}
+#ifndef QT_NO_CURSOR
if (restoreCursor) {
QApplication::restoreOverrideCursor();
restoreCursor = false;
}
+#endif
global_accepted_action = Qt::IgnoreAction;
}
@@ -317,10 +325,12 @@ void QDragManager::cancel(bool deleteSource)
void QDragManager::drop()
{
+#ifndef QT_NO_CURSOR
if (restoreCursor) {
QApplication::restoreOverrideCursor();
restoreCursor = false;
}
+#endif
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 794d15a..67084c4 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -304,11 +304,13 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode)
return format;
}
+#ifndef QT_NO_CURSOR
void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid);
void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node);
void qt_symbian_setGlobalCursor(const QCursor &cursor);
void qt_symbian_set_cursor_visible(bool visible);
bool qt_symbian_is_cursor_visible();
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp
index a480195..2d0d209 100644
--- a/src/gui/kernel/qtooltip.cpp
+++ b/src/gui/kernel/qtooltip.cpp
@@ -290,8 +290,8 @@ void QTipLabel::timerEvent(QTimerEvent *e)
// Fade out tip on mac (makes it invisible).
// The tip will not be deleted until a new tip is shown.
- // DRSWAT - Cocoa
- macWindowFade(qt_mac_window_for(this));
+ // DRSWAT - Cocoa
+ macWindowFade(qt_mac_window_for(this));
QTipLabel::instance->fadingOut = true; // will never be false again.
}
else
@@ -431,7 +431,7 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o)
void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect)
{
- if (QTipLabel::instance){ // a tip does already exist
+ if (QTipLabel::instance && QTipLabel::instance->isVisible()){ // a tip does already exist
if (text.isEmpty()){ // empty text means hide current tip
QTipLabel::instance->hideTip();
return;
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 522ce33..3744377 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -1222,8 +1222,9 @@ void QWidget::releaseMouse()
WId id = effectiveWinId();
id->SetPointerCapture(false);
QWidgetPrivate::mouseGrabber = 0;
-
+#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
+#endif
}
}
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 5abac2f..8343cb9 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -22,6 +22,7 @@ HEADERS += \
painting/qpainter_p.h \
painting/qpainterpath.h \
painting/qpainterpath_p.h \
+ painting/qvectorpath_p.h \
painting/qpathclipper_p.h \
painting/qpdf_p.h \
painting/qpen.h \
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bac0a76..f41d7b4 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3551,7 +3551,7 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,
if (dash >= length) {
dash = length;
- *dashOffset += dash;
+ *dashOffset += dash / width;
length = 0;
} else {
*dashOffset = 0;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index ebaa901..ed1b5d1 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -7464,7 +7464,11 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
Qt::LayoutDirection layout_direction;
- if(option)
+ if (tf & Qt::TextForceLeftToRight)
+ layout_direction = Qt::LeftToRight;
+ else if (tf & Qt::TextForceRightToLeft)
+ layout_direction = Qt::RightToLeft;
+ else if (option)
layout_direction = option->textDirection();
else if (painter)
layout_direction = painter->layoutDirection();
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index 0b33369..66d0c9d 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -707,10 +707,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
if (a == b || width == 0 || d->clipRect.isEmpty())
return;
+ Q_ASSERT(width > 0.0);
+
QPointF pa = a;
QPointF pb = b;
- QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
+ QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
if (squareCap)
offs += QPointF(offs.y(), offs.x());
const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);
diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
index 2614bfb..eef1573 100644
--- a/src/gui/styles/qstyle.cpp
+++ b/src/gui/styles/qstyle.cpp
@@ -463,7 +463,7 @@ QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rect, int a
rect.getRect(&x, &y, &w, &h);
if (!text.isEmpty()) {
result = metrics.boundingRect(x, y, w, h, alignment, text);
- if (!enabled && styleHint(SH_EtchDisabledText)) {
+ if (!enabled && proxy()->styleHint(SH_EtchDisabledText)) {
result.setWidth(result.width()+1);
result.setHeight(result.height()+1);
}
@@ -525,12 +525,12 @@ void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, c
painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
}
if (!enabled) {
- if (styleHint(SH_DitherDisabledText)) {
+ if (proxy()->styleHint(SH_DitherDisabledText)) {
QRect br;
painter->drawText(rect, alignment, text, &br);
painter->fillRect(br, QBrush(painter->background().color(), Qt::Dense5Pattern));
return;
- } else if (styleHint(SH_EtchDisabledText)) {
+ } else if (proxy()->styleHint(SH_EtchDisabledText)) {
QPen pen = painter->pen();
painter->setPen(pal.light().color());
painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text);
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index d65910c..2584003 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -308,6 +308,21 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
if (familyRef) {
fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
goto FamilyFound;
+ } else {
+#if defined(QT_MAC_USE_COCOA)
+ // ATS and CT disagrees on what the family name should be,
+ // use CT to look up the font if ATS fails.
+ QCFString familyName = QString::fromAscii(family_name);
+ QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL);
+ QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef);
+ QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute);
+
+ familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault);
+ if (familyRef) {
+ fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault);
+ goto FamilyFound;
+ }
+#endif
}
}
}
@@ -456,11 +471,27 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
return;
fnt->families.clear();
+#if defined(QT_MAC_USE_COCOA)
+ // Make sure that the family name set on the font matches what
+ // kCTFontFamilyNameAttribute returns in initializeDb().
+ // So far the best solution seems find the installed font
+ // using CoreText and get the family name from it.
+ // (ATSFontFamilyGetName appears to be the correct API, but also
+ // returns the font display name.)
+ for(int i = 0; i < containedFonts.size(); ++i) {
+ QCFString fontPostScriptName;
+ ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
+ QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
+ QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
+ fnt->families.append(familyName);
+ }
+#else
for(int i = 0; i < containedFonts.size(); ++i) {
QCFString family;
ATSFontGetName(containedFonts[i], kATSOptionFlagsDefault, &family);
fnt->families.append(family);
}
+#endif
fnt->handle = handle;
}
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 8dd01d7..e5a88fc 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -946,48 +946,60 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
if (maps + 8 * numTables > endPtr)
return 0;
+ enum {
+ Invalid,
+ Symbol,
+ AppleRoman,
+ Unicode11,
+ Unicode,
+ MicrosoftUnicode,
+ MicrosoftUnicodeExtended
+ };
+
+ int symbolTable = -1;
int tableToUse = -1;
- int score = 0;
+ int score = Invalid;
for (int n = 0; n < numTables; ++n) {
const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2);
switch (platformId) {
case 0: // Unicode
- if (score < 4 &&
+ if (score < Unicode &&
(platformSpecificId == 0 ||
platformSpecificId == 2 ||
platformSpecificId == 3)) {
tableToUse = n;
- score = 4;
- } else if (score < 3 && platformSpecificId == 1) {
+ score = Unicode;
+ } else if (score < Unicode11 && platformSpecificId == 1) {
tableToUse = n;
- score = 3;
+ score = Unicode11;
}
break;
case 1: // Apple
- if (score < 2 && platformSpecificId == 0) { // Apple Roman
+ if (score < AppleRoman && platformSpecificId == 0) { // Apple Roman
tableToUse = n;
- score = 2;
+ score = AppleRoman;
}
break;
case 3: // Microsoft
switch (platformSpecificId) {
case 0:
- if (score < 1) {
+ symbolTable = n;
+ if (score < Symbol) {
tableToUse = n;
- score = 1;
+ score = Symbol;
}
break;
case 1:
- if (score < 5) {
+ if (score < MicrosoftUnicode) {
tableToUse = n;
- score = 5;
+ score = MicrosoftUnicode;
}
break;
case 0xa:
- if (score < 6) {
+ if (score < MicrosoftUnicodeExtended) {
tableToUse = n;
- score = 6;
+ score = MicrosoftUnicodeExtended;
}
break;
default:
@@ -999,7 +1011,9 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
}
if(tableToUse < 0)
return 0;
- *isSymbolFont = (score == 1);
+
+resolveTable:
+ *isSymbolFont = (score == Symbol);
unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
@@ -1019,6 +1033,41 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
if (table + unicode_table + length > endPtr)
return 0;
*cmapSize = length;
+
+ // To support symbol fonts that contain a unicode table for the symbol area
+ // we check the cmap tables and fall back to symbol font unless that would
+ // involve losing information from the unicode table
+ if (symbolTable > -1 && ((score == Unicode) || (score == Unicode11))) {
+ const uchar *selectedTable = table + unicode_table;
+
+ // Check that none of the latin1 range are in the unicode table
+ bool unicodeTableHasLatin1 = false;
+ for (int uc=0x00; uc<0x100; ++uc) {
+ if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
+ unicodeTableHasLatin1 = true;
+ break;
+ }
+ }
+
+ // Check that at least one symbol char is in the unicode table
+ bool unicodeTableHasSymbols = false;
+ if (!unicodeTableHasLatin1) {
+ for (int uc=0xf000; uc<0xf100; ++uc) {
+ if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
+ unicodeTableHasSymbols = true;
+ break;
+ }
+ }
+ }
+
+ // Fall back to symbol table
+ if (!unicodeTableHasLatin1 && unicodeTableHasSymbols) {
+ tableToUse = symbolTable;
+ score = Symbol;
+ goto resolveTable;
+ }
+ }
+
return table + unicode_table;
}