summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorRohan McGovern <rohan.mcgovern@nokia.com>2011-09-19 04:12:35 (GMT)
committerRohan McGovern <rohan.mcgovern@nokia.com>2011-09-19 04:12:35 (GMT)
commit5055f13683dd0670d62a81e61bf097fd220f0d42 (patch)
tree1cf10d701b6d6ba5fffe9a2267ecf894d505e1bd /src/gui
parentfc602cb1737e58b4b814c4a799fa2a68acb6dbcd (diff)
parent53d9e3620ede7492c141402d9365d5c0dd7c10fd (diff)
downloadQt-5055f13683dd0670d62a81e61bf097fd220f0d42.zip
Qt-5055f13683dd0670d62a81e61bf097fd220f0d42.tar.gz
Qt-5055f13683dd0670d62a81e61bf097fd220f0d42.tar.bz2
Merge remote branch 'origin/4.8' into doc-staging-master
Conflicts: dist/changes-4.8.0
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp36
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp6
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp50
-rw-r--r--src/gui/kernel/qapplication_s60.cpp3
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp2
-rw-r--r--src/gui/kernel/qkeysequence.cpp20
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp14
-rw-r--r--src/gui/kernel/qt_s60_p.h26
-rw-r--r--src/gui/kernel/qwidget.cpp10
-rw-r--r--src/gui/kernel/qwidget.h2
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_p.h3
-rw-r--r--src/gui/kernel/qwidget_s60.cpp21
-rw-r--r--src/gui/painting/qpaintengine.cpp7
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp54
-rw-r--r--src/gui/styles/qcommonstyle.cpp18
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp30
-rw-r--r--src/gui/text/qfontengine.cpp5
-rw-r--r--src/gui/text/qfontengine_coretext_p.h8
-rw-r--r--src/gui/text/qfontengine_ft.cpp21
-rw-r--r--src/gui/text/qfontengine_mac.mm23
-rw-r--r--src/gui/text/qfontengine_qpa.cpp13
-rw-r--r--src/gui/text/qfontengine_qpf.cpp13
-rw-r--r--src/gui/text/qfontengine_qws.cpp13
-rw-r--r--src/gui/text/qfontengine_s60.cpp13
-rw-r--r--src/gui/text/qfontengine_win.cpp13
-rw-r--r--src/gui/text/qfontengine_x11.cpp4
-rw-r--r--src/gui/text/qfontenginedirectwrite.cpp13
-rw-r--r--src/gui/text/qglyphrun.cpp33
-rw-r--r--src/gui/text/qglyphrun.h4
-rw-r--r--src/gui/text/qrawfont.cpp139
-rw-r--r--src/gui/text/qrawfont.h6
-rw-r--r--src/gui/text/qrawfont_p.h25
-rw-r--r--src/gui/text/qrawfont_win.cpp82
-rw-r--r--src/gui/text/qtextcontrol.cpp7
-rw-r--r--src/gui/text/qtextcursor.cpp4
-rw-r--r--src/gui/text/qtextengine.cpp21
-rw-r--r--src/gui/text/qtextengine_p.h4
-rw-r--r--src/gui/text/qtexthtmlparser.cpp12
-rw-r--r--src/gui/text/qtextlayout.cpp14
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp8
-rw-r--r--src/gui/widgets/qabstractplatformmenubar_p.h108
-rw-r--r--src/gui/widgets/qlinecontrol.cpp12
-rw-r--r--src/gui/widgets/qmenu_mac.mm4
-rw-r--r--src/gui/widgets/qmenu_p.h6
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp4
-rw-r--r--src/gui/widgets/qmenu_wince.cpp4
-rw-r--r--src/gui/widgets/qmenubar.cpp139
-rw-r--r--src/gui/widgets/qmenubar_p.h39
-rw-r--r--src/gui/widgets/qmenubar_x11.cpp139
-rw-r--r--src/gui/widgets/qmenubar_x11_p.h87
-rw-r--r--src/gui/widgets/qtextedit.cpp2
-rw-r--r--src/gui/widgets/widgets.pri8
55 files changed, 934 insertions, 425 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 0c218fc..9092593 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -5378,11 +5378,9 @@ void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
{
QGraphicsItemPrivate *itemPrivate = this;
do {
- if (itemPrivate->graphicsEffect) {
+ if (itemPrivate->graphicsEffect && !itemPrivate->updateDueToGraphicsEffect) {
itemPrivate->notifyInvalidated = 1;
-
- if (!itemPrivate->updateDueToGraphicsEffect)
- static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
}
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
}
@@ -5690,21 +5688,27 @@ void QGraphicsItem::update(const QRectF &rect)
d_ptr->invalidateParentGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
- if (CacheMode(d_ptr->cacheMode) != NoCache) {
- // Invalidate cache.
- QGraphicsItemCache *cache = d_ptr->extraItemCache();
- if (!cache->allExposed) {
- if (rect.isNull()) {
- cache->allExposed = true;
- cache->exposed.clear();
- } else {
- cache->exposed.append(rect);
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (!d_ptr->updateDueToGraphicsEffect) {
+#endif
+ if (CacheMode(d_ptr->cacheMode) != NoCache) {
+ // Invalidate cache.
+ QGraphicsItemCache *cache = d_ptr->extraItemCache();
+ if (!cache->allExposed) {
+ if (rect.isNull()) {
+ cache->allExposed = true;
+ cache->exposed.clear();
+ } else {
+ cache->exposed.append(rect);
+ }
}
+ // Only invalidate cache; item is already dirty.
+ if (d_ptr->fullUpdatePending)
+ return;
}
- // Only invalidate cache; item is already dirty.
- if (d_ptr->fullUpdatePending)
- return;
+#ifndef QT_NO_GRAPHICSEFFECT
}
+#endif
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, rect);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 1551944..867880c 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -3504,7 +3504,9 @@ bool QGraphicsScene::event(QEvent *event)
}
break;
case QEvent::WindowDeactivate:
- if (!--d->activationRefCount) {
+ if (d->activationRefCount > 0)
+ --d->activationRefCount;
+ if (!d->activationRefCount) {
if (d->activePanel) {
// Deactivate the active panel (but keep it so we can
// reactivate it later).
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 965b1b34..d3562fc 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -1173,6 +1173,12 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
QApplication::sendEvent(this, &event);
break;
}
+ case ItemChildAddedChange: {
+ QGraphicsItem *child = qVariantValue<QGraphicsItem *>(value);
+ if (child->isWidget())
+ static_cast<QGraphicsWidget *>(child)->d_func()->resolveLayoutDirection();
+ break;
+ }
default:
break;
}
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 9857015..8c30838 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -154,6 +154,7 @@ private:
TUint m_textCapabilities;
bool m_inDestruction;
bool m_pendingInputCapabilitiesChanged;
+ bool m_pendingTransactionCancel;
int m_cursorVisibility;
int m_inlinePosition;
MFepInlineTextFormatRetriever *m_formatRetriever;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 5ddd53f..56338b2 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -64,6 +64,8 @@
#define QT_EAknCursorPositionChanged MAknEdStateObserver::EAknEdwinStateEvent(6)
// MAknEdStateObserver::EAknActivatePenInputRequest
#define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7)
+// MAknEdStateObserver::EAknClosePenInputRequest
+#define QT_EAknClosePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(10)
// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards.
// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors
@@ -107,6 +109,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_textCapabilities(TCoeInputCapabilities::EAllText),
m_inDestruction(false),
m_pendingInputCapabilitiesChanged(false),
+ m_pendingTransactionCancel(false),
m_cursorVisibility(1),
m_inlinePosition(0),
m_formatRetriever(0),
@@ -252,9 +255,6 @@ bool QCoeFepInputContext::needsInputPanel()
bool QCoeFepInputContext::filterEvent(const QEvent *event)
{
- // The CloseSoftwareInputPanel event is not handled here, because the VK will automatically
- // close when it discovers that the underlying widget does not have input capabilities.
-
if (!focusWidget())
return false;
@@ -318,6 +318,12 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (!needsInputPanel())
return false;
+ if ((event->type() == QEvent::CloseSoftwareInputPanel)
+ && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)) {
+ m_fepState->ReportAknEdStateEventL(QT_EAknClosePenInputRequest);
+ return false;
+ }
+
if (event->type() == QEvent::RequestSoftwareInputPanel) {
// Only request virtual keyboard if it is not yet active or if this is the first time
// panel is requested for this application.
@@ -354,10 +360,6 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (sControl) {
sControl->setIgnoreFocusChanged(false);
}
- //If m_pointerHandler has already been set, it means that fep inline editing is in progress.
- //When this is happening, do not filter out pointer events.
- if (!m_pointerHandler)
- return true;
}
}
@@ -473,7 +475,7 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
windowToMove->setUpdatesEnabled(false);
if (!alwaysResize) {
- if (gv->scene()) {
+ if (gv->scene() && S60->partial_keyboardAutoTranslation) {
if (gv->scene()->focusItem()) {
// Check if the widget contains cursorPositionChanged signal and disconnect from it.
QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
@@ -580,7 +582,7 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
if (!moveWithinVisibleArea) {
// Check if the widget contains cursorPositionChanged signal and connect to it.
QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- if (gv->scene() && gv->scene()->focusItem()) {
+ if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
if (index != -1)
connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
@@ -1062,15 +1064,24 @@ void QCoeFepInputContext::CancelFepInlineEdit()
// We are not supposed to ever have a tempPreeditString and a real preedit string
// from S60 at the same time, so it should be safe to rely on this test to determine
// whether we should honor S60's request to clear the text or not.
- if (m_hasTempPreeditString)
+ if (m_hasTempPreeditString || m_pendingTransactionCancel)
return;
+ m_pendingTransactionCancel = true;
+
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
event.setCommitString(QLatin1String(""), 0, 0);
m_preeditString.clear();
m_inlinePosition = 0;
sendEvent(event);
+
+ // Sync with native side editor state. Native side can then do various operations
+ // based on editor state, such as removing 'exact word bubble'.
+ if (!m_pendingInputCapabilitiesChanged)
+ ReportAknEdStateEvent(MAknEdStateObserver::EAknSyncEdwinState);
+
+ m_pendingTransactionCancel = false;
}
TInt QCoeFepInputContext::DocumentLengthForFep() const
@@ -1080,7 +1091,18 @@ TInt QCoeFepInputContext::DocumentLengthForFep() const
return 0;
QVariant variant = w->inputMethodQuery(Qt::ImSurroundingText);
- return variant.value<QString>().size() + m_preeditString.size();
+
+ int size = variant.value<QString>().size() + m_preeditString.size();
+
+ // To fix an issue with backspaces not being generated if document size is zero,
+ // fake document length to be at least one always, except when dealing with
+ // hidden text widgets, where this faking would generate extra asterisk. Since the
+ // primary use of hidden text widgets is password fields, they are unlikely to
+ // support multiple lines anyway.
+ if (size == 0 && !(m_textCapabilities & TCoeInputCapabilities::ESecretText))
+ size = 1;
+
+ return size;
}
TInt QCoeFepInputContext::DocumentMaximumLengthForFep() const
@@ -1163,6 +1185,12 @@ void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDoc
// FEP expects the preedit string to be part of the editor content, so let's mix it in.
int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
text.insert(cursor, m_preeditString);
+
+ // Add additional space to empty non-password text to compensate
+ // for the fake length we specified in DocumentLengthForFep().
+ if (text.size() == 0 && !(m_textCapabilities & TCoeInputCapabilities::ESecretText))
+ text += QChar(0x20);
+
aEditorContent.Copy(qt_QString2TPtrC(text.mid(aDocumentPosition, aLengthToRetrieve)));
}
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 361af8b..80bcdf0 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -2767,6 +2767,9 @@ QS60ThreadLocalData::QS60ThreadLocalData()
QS60ThreadLocalData::~QS60ThreadLocalData()
{
+ for (int i = 0; i < releaseFuncs.count(); ++i)
+ releaseFuncs[i]();
+ releaseFuncs.clear();
if (!usingCONEinstances) {
delete screenDevice;
wsSession.Close();
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
index 200696d..3f2e8b2 100644
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_qpa.cpp
@@ -284,7 +284,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_
Q_D(QEventDispatcherQPA);
int retVal = 0;
if (d->hasIntegration()) {
- qint64 timeoutmsec = 0;
+ qint64 timeoutmsec = 1000; // wait a second if we don't have timers
if (timeout)
timeoutmsec = timeout->tv_sec * 1000 + (timeout->tv_usec/1000);
d->selectReturnMutex->lock();
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 117b72f..469973f 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -933,7 +933,7 @@ QKeySequence::QKeySequence(const QString &key)
}
/*!
- \since 4.x
+ \since 4.7
Creates a key sequence from the \a key string based on \a format.
*/
QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat format)
@@ -1130,7 +1130,7 @@ int QKeySequence::assign(const QString &ks)
/*!
\fn int QKeySequence::assign(const QString &keys, QKeySequence::SequenceFormat format)
- \since 4.x
+ \since 4.7
Adds the given \a keys to the key sequence (based on \a format).
\a keys may contain up to four key codes, provided they are
@@ -1381,11 +1381,11 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
QString p;
if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
- if (key < 0x10000) {
- p = QChar(key & 0xffff).toUpper();
+ if (!QChar::requiresSurrogates(key)) {
+ p = QChar(ushort(key)).toUpper();
} else {
- p = QChar((key-0x10000)/0x400+0xd800);
- p += QChar((key-0x10000)%400+0xdc00);
+ p += QChar(QChar::highSurrogate(key));
+ p += QChar(QChar::lowSurrogate(key));
}
} else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
p = nativeText ? QShortcut::tr("F%1").arg(key - Qt::Key_F1 + 1)
@@ -1418,11 +1418,11 @@ NonSymbol:
// Or else characters like Qt::Key_aring may not get displayed
// (Really depends on you locale)
if (!keyname[i].name) {
- if (key < 0x10000) {
- p = QChar(key & 0xffff).toUpper();
+ if (!QChar::requiresSurrogates(key)) {
+ p = QChar(ushort(key)).toUpper();
} else {
- p = QChar((key-0x10000)/0x400+0xd800);
- p += QChar((key-0x10000)%400+0xdc00);
+ p += QChar(QChar::highSurrogate(key));
+ p += QChar(QChar::lowSurrogate(key));
}
}
}
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 510705f..9caa37e 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -123,8 +123,10 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
default:
break;
};
- if (key != 0)
+ if (key != 0) {
QSoftKeyManager::instance()->d_func()->softKeyCommandActions.insert(action, key);
+ connect(action, SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*)));
+ }
#endif
QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
switch (standardKey) {
@@ -157,7 +159,13 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key
QScopedPointer<QAction> action(createAction(standardKey, actionWidget));
connect(action.data(), SIGNAL(triggered()), QSoftKeyManager::instance(), SLOT(sendKeyEvent()));
+
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2)
+ // Don't connect destroyed slot if is was already connected in createAction
+ if (!(QSoftKeyManager::instance()->d_func()->softKeyCommandActions.contains(action.data())))
+#endif
connect(action.data(), SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*)));
+
QSoftKeyManager::instance()->d_func()->keyedActions.insert(action.data(), key);
return action.take();
#endif //QT_NO_ACTION
@@ -166,7 +174,9 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key
void QSoftKeyManager::cleanupHash(QObject *obj)
{
Q_D(QSoftKeyManager);
- QAction *action = qobject_cast<QAction*>(obj);
+ // Can't use qobject_cast in destroyed() signal handler as that'll return NULL,
+ // so use static_cast instead. Since the pointer is only used as a hash key, it is safe.
+ QAction *action = static_cast<QAction *>(obj);
d->keyedActions.remove(action);
#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2)
d->softKeyCommandActions.remove(action);
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 01d5f22..96b8141 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -98,6 +98,10 @@ static const int qt_symbian_max_screens = 4;
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
+class QSymbianTypeFaceExtras;
+typedef QHash<QString, const QSymbianTypeFaceExtras *> QSymbianTypeFaceExtrasHash;
+typedef void (*QThreadLocalReleaseFunc)();
+
class Q_AUTOTEST_EXPORT QS60ThreadLocalData
{
public:
@@ -106,6 +110,8 @@ public:
bool usingCONEinstances;
RWsSession wsSession;
CWsScreenDevice *screenDevice;
+ QSymbianTypeFaceExtrasHash fontData;
+ QVector<QThreadLocalReleaseFunc> releaseFuncs;
};
class QS60Data
@@ -179,6 +185,8 @@ public:
inline CWsScreenDevice* screenDevice(const QWidget *widget);
inline CWsScreenDevice* screenDevice(int screenNumber);
static inline int screenNumberForWidget(const QWidget *widget);
+ inline QSymbianTypeFaceExtrasHash& fontData();
+ inline void addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func);
static inline CCoeAppUi* appUi();
static inline CEikMenuBar* menuBar();
#ifdef Q_WS_S60
@@ -505,6 +513,24 @@ inline int QS60Data::screenNumberForWidget(const QWidget *widget)
return qt_widget_private(const_cast<QWidget *>(w))->symbianScreenNumber;
}
+inline QSymbianTypeFaceExtrasHash& QS60Data::fontData()
+{
+ if (!tls.hasLocalData()) {
+ tls.setLocalData(new QS60ThreadLocalData);
+ }
+ return tls.localData()->fontData;
+}
+
+inline void QS60Data::addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func)
+{
+ if (!tls.hasLocalData()) {
+ tls.setLocalData(new QS60ThreadLocalData);
+ }
+ QS60ThreadLocalData *data = tls.localData();
+ if (!data->releaseFuncs.contains(func))
+ data->releaseFuncs.append(func);
+}
+
inline CCoeAppUi* QS60Data::appUi()
{
return CCoeEnv::Static()-> AppUi();
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index ad8fbb7..0aa1dfa 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -345,6 +345,10 @@ QWidgetPrivate::QWidgetPrivate(int version)
QWidgetPrivate::~QWidgetPrivate()
{
+#ifdef Q_OS_SYMBIAN
+ _q_cleanupWinIds();
+#endif
+
if (widgetItem)
widgetItem->wid = 0;
@@ -12668,9 +12672,11 @@ void QWidget::clearMask()
*/
#ifdef Q_OS_SYMBIAN
-void QWidgetPrivate::_q_delayedDestroy(WId winId)
+void QWidgetPrivate::_q_cleanupWinIds()
{
- delete winId;
+ foreach (WId wid, widCleanupList)
+ delete wid;
+ widCleanupList.clear();
}
#endif
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 1a9987d..8306ed4 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -806,7 +806,7 @@ private:
Q_DISABLE_COPY(QWidget)
Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
#ifdef Q_OS_SYMBIAN
- Q_PRIVATE_SLOT(d_func(), void _q_delayedDestroy(WId winId))
+ Q_PRIVATE_SLOT(d_func(), void void _q_cleanupWinIds())
#endif
QWidgetData *data;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index a51e295..632df78 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -5031,7 +5031,7 @@ void QWidgetPrivate::registerTouchWindow(bool enable)
if (enable == touchEventsEnabled)
return;
- QCocoaView *view = static_cast<QCocoaView *>(qt_mac_effectiveview_for(q));
+ QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_effectiveview_for(q));
if (!view)
return;
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index ad65274..aefffb6 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -419,7 +419,7 @@ public:
#ifdef Q_OS_SYMBIAN
void setSoftKeys_sys(const QList<QAction*> &softkeys);
void activateSymbianWindow(WId wid = 0);
- void _q_delayedDestroy(WId winId);
+ void _q_cleanupWinIds();
#endif
void raise_sys();
@@ -914,6 +914,7 @@ public:
void s60UpdateIsOpaque();
void reparentChildren();
void registerTouchWindow();
+ QList<WId> widCleanupList;
#endif
};
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 256e34b..2b51aaa 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -58,9 +58,7 @@
#endif
// This is necessary in order to be able to perform delayed invocation on slots
-// which take arguments of type WId. One example is
-// QWidgetPrivate::_q_delayedDestroy, which is used to delay destruction of
-// CCoeControl objects until after the CONE event handler has finished running.
+// which take arguments of type WId.
Q_DECLARE_METATYPE(WId)
// Workaround for the fact that S60 SDKs 3.x do not contain the akntoolbar.h
@@ -235,11 +233,22 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
QSize oldSize(q->size());
QRect oldGeom(data.crect);
+ bool checkExtra = true;
+ if (q->isWindow() && (data.window_state & (Qt::WindowFullScreen | Qt::WindowMaximized))) {
+ // Do not allow fullscreen/maximized windows to expand beyond client rect
+ TRect r = S60->clientRect();
+ w = qMin(w, r.Width());
+ h = qMin(h, r.Height());
+
+ if (w == r.Width() && h == r.Height())
+ checkExtra = false;
+ }
+
// Lose maximized status if deliberate resize
if (w != oldSize.width() || h != oldSize.height())
data.window_state &= ~Qt::WindowMaximized;
- if (extra) { // any size restrictions?
+ if (checkExtra && extra) { // any size restrictions?
w = qMin(w,extra->maxw);
h = qMin(h,extra->maxh);
w = qMax(w,extra->minw);
@@ -480,8 +489,8 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
// Delay deletion of the control in case this function is called in the
// context of a CONE event handler such as
// CCoeControl::ProcessPointerEventL
- QMetaObject::invokeMethod(q, "_q_delayedDestroy",
- Qt::QueuedConnection, Q_ARG(WId, destroyw));
+ widCleanupList << destroyw;
+ QMetaObject::invokeMethod(q, "_q_cleanupWinIds", Qt::QueuedConnection);
}
if (q->testAttribute(Qt::WA_AcceptTouchEvents))
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index c46513a..38ba6f9 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -756,14 +756,15 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
path.setFillRule(Qt::WindingFill);
#endif
if (ti.glyphs.numGlyphs)
- ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags);
+ ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags);
if (!path.isEmpty()) {
- bool oldAA = painter()->renderHints() & QPainter::Antialiasing;
+ painter()->save();
painter()->setRenderHint(QPainter::Antialiasing,
bool((painter()->renderHints() & QPainter::TextAntialiasing)
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
+ painter()->translate(p.x(), p.y());
painter()->fillPath(path, state->pen().brush());
- painter()->setRenderHint(QPainter::Antialiasing, oldAA);
+ painter()->restore();
}
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 36786c4..bcc5f9d 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3764,6 +3764,11 @@ extern "C" {
int q_gray_rendered_spans(QT_FT_Raster raster);
}
+static inline uchar *alignAddress(uchar *address, quintptr alignmentMask)
+{
+ return (uchar *)(((quintptr)address + alignmentMask) & ~alignmentMask);
+}
+
void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
ProcessSpans callback,
void *userData, QRasterBuffer *)
@@ -3791,19 +3796,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// minimize memory reallocations. However if initial size for
// raster pool is changed for lower value, reallocations will
// occur normally.
- const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
- int rasterPoolSize = rasterPoolInitialSize;
- unsigned char *rasterPoolBase;
-#if defined(Q_WS_WIN64)
- rasterPoolBase =
- // We make use of setjmp and longjmp in qgrayraster.c which requires
- // 16-byte alignment, hence we hardcode this requirement here..
- (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
-#else
- unsigned char rasterPoolOnStack[rasterPoolInitialSize];
- rasterPoolBase = rasterPoolOnStack;
-#endif
- Q_CHECK_PTR(rasterPoolBase);
+ int rasterPoolSize = MINIMUM_POOL_SIZE;
+ uchar rasterPoolOnStack[MINIMUM_POOL_SIZE + 0xf];
+ uchar *rasterPoolBase = alignAddress(rasterPoolOnStack, 0xf);
+ uchar *rasterPoolOnHeap = 0;
qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
@@ -3839,31 +3835,20 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// Out of memory, reallocate some more and try again...
if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c
- int new_size = rasterPoolSize * 2;
- if (new_size > 1024 * 1024) {
+ rasterPoolSize *= 2;
+ if (rasterPoolSize > 1024 * 1024) {
qWarning("QPainter: Rasterization of primitive failed");
break;
}
rendered_spans += q_gray_rendered_spans(*grayRaster.data());
-#if defined(Q_WS_WIN64)
- _aligned_free(rasterPoolBase);
-#else
- if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
- free(rasterPoolBase);
-#endif
+ free(rasterPoolOnHeap);
+ rasterPoolOnHeap = (uchar *)malloc(rasterPoolSize + 0xf);
- rasterPoolSize = new_size;
- rasterPoolBase =
-#if defined(Q_WS_WIN64)
- // We make use of setjmp and longjmp in qgrayraster.c which requires
- // 16-byte alignment, hence we hardcode this requirement here..
- (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
-#else
- (unsigned char *) malloc(rasterPoolSize);
-#endif
- Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
+ Q_CHECK_PTR(rasterPoolOnHeap); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
+
+ rasterPoolBase = alignAddress(rasterPoolOnHeap, 0xf);
qt_ft_grays_raster.raster_done(*grayRaster.data());
qt_ft_grays_raster.raster_new(grayRaster.data());
@@ -3873,12 +3858,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
}
}
-#if defined(Q_WS_WIN64)
- _aligned_free(rasterPoolBase);
-#else
- if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
- free(rasterPoolBase);
-#endif
+ free(rasterPoolOnHeap);
}
void QRasterPaintEnginePrivate::recalculateFastImages()
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index ad0e151..327bedf 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -837,14 +837,12 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, int role) const
{
- Q_Q(const QCommonStyle);
-
const QWidget *widget = option->widget;
switch (role) {
case Qt::CheckStateRole:
if (option->features & QStyleOptionViewItemV2::HasCheckIndicator)
- return QSize(q->pixelMetric(QStyle::PM_IndicatorWidth, option, widget),
- q->pixelMetric(QStyle::PM_IndicatorHeight, option, widget));
+ return QSize(proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option, widget),
+ proxyStyle->pixelMetric(QStyle::PM_IndicatorHeight, option, widget));
break;
case Qt::DisplayRole:
if (option->features & QStyleOptionViewItemV2::HasDisplay) {
@@ -855,7 +853,7 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, in
textLayout.setFont(option->font);
textLayout.setText(option->text);
const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
- const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1;
+ const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1;
QRect bounds = option->rect;
switch (option->decorationPosition) {
case QStyleOptionViewItem::Left:
@@ -919,9 +917,8 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const
{
- Q_Q(const QCommonStyle);
const QWidget *widget = option->widget;
- const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
+ const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
@@ -999,7 +996,6 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt, QRect *checkRect,
QRect *pixmapRect, QRect *textRect, bool sizehint) const
{
- Q_Q(const QCommonStyle);
Q_ASSERT(checkRect && pixmapRect && textRect);
*pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole));
*textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole));
@@ -1009,9 +1005,9 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt, QRe
const bool hasCheck = checkRect->isValid();
const bool hasPixmap = pixmapRect->isValid();
const bool hasText = textRect->isValid();
- const int textMargin = hasText ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
- const int pixmapMargin = hasPixmap ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
- const int checkMargin = hasCheck ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ const int textMargin = hasText ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ const int pixmapMargin = hasPixmap ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ const int checkMargin = hasCheck ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
int x = opt->rect.left();
int y = opt->rect.top();
int w, h;
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index 8400feb..ffa4e59 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -166,7 +166,6 @@ public:
COpenFontRasterizer *m_rasterizer;
mutable QList<const QSymbianTypeFaceExtras *> m_extras;
- mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
mutable QSet<QString> m_applicationFontFamilies;
};
@@ -269,8 +268,9 @@ void QSymbianFontDatabaseExtrasImplementation::clear()
static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
if (!dbExtras)
return; // initializeDb() has never been called
+ QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData();
if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- qDeleteAll(dbExtras->m_extrasHash);
+ qDeleteAll(extrasHash);
} else {
typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) {
@@ -279,11 +279,16 @@ void QSymbianFontDatabaseExtrasImplementation::clear()
}
dbExtras->m_extras.clear();
}
- dbExtras->m_extrasHash.clear();
+ extrasHash.clear();
}
void qt_cleanup_symbianFontDatabase()
{
+ static bool cleanupDone = false;
+ if (cleanupDone)
+ return;
+ cleanupDone = true;
+
QFontDatabasePrivate *db = privateDb();
if (!db)
return;
@@ -334,9 +339,12 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont)
const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface,
bool bold, bool italic) const
{
+ QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData();
+ if (extrasHash.isEmpty() && QThread::currentThread() != QApplication::instance()->thread())
+ S60->addThreadLocalReleaseFunc(clear);
const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface);
const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
- if (!m_extrasHash.contains(searchKey)) {
+ if (!extrasHash.contains(searchKey)) {
TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
if (bold)
searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
@@ -350,7 +358,7 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c
QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font);
QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font);
sFont.take();
- m_extrasHash.insert(searchKey, extras);
+ extrasHash.insert(searchKey, extras);
} else {
const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
Q_ASSERT(err == KErrNone && font);
@@ -364,20 +372,20 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c
const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
const QString foundKey =
QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
- if (!m_extrasHash.contains(foundKey)) {
+ if (!extrasHash.contains(foundKey)) {
QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font);
QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
sFont.take();
m_extras.append(extras);
- m_extrasHash.insert(searchKey, extras);
- m_extrasHash.insert(foundKey, extras);
+ extrasHash.insert(searchKey, extras);
+ extrasHash.insert(foundKey, extras);
} else {
m_store->ReleaseFont(font);
- m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
+ extrasHash.insert(searchKey, extrasHash.value(foundKey));
}
}
}
- return m_extrasHash.value(searchKey);
+ return extrasHash.value(searchKey);
}
void QSymbianFontDatabaseExtrasImplementation::removeAppFontData(
@@ -973,7 +981,7 @@ bool QFontDatabase::removeAllApplicationFonts()
bool QFontDatabase::supportsThreadedFontRendering()
{
- return false;
+ return QSymbianTypeFaceExtras::symbianFontTableApiAvailable();
}
static
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index dec0982..c9b672b 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -280,6 +280,8 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
int i = glyphs.numGlyphs;
int totalKashidas = 0;
while(i--) {
+ if (glyphs.attributes[i].dontPrint)
+ continue;
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
totalKashidas += glyphs.justifications[i].nKashidas;
@@ -1335,8 +1337,7 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
int glyph_pos = 0;
for (int i = 0; i < len; ++i) {
- bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
- && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
+ bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate());
if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos);
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
index 0a2ae1f..4bd80be 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/gui/text/qfontengine_coretext_p.h
@@ -52,6 +52,10 @@
#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
class QRawFontPrivate;
class QCoreTextFontEngineMulti;
class QCoreTextFontEngine : public QFontEngine
@@ -146,6 +150,10 @@ private:
CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
#endif // QFONTENGINE_CORETEXT_P_H
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 9a5d9d6..e20aa25 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -78,6 +78,10 @@
#include FT_ERRORS_H
#endif
+#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
+# define QT_MAX_CACHED_GLYPH_SIZE 64
+#endif
+
QT_BEGIN_NAMESPACE
/*
@@ -373,7 +377,7 @@ void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize,
*xsize = *ysize = 0;
}
} else {
- *outline_drawing = (*xsize > (64<<6) || *ysize > (64<<6));
+ *outline_drawing = (*xsize > (QT_MAX_CACHED_GLYPH_SIZE<<6) || *ysize > (QT_MAX_CACHED_GLYPH_SIZE<<6));
}
}
@@ -1317,7 +1321,7 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor
if (!gs) {
// don't try to load huge fonts
- bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= 64;
+ bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= QT_MAX_CACHED_GLYPH_SIZE;
if (draw_as_outline)
return 0;
@@ -1418,15 +1422,12 @@ void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_me
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
bool QFontEngineFT::canRender(const QChar *string, int len)
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 9d9eaed..6186b2f 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -257,10 +257,8 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS
#if !defined(QT_NO_DEBUG)
int surrogates = 0;
const QChar *str = item->string;
- for (int i = item->from; i < item->from + item->length - 1; ++i) {
- surrogates += (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00
- && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
- }
+ for (int i = item->from; i < item->from + item->length - 1; ++i)
+ surrogates += (str[i].isHighSurrogate() && str[i+1].isLowSurrogate());
#endif
for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop)
if (item->charAttributes[nextCharStop].charStop)
@@ -328,10 +326,8 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS
if (charOffset < item->length - 1) {
QChar current = item->string[item->from + charOffset];
QChar next = item->string[item->from + charOffset + 1];
- if (current.unicode() >= 0xd800 && current.unicode() < 0xdc00
- && next.unicode() >= 0xdc00 && next.unicode() < 0xe000) {
+ if (current.isHighSurrogate() && next.isLowSurrogate())
item->log_clusters[charOffset + 1] = currentClusterGlyph;
- }
}
}
}
@@ -738,15 +734,12 @@ QFontEngineMac::~QFontEngineMac()
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
// Not used directly for shaping, only used to calculate m_averageCharWidth
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index cb1e7d6..c829c2f 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -226,15 +226,12 @@ QVariant QFontEngineQPA::extractHeaderField(const uchar *data, HeaderTag request
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data)
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index 30a1623..3db5ce1 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -278,15 +278,12 @@ QList<QByteArray> QFontEngineQPF::cleanUpAfterClientCrash(const QList<int> &cras
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
#ifdef QT_FONTS_ARE_RESOURCES
QFontEngineQPF::QFontEngineQPF(const QFontDef &def, const uchar *bytes, int size)
diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp
index 237842b..ade283f 100644
--- a/src/gui/text/qfontengine_qws.cpp
+++ b/src/gui/text/qfontengine_qws.cpp
@@ -83,15 +83,12 @@ QT_BEGIN_NAMESPACE
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
#define FM_SMOOTH 1
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index b0824cb..203b6e1 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -233,15 +233,12 @@ bool QSymbianTypeFaceExtras::symbianFontTableApiAvailable()
// duplicated from qfontengine_xyz.cpp
static inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
extern QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName); // qfontdatabase_s60.cpp
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index aef2145..fc11387 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -224,15 +224,12 @@ void QFontEngineWin::getCMap()
inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index 490866c..6e87f4c 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -358,9 +358,7 @@ bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs
QVarLengthArray<ushort> _s(len);
QChar *str = (QChar *)_s.data();
for (int i = 0; i < len; ++i) {
- if (i < len - 1
- && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00
- && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) {
+ if (s[i].isHighSurrogate() && i < len-1 && s[i+1].isLowSurrogate()) {
*str = QChar();
++i;
} else {
diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp
index d693273..5bac117 100644
--- a/src/gui/text/qfontenginedirectwrite.cpp
+++ b/src/gui/text/qfontenginedirectwrite.cpp
@@ -269,15 +269,12 @@ QFixed QFontEngineDirectWrite::emSquareSize() const
inline unsigned int getChar(const QChar *str, int &i, const int len)
{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
+ uint ucs4 = str[i].unicode();
+ if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4( ucs4, str[i].unicode());
}
- return uc;
+ return ucs4;
}
bool QFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index 442f7cc..7f43378 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -140,14 +140,18 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
return false;
}
- for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) {
- if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i])
- return false;
-
- if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i])
- return false;
+ if (d->glyphIndexData != other.d->glyphIndexData) {
+ for (int i = 0; i < d->glyphIndexDataSize; ++i) {
+ if (d->glyphIndexData[i] != other.d->glyphIndexData[i])
+ return false;
+ }
+ }
+ if (d->glyphPositionData != other.d->glyphPositionData) {
+ for (int i = 0; i < d->glyphPositionDataSize; ++i) {
+ if (d->glyphPositionData[i] != other.d->glyphPositionData[i])
+ return false;
+ }
}
-
return (d->overline == other.d->overline
&& d->underline == other.d->underline
@@ -156,13 +160,11 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
}
/*!
+ \fn bool QGlyphRun::operator!=(const QGlyphRun &other) const
+
Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph
indexes, the list of positions or the font are different, otherwise returns false.
*/
-bool QGlyphRun::operator!=(const QGlyphRun &other) const
-{
- return !(*this == other);
-}
/*!
Returns the font selected for this QGlyphRun object.
@@ -294,6 +296,9 @@ bool QGlyphRun::overline() const
*/
void QGlyphRun::setOverline(bool overline)
{
+ if (d->overline == overline)
+ return;
+
detach();
d->overline = overline;
}
@@ -316,6 +321,9 @@ bool QGlyphRun::underline() const
*/
void QGlyphRun::setUnderline(bool underline)
{
+ if (d->underline == underline)
+ return;
+
detach();
d->underline = underline;
}
@@ -338,6 +346,9 @@ bool QGlyphRun::strikeOut() const
*/
void QGlyphRun::setStrikeOut(bool strikeOut)
{
+ if (d->strikeOut == strikeOut)
+ return;
+
detach();
d->strikeOut = strikeOut;
}
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index cf407a8..bc7f4ff 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -79,8 +79,10 @@ public:
void clear();
QGlyphRun &operator=(const QGlyphRun &other);
+
bool operator==(const QGlyphRun &other) const;
- bool operator!=(const QGlyphRun &other) const;
+ inline bool operator!=(const QGlyphRun &other) const
+ { return !operator==(other); }
void setOverline(bool overline);
bool overline() const;
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 60a6cb3..7c7d4eb 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -46,7 +46,6 @@
#include "qrawfont.h"
#include "qrawfont_p.h"
-#include <QtCore/qthread.h>
#include <QtCore/qendian.h>
QT_BEGIN_NAMESPACE
@@ -77,7 +76,7 @@ QT_BEGIN_NAMESPACE
A QRawFont object represents a single, physical instance of a given font in a given pixel size.
I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
- user specified pixel size to convert metrics into logical pixel units. In can be used in
+ user specified pixel size to convert metrics into logical pixel units. It can be used in
combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
also have accessors to some relevant data in the physical font.
@@ -190,8 +189,7 @@ QRawFont &QRawFont::operator=(const QRawFont &other)
*/
bool QRawFont::isValid() const
{
- Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread());
- return d->fontEngine != 0;
+ return d->isValid();
}
/*!
@@ -225,7 +223,7 @@ void QRawFont::loadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
- detach();
+ d.detach();
d->cleanUp();
d->hintingPreference = hintingPreference;
d->thread = QThread::currentThread();
@@ -240,20 +238,21 @@ void QRawFont::loadFromData(const QByteArray &fontData,
If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be
in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of
the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
- QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization.
+ QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the
+ rasterization.
\sa pathForGlyph(), QPainter::drawGlyphRun()
*/
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
const QTransform &transform) const
{
- if (!isValid())
+ if (!d->isValid())
return QImage();
if (antialiasingType == SubPixelAntialiasing)
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
- else
- return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
+
+ return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
}
/*!
@@ -266,7 +265,7 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias
*/
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
{
- if (!isValid())
+ if (!d->isValid())
return QPainterPath();
QFixedPoint position;
@@ -284,16 +283,19 @@ bool QRawFont::operator==(const QRawFont &other) const
}
/*!
+ \fn bool QRawFont::operator!=(const QRawFont &other) const
+
+ Returns true if this QRawFont is not equal to \a other. Otherwise, returns false.
+*/
+
+/*!
Returns the ascent of this QRawFont in pixel units.
\sa QFontMetricsF::ascent()
*/
qreal QRawFont::ascent() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->ascent().toReal();
+ return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
}
/*!
@@ -303,10 +305,7 @@ qreal QRawFont::ascent() const
*/
qreal QRawFont::descent() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->descent().toReal();
+ return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
}
/*!
@@ -316,10 +315,7 @@ qreal QRawFont::descent() const
*/
qreal QRawFont::xHeight() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->xHeight().toReal();
+ return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
}
/*!
@@ -329,10 +325,7 @@ qreal QRawFont::xHeight() const
*/
qreal QRawFont::leading() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->leading().toReal();
+ return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
}
/*!
@@ -342,10 +335,7 @@ qreal QRawFont::leading() const
*/
qreal QRawFont::averageCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->averageCharWidth().toReal();
+ return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
}
/*!
@@ -355,10 +345,7 @@ qreal QRawFont::averageCharWidth() const
*/
qreal QRawFont::maxCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->maxCharWidth();
+ return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
}
/*!
@@ -370,10 +357,7 @@ qreal QRawFont::maxCharWidth() const
*/
qreal QRawFont::pixelSize() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->fontDef.pixelSize;
+ return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
}
/*!
@@ -386,10 +370,7 @@ qreal QRawFont::pixelSize() const
*/
qreal QRawFont::unitsPerEm() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->emSquareSize().toReal();
+ return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
}
/*!
@@ -397,10 +378,7 @@ qreal QRawFont::unitsPerEm() const
*/
QString QRawFont::familyName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.family;
+ return d->isValid() ? d->fontEngine->fontDef.family : QString();
}
/*!
@@ -410,10 +388,7 @@ QString QRawFont::familyName() const
*/
QString QRawFont::styleName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.styleName;
+ return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
}
/*!
@@ -423,10 +398,7 @@ QString QRawFont::styleName() const
*/
QFont::Style QRawFont::style() const
{
- if (!isValid())
- return QFont::StyleNormal;
-
- return QFont::Style(d->fontEngine->fontDef.style);
+ return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
}
/*!
@@ -436,10 +408,7 @@ QFont::Style QRawFont::style() const
*/
int QRawFont::weight() const
{
- if (!isValid())
- return -1;
-
- return int(d->fontEngine->fontDef.weight);
+ return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
}
/*!
@@ -457,7 +426,7 @@ int QRawFont::weight() const
*/
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<quint32>();
int nglyphs = text.size();
@@ -490,7 +459,7 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
*/
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -507,7 +476,7 @@ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *g
*/
QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<QPointF>();
int numGlyphs = glyphIndexes.size();
@@ -534,7 +503,7 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -560,10 +529,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
*/
QFont::HintingPreference QRawFont::hintingPreference() const
{
- if (!isValid())
- return QFont::PreferDefaultHinting;
-
- return d->hintingPreference;
+ return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
}
/*!
@@ -574,7 +540,7 @@ QFont::HintingPreference QRawFont::hintingPreference() const
*/
QByteArray QRawFont::fontTable(const char *tagName) const
{
- if (!isValid())
+ if (!d->isValid())
return QByteArray();
const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
@@ -597,9 +563,9 @@ extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_tru
*/
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
{
- if (isValid()) {
+ if (d->isValid()) {
QByteArray os2Table = fontTable("OS/2");
- if (!os2Table.isEmpty() && os2Table.size() > 86) {
+ if (os2Table.size() > 86) {
char *data = os2Table.data();
quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
@@ -627,10 +593,7 @@ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
*/
bool QRawFont::supportsCharacter(QChar character) const
{
- if (!isValid())
- return false;
-
- return d->fontEngine->canRender(&character, 1);
+ return d->isValid() && d->fontEngine->canRender(&character, 1);
}
/*!
@@ -641,9 +604,6 @@ bool QRawFont::supportsCharacter(QChar character) const
*/
bool QRawFont::supportsCharacter(quint32 ucs4) const
{
- if (!isValid())
- return false;
-
QChar str[2];
int len;
if (!QChar::requiresSurrogates(ucs4)) {
@@ -655,7 +615,7 @@ bool QRawFont::supportsCharacter(quint32 ucs4) const
len = 2;
}
- return d->fontEngine->canRender(str, len);
+ return d->isValid() && d->fontEngine->canRender(str, len);
}
// qfontdatabase.cpp
@@ -667,6 +627,7 @@ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSyst
*/
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
+ QRawFont rawFont;
#if defined(Q_WS_MAC)
QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font);
layout.beginLayout();
@@ -677,14 +638,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
// Pick the one matches the family name we originally requested,
// if none of them match, just pick the first one
for (int i = 0; i < list.size(); i++) {
- QGlyphRun glyphs = list.at(i);
- QRawFont rawfont = glyphs.rawFont();
- if (rawfont.familyName() == font.family())
- return rawfont;
+ rawFont = list.at(i).rawFont();
+ if (rawFont.familyName() == font.family())
+ return rawFont;
}
return list.at(0).rawFont();
}
- return QRawFont();
#else
QFontPrivate *font_d = QFontPrivate::get(font);
int script = qt_script_for_writing_system(writingSystem);
@@ -700,15 +659,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
}
if (fe != 0) {
- QRawFont rawFont;
rawFont.d.data()->fontEngine = fe;
rawFont.d.data()->fontEngine->ref.ref();
rawFont.d.data()->hintingPreference = font.hintingPreference();
- return rawFont;
- } else {
- return QRawFont();
}
#endif
+ return rawFont;
}
/*!
@@ -719,7 +675,7 @@ void QRawFont::setPixelSize(qreal pixelSize)
if (d->fontEngine == 0)
return;
- detach();
+ d.detach();
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
@@ -734,15 +690,6 @@ void QRawFont::setPixelSize(qreal pixelSize)
/*!
\internal
*/
-void QRawFont::detach()
-{
- if (d->ref != 1)
- d.detach();
-}
-
-/*!
- \internal
-*/
void QRawFontPrivate::cleanUp()
{
platformCleanUp();
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index d5b5680..cf77996 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -81,7 +81,10 @@ public:
bool isValid() const;
QRawFont &operator=(const QRawFont &other);
+
bool operator==(const QRawFont &other) const;
+ inline bool operator!=(const QRawFont &other) const
+ { return !operator==(other); }
QString familyName() const;
QString styleName() const;
@@ -132,9 +135,6 @@ public:
private:
friend class QRawFontPrivate;
-
- void detach();
-
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index fdf7cad..3557751 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -54,7 +54,9 @@
//
#include "qrawfont.h"
+
#include "qfontengine_p.h"
+#include <QtCore/qthread.h>
#include <QtCore/qthreadstorage.h>
#if !defined(QT_NO_RAWFONT)
@@ -71,21 +73,17 @@ public:
, thread(0)
#if defined(Q_WS_WIN)
, fontHandle(NULL)
- , ptrAddFontMemResourceEx(NULL)
- , ptrRemoveFontMemResourceEx(NULL)
#endif
{}
QRawFontPrivate(const QRawFontPrivate &other)
- : hintingPreference(other.hintingPreference)
+ : fontEngine(other.fontEngine)
+ , hintingPreference(other.hintingPreference)
, thread(other.thread)
#if defined(Q_WS_WIN)
, fontHandle(NULL)
- , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
- , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
#endif
{
- fontEngine = other.fontEngine;
if (fontEngine != 0)
fontEngine->ref.ref();
}
@@ -96,6 +94,12 @@ public:
cleanUp();
}
+ inline bool isValid() const
+ {
+ Q_ASSERT(thread == 0 || thread == QThread::currentThread());
+ return fontEngine != 0;
+ }
+
void cleanUp();
void platformCleanUp();
void platformLoadFromData(const QByteArray &fontData,
@@ -111,14 +115,7 @@ public:
#if defined(Q_WS_WIN)
HANDLE fontHandle;
-
- typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
- typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
-
- PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
- PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
-
-#endif // Q_WS_WIN
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp
index 779652f..a729e31 100644
--- a/src/gui/text/qrawfont_win.cpp
+++ b/src/gui/text/qrawfont_win.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qrawfont_p.h"
+
+#if !defined(QT_NO_RAWFONT)
+
#include <private/qsystemlibrary_p.h>
#if !defined(QT_NO_DIRECTWRITE)
@@ -47,8 +50,6 @@
# include <dwrite.h>
#endif
-#if !defined(QT_NO_RAWFONT)
-
QT_BEGIN_NAMESPACE
namespace {
@@ -61,18 +62,16 @@ namespace {
operator T() const
{
T littleEndian = 0;
- for (int i=0; i<sizeof(T); ++i) {
+ for (int i = 0; i < int(sizeof(T)); ++i)
littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8);
- }
return littleEndian;
}
BigEndian<T> &operator=(const T &t)
{
- for (int i=0; i<sizeof(T); ++i) {
+ for (int i = 0; i < int(sizeof(T)); ++i)
data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff);
- }
return *this;
}
@@ -157,7 +156,7 @@ namespace {
class EmbeddedFont
{
public:
- EmbeddedFont(const QByteArray &fontData);
+ EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
QString changeFamilyName(const QString &newFamilyName);
QByteArray data() const { return m_fontData; }
@@ -168,10 +167,6 @@ namespace {
QByteArray m_fontData;
};
- EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData)
- {
- }
-
TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
{
Q_ASSERT(tagName.size() == 4);
@@ -214,9 +209,9 @@ namespace {
+ nameRecord->offset;
const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr);
- for (int j=0; j<nameRecord->length / sizeof(quint16); ++j)
- name += QChar(s[j]);
-
+ const BigEndian<quint16> *e = s + nameRecord->length / sizeof(quint16);
+ while (s != e)
+ name += QChar(*s++);
break;
}
}
@@ -525,41 +520,49 @@ extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
// From qfontdatabase.cpp
extern QFont::Weight weightFromInteger(int weight);
-void QRawFontPrivate::platformCleanUp()
+typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
+static PtrAddFontMemResourceEx ptrAddFontMemResourceEx = 0;
+typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
+static PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = 0;
+
+static void resolveGdi32()
{
- if (fontHandle != NULL) {
- if (ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
+ static bool triedResolve = false;
+ if (!triedResolve) {
+ QSystemLibrary gdi32(QLatin1String("gdi32"));
+ if (gdi32.load()) {
+ ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)gdi32.resolve("AddFontMemResourceEx");
+ ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)gdi32.resolve("RemoveFontMemResourceEx");
}
- if (ptrRemoveFontMemResourceEx == NULL) {
- qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32");
- fontHandle = NULL;
- } else {
+ triedResolve = true;
+ }
+}
+
+void QRawFontPrivate::platformCleanUp()
+{
+ if (fontHandle != NULL) {
+ if (ptrRemoveFontMemResourceEx)
ptrRemoveFontMemResourceEx(fontHandle);
- fontHandle = NULL;
- }
+ fontHandle = NULL;
}
}
-void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
- QByteArray fontData(_fontData);
EmbeddedFont font(fontData);
#if !defined(QT_NO_DIRECTWRITE)
if (hintingPreference == QFont::PreferDefaultHinting
- || hintingPreference == QFont::PreferFullHinting)
+ || hintingPreference == QFont::PreferFullHinting)
#endif
{
GUID guid;
CoCreateGuid(&guid);
- QString uniqueFamilyName = QString::fromLatin1("f")
+ QString uniqueFamilyName = QLatin1Char('f')
+ QString::number(guid.Data1, 36) + QLatin1Char('-')
+ QString::number(guid.Data2, 36) + QLatin1Char('-')
+ QString::number(guid.Data3, 36) + QLatin1Char('-')
@@ -571,22 +574,13 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
return;
}
- if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
-
- func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx");
- ptrAddFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func);
- }
-
Q_ASSERT(fontHandle == NULL);
- if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) {
+ resolveGdi32();
+ if (ptrAddFontMemResourceEx && ptrRemoveFontMemResourceEx) {
DWORD count = 0;
- fontData = font.data();
- fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count);
-
+ QByteArray newFontData = font.data();
+ fontHandle = ptrAddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(),
+ 0, &count);
if (count == 0 && fontHandle != NULL) {
ptrRemoveFontMemResourceEx(fontHandle);
fontHandle = NULL;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index bde2c34..aeeef85 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1638,16 +1638,13 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
return;
}
- if (!mousePressed)
- return;
-
const qreal mouseX = qreal(mousePos.x());
int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
if (newCursorPos == -1)
return;
- if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
+ if (mousePressed && wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
selectedWordOnDoubleClick = cursor;
selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
}
@@ -1656,7 +1653,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
extendBlockwiseSelection(newCursorPos);
else if (selectedWordOnDoubleClick.hasSelection())
extendWordwiseSelection(newCursorPos, mouseX);
- else
+ else if (mousePressed)
setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
if (interactionFlags & Qt::TextEditable) {
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index 7e7ca6c..acef9fa 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -1511,11 +1511,11 @@ void QTextCursor::deletePreviousChar()
const QTextFragmentData * const frag = fragIt.value();
int fpos = fragIt.position();
QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition);
- if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ if (d->anchor > fpos && uc.isLowSurrogate()) {
// second half of a surrogate, check if we have the first half as well,
// if yes delete both at once
uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition);
- if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
+ if (uc.isHighSurrogate())
--d->anchor;
}
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index aa4a20d..2fc1dbd 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -968,7 +968,7 @@ void QTextEngine::shapeText(int item) const
}
for (int i = 0; i < si.num_glyphs; ++i)
- si.width += glyphs.advances_x[i];
+ si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
}
static inline bool hasCaseChange(const QScriptItem &si)
@@ -993,8 +993,7 @@ static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayou
int glyph_pos = 0;
for (int i = 0; i < length; i++) {
- if (uc[i].unicode() >= 0xd800 && uc[i].unicode() < 0xdc00 && i < length-1
- && uc[i+1].unicode() >= 0xdc00 && uc[i+1].unicode() < 0xe000) {
+ if (uc[i].isHighSurrogate() && i < length-1 && uc[i+1].isLowSurrogate()) {
logClusters[i] = glyph_pos;
logClusters[++i] = glyph_pos;
} else {
@@ -1387,6 +1386,7 @@ QTextEngine::~QTextEngine()
if (!stackEngine)
delete layoutData;
delete specialData;
+ resetFontEngineCache();
}
const HB_CharAttributes *QTextEngine::attributes() const
@@ -1447,6 +1447,13 @@ static inline void releaseCachedFontEngine(QFontEngine *fontEngine)
}
}
+void QTextEngine::resetFontEngineCache()
+{
+ releaseCachedFontEngine(feCache.prevFontEngine);
+ releaseCachedFontEngine(feCache.prevScaledFontEngine);
+ feCache.reset();
+}
+
void QTextEngine::invalidate()
{
freeMemory();
@@ -1455,9 +1462,7 @@ void QTextEngine::invalidate()
if (specialData)
specialData->resolvedFormatIndices.clear();
- releaseCachedFontEngine(feCache.prevFontEngine);
- releaseCachedFontEngine(feCache.prevScaledFontEngine);
- feCache.reset();
+ resetFontEngineCache();
}
void QTextEngine::clearLineData()
@@ -2658,7 +2663,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
- w += g.advances_x[j];
+ w += g.advances_x[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
@@ -2951,7 +2956,7 @@ int QTextEngine::lineNumberForTextPosition(int pos)
return lines.size() - 1;
for (int i = 0; i < lines.size(); ++i) {
const QScriptLine& line = lines[i];
- if (line.from + line.length > pos)
+ if (line.from + line.length + line.trailingSpaces > pos)
return i;
}
return -1;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index b1bd0c3..9362022 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -376,7 +376,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
{
// created and filled in QTextLine::layout_helper
QScriptLine()
- : from(0), length(0),
+ : from(0), trailingSpaces(0), length(0),
justified(0), gridfitted(0),
hasTrailingSpaces(0), leadingIncluded(0) {}
QFixed descent;
@@ -388,6 +388,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
QFixed textWidth;
QFixed textAdvance;
int from;
+ unsigned short trailingSpaces;
signed int length : 28;
mutable uint justified : 1;
mutable uint gridfitted : 1;
@@ -628,6 +629,7 @@ public:
int lineNumberForTextPosition(int pos);
int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op);
void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints);
+ void resetFontEngineCache();
private:
void setBoundary(int strPos) const;
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 5b60dfa..d130c61 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -820,15 +820,11 @@ QString QTextHtmlParser::parseEntity()
if (uc >= 0x80 && uc < 0x80 + (sizeof(windowsLatin1ExtendedCharacters)/sizeof(windowsLatin1ExtendedCharacters[0])))
uc = windowsLatin1ExtendedCharacters[uc - 0x80];
QString str;
- if (uc > 0xffff) {
- // surrogate pair
- uc -= 0x10000;
- ushort high = uc/0x400 + 0xd800;
- ushort low = uc%0x400 + 0xdc00;
- str.append(QChar(high));
- str.append(QChar(low));
+ if (QChar::requiresSurrogates(uc)) {
+ str += QChar(QChar::highSurrogate(uc));
+ str += QChar(QChar::lowSurrogate(uc));
} else {
- str.append(QChar(uc));
+ str = QChar(uc);
}
return str;
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 4fd6ddf..d0c1a0e 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -375,7 +375,7 @@ QTextLayout::~QTextLayout()
void QTextLayout::setFont(const QFont &font)
{
d->fnt = font;
- d->feCache.reset();
+ d->resetFontEngineCache();
}
/*!
@@ -515,7 +515,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
}
if (d->block.docHandle())
d->block.docHandle()->documentChange(d->block.position(), d->block.length());
- d->feCache.reset();
+ d->resetFontEngineCache();
}
/*!
@@ -814,7 +814,7 @@ QTextLine QTextLayout::createLine()
if (l && d->lines.at(l-1).length < 0) {
QTextLine(l-1, d).setNumColumns(INT_MAX);
}
- int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length : 0;
+ int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length + d->lines.at(l-1).trailingSpaces : 0;
int strlen = d->layoutData->string.length();
if (l && from >= strlen) {
if (!d->lines.at(l-1).length || d->layoutData->string.at(strlen - 1) != QChar::LineSeparator)
@@ -1708,6 +1708,7 @@ void QTextLine::layout_helper(int maxGlyphs)
{
QScriptLine &line = eng->lines[i];
line.length = 0;
+ line.trailingSpaces = 0;
line.textWidth = 0;
line.hasTrailingSpaces = false;
@@ -1931,7 +1932,7 @@ found:
if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
line.textWidth += lbh.spaceData.textWidth;
if (lbh.spaceData.length) {
- line.length += lbh.spaceData.length;
+ line.trailingSpaces = lbh.spaceData.length;
line.hasTrailingSpaces = true;
}
@@ -1995,7 +1996,7 @@ int QTextLine::textLength() const
&& eng->block.isValid() && i == eng->lines.count()-1) {
return eng->lines[i].length - 1;
}
- return eng->lines[i].length;
+ return eng->lines[i].length + eng->lines[i].trailingSpaces;
}
static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng,
@@ -2506,6 +2507,9 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
int pos = *cursorPos;
int itm;
+ const HB_CharAttributes *attributes = eng->attributes();
+ while (pos < line.from + line.length && !attributes[pos].charStop)
+ pos++;
if (pos == line.from + (int)line.length) {
// end of line ensure we have the last item on the line
itm = eng->findItem(pos-1);
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 8c243ed..7a53224 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -313,12 +313,12 @@ static void handleUrlL(const TDesC& aUrl)
CleanupStack::PopAndDestroy();
}
-static bool handleUrl(const QUrl &url)
+static bool handleUrl(const QUrl &url, bool useEncodedUrl)
{
if (!url.isValid())
return false;
- QString urlString(url.toEncoded());
+ QString urlString(useEncodedUrl ? url.toEncoded() : url.toString());
TPtrC urlPtr(qt_QString2TPtrC(urlString));
TRAPD( err, handleUrlL(urlPtr));
return err ? false : true;
@@ -326,12 +326,12 @@ static bool handleUrl(const QUrl &url)
static bool launchWebBrowser(const QUrl &url)
{
- return handleUrl(url);
+ return handleUrl(url, true);
}
static bool openDocument(const QUrl &file)
{
- return handleUrl(file);
+ return handleUrl(file, false);
}
#endif //USE_SCHEMEHANDLER
diff --git a/src/gui/widgets/qabstractplatformmenubar_p.h b/src/gui/widgets/qabstractplatformmenubar_p.h
new file mode 100644
index 0000000..10e6fdc
--- /dev/null
+++ b/src/gui/widgets/qabstractplatformmenubar_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPLATFORMMENUBAR_P_H
+#define QABSTRACTPLATFORMMENUBAR_P_H
+
+#include <qfactoryinterface.h>
+#include <qglobal.h>
+#include <qplugin.h>
+
+#ifndef QT_NO_MENUBAR
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QActionEvent;
+class QEvent;
+class QMenuBar;
+class QObject;
+class QWidget;
+
+class QAbstractPlatformMenuBar;
+
+struct QPlatformMenuBarFactoryInterface : public QFactoryInterface
+{
+ virtual QAbstractPlatformMenuBar *create() = 0;
+};
+
+#define QPlatformMenuBarFactoryInterface_iid "com.nokia.qt.QPlatformMenuBarFactoryInterface"
+Q_DECLARE_INTERFACE(QPlatformMenuBarFactoryInterface, QPlatformMenuBarFactoryInterface_iid)
+
+/*!
+ The platform-specific implementation of a menubar
+*/
+class QAbstractPlatformMenuBar
+{
+public:
+ virtual ~QAbstractPlatformMenuBar() {}
+
+ virtual void init(QMenuBar *) = 0;
+
+ virtual void setVisible(bool visible) = 0;
+
+ virtual void actionEvent(QActionEvent *) = 0;
+
+ virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow) = 0;
+
+ virtual bool allowCornerWidgets() const = 0;
+
+ virtual void popupAction(QAction *) = 0;
+
+ virtual void setNativeMenuBar(bool) = 0;
+
+ virtual bool isNativeMenuBar() const = 0;
+
+ /*!
+ Return true if the native menubar is capable of listening to the
+ shortcut keys. If false is returned, QMenuBar will trigger actions on
+ shortcut itself.
+ */
+ virtual bool shortcutsHandledByNativeMenuBar() const = 0;
+
+ virtual bool menuBarEventFilter(QObject *, QEvent *event) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MENUBAR
+
+#endif // QABSTRACTPLATFORMMENUBAR_P_H
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index b6e2f90..d58da37 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -60,7 +60,7 @@
QT_BEGIN_NAMESPACE
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
-static int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY;
+static const int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY;
#endif
/*!
@@ -93,8 +93,8 @@ void QLineControl::updateDisplayText(bool forceUpdate)
if (m_echoMode == QLineEdit::Password) {
str.fill(m_passwordCharacter);
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- if (m_passwordEchoTimer != 0 && !str.isEmpty()) {
- int cursor = m_text.length() - 1;
+ if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.length()) {
+ int cursor = m_cursor - 1;
QChar uc = m_text.at(cursor);
str[cursor] = uc;
if (cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
@@ -198,12 +198,10 @@ void QLineControl::backspace()
--m_cursor;
if (m_maskData)
m_cursor = prevMaskBlank(m_cursor);
- QChar uc = m_text.at(m_cursor);
- if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ if (m_cursor > 0 && m_text.at(m_cursor).isLowSurrogate()) {
// second half of a surrogate, check if we have the first half as well,
// if yes delete both at once
- uc = m_text.at(m_cursor - 1);
- if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
+ if (m_text.at(m_cursor - 1).isHighSurrogate()) {
internalDelete(true);
--m_cursor;
}
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 9db068c..56658b3 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -1639,7 +1639,7 @@ QMenuBarPrivate::QMacMenuBarPrivate::~QMacMenuBarPrivate()
}
void
-QMenuBarPrivate::QMacMenuBarPrivate::addAction(QAction *a, QMacMenuAction *before)
+QMenuBarPrivate::QMacMenuBarPrivate::addAction(QAction *a, QAction *before)
{
if (a->isSeparator() || !menu)
return;
@@ -1649,7 +1649,7 @@ QMenuBarPrivate::QMacMenuBarPrivate::addAction(QAction *a, QMacMenuAction *befor
#ifndef QT_MAC_USE_COCOA
action->command = qt_mac_menu_static_cmd_id++;
#endif
- addAction(action, before);
+ addAction(action, findAction(before));
}
void
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 0e63799..82bd932 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -154,6 +154,9 @@ public:
#endif
scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
hasCheckableItems(0), sloppyAction(0), doChildEffects(false)
+#ifdef QT3_SUPPORT
+ ,emitHighlighted(false)
+#endif
#ifdef Q_WS_MAC
,mac_menu(0)
#endif
@@ -163,9 +166,6 @@ public:
#ifdef Q_WS_S60
,symbian_menu(0)
#endif
-#ifdef QT3_SUPPORT
- ,emitHighlighted(false)
-#endif
{ }
~QMenuPrivate()
{
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index c9dbff5..99a1d78 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -398,12 +398,12 @@ void QMenuPrivate::QSymbianMenuPrivate::rebuild(bool)
{
}
-void QMenuBarPrivate::QSymbianMenuBarPrivate::addAction(QAction *a, QSymbianMenuAction *before)
+void QMenuBarPrivate::QSymbianMenuBarPrivate::addAction(QAction *a, QAction *before)
{
QSymbianMenuAction *action = new QSymbianMenuAction;
action->action = a;
action->command = qt_symbian_menu_static_cmd_id++;
- addAction(action, before);
+ addAction(action, findAction(before));
}
void QMenuBarPrivate::QSymbianMenuBarPrivate::addAction(QSymbianMenuAction *action, QSymbianMenuAction *before)
diff --git a/src/gui/widgets/qmenu_wince.cpp b/src/gui/widgets/qmenu_wince.cpp
index 1157fff..b0c6c1b 100644
--- a/src/gui/widgets/qmenu_wince.cpp
+++ b/src/gui/widgets/qmenu_wince.cpp
@@ -504,12 +504,12 @@ void QMenuPrivate::QWceMenuPrivate::removeAction(QWceMenuAction *action)
rebuild();
}
-void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QAction *a, QWceMenuAction *before)
+void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QAction *a, QAction *before)
{
QWceMenuAction *action = new QWceMenuAction;
action->action = a;
action->command = qt_wce_menu_static_cmd_id++;
- addAction(action, before);
+ addAction(action, findAction(before));
}
void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QWceMenuAction *action, QWceMenuAction *before)
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 3ff98a4..3e5365c 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -55,6 +55,9 @@
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qwhatsthis.h>
+#ifdef Q_WS_X11
+#include <qpluginloader.h>
+#endif
#ifndef QT_NO_MENUBAR
@@ -66,6 +69,9 @@
#include "qmenu_p.h"
#include "qmenubar_p.h"
#include "qdebug.h"
+#ifdef Q_WS_X11
+#include "qmenubar_x11_p.h"
+#endif
#ifdef Q_WS_WINCE
extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
@@ -173,7 +179,11 @@ void QMenuBarPrivate::updateGeometries()
return;
int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2);
int q_start = -1;
- if(leftWidget || rightWidget) {
+ if(
+#ifdef Q_WS_X11
+ platformMenuBar->allowCornerWidgets() &&
+#endif
+ (leftWidget || rightWidget)) {
int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q)
+ q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q)
@@ -204,7 +214,11 @@ void QMenuBarPrivate::updateGeometries()
calcActionRects(q_width, q_start);
currentAction = 0;
#ifndef QT_NO_SHORTCUT
- if(itemsDirty) {
+ if(
+#ifdef Q_WS_X11
+ !platformMenuBar->shortcutsHandledByNativeMenuBar() &&
+#endif
+ itemsDirty) {
for(int j = 0; j < shortcutIndexMap.size(); ++j)
q->releaseShortcut(shortcutIndexMap.value(j));
shortcutIndexMap.resize(0); // faster than clear
@@ -212,6 +226,12 @@ void QMenuBarPrivate::updateGeometries()
shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
}
#endif
+#ifdef Q_WS_X11
+ if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
+ itemsDirty = false;
+ return;
+ }
+#endif
itemsDirty = false;
hiddenActions.clear();
@@ -743,6 +763,11 @@ void QMenuBarPrivate::init()
QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
}
#endif
+#ifdef Q_WS_X11
+ platformMenuBar = qt_guiPlatformMenuBarFactory()->create();
+ platformMenuBar->init(q);
+#endif
+
q->setBackgroundRole(QPalette::Button);
oldWindow = oldParent = 0;
#ifdef QT3_SUPPORT
@@ -751,6 +776,10 @@ void QMenuBarPrivate::init()
#ifdef QT_SOFTKEYS_ENABLED
menuBarAction = 0;
#endif
+#ifdef Q_WS_X11
+ cornerWidgetToolBar = 0;
+ cornerWidgetContainer = 0;
+#endif
handleReparent();
q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q));
@@ -821,6 +850,10 @@ QMenuBar::~QMenuBar()
Q_D(QMenuBar);
d->symbianDestroyMenuBar();
#endif
+#ifdef Q_WS_X11
+ Q_D(QMenuBar);
+ delete d->cornerWidgetToolBar;
+#endif
}
/*!
@@ -1072,6 +1105,10 @@ void QMenuBar::paintEvent(QPaintEvent *e)
*/
void QMenuBar::setVisible(bool visible)
{
+#ifdef Q_WS_X11
+ Q_D(QMenuBar);
+ d->platformMenuBar->setVisible(visible);
+#else
#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
if (isNativeMenuBar()) {
if (!visible)
@@ -1080,6 +1117,7 @@ void QMenuBar::setVisible(bool visible)
}
#endif
QWidget::setVisible(visible);
+#endif // Q_WS_X11
}
/*!
@@ -1275,6 +1313,9 @@ void QMenuBar::actionEvent(QActionEvent *e)
{
Q_D(QMenuBar);
d->itemsDirty = true;
+#ifdef Q_WS_X11
+ d->platformMenuBar->actionEvent(e);
+#endif
#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
if (isNativeMenuBar()) {
#ifdef Q_WS_MAC
@@ -1287,7 +1328,7 @@ void QMenuBar::actionEvent(QActionEvent *e)
if (!nativeMenuBar)
return;
if(e->type() == QEvent::ActionAdded)
- nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before()));
+ nativeMenuBar->addAction(e->action(), e->before());
else if(e->type() == QEvent::ActionRemoved)
nativeMenuBar->removeAction(e->action());
else if(e->type() == QEvent::ActionChanged)
@@ -1369,6 +1410,10 @@ void QMenuBarPrivate::handleReparent()
newWindow->installEventFilter(q);
}
+#ifdef Q_WS_X11
+ platformMenuBar->handleReparent(oldParent, newParent, oldWindow, newWindow);
+#endif
+
oldParent = newParent;
oldWindow = newWindow;
@@ -1566,6 +1611,11 @@ bool QMenuBar::event(QEvent *e)
bool QMenuBar::eventFilter(QObject *object, QEvent *event)
{
Q_D(QMenuBar);
+#ifdef Q_WS_X11
+ if (d->platformMenuBar->menuBarEventFilter(object, event)) {
+ return true;
+ }
+#endif
if (object == parent() && object) {
#ifdef QT3_SUPPORT
if (d->doAutoResize && event->type() == QEvent::Resize) {
@@ -1659,7 +1709,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const
QSize QMenuBar::minimumSizeHint() const
{
Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
@@ -1682,6 +1732,9 @@ QSize QMenuBar::minimumSizeHint() const
ret += QSize(2*fw + hmargin, 2*fw + vmargin);
}
int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+#ifdef Q_WS_X11
+ if (d->platformMenuBar->allowCornerWidgets()) {
+#endif
if(d->leftWidget) {
QSize sz = d->leftWidget->minimumSizeHint();
ret.setWidth(ret.width() + sz.width());
@@ -1694,6 +1747,9 @@ QSize QMenuBar::minimumSizeHint() const
if(sz.height() + margin > ret.height())
ret.setHeight(sz.height() + margin);
}
+#ifdef Q_WS_X11
+ }
+#endif
if(as_gui_menubar) {
QStyleOptionMenuItem opt;
opt.rect = rect();
@@ -1715,7 +1771,7 @@ QSize QMenuBar::minimumSizeHint() const
QSize QMenuBar::sizeHint() const
{
Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
@@ -1741,6 +1797,9 @@ QSize QMenuBar::sizeHint() const
ret += QSize(fw + hmargin, fw + vmargin);
}
int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+#ifdef Q_WS_X11
+ if(d->platformMenuBar->allowCornerWidgets()) {
+#endif
if(d->leftWidget) {
QSize sz = d->leftWidget->sizeHint();
ret.setWidth(ret.width() + sz.width());
@@ -1753,6 +1812,9 @@ QSize QMenuBar::sizeHint() const
if(sz.height() + margin > ret.height())
ret.setHeight(sz.height() + margin);
}
+#ifdef Q_WS_X11
+ }
+#endif
if(as_gui_menubar) {
QStyleOptionMenuItem opt;
opt.rect = rect();
@@ -1774,7 +1836,7 @@ QSize QMenuBar::sizeHint() const
int QMenuBar::heightForWidth(int) const
{
Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
@@ -1794,10 +1856,16 @@ int QMenuBar::heightForWidth(int) const
height += 2*vmargin;
}
int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+#ifdef Q_WS_X11
+ if(d->platformMenuBar->allowCornerWidgets()) {
+#endif
if(d->leftWidget)
height = qMax(d->leftWidget->sizeHint().height() + margin, height);
if(d->rightWidget)
height = qMax(d->rightWidget->sizeHint().height() + margin, height);
+#ifdef Q_WS_X11
+ }
+#endif
if(as_gui_menubar) {
QStyleOptionMenuItem opt;
opt.init(this);
@@ -1817,7 +1885,15 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
{
Q_Q(QMenuBar);
QAction *act = actions.at(id);
- setCurrentAction(act, true, true);
+#ifdef Q_WS_X11
+ if (q->isNativeMenuBar()) {
+ platformMenuBar->popupAction(act);
+ } else {
+#endif
+ setCurrentAction(act, true, true);
+#ifdef Q_WS_X11
+ }
+#endif
if (act && !act->menu()) {
activateAction(act, QAction::Trigger);
//100 is the same as the default value in QPushButton::animateClick
@@ -1838,6 +1914,39 @@ void QMenuBarPrivate::_q_updateLayout()
}
}
+#ifdef Q_WS_X11
+void QMenuBarPrivate::updateCornerWidgetToolBar()
+{
+ Q_Q(QMenuBar);
+ if (!cornerWidgetToolBar) {
+ QMainWindow *window = qobject_cast<QMainWindow *>(q->window());
+ if (!window) {
+ qWarning() << "Menubar parent is not a QMainWindow, not showing corner widgets";
+ return;
+ }
+ cornerWidgetToolBar = window->addToolBar(QApplication::translate("QMenuBar", "Corner Toolbar"));
+ cornerWidgetToolBar->setObjectName(QLatin1String("CornerToolBar"));
+ cornerWidgetContainer = new QWidget;
+ cornerWidgetToolBar->addWidget(cornerWidgetContainer);
+ new QHBoxLayout(cornerWidgetContainer);
+ } else {
+ QLayout *layout = cornerWidgetContainer->layout();
+ while (layout->count() > 0) {
+ layout->takeAt(0);
+ }
+ }
+ if (leftWidget) {
+ leftWidget->setParent(cornerWidgetContainer);
+ cornerWidgetContainer->layout()->addWidget(leftWidget);
+ }
+ if (rightWidget) {
+ rightWidget->setParent(cornerWidgetContainer);
+ cornerWidgetContainer->layout()->addWidget(rightWidget);
+ }
+}
+#endif
+
+
/*!
\fn void QMenuBar::setCornerWidget(QWidget *widget, Qt::Corner corner)
@@ -1870,10 +1979,18 @@ void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner)
return;
}
+#ifdef Q_WS_X11
+ if(!d->platformMenuBar->allowCornerWidgets()) {
+ d->updateCornerWidgetToolBar();
+ } else {
+#endif
if (w) {
w->setParent(this);
w->installEventFilter(this);
}
+#ifdef Q_WS_X11
+ }
+#endif
d->_q_updateLayout();
}
@@ -1923,6 +2040,9 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
{
Q_D(QMenuBar);
+#ifdef Q_WS_X11
+ d->platformMenuBar->setNativeMenuBar(nativeMenuBar);
+#else
if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
d->nativeMenuBar = nativeMenuBar;
#ifdef Q_WS_MAC
@@ -1947,15 +2067,20 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
setVisible(true);
#endif
}
+#endif // Q_WS_X11
}
bool QMenuBar::isNativeMenuBar() const
{
Q_D(const QMenuBar);
+#ifdef Q_WS_X11
+ return d->platformMenuBar->isNativeMenuBar();
+#else
if (d->nativeMenuBar == -1) {
return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
}
return d->nativeMenuBar;
+#endif
}
/*!
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index 1ac694e..9a1f758 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -47,7 +47,7 @@
// -------------
//
// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
+// platformMenuBarementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
@@ -61,6 +61,10 @@
#include "qguifunctions_wince.h"
#endif
+#ifdef Q_WS_X11
+#include "qabstractplatformmenubar_p.h"
+#endif
+
#ifndef QT_NO_MENUBAR
#ifdef Q_WS_S60
class CCoeControl;
@@ -71,21 +75,27 @@ class CEikMenuBar;
QT_BEGIN_NAMESPACE
#ifndef QT_NO_MENUBAR
+class QToolBar;
class QMenuBarExtension;
class QMenuBarPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMenuBar)
public:
QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0),
- closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0),
- nativeMenuBar(-1), doChildEffects(false)
+ closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0)
+#ifndef Q_WS_X11
+ , nativeMenuBar(-1)
+#endif
+ , doChildEffects(false)
#ifdef QT3_SUPPORT
, doAutoResize(false)
#endif
#ifdef Q_WS_MAC
, mac_menubar(0)
#endif
-
+#ifdef Q_WS_X11
+ , platformMenuBar(0)
+#endif
#ifdef Q_WS_WINCE
, wce_menubar(0), wceClassicMenu(false)
#endif
@@ -96,6 +106,9 @@ public:
{ }
~QMenuBarPrivate()
{
+#ifdef Q_WS_X11
+ delete platformMenuBar;
+#endif
#ifdef Q_WS_MAC
delete mac_menubar;
#endif
@@ -136,8 +149,9 @@ public:
uint keyboardState : 1, altPressed : 1;
QPointer<QWidget> keyboardFocusWidget;
-
+#ifndef Q_WS_X11
int nativeMenuBar : 3; // Only has values -1, 0, and 1
+#endif
//firing of events
void activateAction(QAction *, QAction::ActionEvent);
@@ -173,6 +187,9 @@ public:
#ifdef QT3_SUPPORT
bool doAutoResize;
#endif
+#ifdef Q_WS_X11
+ QAbstractPlatformMenuBar *platformMenuBar;
+#endif
#ifdef Q_WS_MAC
//mac menubar binding
struct QMacMenuBarPrivate {
@@ -181,7 +198,7 @@ public:
QMacMenuBarPrivate();
~QMacMenuBarPrivate();
- void addAction(QAction *, QMacMenuAction* =0);
+ void addAction(QAction *, QAction* =0);
void addAction(QMacMenuAction *, QMacMenuAction* =0);
void syncAction(QMacMenuAction *);
inline void syncAction(QAction *a) { syncAction(findAction(a)); }
@@ -220,7 +237,7 @@ public:
QWceMenuBarPrivate(QMenuBarPrivate *menubar);
~QWceMenuBarPrivate();
- void addAction(QAction *, QWceMenuAction* =0);
+ void addAction(QAction *, QAction* =0);
void addAction(QWceMenuAction *, QWceMenuAction* =0);
void syncAction(QWceMenuAction *);
inline void syncAction(QAction *a) { syncAction(findAction(a)); }
@@ -250,7 +267,7 @@ public:
QMenuBarPrivate *d;
QSymbianMenuBarPrivate(QMenuBarPrivate *menubar);
~QSymbianMenuBarPrivate();
- void addAction(QAction *, QSymbianMenuAction* =0);
+ void addAction(QAction *, QAction* =0);
void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
void syncAction(QSymbianMenuAction *);
inline void syncAction(QAction *a) { syncAction(findAction(a)); }
@@ -273,6 +290,12 @@ public:
#ifdef QT_SOFTKEYS_ENABLED
QAction *menuBarAction;
#endif
+
+#ifdef Q_WS_X11
+ void updateCornerWidgetToolBar();
+ QToolBar *cornerWidgetToolBar;
+ QWidget *cornerWidgetContainer;
+#endif
};
#endif
diff --git a/src/gui/widgets/qmenubar_x11.cpp b/src/gui/widgets/qmenubar_x11.cpp
new file mode 100644
index 0000000..25336d4
--- /dev/null
+++ b/src/gui/widgets/qmenubar_x11.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmenubar_x11_p.h"
+
+#ifndef QT_NO_MENUBAR
+
+#include "qapplication.h"
+#include "qdebug.h"
+#include "qevent.h"
+#include "qmenu.h"
+#include "qmenubar.h"
+
+#include <private/qfactoryloader_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QX11MenuBar::~QX11MenuBar()
+{
+}
+
+void QX11MenuBar::init(QMenuBar *_menuBar)
+{
+ nativeMenuBar = -1;
+ menuBar = _menuBar;
+}
+
+void QX11MenuBar::setVisible(bool visible)
+{
+ menuBar->QWidget::setVisible(visible);
+}
+
+void QX11MenuBar::actionEvent(QActionEvent *e)
+{
+ Q_UNUSED(e);
+}
+
+void QX11MenuBar::handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow)
+{
+ Q_UNUSED(oldParent)
+ Q_UNUSED(newParent)
+ Q_UNUSED(oldWindow)
+ Q_UNUSED(newWindow)
+}
+
+bool QX11MenuBar::allowCornerWidgets() const
+{
+ return true;
+}
+
+void QX11MenuBar::popupAction(QAction *)
+{
+}
+
+void QX11MenuBar::setNativeMenuBar(bool value)
+{
+ if (nativeMenuBar == -1 || (value != bool(nativeMenuBar))) {
+ nativeMenuBar = value;
+ }
+}
+
+bool QX11MenuBar::isNativeMenuBar() const
+{
+ return false;
+}
+
+bool QX11MenuBar::shortcutsHandledByNativeMenuBar() const
+{
+ return false;
+}
+
+bool QX11MenuBar::menuBarEventFilter(QObject *, QEvent *)
+{
+ return false;
+}
+
+struct QX11MenuBarFactory : public QPlatformMenuBarFactoryInterface
+{
+ QAbstractPlatformMenuBar *create() { return new QX11MenuBar; }
+ virtual QStringList keys() const { return QStringList(); }
+};
+
+QPlatformMenuBarFactoryInterface *qt_guiPlatformMenuBarFactory()
+{
+ static QPlatformMenuBarFactoryInterface *factory = 0;
+ if (!factory) {
+#ifndef QT_NO_LIBRARY
+ QFactoryLoader loader(QPlatformMenuBarFactoryInterface_iid, QLatin1String("/menubar"));
+ factory = qobject_cast<QPlatformMenuBarFactoryInterface *>(loader.instance(QLatin1String("default")));
+#endif // QT_NO_LIBRARY
+ if(!factory) {
+ static QX11MenuBarFactory def;
+ factory = &def;
+ }
+ }
+ return factory;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MENUBAR
diff --git a/src/gui/widgets/qmenubar_x11_p.h b/src/gui/widgets/qmenubar_x11_p.h
new file mode 100644
index 0000000..41debd0
--- /dev/null
+++ b/src/gui/widgets/qmenubar_x11_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QX11MENUBAR_P_H
+#define QX11MENUBAR_P_H
+
+#ifndef QT_NO_MENUBAR
+
+#include "qabstractplatformmenubar_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMenuBar;
+
+class QX11MenuBar : public QAbstractPlatformMenuBar
+{
+public:
+ ~QX11MenuBar();
+
+ virtual void init(QMenuBar *);
+
+ virtual void setVisible(bool visible);
+
+ virtual void actionEvent(QActionEvent *e);
+
+ virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow);
+
+ virtual bool allowCornerWidgets() const;
+
+ virtual void popupAction(QAction*);
+
+ virtual void setNativeMenuBar(bool);
+ virtual bool isNativeMenuBar() const;
+
+ virtual bool shortcutsHandledByNativeMenuBar() const;
+ virtual bool menuBarEventFilter(QObject *, QEvent *event);
+
+private:
+ QMenuBar *menuBar;
+ int nativeMenuBar : 3; // Only has values -1, 0, and 1
+};
+
+QPlatformMenuBarFactoryInterface *qt_guiPlatformMenuBarFactory();
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MENUBAR
+
+#endif /* QX11MENUBAR_P_H */
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index 2670089..61d4fed 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -2472,6 +2472,8 @@ bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
and the text edit will try to guess the right format.
Use setHtml() or setPlainText() directly to avoid text edit's guessing.
+
+ \sa toPlainText(), toHtml()
*/
void QTextEdit::setText(const QString &text)
{
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
index 669b838..6b3d6a9 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -144,6 +144,14 @@ SOURCES += \
widgets/qplaintextedit.cpp \
widgets/qprintpreviewwidget.cpp
+x11: {
+ HEADERS += \
+ widgets/qabstractplatformmenubar_p.h
+
+ SOURCES += \
+ widgets/qmenubar_x11.cpp
+}
+
!embedded:!qpa:mac {
HEADERS += widgets/qmacnativewidget_mac.h \
widgets/qmaccocoaviewcontainer_mac.h