summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qobject.cpp6
-rw-r--r--src/corelib/kernel/qobject_p.h1
-rw-r--r--src/corelib/tools/qdatetime.cpp1
-rw-r--r--src/corelib/tools/qlinkedlist.cpp4
-rw-r--r--src/corelib/tools/qlist.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp15
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp55
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea_p_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativepainteditem.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp6
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp959
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p_p.h48
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp21
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h4
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp30
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp1
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h20
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp86
-rw-r--r--src/declarative/qml/qdeclarativefastproperties.cpp9
-rw-r--r--src/declarative/qml/qdeclarativeglobal_p.h13
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp11
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp9
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp8
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp25
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h19
-rw-r--r--src/declarative/util/qdeclarativefontloader.cpp1
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent.cpp2
-rw-r--r--src/gui/dialogs/qinputdialog.cpp6
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp18
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp76
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp16
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/image/qpixmap_s60.cpp3
-rw-r--r--src/gui/image/qpixmap_x11_p.h1
-rw-r--r--src/gui/kernel/qapplication_s60.cpp7
-rw-r--r--src/gui/kernel/qt_s60_p.h9
-rw-r--r--src/gui/kernel/qwidget.cpp11
-rw-r--r--src/gui/kernel/qwidget_p.h3
-rw-r--r--src/gui/kernel/qwidget_s60.cpp28
-rw-r--r--src/gui/painting/qcups_p.h1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp6
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp8
-rw-r--r--src/gui/s60framework/qs60mainapplication.cpp5
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp28
-rw-r--r--src/gui/s60framework/s60framework.pri18
-rw-r--r--src/gui/text/qfontengine_s60.cpp68
-rw-r--r--src/gui/text/qfontengine_s60_p.h3
-rw-r--r--src/gui/text/qtextengine.cpp16
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp2
-rw-r--r--src/opengl/qgl.cpp3
-rw-r--r--src/opengl/qgl_p.h3
-rw-r--r--src/opengl/qglshaderprogram.cpp10
-rw-r--r--src/openvg/qpaintengine_vg.cpp9
-rw-r--r--src/openvg/qvg_p.h5
-rw-r--r--src/openvg/qvg_symbian.cpp12
-rw-r--r--src/openvg/qvgfontglyphcache_p.h6
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.cpp32
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.h15
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp203
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h21
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp30
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.h1
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp8
-rw-r--r--src/s60installs/bwins/QtCoreu.def1
-rw-r--r--src/s60installs/bwins/QtDeclarativeu.def1
-rw-r--r--src/s60installs/eabi/QtCoreu.def1
-rw-r--r--src/s60installs/eabi/QtDeclarativeu.def1
-rw-r--r--src/s60installs/qt.iby6
-rw-r--r--src/s60installs/qtdemoapps.iby15
-rw-r--r--src/s60installs/s60installs.pro18
-rw-r--r--src/s60main/newallocator_hook.cpp87
-rw-r--r--src/s60main/s60main.pro3
-rw-r--r--src/s60main/s60main.rsg3
81 files changed, 1516 insertions, 716 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 8330e47..579c225 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -127,6 +127,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
+void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0;
QObjectData::~QObjectData() {}
@@ -1094,7 +1095,12 @@ QString QObject::objectName() const
void QObject::setObjectName(const QString &name)
{
Q_D(QObject);
+ bool objectNameChanged = d->declarativeData && d->objectName != name;
+
d->objectName = name;
+
+ if (objectNameChanged)
+ d->declarativeData->objectNameChanged(d->declarativeData, this);
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 4800e6a..814769c 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -89,6 +89,7 @@ class Q_CORE_EXPORT QAbstractDeclarativeData
public:
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
+ static void (*objectNameChanged)(QAbstractDeclarativeData *, QObject *);
};
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index ab7530d..c252e64 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -1630,6 +1630,7 @@ QString QTime::toString(Qt::DateFormat format) const
\endtable
If the datetime is invalid, an empty string will be returned.
+ If \a format is empty, the default format "hh:mm:ss" is used.
\sa QDate::toString() QDateTime::toString()
*/
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 909d940..7213c6e 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -254,7 +254,7 @@ QLinkedListData QLinkedListData::shared_null = {
\sa insert()
*/
-/*!
+/*!
\fn bool QLinkedList::removeOne(const T &value)
\since 4.4
@@ -830,7 +830,7 @@ QLinkedListData QLinkedListData::shared_null = {
QLinkedList\<T\>::const_iterator allows you to iterate over a
QLinkedList\<T\>. If you want modify the QLinkedList as you iterate
- over it, you must use QLinkedList::const_iterator instead. It is
+ over it, you must use QLinkedList::iterator instead. It is
generally good practice to use QLinkedList::const_iterator on a
non-const QLinkedList as well, unless you need to change the
QLinkedList through the iterator. Const iterators are slightly
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 6cc6fc1..9ba3768 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -936,7 +936,7 @@ void **QListData::erase(void **xi)
This function requires the value type to have an implementation of
\c operator==().
- Note that QList uses 0-based indexes, just like C++ arrays. Negative
+ Note that QList uses 0-based indexes, just like C++ arrays. Negative
indexes are not supported with the exception of the value mentioned
above.
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 33c21b1..001abca 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -466,7 +466,7 @@ QDeclarativeFlickable::~QDeclarativeFlickable()
qreal QDeclarativeFlickable::contentX() const
{
Q_D(const QDeclarativeFlickable);
- return -d->hData.move.value();
+ return -d->contentItem->x();
}
void QDeclarativeFlickable::setContentX(qreal pos)
@@ -484,7 +484,7 @@ void QDeclarativeFlickable::setContentX(qreal pos)
qreal QDeclarativeFlickable::contentY() const
{
Q_D(const QDeclarativeFlickable);
- return -d->vData.move.value();
+ return -d->contentItem->y();
}
void QDeclarativeFlickable::setContentY(qreal pos)
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 8216ab7..6ee6b0d 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -218,7 +218,14 @@ public:
return visibleItems.last()->rowPos() + rows * rowSize();
}
} else {
- return (modelIndex / columns) * rowSize();
+ qreal pos = (modelIndex / columns) * rowSize();
+ if (header) {
+ qreal headerSize = flow == QDeclarativeGridView::LeftToRight
+ ? header->item->height()
+ : header->item->width();
+ pos += headerSize;
+ }
+ return pos;
}
return 0;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index 02b4807..c3bac2d 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -46,8 +46,6 @@
#include <qdeclarativeinfo.h>
#include <qdeclarativepixmapcache_p.h>
-#include <QFile>
-
QT_BEGIN_NAMESPACE
QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent)
@@ -115,6 +113,7 @@ void QDeclarativeImageBase::setSourceSize(const QSize& size)
return;
d->sourcesize = size;
+ d->explicitSourceSize = true;
emit sourceSizeChanged();
if (isComponentComplete())
load();
@@ -123,7 +122,10 @@ void QDeclarativeImageBase::setSourceSize(const QSize& size)
QSize QDeclarativeImageBase::sourceSize() const
{
Q_D(const QDeclarativeImageBase);
- return d->sourcesize.isValid() ? d->sourcesize : QSize(implicitWidth(),implicitHeight());
+
+ int width = d->sourcesize.width();
+ int height = d->sourcesize.height();
+ return QSize(width != -1 ? width : implicitWidth(), height != -1 ? height : implicitHeight());
}
void QDeclarativeImageBase::load()
@@ -141,7 +143,7 @@ void QDeclarativeImageBase::load()
pixmapChange();
update();
} else {
- d->pix.load(qmlEngine(this), d->url, d->sourcesize, d->async);
+ d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), d->async);
if (d->pix.isLoading()) {
d->progress = 0.0;
@@ -186,11 +188,8 @@ void QDeclarativeImageBase::requestFinished()
setImplicitWidth(d->pix.width());
setImplicitHeight(d->pix.height());
- if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) {
- d->sourcesize.setWidth(d->pix.width());
- d->sourcesize.setHeight(d->pix.height());
+ if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
emit sourceSizeChanged();
- }
if (d->status != oldStatus)
emit statusChanged(d->status);
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
index aee8b28..3d23ba9 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
@@ -69,6 +69,7 @@ public:
QDeclarativeImageBasePrivate()
: status(QDeclarativeImageBase::Null),
progress(0.0),
+ explicitSourceSize(false),
async(false)
{
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
@@ -79,6 +80,7 @@ public:
QUrl url;
qreal progress;
QSize sourcesize;
+ bool explicitSourceSize : 1;
bool async : 1;
};
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index b135e84..95a4fd6 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -56,7 +56,6 @@
#include <QDebug>
#include <QPen>
-#include <QFile>
#include <QEvent>
#include <QGraphicsSceneMouseEvent>
#include <QtCore/qnumeric.h>
@@ -1180,7 +1179,7 @@ void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post)
d->inPress = true;
for (int ii = 0; ii < d->targets.count(); ++ii) {
QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
- if (i) {
+ if (i && i->isVisible()) {
d->item->scene()->sendEvent(i, event);
if (event->isAccepted()) {
d->inPress = false;
@@ -1222,7 +1221,7 @@ void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post)
d->inRelease = true;
for (int ii = 0; ii < d->targets.count(); ++ii) {
QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
- if (i) {
+ if (i && i->isVisible()) {
d->item->scene()->sendEvent(i, event);
if (event->isAccepted()) {
d->inRelease = false;
@@ -1247,7 +1246,7 @@ void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool p
d->inIM = true;
for (int ii = 0; ii < d->targets.count(); ++ii) {
QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
- if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
+ if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
d->item->scene()->sendEvent(i, event);
if (event->isAccepted()) {
d->imeItem = i;
@@ -1275,7 +1274,7 @@ QVariant QDeclarativeKeysAttached::inputMethodQuery(Qt::InputMethodQuery query)
if (d->item) {
for (int ii = 0; ii < d->targets.count(); ++ii) {
QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
- if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check?
+ if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check?
QVariant v = static_cast<QDeclarativeItemAccessor *>(i)->doInputMethodQuery(query);
if (v.userType() == QVariant::RectF)
v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 6b46bc5..6fd3b71 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -775,7 +775,6 @@ void QDeclarativeListViewPrivate::layout()
setPosition(0);
return;
}
- updateSections();
if (!visibleItems.isEmpty()) {
qreal oldEnd = visibleItems.last()->endPosition();
qreal pos = visibleItems.first()->endPosition() + spacing + 1;
@@ -934,6 +933,7 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem)
return;
if (listItem->attached->m_prevSection != listItem->attached->m_section) {
if (!listItem->section) {
+ qreal pos = listItem->position();
int i = sectionCacheSize-1;
while (i >= 0 && !sectionCache[i])
--i;
@@ -961,8 +961,10 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem)
delete context;
}
}
+ listItem->setPosition(pos);
}
} else if (listItem->section) {
+ qreal pos = listItem->position();
int i = 0;
do {
if (!sectionCache[i]) {
@@ -975,12 +977,13 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem)
} while (i < sectionCacheSize);
delete listItem->section;
listItem->section = 0;
+ listItem->setPosition(pos);
}
}
void QDeclarativeListViewPrivate::updateSections()
{
- if (sectionCriteria) {
+ if (sectionCriteria && !visibleItems.isEmpty()) {
QString prevSection;
if (visibleIndex > 0)
prevSection = sectionAt(visibleIndex-1);
@@ -990,6 +993,8 @@ void QDeclarativeListViewPrivate::updateSections()
if (visibleItems.at(i)->index != -1) {
QDeclarativeListViewAttached *attached = visibleItems.at(i)->attached;
attached->setPrevSection(prevSection);
+ QString propValue = model->stringValue(visibleItems.at(i)->index, sectionCriteria->property());
+ attached->setSection(sectionCriteria->sectionString(propValue));
if (prevAtt)
prevAtt->setNextSection(attached->section());
createSection(visibleItems.at(i));
@@ -1009,18 +1014,27 @@ void QDeclarativeListViewPrivate::updateSections()
void QDeclarativeListViewPrivate::updateCurrentSection()
{
+ Q_Q(QDeclarativeListView);
if (!sectionCriteria || visibleItems.isEmpty()) {
- currentSection.clear();
+ if (!currentSection.isEmpty()) {
+ currentSection.clear();
+ emit q->currentSectionChanged();
+ }
return;
}
int index = 0;
while (index < visibleItems.count() && visibleItems.at(index)->endPosition() < position())
++index;
+ QString newSection = currentSection;
if (index < visibleItems.count())
- currentSection = visibleItems.at(index)->attached->section();
+ newSection = visibleItems.at(index)->attached->section();
else
- currentSection = visibleItems.first()->attached->section();
+ newSection = visibleItems.first()->attached->section();
+ if (newSection != currentSection) {
+ currentSection = newSection;
+ emit q->currentSectionChanged();
+ }
}
void QDeclarativeListViewPrivate::updateCurrent(int modelIndex)
@@ -1551,6 +1565,7 @@ void QDeclarativeListView::setModel(const QVariant &model)
disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
+ disconnect(d->model, SIGNAL(itemsChanged(int,int)), this, SLOT(itemsChanged(int,int)));
disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
disconnect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
@@ -1581,6 +1596,7 @@ void QDeclarativeListView::setModel(const QVariant &model)
if (d->model) {
d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter;
if (isComponentComplete()) {
+ updateSections();
refill();
if (d->currentIndex >= d->model->count() || d->currentIndex < 0) {
setCurrentIndex(0);
@@ -1596,6 +1612,7 @@ void QDeclarativeListView::setModel(const QVariant &model)
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
+ connect(d->model, SIGNAL(itemsChanged(int,int)), this, SLOT(itemsChanged(int,int)));
connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
connect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
@@ -1653,6 +1670,7 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate)
d->visibleItems.clear();
d->releaseItem(d->currentItem);
d->currentItem = 0;
+ updateSections();
refill();
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
@@ -2066,8 +2084,10 @@ void QDeclarativeListView::setCacheBuffer(int b)
QDeclarativeViewSection *QDeclarativeListView::sectionCriteria()
{
Q_D(QDeclarativeListView);
- if (!d->sectionCriteria)
+ if (!d->sectionCriteria) {
d->sectionCriteria = new QDeclarativeViewSection(this);
+ connect(d->sectionCriteria, SIGNAL(propertyChanged()), this, SLOT(updateSections()));
+ }
return d->sectionCriteria;
}
@@ -2660,6 +2680,7 @@ void QDeclarativeListView::componentComplete()
{
Q_D(QDeclarativeListView);
QDeclarativeFlickable::componentComplete();
+ updateSections();
if (d->isValid()) {
refill();
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
@@ -2676,6 +2697,18 @@ void QDeclarativeListView::componentComplete()
}
}
+void QDeclarativeListView::updateSections()
+{
+ Q_D(QDeclarativeListView);
+ if (isComponentComplete() && d->model) {
+ QList<QByteArray> roles;
+ if (d->sectionCriteria && !d->sectionCriteria->property().isEmpty())
+ roles << d->sectionCriteria->property().toUtf8();
+ d->model->setWatchedRoles(roles);
+ d->updateSections();
+ }
+}
+
void QDeclarativeListView::refill()
{
Q_D(QDeclarativeListView);
@@ -2885,6 +2918,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
for (int j = 0; j < added.count(); ++j)
added.at(j)->attached->emitAdd();
+ d->updateSections();
d->itemCount += count;
emit countChanged();
}
@@ -2977,6 +3011,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
}
}
+ d->updateSections();
emit countChanged();
}
@@ -3098,6 +3133,14 @@ void QDeclarativeListView::itemsMoved(int from, int to, int count)
// Ensure we don't cause an ugly list scroll.
d->visibleItems.first()->setPosition(d->visibleItems.first()->position() + moveBy);
+ d->updateSections();
+ d->layout();
+}
+
+void QDeclarativeListView::itemsChanged(int, int)
+{
+ Q_D(QDeclarativeListView);
+ d->updateSections();
d->layout();
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 735b248..2678b90 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -250,11 +250,13 @@ protected:
virtual void componentComplete();
private Q_SLOTS:
+ void updateSections();
void refill();
void trackedPositionChanged();
void itemsInserted(int index, int count);
void itemsRemoved(int index, int count);
void itemsMoved(int from, int to, int count);
+ void itemsChanged(int index, int count);
void modelReset();
void destroyRemoved();
void createdItem(int index, QDeclarativeItem *item);
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index a0208ef..1533d55 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -557,6 +557,7 @@ void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
ungrabMouse();
setKeepMouseGrab(false);
}
+ d->doubleClick = false;
}
void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
@@ -565,14 +566,12 @@ void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even
if (!d->absorb) {
QDeclarativeItem::mouseDoubleClickEvent(event);
} else {
+ d->doubleClick = true;
d->saveEvent(event);
QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
me.setAccepted(d->isDoubleClickConnected());
emit this->doubleClicked(&me);
- if (!me.isAccepted()) {
- // Only deliver the press event if we haven't accepted the double click.
- QDeclarativeItem::mouseDoubleClickEvent(event);
- }
+ QDeclarativeItem::mouseDoubleClickEvent(event);
}
}
@@ -841,7 +840,8 @@ bool QDeclarativeMouseArea::setPressed(bool p)
d->pressed = p;
QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
if (d->pressed) {
- emit pressed(&me);
+ if (!d->doubleClick)
+ emit pressed(&me);
me.setX(d->lastPos.x());
me.setY(d->lastPos.y());
emit mousePositionChanged(&me);
@@ -849,7 +849,7 @@ bool QDeclarativeMouseArea::setPressed(bool p)
emit released(&me);
me.setX(d->lastPos.x());
me.setY(d->lastPos.y());
- if (isclick && !d->longPress)
+ if (isclick && !d->longPress && !d->doubleClick)
emit clicked(&me);
}
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
index 48a56d9..06a01d3 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
@@ -68,7 +68,7 @@ class QDeclarativeMouseAreaPrivate : public QDeclarativeItemPrivate
public:
QDeclarativeMouseAreaPrivate()
: absorb(true), hovered(false), pressed(false), longPress(false),
- moved(false), stealMouse(false), drag(0)
+ moved(false), stealMouse(false), doubleClick(false), drag(0)
{
}
@@ -109,6 +109,7 @@ public:
bool dragX : 1;
bool dragY : 1;
bool stealMouse : 1;
+ bool doubleClick : 1;
QDeclarativeDrag *drag;
QPointF startScene;
qreal startX;
diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
index a6db1fa..b470b3a 100644
--- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
@@ -44,7 +44,6 @@
#include <QDebug>
#include <QPen>
-#include <QFile>
#include <QEvent>
#include <QApplication>
#include <QGraphicsSceneMouseEvent>
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 31943b2..81c84f5 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -1112,16 +1112,16 @@ void QDeclarativePathViewPrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (!interactive || !lastPosTime.isValid())
return;
+ qreal newPc;
+ QPointF pathPoint = pointNear(event->pos(), &newPc);
if (!stealMouse) {
- QPointF delta = event->pos() - startPoint;
+ QPointF delta = pathPoint - startPoint;
if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance())
stealMouse = true;
}
if (stealMouse) {
moveReason = QDeclarativePathViewPrivate::Mouse;
- qreal newPc;
- pointNear(event->pos(), &newPc);
qreal diff = (newPc - startPc)*modelCount*mappedRange;
if (diff) {
setOffset(offset + diff);
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 65f1564..308aefa 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -82,15 +82,16 @@ private:
static QSet<QUrl> errors;
};
-DEFINE_BOOL_CONFIG_OPTION(disableImageCache, QML_DISABLE_IMAGE_CACHE);
+DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
QDeclarativeTextPrivate::QDeclarativeTextPrivate()
-: color((QRgb)0), style(QDeclarativeText::Normal),
- hAlign(QDeclarativeText::AlignLeft), vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone),
- imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), internalWidthUpdate(false), doc(0),
- format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap)
+: color((QRgb)0), style(QDeclarativeText::Normal), hAlign(QDeclarativeText::AlignLeft),
+ vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone),
+ format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap), imageCacheDirty(true),
+ updateOnComponentComplete(true), richText(false), singleline(false), cacheAllTextAsImage(true),
+ internalWidthUpdate(false), doc(0)
{
- cache = !disableImageCache();
+ cacheAllTextAsImage = enableImageCache();
QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton;
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
@@ -151,7 +152,6 @@ void QTextDocumentWithImageResources::requestFinished()
#endif
QDeclarativeTextPrivate *d = QDeclarativeTextPrivate::get(textItem);
d->updateLayout();
- d->markImgDirty();
}
}
@@ -172,6 +172,382 @@ void QTextDocumentWithImageResources::setText(const QString &text)
QSet<QUrl> QTextDocumentWithImageResources::errors;
+QDeclarativeTextPrivate::~QDeclarativeTextPrivate()
+{
+}
+
+void QDeclarativeTextPrivate::updateLayout()
+{
+ Q_Q(QDeclarativeText);
+ if (!q->isComponentComplete()) {
+ updateOnComponentComplete = true;
+ return;
+ }
+
+ // Setup instance of QTextLayout for all cases other than richtext
+ if (!richText) {
+ layout.clearLayout();
+ layout.setFont(font);
+ if (format != QDeclarativeText::StyledText) {
+ QString tmp = text;
+ tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ singleline = !tmp.contains(QChar::LineSeparator);
+ if (singleline && elideMode != QDeclarativeText::ElideNone && q->widthValid()) {
+ QFontMetrics fm(font);
+ tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); // XXX still worth layout...?
+ }
+ layout.setText(tmp);
+ } else {
+ singleline = false;
+ QDeclarativeStyledText::parse(text, layout);
+ }
+ }
+
+ updateSize();
+}
+
+void QDeclarativeTextPrivate::updateSize()
+{
+ Q_Q(QDeclarativeText);
+
+ if (!q->isComponentComplete()) {
+ updateOnComponentComplete = true;
+ return;
+ }
+
+ invalidateImageCache();
+
+ QFontMetrics fm(font);
+ if (text.isEmpty()) {
+ q->setImplicitHeight(fm.height());
+ emit q->paintedSizeChanged();
+ return;
+ }
+
+ int dy = q->height();
+ QSize size(0, 0);
+
+ //setup instance of QTextLayout for all cases other than richtext
+ if (!richText) {
+ size = setupTextLayout();
+ if (layedOutTextSize != size) {
+ q->prepareGeometryChange();
+ layedOutTextSize = size;
+ }
+ dy -= size.height();
+ } else {
+ singleline = false; // richtext can't elide or be optimized for single-line case
+ ensureDoc();
+ doc->setDefaultFont(font);
+ QTextOption option((Qt::Alignment)int(hAlign | vAlign));
+ option.setWrapMode(QTextOption::WrapMode(wrapMode));
+ doc->setDefaultTextOption(option);
+ if (wrapMode != QDeclarativeText::NoWrap && q->widthValid())
+ doc->setTextWidth(q->width());
+ else
+ doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
+ dy -= (int)doc->size().height();
+ QSize dsize = doc->size().toSize();
+ if (dsize != layedOutTextSize) {
+ q->prepareGeometryChange();
+ layedOutTextSize = dsize;
+ }
+ size = QSize(int(doc->idealWidth()),dsize.height());
+ }
+ int yoff = 0;
+
+ if (q->heightValid()) {
+ if (vAlign == QDeclarativeText::AlignBottom)
+ yoff = dy;
+ else if (vAlign == QDeclarativeText::AlignVCenter)
+ yoff = dy/2;
+ }
+ q->setBaselineOffset(fm.ascent() + yoff);
+
+ //### need to comfirm cost of always setting these for richText
+ internalWidthUpdate = true;
+ q->setImplicitWidth(size.width());
+ internalWidthUpdate = false;
+ q->setImplicitHeight(size.height());
+ emit q->paintedSizeChanged();
+}
+
+/*!
+ Lays out the QDeclarativeTextPrivate::layout QTextLayout in the constraints of the QDeclarativeText.
+
+ Returns the size of the final text. This can be used to position the text vertically (the text is
+ already absolutely positioned horizontally).
+*/
+QSize QDeclarativeTextPrivate::setupTextLayout()
+{
+ // ### text layout handling should be profiled and optimized as needed
+ // what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
+
+ Q_Q(QDeclarativeText);
+ layout.setCacheEnabled(true);
+
+ int height = 0;
+ qreal widthUsed = 0;
+ qreal lineWidth = 0;
+
+ //set manual width
+ if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
+ lineWidth = q->width();
+
+ QTextOption textOption = layout.textOption();
+ textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
+ layout.setTextOption(textOption);
+
+ layout.beginLayout();
+ while (1) {
+ QTextLine line = layout.createLine();
+ if (!line.isValid())
+ break;
+
+ if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
+ line.setLineWidth(lineWidth);
+ }
+ layout.endLayout();
+
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ QTextLine line = layout.lineAt(i);
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+
+ qreal layoutWidth = q->widthValid()?q->width():widthUsed;
+
+ int x = 0;
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ QTextLine line = layout.lineAt(i);
+ line.setPosition(QPointF(0, height));
+ height += int(line.height());
+
+ if (!cacheAllTextAsImage) {
+ if (hAlign == QDeclarativeText::AlignLeft) {
+ x = 0;
+ } else if (hAlign == QDeclarativeText::AlignRight) {
+ x = layoutWidth - (int)line.naturalTextWidth();
+ } else if (hAlign == QDeclarativeText::AlignHCenter) {
+ x = (layoutWidth - (int)line.naturalTextWidth()) / 2;
+ }
+ line.setPosition(QPoint(x, (int)line.y()));
+ }
+ }
+
+ return QSize(qCeil(widthUsed), height);
+}
+
+/*!
+ Returns a painted version of the QDeclarativeTextPrivate::layout QTextLayout.
+ If \a drawStyle is true, the style color overrides all colors in the document.
+*/
+QPixmap QDeclarativeTextPrivate::textLayoutImage(bool drawStyle)
+{
+ //do layout
+ QSize size = layedOutTextSize;
+
+ int x = 0;
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ QTextLine line = layout.lineAt(i);
+ if (hAlign == QDeclarativeText::AlignLeft) {
+ x = 0;
+ } else if (hAlign == QDeclarativeText::AlignRight) {
+ x = size.width() - (int)line.naturalTextWidth();
+ } else if (hAlign == QDeclarativeText::AlignHCenter) {
+ x = (size.width() - (int)line.naturalTextWidth()) / 2;
+ }
+ line.setPosition(QPoint(x, (int)line.y()));
+ }
+
+ //paint text
+ QPixmap img(size);
+ if (!size.isEmpty()) {
+ img.fill(Qt::transparent);
+#ifdef Q_WS_MAC
+ bool oldSmooth = qt_applefontsmoothing_enabled;
+ qt_applefontsmoothing_enabled = false;
+#endif
+ QPainter p(&img);
+#ifdef Q_WS_MAC
+ qt_applefontsmoothing_enabled = oldSmooth;
+#endif
+ drawTextLayout(&p, QPointF(0,0), drawStyle);
+ }
+ return img;
+}
+
+/*!
+ Paints the QDeclarativeTextPrivate::layout QTextLayout into \a painter at \a pos. If
+ \a drawStyle is true, the style color overrides all colors in the document.
+*/
+void QDeclarativeTextPrivate::drawTextLayout(QPainter *painter, const QPointF &pos, bool drawStyle)
+{
+ if (drawStyle)
+ painter->setPen(styleColor);
+ else
+ painter->setPen(color);
+ painter->setFont(font);
+ layout.draw(painter, pos);
+}
+
+/*!
+ Returns a painted version of the QDeclarativeTextPrivate::doc QTextDocument.
+ If \a drawStyle is true, the style color overrides all colors in the document.
+*/
+QPixmap QDeclarativeTextPrivate::textDocumentImage(bool drawStyle)
+{
+ QSize size = doc->size().toSize();
+
+ //paint text
+ QPixmap img(size);
+ img.fill(Qt::transparent);
+#ifdef Q_WS_MAC
+ bool oldSmooth = qt_applefontsmoothing_enabled;
+ qt_applefontsmoothing_enabled = false;
+#endif
+ QPainter p(&img);
+#ifdef Q_WS_MAC
+ qt_applefontsmoothing_enabled = oldSmooth;
+#endif
+
+ QAbstractTextDocumentLayout::PaintContext context;
+
+ QTextOption oldOption(doc->defaultTextOption());
+ if (drawStyle) {
+ context.palette.setColor(QPalette::Text, styleColor);
+ QTextOption colorOption(doc->defaultTextOption());
+ colorOption.setFlags(QTextOption::SuppressColors);
+ doc->setDefaultTextOption(colorOption);
+ } else {
+ context.palette.setColor(QPalette::Text, color);
+ }
+ doc->documentLayout()->draw(&p, context);
+ if (drawStyle)
+ doc->setDefaultTextOption(oldOption);
+ return img;
+}
+
+/*!
+ Mark the image cache as dirty.
+*/
+void QDeclarativeTextPrivate::invalidateImageCache()
+{
+ Q_Q(QDeclarativeText);
+
+ if (imageCacheDirty)
+ return;
+
+ imageCacheDirty = true;
+ imageCache = QPixmap();
+
+ if (q->isComponentComplete())
+ q->update();
+}
+
+/*!
+ Tests if the image cache is dirty, and repaints it if it is.
+*/
+void QDeclarativeTextPrivate::checkImageCache()
+{
+ if (!imageCacheDirty)
+ return;
+
+ if (text.isEmpty()) {
+
+ imageCache = QPixmap();
+
+ } else {
+
+ QPixmap textImage;
+ QPixmap styledImage;
+
+ if (richText) {
+ textImage = textDocumentImage(false);
+ if (style != QDeclarativeText::Normal)
+ styledImage = textDocumentImage(true); //### should use styleColor
+ } else {
+ textImage = textLayoutImage(false);
+ if (style != QDeclarativeText::Normal)
+ styledImage = textLayoutImage(true); //### should use styleColor
+ }
+
+ switch (style) {
+ case QDeclarativeText::Outline:
+ imageCache = drawOutline(textImage, styledImage);
+ break;
+ case QDeclarativeText::Sunken:
+ imageCache = drawOutline(textImage, styledImage, -1);
+ break;
+ case QDeclarativeText::Raised:
+ imageCache = drawOutline(textImage, styledImage, 1);
+ break;
+ default:
+ imageCache = textImage;
+ break;
+ }
+
+ }
+
+ imageCacheDirty = false;
+}
+
+/*!
+ Ensures the QDeclarativeTextPrivate::doc variable is set to a valid text document
+*/
+void QDeclarativeTextPrivate::ensureDoc()
+{
+ if (!doc) {
+ Q_Q(QDeclarativeText);
+ doc = new QTextDocumentWithImageResources(q);
+ doc->setDocumentMargin(0);
+ }
+}
+
+/*!
+ Draw \a styleSource as an outline around \a source and return the new image.
+*/
+QPixmap QDeclarativeTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource)
+{
+ QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
+ img.fill(Qt::transparent);
+
+ QPainter ppm(&img);
+
+ QPoint pos(0, 0);
+ pos += QPoint(-1, 0);
+ ppm.drawPixmap(pos, styleSource);
+ pos += QPoint(2, 0);
+ ppm.drawPixmap(pos, styleSource);
+ pos += QPoint(-1, -1);
+ ppm.drawPixmap(pos, styleSource);
+ pos += QPoint(0, 2);
+ ppm.drawPixmap(pos, styleSource);
+
+ pos += QPoint(0, -1);
+ ppm.drawPixmap(pos, source);
+ ppm.end();
+
+ return img;
+}
+
+/*!
+ Draw \a styleSource below \a source at \a yOffset and return the new image.
+*/
+QPixmap QDeclarativeTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset)
+{
+ QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
+ img.fill(Qt::transparent);
+
+ QPainter ppm(&img);
+
+ ppm.drawPixmap(QPoint(0, yOffset), styleSource);
+ ppm.drawPixmap(0, 0, source);
+
+ ppm.end();
+
+ return img;
+}
+
/*!
\qmlclass Text QDeclarativeText
\ingroup qml-basic-visual-elements
@@ -211,10 +587,44 @@ QDeclarativeText::~QDeclarativeText()
{
}
+/*!
+ \qmlproperty bool Text::clip
+ This property holds whether the text is clipped.
-QDeclarativeTextPrivate::~QDeclarativeTextPrivate()
-{
-}
+ Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
+
+ If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
+*/
+
+/*!
+ \qmlproperty bool Text::smooth
+
+ This property holds whether the text is smoothly scaled or transformed.
+
+ Smooth filtering gives better visual quality, but is slower. If
+ the item is displayed at its natural size, this property has no visual or
+ performance effect.
+
+ \note Generally scaling artifacts are only visible if the item is stationary on
+ the screen. A common pattern when animating an item is to disable smooth
+ filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+/*!
+ \qmlsignal Text::onLinkActivated(string link)
+
+ This handler is called when the user clicks on a link embedded in the text.
+ The link must be in rich text or HTML format and the
+ \a link string provides access to the particular link.
+
+ \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
+
+ The example code will display the text
+ "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
+
+ Clicking on the highlighted link will output
+ \tt{http://qt.nokia.com link activated} to the console.
+*/
/*!
\qmlproperty string Text::font.family
@@ -320,7 +730,6 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate()
Text { text: "Hello"; font.capitalization: Font.AllLowercase }
\endqml
*/
-
QFont QDeclarativeText::font() const
{
Q_D(const QDeclarativeText);
@@ -334,30 +743,9 @@ void QDeclarativeText::setFont(const QFont &font)
return;
d->font = font;
-
d->updateLayout();
- d->markImgDirty();
- emit fontChanged(d->font);
-}
-
-void QDeclarativeText::setText(const QString &n)
-{
- Q_D(QDeclarativeText);
- if (d->text == n)
- return;
- d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(n));
- if (d->richText) {
- if (isComponentComplete()) {
- d->ensureDoc();
- d->doc->setText(n);
- }
- }
-
- d->text = n;
- d->updateLayout();
- d->markImgDirty();
- emit textChanged(d->text);
+ emit fontChanged(d->font);
}
/*!
@@ -374,17 +762,25 @@ QString QDeclarativeText::text() const
return d->text;
}
-void QDeclarativeText::setColor(const QColor &color)
+void QDeclarativeText::setText(const QString &n)
{
Q_D(QDeclarativeText);
- if (d->color == color)
+ if (d->text == n)
return;
- d->color = color;
- d->markImgDirty();
- emit colorChanged(d->color);
+ d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(n));
+ if (d->richText && isComponentComplete()) {
+ d->ensureDoc();
+ d->doc->setText(n);
+ }
+
+ d->text = n;
+ d->updateLayout();
+
+ emit textChanged(d->text);
}
+
/*!
\qmlproperty color Text::color
@@ -398,13 +794,23 @@ void QDeclarativeText::setColor(const QColor &color)
Text { color: "steelblue"; ... }
\endqml
*/
-
QColor QDeclarativeText::color() const
{
Q_D(const QDeclarativeText);
return d->color;
}
+void QDeclarativeText::setColor(const QColor &color)
+{
+ Q_D(QDeclarativeText);
+ if (d->color == color)
+ return;
+
+ d->color = color;
+ d->invalidateImageCache();
+ emit colorChanged(d->color);
+}
+
/*!
\qmlproperty enumeration Text::style
@@ -445,21 +851,10 @@ void QDeclarativeText::setStyle(QDeclarativeText::TextStyle style)
if (isComponentComplete() && (d->style == Normal || style == Normal))
prepareGeometryChange();
d->style = style;
- d->markImgDirty();
+ d->invalidateImageCache();
emit styleChanged(d->style);
}
-void QDeclarativeText::setStyleColor(const QColor &color)
-{
- Q_D(QDeclarativeText);
- if (d->styleColor == color)
- return;
-
- d->styleColor = color;
- d->markImgDirty();
- emit styleColorChanged(d->styleColor);
-}
-
/*!
\qmlproperty color Text::styleColor
@@ -481,6 +876,18 @@ QColor QDeclarativeText::styleColor() const
return d->styleColor;
}
+void QDeclarativeText::setStyleColor(const QColor &color)
+{
+ Q_D(QDeclarativeText);
+ if (d->styleColor == color)
+ return;
+
+ d->styleColor = color;
+ d->invalidateImageCache();
+ emit styleColorChanged(d->styleColor);
+}
+
+
/*!
\qmlproperty enumeration Text::horizontalAlignment
\qmlproperty enumeration Text::verticalAlignment
@@ -511,7 +918,10 @@ void QDeclarativeText::setHAlign(HAlignment align)
if (isComponentComplete())
prepareGeometryChange();
+
d->hAlign = align;
+ d->updateLayout();
+
emit horizontalAlignmentChanged(align);
}
@@ -559,9 +969,8 @@ void QDeclarativeText::setWrapMode(WrapMode mode)
return;
d->wrapMode = mode;
-
d->updateLayout();
- d->markImgDirty();
+
emit wrapModeChanged();
}
@@ -621,7 +1030,6 @@ Column {
\o \image declarative-textformat.png
\endtable
*/
-
QDeclarativeText::TextFormat QDeclarativeText::textFormat() const
{
Q_D(const QDeclarativeText);
@@ -637,19 +1045,13 @@ void QDeclarativeText::setTextFormat(TextFormat format)
bool wasRich = d->richText;
d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
- if (wasRich && !d->richText) {
- //### delete control? (and vice-versa below)
- d->updateLayout();
- d->markImgDirty();
- } else if (!wasRich && d->richText) {
- if (isComponentComplete()) {
- d->ensureDoc();
- d->doc->setText(d->text);
- }
- d->updateLayout();
- d->markImgDirty();
+ if (!wasRich && d->richText && isComponentComplete()) {
+ d->ensureDoc();
+ d->doc->setText(d->text);
}
+ d->updateLayout();
+
emit textFormatChanged(d->format);
}
@@ -688,12 +1090,12 @@ void QDeclarativeText::setElideMode(QDeclarativeText::TextElideMode mode)
return;
d->elideMode = mode;
-
d->updateLayout();
- d->markImgDirty();
+
emit elideModeChanged(d->elideMode);
}
+/*! \internal */
QRectF QDeclarativeText::boundingRect() const
{
Q_D(const QDeclarativeText);
@@ -704,7 +1106,7 @@ QRectF QDeclarativeText::boundingRect() const
int x = 0;
int y = 0;
- QSize size = d->cachedLayoutSize;
+ QSize size = d->layedOutTextSize;
if (d->style != Normal)
size += QSize(2,2);
@@ -737,117 +1139,23 @@ QRectF QDeclarativeText::boundingRect() const
return QRectF(x,y,size.width(),size.height());
}
-void QDeclarativeText::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+/*! \internal */
+void QDeclarativeText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QDeclarativeText);
- if (!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width()) {
- if (d->wrapMode != QDeclarativeText::NoWrap || d->elideMode != QDeclarativeText::ElideNone) {
- //re-elide if needed
- if (d->singleline && d->elideMode != QDeclarativeText::ElideNone &&
- isComponentComplete() && widthValid()) {
-
- QFontMetrics fm(d->font);
- QString tmp = fm.elidedText(d->text,(Qt::TextElideMode)d->elideMode,width()); // XXX still worth layout...?
- d->layout.setText(tmp);
- }
+ if (!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width() &&
+ (d->wrapMode != QDeclarativeText::NoWrap || d->elideMode != QDeclarativeText::ElideNone)) {
- d->imgDirty = true;
+ if (d->singleline && d->elideMode != QDeclarativeText::ElideNone && widthValid()) {
+ // We need to re-elide
+ d->updateLayout();
+ } else {
+ // We just need to re-layout
d->updateSize();
}
}
- QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-void QDeclarativeTextPrivate::updateLayout()
-{
- Q_Q(QDeclarativeText);
- if (q->isComponentComplete()) {
- //setup instance of QTextLayout for all cases other than richtext
- if (!richText) {
- layout.clearLayout();
- layout.setFont(font);
- if (format != QDeclarativeText::StyledText) {
- QString tmp = text;
- tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
- singleline = !tmp.contains(QChar::LineSeparator);
- if (singleline && elideMode != QDeclarativeText::ElideNone && q->widthValid()) {
- QFontMetrics fm(font);
- tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); // XXX still worth layout...?
- }
- layout.setText(tmp);
- } else {
- singleline = false;
- QDeclarativeStyledText::parse(text, layout);
- }
- }
- updateSize();
- } else {
- dirty = true;
- }
-}
-
-
-void QDeclarativeTextPrivate::updateSize()
-{
- Q_Q(QDeclarativeText);
- if (q->isComponentComplete()) {
- QFontMetrics fm(font);
- if (text.isEmpty()) {
- q->setImplicitHeight(fm.height());
- emit q->paintedSizeChanged();
- return;
- }
-
- int dy = q->height();
- QSize size(0, 0);
-
- //setup instance of QTextLayout for all cases other than richtext
- if (!richText) {
- size = setupTextLayout();
- if (cachedLayoutSize != size) {
- q->prepareGeometryChange();
- cachedLayoutSize = size;
- }
- dy -= size.height();
- } else {
- singleline = false; // richtext can't elide or be optimized for single-line case
- ensureDoc();
- doc->setDefaultFont(font);
- QTextOption option((Qt::Alignment)int(hAlign | vAlign));
- option.setWrapMode(QTextOption::WrapMode(wrapMode));
- doc->setDefaultTextOption(option);
- if (wrapMode != QDeclarativeText::NoWrap && q->widthValid())
- doc->setTextWidth(q->width());
- else
- doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
- dy -= (int)doc->size().height();
- QSize dsize = doc->size().toSize();
- if (dsize != cachedLayoutSize) {
- q->prepareGeometryChange();
- cachedLayoutSize = dsize;
- }
- size = QSize(int(doc->idealWidth()),dsize.height());
- }
- int yoff = 0;
- if (q->heightValid()) {
- if (vAlign == QDeclarativeText::AlignBottom)
- yoff = dy;
- else if (vAlign == QDeclarativeText::AlignVCenter)
- yoff = dy/2;
- }
- q->setBaselineOffset(fm.ascent() + yoff);
-
- //### need to comfirm cost of always setting these for richText
- internalWidthUpdate = true;
- q->setImplicitWidth(size.width());
- internalWidthUpdate = false;
- q->setImplicitHeight(size.height());
- emit q->paintedSizeChanged();
- } else {
- dirty = true;
- }
+ QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
}
/*!
@@ -872,228 +1180,6 @@ qreal QDeclarativeText::paintedHeight() const
return implicitHeight();
}
-
-
-// ### text layout handling should be profiled and optimized as needed
-// what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
-
-void QDeclarativeTextPrivate::drawOutline()
-{
- QPixmap img = QPixmap(imgStyleCache.width()+2,imgStyleCache.height()+2);
- img.fill(Qt::transparent);
-
- QPainter ppm(&img);
-
- QPoint pos(imgCache.rect().topLeft());
- pos += QPoint(-1, 0);
- ppm.drawPixmap(pos, imgStyleCache);
- pos += QPoint(2, 0);
- ppm.drawPixmap(pos, imgStyleCache);
- pos += QPoint(-1, -1);
- ppm.drawPixmap(pos, imgStyleCache);
- pos += QPoint(0, 2);
- ppm.drawPixmap(pos, imgStyleCache);
-
- pos += QPoint(0, -1);
- ppm.drawPixmap(pos, imgCache);
- ppm.end();
-
- imgCache = img;
-}
-
-void QDeclarativeTextPrivate::drawOutline(int yOffset)
-{
- QPixmap img = QPixmap(imgStyleCache.width()+2,imgStyleCache.height()+2);
- img.fill(Qt::transparent);
-
- QPainter ppm(&img);
-
- QPoint pos(imgCache.rect().topLeft());
- pos += QPoint(0, yOffset);
- ppm.drawPixmap(pos, imgStyleCache);
-
- pos += QPoint(0, -yOffset);
- ppm.drawPixmap(pos, imgCache);
- ppm.end();
-
- imgCache = img;
-}
-
-QSize QDeclarativeTextPrivate::setupTextLayout()
-{
- Q_Q(QDeclarativeText);
- layout.setCacheEnabled(true);
-
- int height = 0;
- qreal widthUsed = 0;
- qreal lineWidth = 0;
-
- //set manual width
- if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
- lineWidth = q->width();
-
- QTextOption textOption = layout.textOption();
- textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
- layout.setTextOption(textOption);
-
- layout.beginLayout();
-
- while (1) {
- QTextLine line = layout.createLine();
- if (!line.isValid())
- break;
-
- if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
- line.setLineWidth(lineWidth);
- }
- layout.endLayout();
-
- int x = 0;
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
- line.setPosition(QPointF(0, height));
- height += int(line.height());
-
- if (!cache) {
- if (hAlign == QDeclarativeText::AlignLeft) {
- x = 0;
- } else if (hAlign == QDeclarativeText::AlignRight) {
- x = q->width() - (int)line.naturalTextWidth();
- } else if (hAlign == QDeclarativeText::AlignHCenter) {
- x = (q->width() - (int)line.naturalTextWidth()) / 2;
- }
- line.setPosition(QPoint(x, (int)line.y()));
- }
- }
-
- return QSize(qCeil(widthUsed), height);
-}
-
-QPixmap QDeclarativeTextPrivate::wrappedTextImage(bool drawStyle)
-{
- //do layout
- QSize size = cachedLayoutSize;
-
- int x = 0;
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- if (hAlign == QDeclarativeText::AlignLeft) {
- x = 0;
- } else if (hAlign == QDeclarativeText::AlignRight) {
- x = size.width() - (int)line.naturalTextWidth();
- } else if (hAlign == QDeclarativeText::AlignHCenter) {
- x = (size.width() - (int)line.naturalTextWidth()) / 2;
- }
- line.setPosition(QPoint(x, (int)line.y()));
- }
-
- //paint text
- QPixmap img(size);
- if (!size.isEmpty()) {
- img.fill(Qt::transparent);
-#ifdef Q_WS_MAC
- bool oldSmooth = qt_applefontsmoothing_enabled;
- qt_applefontsmoothing_enabled = false;
-#endif
- QPainter p(&img);
-#ifdef Q_WS_MAC
- qt_applefontsmoothing_enabled = oldSmooth;
-#endif
- drawWrappedText(&p, QPointF(0,0), drawStyle);
- }
- return img;
-}
-
-void QDeclarativeTextPrivate::drawWrappedText(QPainter *p, const QPointF &pos, bool drawStyle)
-{
- if (drawStyle)
- p->setPen(styleColor);
- else
- p->setPen(color);
- p->setFont(font);
- layout.draw(p , pos);
-}
-
-QPixmap QDeclarativeTextPrivate::richTextImage(bool drawStyle)
-{
- QSize size = doc->size().toSize();
-
- //paint text
- QPixmap img(size);
- img.fill(Qt::transparent);
-#ifdef Q_WS_MAC
- bool oldSmooth = qt_applefontsmoothing_enabled;
- qt_applefontsmoothing_enabled = false;
-#endif
- QPainter p(&img);
-#ifdef Q_WS_MAC
- qt_applefontsmoothing_enabled = oldSmooth;
-#endif
-
- QAbstractTextDocumentLayout::PaintContext context;
-
- QTextOption oldOption(doc->defaultTextOption());
- if (drawStyle) {
- context.palette.setColor(QPalette::Text, styleColor);
- QTextOption colorOption(doc->defaultTextOption());
- colorOption.setFlags(QTextOption::SuppressColors);
- doc->setDefaultTextOption(colorOption);
- } else {
- context.palette.setColor(QPalette::Text, color);
- }
- doc->documentLayout()->draw(&p, context);
- if (drawStyle)
- doc->setDefaultTextOption(oldOption);
- return img;
-}
-
-void QDeclarativeTextPrivate::checkImgCache()
-{
- if (!imgDirty)
- return;
-
- bool empty = text.isEmpty();
- QPixmap newImgCache;
- if (empty) {
- imgStyleCache = QPixmap();
- } else if (richText) {
- newImgCache = richTextImage(false);
- if (style != QDeclarativeText::Normal)
- imgStyleCache = richTextImage(true); //### should use styleColor
- } else {
- newImgCache = wrappedTextImage(false);
- if (style != QDeclarativeText::Normal)
- imgStyleCache = wrappedTextImage(true); //### should use styleColor
- }
- imgCache = newImgCache;
- if (!empty)
- switch (style) {
- case QDeclarativeText::Outline:
- drawOutline();
- break;
- case QDeclarativeText::Sunken:
- drawOutline(-1);
- break;
- case QDeclarativeText::Raised:
- drawOutline(1);
- break;
- default:
- break;
- }
-
- imgDirty = false;
-}
-
-void QDeclarativeTextPrivate::ensureDoc()
-{
- if (!doc) {
- Q_Q(QDeclarativeText);
- doc = new QTextDocumentWithImageResources(q);
- doc->setDocumentMargin(0);
- }
-}
-
/*!
Returns the number of resources (images) that are being loaded asynchronously.
*/
@@ -1103,22 +1189,14 @@ int QDeclarativeText::resourcesLoading() const
return d->doc ? d->doc->resourcesLoading() : 0;
}
-/*!
- \qmlproperty bool Text::clip
- This property holds whether the text is clipped.
-
- Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
-
- If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
-*/
-
+/*! \internal */
void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeText);
- if (d->cache || d->style != Normal) {
- d->checkImgCache();
- if (d->imgCache.isNull())
+ if (d->cacheAllTextAsImage || d->style != Normal) {
+ d->checkImageCache();
+ if (d->imageCache.isNull())
return;
bool oldAA = p->testRenderHint(QPainter::Antialiasing);
@@ -1128,23 +1206,23 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
QRect br = boundingRect().toRect();
- bool needClip = clip() && (d->imgCache.width() > width() ||
- d->imgCache.height() > height());
+ bool needClip = clip() && (d->imageCache.width() > width() ||
+ d->imageCache.height() > height());
if (needClip)
- p->drawPixmap(0, 0, width(), height(), d->imgCache, -br.x(), -br.y(), width(), height());
+ p->drawPixmap(0, 0, width(), height(), d->imageCache, -br.x(), -br.y(), width(), height());
else
- p->drawPixmap(br.x(), br.y(), d->imgCache);
+ p->drawPixmap(br.x(), br.y(), d->imageCache);
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
} else {
- qreal y = boundingRect().y();
+ QRectF bounds = boundingRect();
- bool needClip = clip() && (d->cachedLayoutSize.width() > width() ||
- d->cachedLayoutSize.height() > height());
+ bool needClip = clip() && (d->layedOutTextSize.width() > width() ||
+ d->layedOutTextSize.height() > height());
if (needClip) {
p->save();
@@ -1153,49 +1231,35 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
if (d->richText) {
QAbstractTextDocumentLayout::PaintContext context;
context.palette.setColor(QPalette::Text, d->color);
- p->translate(0, y);
+ p->translate(bounds.x(), bounds.y());
d->doc->documentLayout()->draw(p, context);
- p->translate(0, -y);
+ p->translate(-bounds.x(), -bounds.y());
} else {
- d->drawWrappedText(p, QPointF(0,y), false);
+ d->drawTextLayout(p, QPointF(0, bounds.y()), false);
}
- if (needClip)
+
+ if (needClip) {
p->restore();
+ }
}
}
-/*!
- \qmlproperty bool Text::smooth
-
- This property holds whether the text is smoothly scaled or transformed.
-
- Smooth filtering gives better visual quality, but is slower. If
- the item is displayed at its natural size, this property has no visual or
- performance effect.
-
- \note Generally scaling artifacts are only visible if the item is stationary on
- the screen. A common pattern when animating an item is to disable smooth
- filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
+/*! \internal */
void QDeclarativeText::componentComplete()
{
Q_D(QDeclarativeText);
QDeclarativeItem::componentComplete();
- if (d->dirty) {
+ if (d->updateOnComponentComplete) {
+ d->updateOnComponentComplete = false;
if (d->richText) {
d->ensureDoc();
d->doc->setText(d->text);
}
d->updateLayout();
- d->dirty = false;
}
}
-/*!
- \overload
- Handles the given mouse \a event.
- */
+/*! \internal */
void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarativeText);
@@ -1214,26 +1278,7 @@ void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
-/*!
- \qmlsignal Text::onLinkActivated(string link)
-
- This handler is called when the user clicks on a link embedded in the text.
- The link must be in rich text or HTML format and the
- \a link string provides access to the particular link.
-
- \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
-
- The example code will display the text
- "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
-
- Clicking on the highlighted link will output
- \tt{http://qt.nokia.com link activated} to the console.
-*/
-
-/*!
- \overload
- Handles the given mouse \a event.
- */
+/*! \internal */
void QDeclarativeText::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarativeText);
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p_p.h b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
index db68558..e37f477 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
@@ -74,24 +74,8 @@ public:
~QDeclarativeTextPrivate();
- void ensureDoc();
void updateSize();
void updateLayout();
- void markImgDirty() {
- Q_Q(QDeclarativeText);
- imgDirty = true;
- if (q->isComponentComplete())
- q->update();
- }
- void checkImgCache();
-
- void drawOutline();
- void drawOutline(int yOffset);
-
- QPixmap wrappedTextImage(bool drawStyle);
- void drawWrappedText(QPainter *p, const QPointF &pos, bool drawStyle);
- QPixmap richTextImage(bool drawStyle);
- QSize setupTextLayout();
QString text;
QFont font;
@@ -99,23 +83,37 @@ public:
QDeclarativeText::TextStyle style;
QColor styleColor;
QString activeLink;
- QPixmap imgCache;
- QPixmap imgStyleCache;
QDeclarativeText::HAlignment hAlign;
QDeclarativeText::VAlignment vAlign;
QDeclarativeText::TextElideMode elideMode;
- bool imgDirty:1;
- bool dirty:1;
+ QDeclarativeText::TextFormat format;
+ QDeclarativeText::WrapMode wrapMode;
+
+ void invalidateImageCache();
+ void checkImageCache();
+ QPixmap imageCache;
+
+ bool imageCacheDirty:1;
+ bool updateOnComponentComplete:1;
bool richText:1;
bool singleline:1;
- bool cache:1;
+ bool cacheAllTextAsImage:1;
bool internalWidthUpdate:1;
+
+ QSize layedOutTextSize;
+
+ void ensureDoc();
+ QPixmap textDocumentImage(bool drawStyle);
QTextDocumentWithImageResources *doc;
+
+ QSize setupTextLayout();
+ QPixmap textLayoutImage(bool drawStyle);
+ void drawTextLayout(QPainter *p, const QPointF &pos, bool drawStyle);
QDeclarativeTextLayout layout;
- QSize cachedLayoutSize;
- QDeclarativeText::TextFormat format;
- QDeclarativeText::WrapMode wrapMode;
-
+
+ static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource);
+ static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset);
+
static inline QDeclarativeTextPrivate *get(QDeclarativeText *t) {
return t->d_func();
}
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 6f5608a..e05f4e4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -319,6 +319,7 @@ void QDeclarativeTextEdit::setTextFormat(TextFormat format)
updateSize();
}
d->format = format;
+ d->control->setAcceptRichText(d->format != PlainText);
emit textFormatChanged(d->format);
}
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index 439f500..e569dd2 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -403,6 +403,8 @@ public:
QDeclarativeListAccessor *m_listAccessor;
QModelIndex m_root;
+ QList<QByteArray> watchedRoles;
+ QList<int> watchedRoleIds;
};
class QDeclarativeVisualDataModelDataMetaObject : public QDeclarativeOpenMetaObject
@@ -1170,10 +1172,25 @@ int QDeclarativeVisualDataModel::indexOf(QDeclarativeItem *item, QObject *) cons
return -1;
}
+void QDeclarativeVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
+{
+ Q_D(QDeclarativeVisualDataModel);
+ d->watchedRoles = roles;
+ d->watchedRoleIds.clear();
+}
+
void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count,
const QList<int> &roles)
{
Q_D(QDeclarativeVisualDataModel);
+ bool changed = false;
+ if (!d->watchedRoles.isEmpty() && d->watchedRoleIds.isEmpty()) {
+ foreach (QByteArray r, d->watchedRoles) {
+ if (d->m_roleNames.contains(r))
+ d->watchedRoleIds << d->m_roleNames.value(r);
+ }
+ }
+
for (QHash<int,QDeclarativeVisualDataModelPrivate::ObjectRef>::ConstIterator iter = d->m_cache.begin();
iter != d->m_cache.end(); ++iter) {
const int idx = iter.key();
@@ -1183,6 +1200,8 @@ void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count,
QDeclarativeVisualDataModelData *data = d->data(objRef.obj);
for (int roleIdx = 0; roleIdx < roles.count(); ++roleIdx) {
int role = roles.at(roleIdx);
+ if (!changed && !d->watchedRoleIds.isEmpty() && d->watchedRoleIds.contains(role))
+ changed = true;
int propId = data->propForRole(role);
if (propId != -1) {
if (data->hasValue(propId)) {
@@ -1217,6 +1236,8 @@ void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count,
}
}
}
+ if (changed)
+ emit itemsChanged(index, count);
}
void QDeclarativeVisualDataModel::_q_itemsInserted(int index, int count)
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
index f09d8dd..5e187c2 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h
@@ -79,6 +79,7 @@ public:
virtual bool completePending() const = 0;
virtual void completeItem() = 0;
virtual QString stringValue(int, const QString &) = 0;
+ virtual void setWatchedRoles(QList<QByteArray> roles) = 0;
virtual int indexOf(QDeclarativeItem *item, QObject *objectContext) const = 0;
@@ -87,6 +88,7 @@ Q_SIGNALS:
void itemsInserted(int index, int count);
void itemsRemoved(int index, int count);
void itemsMoved(int from, int to, int count);
+ void itemsChanged(int index, int count);
void modelReset();
void createdItem(int index, QDeclarativeItem *item);
void destroyingItem(QDeclarativeItem *item);
@@ -120,6 +122,7 @@ public:
virtual bool completePending() const;
virtual void completeItem();
virtual QString stringValue(int index, const QString &role);
+ virtual void setWatchedRoles(QList<QByteArray>) {}
virtual int indexOf(QDeclarativeItem *item, QObject *objectContext) const;
@@ -174,6 +177,7 @@ public:
bool completePending() const;
void completeItem();
virtual QString stringValue(int index, const QString &role);
+ virtual void setWatchedRoles(QList<QByteArray> roles);
int indexOf(QDeclarativeItem *item, QObject *objectContext) const;
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index dc28e22..74bc5bd 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -1932,6 +1932,9 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
{
obj->addValueProperty(prop);
+ if (prop->values.count() > 1)
+ COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign multiple values to a singular property") );
+
for (int ii = 0; ii < prop->values.count(); ++ii) {
Value *v = prop->values.at(ii);
if (v->object) {
@@ -2562,8 +2565,8 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
QStringList alias = astNodeToStringList(node);
- if (alias.count() != 1 && alias.count() != 2)
- COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>"));
+ if (alias.count() < 1 || alias.count() > 3)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
if (!compileState.ids.contains(alias.at(0)))
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
@@ -2575,11 +2578,14 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
int propIdx = -1;
int flags = 0;
bool writable = false;
- if (alias.count() == 2) {
+ if (alias.count() == 2 || alias.count() == 3) {
propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
- if (-1 == propIdx)
+ if (-1 == propIdx) {
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+ } else if (propIdx > 0xFFFF) {
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Alias property exceeds alias bounds"));
+ }
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
if (!aliasProperty.isScriptable())
@@ -2587,6 +2593,22 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
writable = aliasProperty.isWritable();
+ if (alias.count() == 3) {
+ QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
+ if (!valueType)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+
+ propIdx |= ((unsigned int)aliasProperty.type()) << 24;
+
+ int valueTypeIndex = valueType->metaObject()->indexOfProperty(alias.at(2).toUtf8().constData());
+ if (valueTypeIndex == -1)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+ Q_ASSERT(valueTypeIndex <= 0xFF);
+
+ aliasProperty = valueType->metaObject()->property(valueTypeIndex);
+ propIdx |= (valueTypeIndex << 16);
+ }
+
if (aliasProperty.isEnumType())
typeName = "int"; // Avoid introducing a dependency on the aliased metaobject
else
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index b532b0c..cfef9cf 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -57,7 +57,6 @@
#include <QStack>
#include <QStringList>
-#include <QFileInfo>
#include <QtCore/qdebug.h>
#include <QApplication>
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index e916273..def4188 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -64,6 +64,7 @@ class QDeclarativeAbstractBinding;
class QDeclarativeContext;
class QDeclarativePropertyCache;
class QDeclarativeContextData;
+class QDeclarativeNotifier;
// This class is structured in such a way, that simply zero'ing it is the
// default state for elemental object allocations. This is crucial in the
// workings of the QDeclarativeInstruction::CreateSimpleObject instruction.
@@ -75,20 +76,23 @@ public:
: ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0),
bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0),
- attachedProperties(0), scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0) {
+ scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0), extendedData(0) {
init();
}
static inline void init() {
QAbstractDeclarativeData::destroyed = destroyed;
QAbstractDeclarativeData::parentChanged = parentChanged;
+ QAbstractDeclarativeData::objectNameChanged = objectNameChanged;
}
static void destroyed(QAbstractDeclarativeData *, QObject *);
static void parentChanged(QAbstractDeclarativeData *, QObject *, QObject *);
+ static void objectNameChanged(QAbstractDeclarativeData *, QObject *);
void destroyed(QObject *);
void parentChanged(QObject *, QObject *);
+ void objectNameChanged(QObject *);
void setImplicitDestructible() {
if (!explicitIndestructibleSet) indestructible = false;
@@ -123,8 +127,6 @@ public:
QDeclarativeCompiledData *deferredComponent; // Can't this be found from the context?
unsigned int deferredIdx;
- QHash<int, QObject *> *attachedProperties;
-
// ### Can we make this QScriptValuePrivate so we incur no additional allocation
// cost?
QScriptValue *scriptValue;
@@ -147,6 +149,18 @@ public:
return 0;
}
}
+
+ QDeclarativeNotifier *objectNameNotifier() const;
+ QHash<int, QObject *> *attachedProperties() const;
+
+ struct ExtendedData {
+ ExtendedData();
+ ~ExtendedData();
+
+ QHash<int, QObject *> attachedProperties;
+ void *objectNameNotifier;
+ };
+ mutable ExtendedData *extendedData;
};
template<class T>
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 584c5ec..c3fdf36 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -68,6 +68,7 @@
#include "private/qdeclarativelist_p.h"
#include "private/qdeclarativetypenamecache_p.h"
#include "private/qdeclarativeinclude_p.h"
+#include "private/qdeclarativenotifier_p.h"
#include <QtCore/qmetaobject.h>
#include <QScriptClass>
@@ -104,6 +105,7 @@
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
#include <qlibrary.h>
+#include <windows.h>
#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
@@ -468,6 +470,11 @@ void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QO
static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
}
+void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
+{
+ static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
+}
+
void QDeclarativeEnginePrivate::init()
{
Q_Q(QDeclarativeEngine);
@@ -949,7 +956,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
if (!data)
return 0; // Attached properties are only on objects created by QML
- QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0;
+ QObject *rv = data->extendedData?data->attachedProperties()->value(id):0;
if (rv || !create)
return rv;
@@ -959,11 +966,8 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
rv = pf(const_cast<QObject *>(object));
- if (rv) {
- if (!data->attachedProperties)
- data->attachedProperties = new QHash<int, QObject *>();
- data->attachedProperties->insert(id, rv);
- }
+ if (rv)
+ data->attachedProperties()->insert(id, rv);
return rv;
}
@@ -984,8 +988,6 @@ void QDeclarativeData::destroyed(QObject *object)
{
if (deferredComponent)
deferredComponent->release();
- if (attachedProperties)
- delete attachedProperties;
if (nextContextObject)
nextContextObject->prevContextObject = prevContextObject;
@@ -1019,6 +1021,9 @@ void QDeclarativeData::destroyed(QObject *object)
if (scriptValue)
delete scriptValue;
+ if (extendedData)
+ delete extendedData;
+
if (ownMemory)
delete this;
}
@@ -1028,6 +1033,11 @@ void QDeclarativeData::parentChanged(QObject *, QObject *parent)
if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
}
+void QDeclarativeData::objectNameChanged(QObject *)
+{
+ if (extendedData) objectNameNotifier()->notify();
+}
+
bool QDeclarativeData::hasBindingBit(int bit) const
{
if (bindingBitsSize > bit)
@@ -1064,6 +1074,28 @@ void QDeclarativeData::setBindingBit(QObject *obj, int bit)
bindingBits[bit / 32] |= (1 << (bit % 32));
}
+QDeclarativeData::ExtendedData::ExtendedData()
+: objectNameNotifier(0)
+{
+}
+
+QDeclarativeData::ExtendedData::~ExtendedData()
+{
+ ((QDeclarativeNotifier *)&objectNameNotifier)->~QDeclarativeNotifier();
+}
+
+QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
+{
+ if (!extendedData) extendedData = new ExtendedData;
+ return (QDeclarativeNotifier *)&extendedData->objectNameNotifier;
+}
+
+QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
+{
+ if (!extendedData) extendedData = new ExtendedData;
+ return &extendedData->attachedProperties;
+}
+
/*!
Creates a QScriptValue allowing you to use \a object in QML script.
\a engine is the QDeclarativeEngine it is to be created in.
@@ -2159,4 +2191,42 @@ const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
}
}
+bool QDeclarative_isFileCaseCorrect(const QString &fileName)
+{
+#if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
+ QFileInfo info(fileName);
+
+ QString absolute = info.absoluteFilePath();
+
+#if defined(Q_OS_MAC)
+ QString canonical = info.canonicalFilePath();
+#elif defined(Q_OS_WIN32)
+ wchar_t buffer[1024];
+
+ DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
+ if (rv == 0 || rv >= 1024) return true;
+ rv = ::GetLongPathName(buffer, buffer, 1024);
+ if (rv == 0 || rv >= 1024) return true;
+
+ QString canonical((QChar *)buffer);
+#endif
+
+ int absoluteLength = absolute.length();
+ int canonicalLength = canonical.length();
+
+ int length = qMin(absoluteLength, canonicalLength);
+ for (int ii = 0; ii < length; ++ii) {
+ const QChar &a = absolute.at(absoluteLength - 1 - ii);
+ const QChar &c = canonical.at(canonicalLength - 1 - ii);
+
+ if (a.toLower() != c.toLower())
+ return true;
+ if (a != c)
+ return false;
+ }
+#endif
+
+ return true;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp
index eb69b6a..78e3afd 100644
--- a/src/declarative/qml/qdeclarativefastproperties.cpp
+++ b/src/declarative/qml/qdeclarativefastproperties.cpp
@@ -51,10 +51,19 @@ QT_BEGIN_NAMESPACE
// primarily read from bindings is a candidate for inclusion as a fast
// property.
+static void QObject_objectName(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint)
+{
+ if (endpoint)
+ endpoint->connect(QDeclarativeData::get(object, true)->objectNameNotifier());
+ *((QString *)output) = object->objectName();
+}
+
QDeclarativeFastProperties::QDeclarativeFastProperties()
{
add(&QDeclarativeItem::staticMetaObject, QDeclarativeItem::staticMetaObject.indexOfProperty("parent"),
QDeclarativeItemPrivate::parentProperty);
+ add(&QObject::staticMetaObject, QObject::staticMetaObject.indexOfProperty("objectName"),
+ QObject_objectName);
}
int QDeclarativeFastProperties::accessorIndexForProperty(const QMetaObject *metaObject, int propertyIndex)
diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h
index 1041992..65d9b24 100644
--- a/src/declarative/qml/qdeclarativeglobal_p.h
+++ b/src/declarative/qml/qdeclarativeglobal_p.h
@@ -75,6 +75,19 @@ struct QDeclarativeGraphics_DerivedObject : public QObject
};
/*!
+ Returns true if the case of \a fileName is equivalent to the file case of
+ \a fileName on disk, and false otherwise.
+
+ This is used to ensure that the behavior of QML on a case-insensitive file
+ system is the same as on a case-sensitive file system. This function
+ performs a "best effort" attempt to determine the real case of the file.
+ It may have false positives (say the case is correct when it isn't), but it
+ should never have a false negative (say the case is incorrect when it is
+ correct).
+*/
+bool QDeclarative_isFileCaseCorrect(const QString &fileName);
+
+/*!
Makes the \a object a child of \a parent. Note that when using this method,
neither \a parent nor the object's previous parent (if it had one) will
receive ChildRemoved or ChildAdded events.
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index fe4ed48..6f5216a 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -351,7 +351,11 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
{
QFile file(absoluteFilePath);
QString filecontent;
- if (file.open(QFile::ReadOnly)) {
+ if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
+ if (errorString)
+ *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath);
+ return false;
+ } else if (file.open(QFile::ReadOnly)) {
filecontent = QString::fromUtf8(file.readAll());
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
@@ -913,6 +917,11 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
}
if (!engineInitialized || !typesRegistered) {
+ if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
+ if (errorString)
+ *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath);
+ return false;
+ }
QPluginLoader loader(absoluteFilePath);
if (!loader.load()) {
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index ab6ff74..61a1f55 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -239,8 +239,13 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name)
}
} else {
if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) {
- enginePriv->capturedProperties <<
- QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex);
+ if (lastData->coreIndex == 0) {
+ enginePriv->capturedProperties <<
+ QDeclarativeEnginePrivate::CapturedProperty(QDeclarativeData::get(obj, true)->objectNameNotifier());
+ } else {
+ enginePriv->capturedProperties <<
+ QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex);
+ }
}
if (QDeclarativeValueTypeFactory::isValueType((uint)lastData->propType)) {
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 061f309..c8e1a07 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -44,6 +44,7 @@
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativecompiler_p.h>
#include <private/qdeclarativecomponent_p.h>
+#include <private/qdeclarativeglobal_p.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
@@ -493,6 +494,13 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(blob->m_url);
if (!lf.isEmpty()) {
+ if (!QDeclarative_isFileCaseCorrect(lf)) {
+ QDeclarativeError error;
+ error.setUrl(blob->m_url);
+ error.setDescription(QLatin1String("File name case mismatch"));
+ blob->setError(error);
+ return;
+ }
QFile file(lf);
if (file.open(QFile::ReadOnly)) {
QByteArray data = file.readAll();
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 37f08fc..e28062b 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -459,7 +459,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
id -= propOffset;
if (id < metaData->propertyCount) {
- int t = (metaData->propertyData() + id)->propertyType;
+ int t = (metaData->propertyData() + id)->propertyType;
bool needActivate = false;
if (t == -1) {
@@ -586,11 +586,26 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
connectAlias(id);
- if (d->propertyIdx == -1) {
+ if (d->isObjectAlias()) {
*reinterpret_cast<QObject **>(a[0]) = target;
return -1;
+ } else if (d->isValueTypeAlias()) {
+ // Value type property
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
+
+ QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()];
+ Q_ASSERT(valueType);
+
+ valueType->read(target, d->propertyIndex());
+ int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a);
+
+ if (c == QMetaObject::WriteProperty)
+ valueType->write(target, d->propertyIndex(), 0x00);
+
+ return rv;
+
} else {
- return QMetaObject::metacall(target, c, d->propertyIdx, a);
+ return QMetaObject::metacall(target, c, d->propertyIndex(), a);
}
}
@@ -823,8 +838,8 @@ void QDeclarativeVMEMetaObject::connectAlias(int aliasId)
int sigIdx = methodOffset + aliasId + metaData->propertyCount;
QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);
- if (d->propertyIdx != -1) {
- QMetaProperty prop = target->metaObject()->property(d->propertyIdx);
+ if (!d->isObjectAlias()) {
+ QMetaProperty prop = target->metaObject()->property(d->propertyIndex());
if (prop.hasNotifySignal())
QDeclarativePropertyPrivate::connect(target, prop.notifySignalIndex(), object, sigIdx);
}
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index 4ccaa73..5134763 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -84,6 +84,25 @@ struct QDeclarativeVMEMetaData
int contextIdx;
int propertyIdx;
int flags;
+
+ bool isObjectAlias() const {
+ return propertyIdx == -1;
+ }
+ bool isPropertyAlias() const {
+ return !isObjectAlias() && !(propertyIdx & 0xFF000000);
+ }
+ bool isValueTypeAlias() const {
+ return !isObjectAlias() && (propertyIdx & 0xFF000000);
+ }
+ int propertyIndex() const {
+ return propertyIdx & 0x0000FFFF;
+ }
+ int valueTypeIndex() const {
+ return (propertyIdx & 0x00FF0000) >> 16;
+ }
+ int valueType() const {
+ return ((unsigned int)propertyIdx) >> 24;
+ }
};
struct PropertyData {
diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp
index 3e4a81a..d2f65ef 100644
--- a/src/declarative/util/qdeclarativefontloader.cpp
+++ b/src/declarative/util/qdeclarativefontloader.cpp
@@ -49,7 +49,6 @@
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
-#include <QFile>
#include <QFontDatabase>
#include <private/qobject_p.h>
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
index 6804d4a..852b055 100644
--- a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
@@ -208,7 +208,7 @@ bool QDeclarativeListModelWorkerAgent::event(QEvent *e)
const QList<Change> &changes = s->data.changes;
if (m_copy) {
- bool cc = m_copy->count() != s->list->count();
+ bool cc = m_orig->count() != s->list->count();
FlatListModel *orig = m_orig->m_flat;
FlatListModel *copy = s->list->m_flat;
diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/gui/dialogs/qinputdialog.cpp
index e996ee9..700b234 100644
--- a/src/gui/dialogs/qinputdialog.cpp
+++ b/src/gui/dialogs/qinputdialog.cpp
@@ -244,6 +244,9 @@ void QInputDialogPrivate::ensureLineEdit()
Q_Q(QInputDialog);
if (!lineEdit) {
lineEdit = new QLineEdit(q);
+#ifndef QT_NO_IM
+ qt_widget_private(lineEdit)->inheritsInputMethodHints = 1;
+#endif
lineEdit->hide();
QObject::connect(lineEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_textChanged(QString)));
@@ -255,6 +258,9 @@ void QInputDialogPrivate::ensureComboBox()
Q_Q(QInputDialog);
if (!comboBox) {
comboBox = new QComboBox(q);
+#ifndef QT_NO_IM
+ qt_widget_private(comboBox)->inheritsInputMethodHints = 1;
+#endif
comboBox->hide();
QObject::connect(comboBox, SIGNAL(editTextChanged(QString)),
q, SLOT(_q_textChanged(QString)));
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index fc44a44..e63acac 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2125,7 +2125,7 @@ void QGraphicsItem::setToolTip(const QString &toolTip)
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2
- If no cursor has been set, the parent's cursor is used.
+ If no cursor has been set, the cursor of the item beneath is used.
\sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
QApplication::overrideCursor()
@@ -2365,7 +2365,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
fsi = fsi->d_ptr->focusScopeItem;
fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
- /* focusFromShow = */ true);
+ /* focusFromHide = */ false);
}
break;
}
@@ -2375,6 +2375,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
QGraphicsItem *fi = subFocusItem;
if (fi && fi != scene->focusItem()) {
scene->setFocusItem(fi);
+ } else if (flags & QGraphicsItem::ItemIsFocusScope &&
+ !scene->focusItem() &&
+ q->isAncestorOf(scene->d_func()->lastFocusItem)) {
+ q_ptr->setFocus();
}
}
} else {
@@ -2385,7 +2389,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
if (p->d_ptr->visible) {
p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
- /* focusFromShow = */ true);
+ /* focusFromHide = */ true);
}
break;
}
@@ -3245,13 +3249,13 @@ bool QGraphicsItem::hasFocus() const
*/
void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
{
- d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromShow = */ false);
+ d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
}
/*!
\internal
*/
-void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow)
+void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
{
// Disabled / unfocusable items cannot accept focus.
if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
@@ -3272,7 +3276,7 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
p->d_ptr->focusScopeItem = q_ptr;
- if (!p->focusItem() && !focusFromShow) {
+ if (!p->focusItem() && !focusFromHide) {
if (oldFocusScopeItem)
oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
focusScopeItemChange(true);
@@ -3334,7 +3338,7 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
while (p) {
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
- /* focusFromShow = */ false);
+ /* focusFromHide = */ false);
return;
}
p = p->d_ptr->parent;
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index c8a7699..8480c19 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -477,7 +477,7 @@ public:
inline void markParentDirty(bool updateBoundingRect = false);
- void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow);
+ void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide);
void clearFocusHelper(bool giveFocusToParent);
void setSubFocus(QGraphicsItem *rootItem = 0);
void clearSubFocus(QGraphicsItem *rootItem = 0);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index e58b93c..a0015dc 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -4362,6 +4362,50 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &
}
}
+// Copied from qpaintengine_vg.cpp
+// Returns true for 90, 180, and 270 degree rotations.
+static inline bool transformIsSimple(const QTransform& transform)
+{
+ QTransform::TransformationType type = transform.type();
+ if (type == QTransform::TxNone || type == QTransform::TxTranslate) {
+ return true;
+ } else if (type == QTransform::TxScale) {
+ // Check for 0 and 180 degree rotations.
+ // (0 might happen after 4 rotations of 90 degrees).
+ qreal m11 = transform.m11();
+ qreal m12 = transform.m12();
+ qreal m21 = transform.m21();
+ qreal m22 = transform.m22();
+ if (m12 == 0.0f && m21 == 0.0f) {
+ if (m11 == 1.0f && m22 == 1.0f)
+ return true; // 0 degrees
+ else if (m11 == -1.0f && m22 == -1.0f)
+ return true; // 180 degrees.
+ if(m11 == 1.0f && m22 == -1.0f)
+ return true; // 0 degrees inverted y.
+ else if(m11 == -1.0f && m22 == 1.0f)
+ return true; // 180 degrees inverted y.
+ }
+ } else if (type == QTransform::TxRotate) {
+ // Check for 90, and 270 degree rotations.
+ qreal m11 = transform.m11();
+ qreal m12 = transform.m12();
+ qreal m21 = transform.m21();
+ qreal m22 = transform.m22();
+ if (m11 == 0.0f && m22 == 0.0f) {
+ if (m12 == 1.0f && m21 == -1.0f)
+ return true; // 90 degrees.
+ else if (m12 == -1.0f && m21 == 1.0f)
+ return true; // 270 degrees.
+ else if (m12 == -1.0f && m21 == -1.0f)
+ return true; // 90 degrees inverted y.
+ else if (m12 == 1.0f && m21 == 1.0f)
+ return true; // 270 degrees inverted y.
+ }
+ }
+ return false;
+}
+
/*!
\internal
@@ -4530,32 +4574,28 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (invertable)
diff *= painter->worldTransform();
deviceData->lastTransform = painter->worldTransform();
- if (!invertable
- || diff.type() > QTransform::TxTranslate
- || painter->worldTransform().type() > QTransform::TxScale) {
+ bool allowPartialCacheExposure = false;
+ bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate
+ && transformIsSimple(painter->worldTransform());
+ if (!simpleTransform) {
pixModified = true;
itemCache->allExposed = true;
itemCache->exposed.clear();
+ deviceData->cacheIndent = QPoint();
pix = QPixmap();
+ } else {
+ allowPartialCacheExposure = deviceData->cacheIndent != QPoint();
}
- // ### This is a pretty bad way to determine when to start partial
- // exposure for DeviceCoordinateCache but it's the least intrusive
- // approach for now.
-#if 0
- // Only if the device rect isn't fully contained.
- bool allowPartialCacheExposure = !viewRect.contains(deviceRect);
-#else
- // Only if deviceRect is 20% taller or wider than the desktop.
- bool allowPartialCacheExposure = false;
- if (widget) {
- QRect desktopRect = QApplication::desktop()->availableGeometry(widget);
- allowPartialCacheExposure = (desktopRect.width() * 1.2 < deviceRect.width()
- || desktopRect.height() * 1.2 < deviceRect.height());
+ // Allow partial cache exposure if the device rect isn't fully contained and
+ // deviceRect is 20% taller or wider than the viewRect.
+ if (!allowPartialCacheExposure && !viewRect.contains(deviceRect)) {
+ allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width())
+ || (viewRect.height() * 1.2 < deviceRect.height());
}
-#endif
+
QRegion scrollExposure;
- if (deviceData->cacheIndent != QPoint() || allowPartialCacheExposure) {
+ if (allowPartialCacheExposure) {
// Part of pixmap is drawn. Either device contains viewrect (big
// item covers whole screen) or parts of device are outside the
// viewport. In either case the device rect must be the intersect
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 1bfe266..4a733be 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -750,6 +750,22 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
/*!
\property QGraphicsWidget::layout
\brief The layout of the widget
+
+ Any existing layout manager is deleted before the new layout is assigned. If
+ \a layout is 0, the widget is left without a layout. Existing subwidgets'
+ geometries will remain unaffected.
+
+ QGraphicsWidget takes ownership of \a layout.
+
+ All widgets that are currently managed by \a layout or all of its
+ sublayouts, are automatically reparented to this item. The layout is then
+ invalidated, and the child widget geometries are adjusted according to
+ this item's geometry() and contentsMargins(). Children who are not
+ explicitly managed by \a layout remain unaffected by the layout after
+ it has been assigned to this widget.
+
+ If no layout is currently managing this widget, layout() will return 0.
+
*/
/*!
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index ac148ee..1157b93 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -6607,6 +6607,10 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla
if (format == newFormat)
return true;
+ // No in-place conversion if we have to detach
+ if (ref > 1)
+ return false;
+
const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat];
InPlace_Image_Converter converter = *converterPtr;
if (converter)
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index 47249d9..b7c8acb 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -968,11 +968,12 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType)
if (needsCopy) {
TSize size = sourceBitmap->SizeInPixels();
+ int bytesPerLine = sourceBitmap->ScanLineLength(size.iWidth, displayMode);
QSymbianBitmapDataAccess da;
da.beginDataAccess(sourceBitmap);
uchar *bytes = (uchar*)sourceBitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
+ QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
img = img.copy();
da.endDataAccess(sourceBitmap);
diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h
index 821fb69..f171281 100644
--- a/src/gui/image/qpixmap_x11_p.h
+++ b/src/gui/image/qpixmap_x11_p.h
@@ -115,6 +115,7 @@ private:
friend class QEglContext; // Needs gl_surface
friend class QGLContext; // Needs gl_surface
friend class QX11GLPixmapData; // Needs gl_surface
+ friend class QMeeGoGraphicsSystem; // Needs gl_surface and flags
friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface
void release();
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 296f24f..5ff2fd4 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1237,10 +1237,11 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
#ifdef Q_WS_S60
// If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
- const bool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ QWidget *const window = qwidget->window();
+ const bool visible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
const bool statusPaneVisibility = visible;
- const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ const bool isFullscreen = window->windowState() & Qt::WindowFullScreen;
+ const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint;
const bool buttonGroupVisibility = (visible || (isFullscreen && cbaVisibilityHint));
S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
#endif
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 7fd2baa..93f64f6 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -142,6 +142,7 @@ public:
int avkonComponentsSupportTransparency : 1;
int menuBeingConstructed : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
+ static CEikButtonGroupContainer *cba;
enum ScanCodeState {
Unpressed,
@@ -162,6 +163,7 @@ public:
static inline CAknTitlePane* titlePane();
static inline CAknContextPane* contextPane();
static inline CEikButtonGroupContainer* buttonGroupContainer();
+ static inline void setButtonGroupContainer(CEikButtonGroupContainer* newCba);
static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible);
#endif
static void controlVisibilityChanged(CCoeControl *control, bool visible);
@@ -383,7 +385,12 @@ inline CAknContextPane* QS60Data::contextPane()
inline CEikButtonGroupContainer* QS60Data::buttonGroupContainer()
{
- return CEikonEnv::Static()->AppUiFactory()->Cba();
+ return QS60Data::cba;
+}
+
+inline void QS60Data::setButtonGroupContainer(CEikButtonGroupContainer *newCba)
+{
+ QS60Data::cba = newCba;
}
#endif // Q_WS_S60
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 2f85cd0..f7c795e 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -273,6 +273,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
, isMoved(0)
, isGLWidget(0)
, usesDoubleBufferedGLContext(0)
+#ifndef QT_NO_IM
+ , inheritsInputMethodHints(0)
+#endif
#if defined(Q_WS_X11)
, picture(0)
#elif defined(Q_WS_WIN)
@@ -9228,9 +9231,13 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
*/
Qt::InputMethodHints QWidget::inputMethodHints() const
{
- Q_D(const QWidget);
#ifndef QT_NO_IM
- return d->imHints;
+ const QWidgetPrivate *priv = d_func();
+ while (priv->inheritsInputMethodHints) {
+ priv = priv->q_func()->parentWidget()->d_func();
+ Q_ASSERT(priv);
+ }
+ return priv->imHints;
#else //QT_NO_IM
return 0;
#endif //QT_NO_IM
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 4a79dc7..6c89659 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -748,6 +748,9 @@ public:
uint isMoved : 1;
uint isGLWidget : 1;
uint usesDoubleBufferedGLContext : 1;
+#ifndef QT_NO_IM
+ uint inheritsInputMethodHints : 1;
+#endif
// *************************** Platform specific ************************************
#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 4109ed8..9a451ce 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -69,6 +69,7 @@ extern bool qt_nograb();
QWidget *QWidgetPrivate::mouseGrabber = 0;
QWidget *QWidgetPrivate::keyboardGrabber = 0;
+CEikButtonGroupContainer *QS60Data::cba = 0;
static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
{
@@ -494,9 +495,27 @@ void QWidgetPrivate::show_sys()
// Create the status pane and CBA here
CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi());
MEikAppUiFactory *factory = CEikonEnv::Static()->AppUiFactory();
- TRAP_IGNORE(factory->ReadAppInfoResourceL(0, ui));
- if (S60->buttonGroupContainer())
- S60->buttonGroupContainer()->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
+ QT_TRAP_THROWING(
+ factory->CreateResourceIndependentFurnitureL(ui);
+
+ TRect boundingRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+
+ CEikButtonGroupContainer *cba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba,
+ CEikButtonGroupContainer::EHorizontal,ui,R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
+ CEikButtonGroupContainer *oldCba = CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(cba);
+ Q_ASSERT(!oldCba);
+ S60->setButtonGroupContainer(cba);
+
+ CEikMenuBar *menuBar = new(ELeave) CEikMenuBar;
+ menuBar->ConstructL(ui, 0, R_AVKON_MENUPANE_EMPTY);
+ menuBar->SetMenuType(CEikMenuBar::EMenuOptions);
+ S60->appUi()->AddToStackL(menuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus);
+
+ CEikMenuBar *oldMenu = CEikonEnv::Static()->AppUiFactory()->SwapMenuBar(menuBar);
+ Q_ASSERT(!oldMenu);
+ )
if (S60->statusPane()) {
// Use QDesktopWidget as the status pane observer to proxy for the AppUi.
@@ -1233,7 +1252,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
// At this point the backing store should already be destroyed
// so we flush the command buffer to ensure that the freeing of
// those resources and deleting the window can happen "atomically"
- S60->wsSession().Flush();
+ if (qApp)
+ S60->wsSession().Flush();
}
}
diff --git a/src/gui/painting/qcups_p.h b/src/gui/painting/qcups_p.h
index 9259679..239c244 100644
--- a/src/gui/painting/qcups_p.h
+++ b/src/gui/painting/qcups_p.h
@@ -59,6 +59,7 @@
#ifndef QT_NO_CUPS
#include <QtCore/qlibrary.h>
#include <cups/cups.h>
+#include <cups/ppd.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 9749244..c92d291 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3164,10 +3164,8 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti)
const TUint8 *glyphBitmapBytes;
TSize glyphBitmapSize;
fe->getCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize);
- const glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);
- const int x = qFloor(positions[i].x + metrics.x + aliasDelta);
- const int y = qFloor(positions[i].y + metrics.y + aliasDelta);
-
+ const int x = qFloor(positions[i].x + tmetrics.HorizBearingX() + aliasDelta);
+ const int y = qFloor(positions[i].y - tmetrics.HorizBearingY() + aliasDelta);
alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight);
}
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 8bac1f5..ea19fcd 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -101,9 +101,11 @@ QS60WindowSurface::~QS60WindowSurface()
// Issue empty redraw to clear the UI surface
QWidget *w = window();
- RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow());
- window->BeginRedraw();
- window->EndRedraw();
+ if (w->testAttribute(Qt::WA_WState_Created)) {
+ RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow());
+ window->BeginRedraw();
+ window->EndRedraw();
+ }
}
}
#endif
diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp
index 5d4c54e..74432af 100644
--- a/src/gui/s60framework/qs60mainapplication.cpp
+++ b/src/gui/s60framework/qs60mainapplication.cpp
@@ -58,7 +58,6 @@ CApaApplication *newS60Application()
return new QS60MainApplication;
}
-_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main" QT_LIBINFIX_UNICODE L".rsc");
/*!
\class QS60MainApplication
@@ -129,10 +128,6 @@ TUid QS60MainApplication::AppDllUid() const
*/
TFileName QS60MainApplication::ResourceFileName() const
{
- TFindFile finder(iCoeEnv->FsSession());
- TInt err = finder.FindByDir(KQtWrapperResourceFile, KNullDesC);
- if (err == KErrNone)
- return finder.File();
return KNullDesC();
}
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index ea9dbb3..92b3b55 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -50,16 +50,6 @@
#endif
#include <barsread.h>
#include <qconfig.h>
-#ifdef Q_WS_S60
-# if defined(QT_LIBINFIX_UNQUOTED)
-// Two level macro needed for proper expansion of libinfix
-# define QT_S60MAIN_RSG_2(x) <s60main##x##.rsg>
-# define QT_S60MAIN_RSG(x) QT_S60MAIN_RSG_2(x)
-# include QT_S60MAIN_RSG(QT_LIBINFIX_UNQUOTED)
-# else
-# include <s60main.rsg>
-# endif
-#endif
#include "qs60mainappui.h"
#include <QtGui/qapplication.h>
@@ -125,8 +115,8 @@ void QS60MainAppUi::ConstructL()
#ifdef Q_WS_S60
flags |= CAknAppUi::EAknEnableSkin;
// After 5th Edition S60, native side supports animated wallpapers.
- // However, there is no support for that feature on Qt side, so indicate to
- // native UI framework that this application will not support background animations.
+ // However, there is no support for that feature on Qt side, so indicate to
+ // native UI framework that this application will not support background animations.
if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
flags |= KAknDisableAnimationBackground;
#endif
@@ -244,7 +234,7 @@ void QS60MainAppUi::DynInitMenuBarL(TInt /* resourceId */, CEikMenuBar * /* menu
void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane)
{
#ifdef Q_WS_S60
- if (resourceId == R_QT_WRAPPERAPP_MENU) {
+ if (resourceId == R_AVKON_MENUPANE_EMPTY) {
if (menuPane->NumberOfItemsInPane() <= 1)
QT_TRYCATCH_LEAVING(qt_symbian_show_toplevel(menuPane));
@@ -274,7 +264,17 @@ void QS60MainAppUi::RestoreMenuL(CCoeControl *menuWindow, TInt resourceId, TMenu
DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow);
else
DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow);
- } else
+ } else if(resourceId == R_AVKON_MENUPANE_EMPTY) {
+ CEikMenuBarTitle *title = new(ELeave) CEikMenuBarTitle;
+ CleanupStack::PushL(title);
+
+ title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY;
+ title->iTitleFlags = 0;
+
+ S60->menuBar()->TitleArray()->AddTitleL(title);
+ CleanupStack::Pop( title );
+ }
+ else
#endif
{
QS60MainAppUiBase::RestoreMenuL(menuWindow, resourceId, menuType);
diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri
index edbacc0..19525b7 100644
--- a/src/gui/s60framework/s60framework.pri
+++ b/src/gui/s60framework/s60framework.pri
@@ -1,21 +1,3 @@
-contains(QT_CONFIG, s60) {
-# This block serves the minimalistic resource file for S60 3.1 platforms.
-# Note there is no way to ifdef S60 version in mmp file, that is why the resource
-# file is always compiled for WINSCW
-
- minimalAppResource31 = \
- "SOURCEPATH s60framework" \
- "START RESOURCE s60main.rss" \
- "TARGET s60main$${QT_LIBINFIX}" \
- "HEADER" \
- "TARGETPATH /resource/apps" \
- "END"
-
- MMP_RULES += minimalAppResource31
-
- SYMBIAN_RESOURCES += s60framework/s60main.rss
-}
-
SOURCES += s60framework/qs60mainapplication.cpp \
s60framework/qs60mainappui.cpp \
s60framework/qs60maindocument.cpp
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 5980f20..bf30e1c 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -41,6 +41,7 @@
#include "qfontengine_s60_p.h"
#include "qtextengine_p.h"
+#include "qendian.h"
#include "qglobal.h"
#include <private/qapplication_p.h>
#include "qimage.h"
@@ -176,6 +177,24 @@ CFont *QSymbianTypeFaceExtras::fontOwner() const
return m_cFont;
}
+QFixed QSymbianTypeFaceExtras::unitsPerEm() const
+{
+ if (m_unitsPerEm.value() != 0)
+ return m_unitsPerEm;
+ const QByteArray head = getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
+ const int unitsPerEmOffset = 18;
+ if (head.size() > unitsPerEmOffset + sizeof(quint16)) {
+ const uchar* tableData = reinterpret_cast<const uchar*>(head.constData());
+ const uchar* unitsPerEm = tableData + unitsPerEmOffset;
+ m_unitsPerEm = qFromBigEndian<quint16>(unitsPerEm);
+ } else {
+ // Bitmap font? Corrupt font?
+ // We return -1 and let the QFontEngineS60 return the pixel size.
+ m_unitsPerEm = -1;
+ }
+ return m_unitsPerEm;
+}
+
// duplicated from qfontengine_xyz.cpp
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
@@ -248,6 +267,13 @@ QFontEngineS60::~QFontEngineS60()
releaseFont(m_scaledFont);
}
+QFixed QFontEngineS60::emSquareSize() const
+{
+ const QFixed unitsPerEm = m_extras->unitsPerEm();
+ return unitsPerEm.toInt() == -1 ?
+ QFixed::fromReal(m_originalFontSizeInPixels) : unitsPerEm;
+}
+
bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
{
if (*nglyphs < len) {
@@ -277,10 +303,13 @@ bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout
void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
{
Q_UNUSED(flags);
+ TOpenFontCharMetrics metrics;
+ const TUint8 *glyphBitmapBytes;
+ TSize glyphBitmapSize;
for (int i = 0; i < glyphs->numGlyphs; i++) {
- const glyph_metrics_t bbox = boundingBox_const(glyphs->glyphs[i]);
- glyphs->advances_x[i] = bbox.xoff;
- glyphs->advances_y[i] = bbox.yoff;
+ getCharacterData(glyphs->glyphs[i], metrics, glyphBitmapBytes, glyphBitmapSize);
+ glyphs->advances_x[i] = metrics.HorizAdvance();
+ glyphs->advances_y[i] = 0;
}
}
@@ -308,6 +337,7 @@ void QFontEngineS60::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions,
parseGlyphPathData(outlineChar, outlineEnd, *path, fontSizeInPixels,
positions[count++].toPointF(), false);
} while(KErrNone == iterator.Next() && count <= nglyphs);
+ iterator.Close();
#else // Q_SYMBIAN_HAS_GLYPHOUTLINE_API
QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags);
#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API
@@ -315,29 +345,17 @@ void QFontEngineS60::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions,
QImage QFontEngineS60::alphaMapForGlyph(glyph_t glyph)
{
+ // Note: On some Symbian versions (apparently <= Symbian^1), this
+ // function will return gray values 0x00, 0x10 ... 0xe0, 0xf0 due
+ // to a bug. The glyphs are nowhere perfectly opaque.
+ // This has been fixed for Symbian^3.
+
TOpenFontCharMetrics metrics;
const TUint8 *glyphBitmapBytes;
TSize glyphBitmapSize;
getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize);
QImage result(glyphBitmapBytes, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight, glyphBitmapSize.iWidth, QImage::Format_Indexed8);
result.setColorTable(grayPalette());
-
- // The above setColorTable() call detached the image data anyway, so why not shape tha data a bit, while we can.
- // CFont::GetCharacterData() returns 8-bit data that obviously was 4-bit data before, and converted to 8-bit incorrectly.
- // The data values are 0x00, 0x10 ... 0xe0, 0xf0. So, a real opaque 0xff is never reached, which we get punished
- // for every time we want to blit this glyph in the raster paint engine.
- // "Fix" is to convert all 0xf0 to 0xff. Is fine, quality wise, and I assume faster than correcting all values.
- // Blitting is however, evidentially faster now.
- const int bpl = result.bytesPerLine();
- for (int row = 0; row < result.height(); ++row) {
- uchar *scanLine = result.scanLine(row);
- for (int column = 0; column < bpl; ++column) {
- if (*scanLine == 0xf0)
- *scanLine = 0xff;
- scanLine++;
- }
- }
-
return result;
}
@@ -359,13 +377,11 @@ glyph_metrics_t QFontEngineS60::boundingBox_const(glyph_t glyph) const
const TUint8 *glyphBitmapBytes;
TSize glyphBitmapSize;
getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize);
- TRect glyphBounds;
- metrics.GetHorizBounds(glyphBounds);
const glyph_metrics_t result(
- glyphBounds.iTl.iX,
- glyphBounds.iTl.iY,
- glyphBounds.Width(),
- glyphBounds.Height(),
+ metrics.HorizBearingX(),
+ -metrics.HorizBearingY(),
+ metrics.Width(),
+ metrics.Height(),
metrics.HorizAdvance(),
0
);
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
index d05c23c..c65ce55 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/gui/text/qfontengine_s60_p.h
@@ -82,11 +82,13 @@ public:
const uchar *cmap() const;
CFont *fontOwner() const;
bool isSymbolCMap() const;
+ QFixed unitsPerEm() const;
private:
CFont* m_cFont;
mutable bool m_symbolCMap;
mutable QByteArray m_cmapTable;
+ mutable QFixed m_unitsPerEm;
#ifndef Q_SYMBIAN_HAS_FONTTABLE_API
COpenFont *m_openFont;
mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
@@ -99,6 +101,7 @@ public:
QFontEngineS60(const QFontDef &fontDef, const QSymbianTypeFaceExtras *extras);
~QFontEngineS60();
+ QFixed emSquareSize() const;
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 05de8f5..3bd6122 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1949,9 +1949,11 @@ void QTextEngine::justify(const QScriptLine &line)
if (kashida_pos >= 0) {
// qDebug("kashida position at %d in word", kashida_pos);
set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
- minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
- maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
- ++nPoints;
+ if (justificationPoints[nPoints].kashidaWidth > 0) {
+ minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
+ maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
+ ++nPoints;
+ }
}
kashida_pos = -1;
kashida_type = HB_Arabic_Normal;
@@ -1975,9 +1977,11 @@ void QTextEngine::justify(const QScriptLine &line)
}
if (kashida_pos >= 0) {
set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
- minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
- maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
- ++nPoints;
+ if (justificationPoints[nPoints].kashidaWidth > 0) {
+ minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
+ maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
+ ++nPoints;
+ }
}
}
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 9a5bac0..919c542 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -137,7 +137,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
QImageTextureGlyphCache::resizeTextureData(width, height);
Q_ASSERT(image().depth() == 8);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
glDeleteTextures(1, &oldTexture);
return;
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 9e74e04..7f25887 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -5264,8 +5264,6 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= FragmentShader;
if (extensions.match("GL_ARB_shader_objects"))
glExtensions |= FragmentShader;
- if (extensions.match("GL_ARB_ES2_compatibility"))
- glExtensions |= ES2Compatibility;
if (extensions.match("GL_ARB_texture_mirrored_repeat"))
glExtensions |= MirroredRepeat;
if (extensions.match("GL_EXT_framebuffer_object"))
@@ -5286,7 +5284,6 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= FramebufferObject;
glExtensions |= GenerateMipmap;
glExtensions |= FragmentShader;
- glExtensions |= ES2Compatibility;
#endif
#if defined(QT_OPENGL_ES_1)
if (extensions.match("GL_OES_framebuffer_object"))
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 623eeaf..387c8f7 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -284,8 +284,7 @@ public:
DDSTextureCompression = 0x00008000,
ETC1TextureCompression = 0x00010000,
PVRTCTextureCompression = 0x00020000,
- FragmentShader = 0x00040000,
- ES2Compatibility = 0x00080000
+ FragmentShader = 0x00040000
};
Q_DECLARE_FLAGS(Extensions, Extension)
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index bc1c009..74382b0 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -97,10 +97,6 @@ QT_BEGIN_NAMESPACE
to just features that are present in GLSL/ES, and avoid
standard variable names that only work on the desktop.
- If the \c{GL_ARB_ES2_compatibility} extension is present,
- then the above prefix is not added because the desktop OpenGL
- implementation supports precision qualifiers.
-
\section1 Simple shader example
\snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 1
@@ -398,10 +394,8 @@ bool QGLShader::compileSourceCode(const char *source)
srclen.append(GLint(headerLen));
}
#ifdef QGL_DEFINE_QUALIFIERS
- if (!(QGLExtensions::glExtensions() & QGLExtensions::ES2Compatibility)) {
- src.append(qualifierDefines);
- srclen.append(GLint(sizeof(qualifierDefines) - 1));
- }
+ src.append(qualifierDefines);
+ srclen.append(GLint(sizeof(qualifierDefines) - 1));
#endif
#ifdef QGL_REDEFINE_HIGHP
if (d->shaderType == Fragment) {
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index f6d2435..ce9d11a 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -61,11 +61,6 @@
QT_BEGIN_NAMESPACE
-// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
-#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
-#define QVG_NO_DRAW_GLYPHS 1
-#endif
-
// vgRenderToMask() only exists in OpenVG 1.1 and higher.
// Also, disable masking completely if we are using the scissor to clip.
#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_RENDER_TO_MASK)
@@ -75,11 +70,11 @@ QT_BEGIN_NAMESPACE
#define QVG_NO_RENDER_TO_MASK 1
#endif
-#if !defined(QVG_NO_DRAW_GLYPHS)
-
// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
+#if !defined(QVG_NO_DRAW_GLYPHS)
+
Q_DECL_IMPORT extern int qt_defaultDpiX();
Q_DECL_IMPORT extern int qt_defaultDpiY();
diff --git a/src/openvg/qvg_p.h b/src/openvg/qvg_p.h
index 51abbee..94d1eae 100644
--- a/src/openvg/qvg_p.h
+++ b/src/openvg/qvg_p.h
@@ -55,6 +55,11 @@
// We mean it.
//
+// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
+#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
+#define QVG_NO_DRAW_GLYPHS 1
+#endif
+
#include <QtGui/qimage.h>
#if !defined(QT_NO_EGL)
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index ef0160c..41b35fc 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -185,10 +185,11 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
QImage::Format format = qt_TDisplayMode2Format(displayMode);
TSize size = bitmap->SizeInPixels();
+ int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode);
bitmap->BeginDataAccess();
uchar *bytes = (uchar*)bitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
+ QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
img = img.copy();
bitmap->EndDataAccess();
@@ -228,7 +229,7 @@ void* QVGPixmapData::toNativeType(NativeType type)
sgInfo.iSizeInPixels.SetSize(w, h);
sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
- RSgImage *sgImage = q_check_ptr(new RSgImage());
+ QScopedPointer<RSgImage> sgImage(new RSgImage());
err = sgImage->Create(sgInfo, NULL, NULL);
if (err != KErrNone) {
driver.Close();
@@ -239,7 +240,7 @@ void* QVGPixmapData::toNativeType(NativeType type)
EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
EGL_NO_CONTEXT,
EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)sgImage,
+ (EGLClientBuffer)sgImage.data(),
(EGLint*)KEglImageAttribs);
if (!eglImage || eglGetError() != EGL_SUCCESS) {
sgImage->Close();
@@ -261,13 +262,14 @@ void* QVGPixmapData::toNativeType(NativeType type)
if (vgGetError() != VG_NO_ERROR) {
sgImage->Close();
- sgImage = 0;
+ sgImage.reset();
}
+
// release stuff
vgDestroyImage(dstVgImage);
QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
driver.Close();
- return reinterpret_cast<void*>(sgImage);
+ return reinterpret_cast<void*>(sgImage.take());
#endif
} else if (type == QPixmapData::FbsBitmap) {
CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h
index b32a873..8bcdcc7 100644
--- a/src/openvg/qvgfontglyphcache_p.h
+++ b/src/openvg/qvgfontglyphcache_p.h
@@ -56,10 +56,14 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qfontengine_p.h>
+#include <qvg_p.h>
+
QT_BEGIN_NAMESPACE
class QVGPaintEnginePrivate;
+#ifndef QVG_NO_DRAW_GLYPHS
+
class QVGFontGlyphCache
{
public:
@@ -90,6 +94,8 @@ public:
};
#endif
+#endif
+
QT_END_NAMESPACE
#endif // QVGFONTGLYPHCACHE_H
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
index e7f6439..611c962 100644
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
@@ -46,6 +46,7 @@
bool QMeeGoExtensions::initialized = false;
bool QMeeGoExtensions::hasImageShared = false;
bool QMeeGoExtensions::hasSurfaceScaling = false;
+bool QMeeGoExtensions::hasLockSurface = false;
/* Extension funcs */
@@ -53,11 +54,15 @@ typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR,
typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*);
typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK);
typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHRFunc)(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay display, EGLSurface surface);
static eglQueryImageNOKFunc _eglQueryImageNOK = 0;
static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0;
static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0;
static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0;
+static eglLockSurfaceKHRFunc _eglLockSurfaceKHR = 0;
+static eglUnlockSurfaceKHRFunc _eglUnlockSurfaceKHR = 0;
/* Public */
@@ -101,6 +106,22 @@ bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surfac
return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height);
}
+bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+ if (! hasLockSurface)
+ qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
+
+ return _eglLockSurfaceKHR(display, surface, attrib_list);
+}
+
+bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+ if (! hasLockSurface)
+ qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
+
+ return _eglUnlockSurfaceKHR(display, surface);
+}
+
/* Private */
void QMeeGoExtensions::initialize()
@@ -113,6 +134,8 @@ void QMeeGoExtensions::initialize()
_eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK");
_eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK");
_eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK");
+ _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
+ _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK);
hasImageShared = true;
@@ -125,5 +148,14 @@ void QMeeGoExtensions::initialize()
Q_ASSERT(_eglSetSurfaceScalingNOK);
hasSurfaceScaling = true;
}
+
+ if (QEgl::hasExtension("EGL_KHR_lock_surface2")) {
+ qDebug("MeegoGraphics: found EGL_KHR_lock_surface2");
+ _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
+ _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
+
+ Q_ASSERT(_eglLockSurfaceKHR && _eglUnlockSurfaceKHR);
+ hasLockSurface = true;
+ }
}
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.h b/src/plugins/graphicssystems/meego/qmeegoextensions.h
index ee20bd8..9e78caf 100644
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.h
+++ b/src/plugins/graphicssystems/meego/qmeegoextensions.h
@@ -65,6 +65,18 @@ typedef void* EGLNativeSharedImageTypeNOK;
#define EGL_FIXED_HEIGHT_NOK 0x30DC
#endif
+#ifndef EGL_BITMAP_POINTER_KHR
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#endif
+
+#ifndef EGL_MAP_PRESERVE_PIXELS_KHR
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#endif
+
/* Class */
class QMeeGoExtensions
@@ -76,6 +88,8 @@ public:
static bool eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v);
static bool eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img);
static bool eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height);
+ static bool eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+ static bool eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface);
private:
static void initialize();
@@ -83,6 +97,7 @@ private:
static bool initialized;
static bool hasImageShared;
static bool hasSurfaceScaling;
+ static bool hasLockSurface;
};
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
index 2a64d49..f8b228c 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
@@ -51,6 +51,7 @@
#include <private/qimage_p.h>
#include <private/qeglproperties_p.h>
#include <private/qeglcontext_p.h>
+#include <private/qpixmap_x11_p.h>
#include "qmeegopixmapdata.h"
#include "qmeegographicssystem.h"
@@ -58,6 +59,8 @@
bool QMeeGoGraphicsSystem::surfaceWasCreated = false;
+QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps;
+
QMeeGoGraphicsSystem::QMeeGoGraphicsSystem()
{
qDebug("Using the meego graphics system");
@@ -170,6 +173,22 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl
}
}
+QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLImage(Qt::HANDLE handle)
+{
+ if (QMeeGoGraphicsSystem::meeGoRunning()) {
+ QMeeGoPixmapData *pmd = new QMeeGoPixmapData;
+ pmd->fromEGLImage(handle);
+
+ // FIXME Ok. This is a bit BAD BAD BAD. We're abusing here the fact that we KNOW
+ // that this function is used for the live pixmap...
+ pmd->texture()->options &= ~QGLContext::InvertedYBindOption;
+ return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
+ } else {
+ qFatal("Can't create from EGL image when not running meego graphics system!");
+ return NULL;
+ }
+}
+
void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap)
{
QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData();
@@ -188,6 +207,109 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
}
+Qt::HANDLE QMeeGoGraphicsSystem::createLiveTexture(int w, int h, QImage::Format format)
+{
+ // No need to wrap the QPixmapData here. This QPixmap(Data) is a
+ // internal implementation and we don't migrate it between
+ // graphics system switching.
+
+ // We use a bit ugly way of enforcing a color format on the X pixmap -- we create
+ // a local QImage and fromImage from there. This is quite redundant (extra overhead of creating
+ // the useless image only to delete it) but shouldn't be too bad for now... you're not expected
+ // to call createLiveTexture too often anyways. Would be great if QX11PixmapData had a way to
+ // force the X format upon creation or resize.
+
+ QImage image(w, h, format);
+ QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
+ pmd->fromImage(image, Qt::NoOpaqueDetection);
+ QPixmap *p = new QPixmap(pmd);
+
+ liveTexturePixmaps.insert(p->handle(), p);
+ return p->handle();
+}
+
+void QMeeGoGraphicsSystem::destroyLiveTexture(Qt::HANDLE h)
+{
+ if (liveTexturePixmaps.contains(h)) {
+ QPixmap *p = liveTexturePixmaps.value(h);
+ delete p;
+ liveTexturePixmaps.remove(h);
+ } else
+ qWarning("Trying to destroy live texture %ld which was not found!", h);
+}
+
+bool QMeeGoGraphicsSystem::lockLiveTexture(Qt::HANDLE h)
+{
+ if (! liveTexturePixmaps.contains(h)) {
+ qWarning("Trying to lock live texture %ld which was not found!", h);
+ return false;
+ }
+
+ EGLint attribs[] = {
+ EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
+ EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
+ EGL_NONE
+ };
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
+ return QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, attribs);
+}
+
+bool QMeeGoGraphicsSystem::unlockLiveTexture(Qt::HANDLE h)
+{
+ if (! liveTexturePixmaps.contains(h)) {
+ qWarning("Trying to lock live texture %ld which was not found!", h);
+ return false;
+ }
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
+ if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface)) {
+ glFinish();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch)
+{
+ // FIXME Only allow this on locked surfaces
+ if (! liveTexturePixmaps.contains(h)) {
+ qWarning("Trying to query live texture %ld which was not found!", h);
+ return;
+ }
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
+ eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) data);
+ eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) pitch);
+}
+
+Qt::HANDLE QMeeGoGraphicsSystem::liveTextureToEGLImage(Qt::HANDLE h)
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ EGLint attribs[] = {
+ EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE
+ };
+
+ EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer) h, attribs);
+
+ if (eglImage == EGL_NO_IMAGE_KHR)
+ qWarning("eglCreateImageKHR failed!");
+
+ return (Qt::HANDLE) eglImage;
+}
+
bool QMeeGoGraphicsSystem::meeGoRunning()
{
if (! QApplicationPrivate::instance()) {
@@ -204,6 +326,52 @@ bool QMeeGoGraphicsSystem::meeGoRunning()
return (name == "meego");
}
+void QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(QPixmapData* pmd)
+{
+ Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
+ if (pixmapData->gl_surface) {
+ eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
+ pixmapData->gl_surface = 0;
+ }
+}
+
+EGLSurface QMeeGoGraphicsSystem::getSurfaceForLiveTexturePixmap(QPixmap *pixmap)
+{
+ // This code is a crative remix of the stuff that can be found in the
+ // Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
+ Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
+ bool hasAlpha = pixmapData->hasAlphaChannel();
+
+ if (pixmapData->gl_surface &&
+ hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
+ return pixmapData->gl_surface;
+
+ // Check to see if the surface is still valid
+ if (pixmapData->gl_surface &&
+ hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) {
+ // Surface is invalid!
+ QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(pixmapData);
+ }
+
+ if (pixmapData->gl_surface == 0) {
+ EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
+ QEgl::OpenGL,
+ hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
+
+ pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config);
+
+ if (hasAlpha)
+ pixmapData->flags = pixmapData->flags | QX11PixmapData::GlSurfaceCreatedWithAlpha;
+
+ if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
+ return NULL;
+ }
+
+ return pixmapData->gl_surface;
+}
+
/* C API */
int qt_meego_image_to_egl_shared_image(const QImage &image)
@@ -216,6 +384,11 @@ QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const
return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage);
}
+QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle)
+{
+ return QMeeGoGraphicsSystem::pixmapDataFromEGLImage(handle);
+}
+
QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h)
{
return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h);
@@ -245,3 +418,33 @@ void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap)
{
QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap);
}
+
+Qt::HANDLE qt_meego_live_texture_create(int w, int h, QImage::Format format)
+{
+ return QMeeGoGraphicsSystem::createLiveTexture(w, h, format);
+}
+
+void qt_meego_live_texture_destroy(Qt::HANDLE h)
+{
+ QMeeGoGraphicsSystem::destroyLiveTexture(h);
+}
+
+bool qt_meego_live_texture_lock(Qt::HANDLE h)
+{
+ return QMeeGoGraphicsSystem::lockLiveTexture(h);
+}
+
+bool qt_meego_live_texture_unlock(Qt::HANDLE h)
+{
+ return QMeeGoGraphicsSystem::unlockLiveTexture(h);
+}
+
+void qt_meego_live_texture_query(Qt::HANDLE h, void **data, int *pitch)
+{
+ return QMeeGoGraphicsSystem::queryLiveTexture(h, data, pitch);
+}
+
+Qt::HANDLE qt_meego_live_texture_to_egl_image(Qt::HANDLE h)
+{
+ return QMeeGoGraphicsSystem::liveTextureToEGLImage(h);
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
index 905f0c3..934d32d 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
@@ -43,6 +43,9 @@
#define MGRAPHICSSYSTEM_H
#include <private/qgraphicssystem_p.h>
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
class QMeeGoGraphicsSystem : public QGraphicsSystem
{
@@ -60,13 +63,24 @@ public:
static void setTranslucent(bool translucent);
static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+ static QPixmapData *pixmapDataFromEGLImage(Qt::HANDLE handle);
static QPixmapData *pixmapDataWithGLTexture(int w, int h);
static void updateEGLSharedImagePixmap(QPixmap *pixmap);
+ static Qt::HANDLE createLiveTexture(int w, int h, QImage::Format format);
+ static void destroyLiveTexture(Qt::HANDLE h);
+ static bool lockLiveTexture(Qt::HANDLE h);
+ static bool unlockLiveTexture(Qt::HANDLE h);
+ static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch);
+ static Qt::HANDLE liveTextureToEGLImage(Qt::HANDLE h);
+
private:
static bool meeGoRunning();
+ static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap);
+ static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd);
static bool surfaceWasCreated;
+ static QHash <Qt::HANDLE, QPixmap*> liveTexturePixmaps;
};
/* C api */
@@ -74,12 +88,19 @@ private:
extern "C" {
Q_DECL_EXPORT int qt_meego_image_to_egl_shared_image(const QImage &image);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage);
+ Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h);
Q_DECL_EXPORT void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap);
Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle);
Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height);
Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height);
Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
+ Q_DECL_EXPORT Qt::HANDLE m_live_texture_create(int w, int h, QImage::Format format);
+ Q_DECL_EXPORT void m_live_texture_destroy(Qt::HANDLE h);
+ Q_DECL_EXPORT bool m_live_texture_lock(Qt::HANDLE h);
+ Q_DECL_EXPORT bool m_live_texture_unlock(Qt::HANDLE h);
+ Q_DECL_EXPORT void m_live_texture_query(Qt::HANDLE h, void **data, int *pitch);
+ Q_DECL_EXPORT Qt::HANDLE m_live_texture_to_egl_image(Qt::HANDLE h);
}
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
index 33611dc..84fc593 100644
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
@@ -87,6 +87,36 @@ void QMeeGoPixmapData::fromImage(const QImage &image,
}
}
+void QMeeGoPixmapData::fromEGLImage(Qt::HANDLE handle)
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ bool textureIsBound = false;
+ GLuint newTextureId;
+ GLint newWidth, newHeight;
+
+ glGenTextures(1, &newTextureId);
+ glBindTexture(GL_TEXTURE_2D, newTextureId);
+
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) handle);
+ GLint err = glGetError();
+ if (err == GL_NO_ERROR)
+ textureIsBound = true;
+
+ QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_WIDTH, &newWidth);
+ QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_HEIGHT, &newHeight);
+
+ if (textureIsBound) {
+ // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix
+ // for QGLPixmapData.
+ fromTexture(newTextureId, newWidth, newHeight, true);
+ } else {
+ qWarning("Failed to create a texture from an egl image!");
+ glDeleteTextures(1, &newTextureId);
+ }
+}
+
void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
{
if (si.isNull())
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
index 8af33bd..8b1ae14 100644
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
+++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
@@ -56,6 +56,7 @@ public:
QMeeGoPixmapData();
void fromTexture(GLuint textureId, int w, int h, bool alpha);
+ virtual void fromEGLImage(Qt::HANDLE handle);
virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags);
virtual QImage toImage() const;
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
index 2c7c0b7..9674233 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
@@ -42,6 +42,9 @@
#include "qgraphicssystem_vg_p.h"
#include <QtOpenVG/private/qpixmapdata_vg_p.h>
#include <QtOpenVG/private/qwindowsurface_vg_p.h>
+#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
+#include <QtGui/private/qwidget_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -64,6 +67,11 @@ QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) co
QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
{
+#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
+ QWidgetPrivate *d = qt_widget_private(widget);
+ if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
+ return d->createDefaultWindowSurface_sys();
+#endif
return new QVGWindowSurface(widget);
}
diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def
index 5eeb244..f4e3a28 100644
--- a/src/s60installs/bwins/QtCoreu.def
+++ b/src/s60installs/bwins/QtCoreu.def
@@ -4483,4 +4483,5 @@ EXPORTS
?msecsSinceReference@QElapsedTimer@@QBE_JXZ @ 4482 NONAME ; long long QElapsedTimer::msecsSinceReference(void) const
?selectThread@QEventDispatcherSymbian@@AAEAAVQSelectThread@@XZ @ 4483 NONAME ; class QSelectThread & QEventDispatcherSymbian::selectThread(void)
?qt_symbian_SetupThreadHeap@@YAHHAAUSStdEpocThreadCreateInfo@@@Z @ 4484 NONAME ; int qt_symbian_SetupThreadHeap(int, struct SStdEpocThreadCreateInfo &)
+ ?objectNameChanged@QAbstractDeclarativeData@@2P6AXPAV1@PAVQObject@@@ZA @ 4485 NONAME ; void (*QAbstractDeclarativeData::objectNameChanged)(class QAbstractDeclarativeData *, class QObject *)
diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def
index cf0398a..b72147e 100644
--- a/src/s60installs/bwins/QtDeclarativeu.def
+++ b/src/s60installs/bwins/QtDeclarativeu.def
@@ -1838,4 +1838,5 @@ EXPORTS
?addChanged@QDeclarativeBasePositioner@@IAEXXZ @ 1837 NONAME ; void QDeclarativeBasePositioner::addChanged(void)
?start@QDeclarativeAbstractAnimation@@QAEXXZ @ 1838 NONAME ; void QDeclarativeAbstractAnimation::start(void)
?qt_metacall@QDeclarativeAbstractAnimation@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1839 NONAME ; int QDeclarativeAbstractAnimation::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ?connect@QDeclarativePropertyPrivate@@SA_NPBVQObject@@H0HHPAH@Z @ 1840 NONAME ; bool QDeclarativePropertyPrivate::connect(class QObject const *, int, class QObject const *, int, int, int *)
diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def
index f496839..eb53dca 100644
--- a/src/s60installs/eabi/QtCoreu.def
+++ b/src/s60installs/eabi/QtCoreu.def
@@ -3712,4 +3712,5 @@ EXPORTS
_ZltRK13QElapsedTimerS1_ @ 3711 NONAME
_ZrsR11QDataStreamR12QEasingCurve @ 3712 NONAME
_Z26qt_symbian_SetupThreadHeapiR24SStdEpocThreadCreateInfo @ 3713 NONAME
+ _ZN24QAbstractDeclarativeData17objectNameChangedE @ 3714 NONAME DATA 4
diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def
index d4084cc..cbfafdc 100644
--- a/src/s60installs/eabi/QtDeclarativeu.def
+++ b/src/s60installs/eabi/QtDeclarativeu.def
@@ -1883,4 +1883,5 @@ EXPORTS
_ZThn8_N29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1882 NONAME
_ZThn8_N29QDeclarativeAbstractAnimationD0Ev @ 1883 NONAME
_ZThn8_N29QDeclarativeAbstractAnimationD1Ev @ 1884 NONAME
+ _ZN27QDeclarativePropertyPrivate7connectEPK7QObjectiS2_iiPi @ 1885 NONAME
diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby
index b6cdce9..4afbf05 100644
--- a/src/s60installs/qt.iby
+++ b/src/s60installs/qt.iby
@@ -53,6 +53,9 @@ file=ABI_DIR\BUILD_DIR\qaudio.dll SHARED_LIB_DIR\qaudio.dll
file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll
file=ABI_DIR\BUILD_DIR\qglgraphicssystem.dll SHARED_LIB_DIR\qglgraphicssystem.dll
+// bearer
+file=ABI_DIR\BUILD_DIR\qsymbianbearer.dll SHARED_LIB_DIR\qsymbianbearer.dll
+
// S60 version compatibility plugins for 5.0 (3.1 and 3.2 devices are never likely to have this in ROM,
// so don't bother including those plugins
file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll
@@ -99,6 +102,9 @@ data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio
data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin
data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin
+// bearer stub
+data=\epoc32\data\z\resource\qt\plugins\bearer\qsymbianbearer.qtplugin resource\qt\plugins\bearer\qsymbianbearer.qtplugin
+
// Stub sis file
data=ZSYSTEM\install\qt_stub.sis System\Install\qt_stub.sis
data=ZSYSTEM\install\qtwebkit_stub.sis System\Install\qtwebkit_stub.sis
diff --git a/src/s60installs/qtdemoapps.iby b/src/s60installs/qtdemoapps.iby
deleted file mode 100644
index d888135..0000000
--- a/src/s60installs/qtdemoapps.iby
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef QTDEMOAPPS_IBY
-#define QTDEMOAPPS_IBY
-
-// A subset of Qt demo & example applications
-
-// Note that star requires OpenVG and the Qt OpenVG paint engine
-S60_APP_EXE(star)
-S60_APP_RESOURCE(star)
-data=\epoc32\data\Z\private\10003a3f\import\Apps\star_reg.rsc \private\10003a3f\import\apps\star_reg.rsc
-
-S60_APP_EXE(wiggly)
-S60_APP_RESOURCE(wiggly)
-data=\epoc32\data\Z\private\10003a3f\import\Apps\wiggly_reg.rsc \private\10003a3f\import\apps\wiggly_reg.rsc
-
-#endif // QTDEMOAPPS_IBY
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 1f622c0..d63b97c 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -11,10 +11,10 @@ symbian: {
isEmpty(QT_LIBINFIX) {
TARGET.UID3 = 0x2001E61C
-
+
# Sqlite3 is expected to be already found on phone if infixed configuration is built.
# It is also expected that devices newer than those based on S60 5.0 all have sqlite3.dll.
- contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
+ contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
BLD_INF_RULES.prj_exports += \
"sqlite3.sis /epoc32/data/qt/sis/sqlite3.sis" \
"sqlite3_selfsigned.sis /epoc32/data/qt/sis/sqlite3_selfsigned.sis"
@@ -35,15 +35,6 @@ symbian: {
}
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
- symbian-abld|symbian-sbsv2 {
- qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main$${QT_LIBINFIX}.rsc
- } else {
- qtresources.sources = $$QMAKE_LIBDIR_QT/s60main$${QT_LIBINFIX}.rsc
- DESTDIR = $$QMAKE_LIBDIR_QT
- }
- qtresources.path = c:$$APP_RESOURCE_DIR
- DEPLOYMENT += qtresources
-
qtlibraries.sources = \
$$QMAKE_LIBDIR_QT/QtCore$${QT_LIBINFIX}.dll \
$$QMAKE_LIBDIR_QT/QtXml$${QT_LIBINFIX}.dll \
@@ -109,9 +100,9 @@ symbian: {
qtlibraries.pkg_prerules = vendorinfo
qtlibraries.pkg_prerules += "; Dependencies of Qt libraries"
-
+
# It is expected that Symbian^3 and newer phones will have sufficiently new OpenC already installed
- contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
+ contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
qtlibraries.pkg_prerules += "(0x20013851), 1, 5, 1, {\"PIPS Installer\"}"
contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
qtlibraries.pkg_prerules += "(0x200110CB), 1, 5, 1, {\"Open C LIBSSL Common\"}"
@@ -209,5 +200,4 @@ symbian: {
}
BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)"
- BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CUSTOMER_VARIANT_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)"
}
diff --git a/src/s60main/newallocator_hook.cpp b/src/s60main/newallocator_hook.cpp
index 9cc6afb..9ea2ef0 100644
--- a/src/s60main/newallocator_hook.cpp
+++ b/src/s60main/newallocator_hook.cpp
@@ -41,6 +41,11 @@
#include <e32std.h>
#include <qglobal.h>
+#ifdef QT_EXPORTS_NOT_FROZEN
+// If exports in Qt DLLs are not frozen in this build, then we have to pick up the
+// allocator creation function by import link. We know the function will be present
+// in the DLLs we test with, as we have to use the DLLs we have built.
+
struct SStdEpocThreadCreateInfo;
Q_CORE_EXPORT TInt qt_symbian_SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
@@ -51,8 +56,88 @@ Q_CORE_EXPORT TInt qt_symbian_SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCre
* Uses link-time symbol preemption to capture a call from the application
* startup. On return, there is some kind of heap allocator installed on the
* thread.
-*/
+*/
TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
{
return qt_symbian_SetupThreadHeap(aNotFirst, aInfo);
}
+
+#else // QT_EXPORTS_NOT_FROZEN
+// If we are using an export frozen build, it should be compatible with all 4.7.x Qt releases.
+// We want to use the allocator creation function introduced in qtcore.dll after 4.7.1. But we
+// can't import link to it, as it may not be present in whatever 4.7.x DLLs we are running with.
+// So the function is found and called dynamically, by library lookup. If it is not found, we
+// use the OS allocator creation functions instead.
+
+struct SThreadCreateInfo
+ {
+ TAny* iHandle;
+ TInt iType;
+ TThreadFunction iFunction;
+ TAny* iPtr;
+ TAny* iSupervisorStack;
+ TInt iSupervisorStackSize;
+ TAny* iUserStack;
+ TInt iUserStackSize;
+ TInt iInitialThreadPriority;
+ TPtrC iName;
+ TInt iTotalSize; // Size including any extras (must be a multiple of 8 bytes)
+ };
+
+struct SStdEpocThreadCreateInfo : public SThreadCreateInfo
+ {
+ RAllocator* iAllocator;
+ TInt iHeapInitialSize;
+ TInt iHeapMaxSize;
+ TInt iPadding; // Make structure size a multiple of 8 bytes
+ };
+
+
+/* \internal
+ *
+ * Uses link-time symbol preemption to capture a call from the application
+ * startup. On return, there is some kind of heap allocator installed on the
+ * thread.
+*/
+TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
+{
+ TInt r = KErrNone;
+
+#ifndef __WINS__
+ // attempt to create the fast allocator through a known export ordinal in qtcore.dll
+ RLibrary qtcore;
+ if (qtcore.Load(_L("qtcore.dll")) == KErrNone)
+ {
+ const int qt_symbian_SetupThreadHeap_eabi_ordinal = 3713;
+ TLibraryFunction libFunc = qtcore.Lookup(qt_symbian_SetupThreadHeap_eabi_ordinal);
+ if (libFunc)
+ {
+ typedef int (*TSetupThreadHeapFunc)(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
+ TSetupThreadHeapFunc p_qt_symbian_SetupThreadHeap = TSetupThreadHeapFunc(libFunc);
+ r = (*p_qt_symbian_SetupThreadHeap)(aNotFirst, aInfo);
+ }
+ qtcore.Close();
+ if (libFunc)
+ return r;
+ }
+#endif
+
+ // no fast allocator support - use default allocator creation
+ if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
+ {
+ // new heap required
+ RHeap* pH = NULL;
+ r = UserHeap::CreateThreadHeap(aInfo, pH);
+ }
+ else if (aInfo.iAllocator)
+ {
+ // sharing a heap
+ RAllocator* pA = aInfo.iAllocator;
+ pA->Open();
+ User::SwitchAllocator(pA);
+ r = KErrNone;
+ }
+ return r;
+}
+
+#endif // QT_EXPORTS_NOT_FROZEN
diff --git a/src/s60main/s60main.pro b/src/s60main/s60main.pro
index 664f155..8ab3bd3 100644
--- a/src/s60main/s60main.pro
+++ b/src/s60main/s60main.pro
@@ -31,6 +31,9 @@ symbian {
# against GCCE apps, so remove it
MMP_RULES -= $$MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA
linux-armcc:QMAKE_CXXFLAGS *= --export_all_vtbl
+
+ # Flag if exports are not frozen to avoid lookup of qtcore allocator creation function by ordinal
+ contains(CONFIG, def_files_disabled): DEFINES += QT_EXPORTS_NOT_FROZEN
} else {
error("$$_FILE_ is intended only for Symbian!")
}
diff --git a/src/s60main/s60main.rsg b/src/s60main/s60main.rsg
deleted file mode 100644
index 8cdf3ba..0000000
--- a/src/s60main/s60main.rsg
+++ /dev/null
@@ -1,3 +0,0 @@
-#define R_DEFAULT_DOCUMENT_NAME 0x55567002
-#define R_QT_WRAPPERAPP_MENUBAR 0x55567004
-#define R_QT_WRAPPERAPP_MENU 0x55567005