diff options
author | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2011-09-28 11:55:00 (GMT) |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2011-09-28 11:55:00 (GMT) |
commit | d81ddfd44455c79d0a44ab1caf29939b287dd895 (patch) | |
tree | 9b4383c5c23b405170ff9b2b5edb6762165828bb /src/gui | |
parent | 89ae1ec634f82f89e97f3e19b5d5fb0da9b3092f (diff) | |
parent | c75aabbb022e3c2db246e2fd90a36662cf28ec24 (diff) | |
download | Qt-d81ddfd44455c79d0a44ab1caf29939b287dd895.zip Qt-d81ddfd44455c79d0a44ab1caf29939b287dd895.tar.gz Qt-d81ddfd44455c79d0a44ab1caf29939b287dd895.tar.bz2 |
Merge remote-tracking branch 'mainline/4.8'
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/accessible/qaccessible_win.cpp | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 9 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 36 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 4 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 16 | ||||
-rw-r--r-- | src/gui/image/qpixmapfilter.cpp | 12 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_p.h | 50 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 567 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_s60.cpp | 22 | ||||
-rw-r--r-- | src/gui/styles/qs60style.cpp | 66 | ||||
-rw-r--r-- | src/gui/styles/qs60style_s60.cpp | 28 | ||||
-rw-r--r-- | src/gui/text/qrawfont.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 12 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 10 | ||||
-rw-r--r-- | src/gui/util/qdesktopservices.cpp | 3 | ||||
-rw-r--r-- | src/gui/widgets/qlabel.cpp | 8 |
17 files changed, 735 insertions, 114 deletions
diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp index caabae5..1fd1bfd 100644 --- a/src/gui/accessible/qaccessible_win.cpp +++ b/src/gui/accessible/qaccessible_win.cpp @@ -1316,7 +1316,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIAN (*pvarState).vt = VT_I4; AccessibleElement elem(varID.lVal, accessible); - (*pvarState).lVal = elem.iface ? elem.iface->state(elem.entry) : 0; + (*pvarState).lVal = elem.iface ? elem.iface->state(elem.entry) : State(Normal); return S_OK; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index eaa8ac2..deda3ff 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2966,11 +2966,12 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint AnchorData *ad = variables.at(i); ad->sizeAtPreferred = ad->result - g_offset; } - - // Make sure we delete the simplex solver -before- we delete the - // constraints used by it. - delete simplex; } + + // Make sure we delete the simplex solver -before- we delete the + // constraints used by it. + delete simplex; + // Delete constraints and variables we created. qDeleteAll(preferredConstraints); qDeleteAll(preferredVariables); 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..c275968 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -152,7 +152,7 @@ QT_BEGIN_NAMESPACE \row \o Qt::WA_SetPalette \o Set by setPalette(). \row \o Qt::WA_SetFont - \o Set by setPalette(). + \o Set by setFont(). \row \o Qt::WA_WindowPropagation \o Enables propagation to window widgets. \endtable @@ -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; } @@ -1668,7 +1674,7 @@ void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::GrabMouse events. + receive notifications for QEvent::GrabMouse events. \sa grabMouse(), grabKeyboard() */ @@ -1679,7 +1685,7 @@ void QGraphicsWidget::grabMouseEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::UngrabMouse events. + receive notifications for QEvent::UngrabMouse events. \sa ungrabMouse(), ungrabKeyboard() */ @@ -1690,7 +1696,7 @@ void QGraphicsWidget::ungrabMouseEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::GrabKeyboard events. + receive notifications for QEvent::GrabKeyboard events. \sa grabKeyboard(), grabMouse() */ @@ -1701,7 +1707,7 @@ void QGraphicsWidget::grabKeyboardEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::UngrabKeyboard events. + receive notifications for QEvent::UngrabKeyboard events. \sa ungrabKeyboard(), ungrabMouse() */ diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index a33e173..6c03990 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -1362,16 +1362,14 @@ void QPixmapDropShadowFilter::draw(QPainter *p, qt_blurImage(&blurPainter, tmp, d->radius, false, true); blurPainter.end(); - tmp = blurred; - // blacken the image... - tmpPainter.begin(&tmp); - tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); - tmpPainter.fillRect(tmp.rect(), d->color); - tmpPainter.end(); + QPainter blackenPainter(&blurred); + blackenPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); + blackenPainter.fillRect(blurred.rect(), d->color); + blackenPainter.end(); // draw the blurred drop shadow... - p->drawImage(pos, tmp); + p->drawImage(pos, blurred); // Draw the actual pixmap... p->drawPixmap(pos, px, src); diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 8c30838..8ef9726 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -63,13 +63,36 @@ #include <fepbase.h> #include <aknedsts.h> +#include <eikccpu.h> QT_BEGIN_NAMESPACE +class QCoeFepInputMaskHandler +{ +public: + QCoeFepInputMaskHandler(const QString &mask); + ~QCoeFepInputMaskHandler(); + bool canPasteClipboard(const QString &text); +private: + bool isValidInput(QChar key, QChar mask) const; +private: + struct MaskInputData { + enum Casemode { NoCaseMode, Upper, Lower }; + QChar maskChar; + bool separator; + Casemode caseMode; + }; + int m_maxLength; + QChar m_blank; + MaskInputData *m_maskData; +}; + class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, - public MObjectProvider + public MObjectProvider, + public MEikCcpuEditor + { Q_OBJECT @@ -135,6 +158,25 @@ private: void DoCommitFepInlineEditL(); MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue); void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType); + void enableSymbianCcpuSupport(); + void changeCBA(bool showCopyAndOrPaste); + void copyOrCutTextToClipboard(const char *operation); + + //From MEikCcpuEditor interface +public: + TBool CcpuIsFocused() const; + TBool CcpuCanCut() const; + void CcpuCutL(); + TBool CcpuCanCopy() const; + void CcpuCopyL(); + TBool CcpuCanPaste() const; + void CcpuPasteL(); + TBool CcpuCanUndo() const; + void CcpuUndoL(); + +private slots: + void copy(); + void paste(); // From MCoeFepAwareTextEditor_Extension1 public: @@ -167,6 +209,12 @@ private: Qt::WindowStates m_splitViewPreviousWindowStates; QRectF m_transformation; + CAknCcpuSupport *m_ccpu; + QAction *m_copyAction; + QAction *m_pasteAction; + QPointer<QWidget> m_lastFocusedEditor; + QPointer<QObject> m_lastFocusedObject; + friend class tst_QInputContext; }; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 56338b2..9025221 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -57,6 +57,21 @@ #include <e32property.h> #include <limits.h> + +#include <eikccpu.h> +#include <aknedsts.h> +#include <coeinput.h> +#include <w32std.h> +#include <akndiscreetpopup.h> + +#include <qtextedit.h> +#include <qplaintextedit.h> +#include <qlineedit.h> +#include <qclipboard.h> +#include <qvalidator.h> +#include <qgraphicsproxywidget.h> +#include <qgraphicsitem.h> + // You only find these enumerations on SDK 5 onwards, so we need to provide our own // to remain compatible with older releases. They won't be called by pre-5.0 SDKs. @@ -79,8 +94,253 @@ #define QT_EPSUidAknFep 0x100056de #define QT_EAknFepTouchInputActive 0x00000004 +_LIT(KAvkonResourceFile, "z:\\resource\\avkon.rsc" ); + QT_BEGIN_NAMESPACE +static QWidget* getFocusedChild(const QList<QObject*>& objectList) +{ + for (int j = 0; j < objectList.count(); j++) { + if (QWidget* ow = qobject_cast<QWidget *>(objectList[j])) { + if (ow->hasFocus()) { + return ow; + } else { + if (QWidget* rw = getFocusedChild(ow->children())) + return rw; + } + } + } + return 0; +} + +// A generic method for invoking "cut", "copy", and "paste" slots on editor +// All supported editors are expected to have these. +static bool ccpuInvokeSlot(QObject *obj, QObject *focusObject, const char *member) +{ + QObject *invokeTarget = obj; + if (focusObject) + invokeTarget = focusObject; + + return QMetaObject::invokeMethod(invokeTarget, member, Qt::DirectConnection); +} + +// focusObject is used to return a pointer to focused graphics object, if any +static QWidget *getQWidgetFromQGraphicsView(QWidget *widget, QObject **focusObject = 0) +{ + if (focusObject) + *focusObject = 0; + + if (!widget) + return 0; + + if (QGraphicsView* qgv = qobject_cast<QGraphicsView *>(widget)) { + QGraphicsItem *focusItem = 0; + if (qgv->scene()) + focusItem = qgv->scene()->focusItem(); + if (focusItem) { + if (focusObject) + *focusObject = focusItem->toGraphicsObject(); + if (QGraphicsProxyWidget* const qgpw = qgraphicsitem_cast<QGraphicsProxyWidget* const>(focusItem)) { + if (QWidget* w = qgpw->widget()) { + if (w->layout()) { + if (QWidget* rw = getFocusedChild(w->children())) + return rw; + } else { + return w; + } + } + } + } + } + return widget; +} + +QCoeFepInputMaskHandler::QCoeFepInputMaskHandler(const QString &mask) +{ + QString inputMask; + int delimiter = mask.indexOf(QLatin1Char(';')); + if (mask.isEmpty() || delimiter == 0) + return; + + if (delimiter == -1) { + m_blank = QLatin1Char(' '); + inputMask = mask; + } else { + inputMask = mask.left(delimiter); + m_blank = (delimiter + 1 < mask.length()) ? mask[delimiter + 1] : QLatin1Char(' '); + } + + // Calculate m_maxLength / m_maskData length + m_maxLength = 0; + QChar c = 0; + for (int i = 0; i < inputMask.length(); i++) { + c = inputMask.at(i); + if (i > 0 && inputMask.at(i - 1) == QLatin1Char('\\')) { + m_maxLength++; + continue; + } + if (c != QLatin1Char('\\') && c != QLatin1Char('!') + && c != QLatin1Char('<') && c != QLatin1Char('>') + && c != QLatin1Char('{') && c != QLatin1Char('}') + && c != QLatin1Char('[') && c != QLatin1Char(']')) { + m_maxLength++; + } + } + + m_maskData = new MaskInputData[m_maxLength]; + + MaskInputData::Casemode m = MaskInputData::NoCaseMode; + c = 0; + bool s = false; + bool escape = false; + int index = 0; + for (int i = 0; i < inputMask.length(); i++) { + c = inputMask.at(i); + if (escape) { + s = true; + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + escape = false; + } else if (c == QLatin1Char('<')) { + m = MaskInputData::Lower; + } else if (c == QLatin1Char('>')) { + m = MaskInputData::Upper; + } else if (c == QLatin1Char('!')) { + m = MaskInputData::NoCaseMode; + } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) { + switch (c.unicode()) { + case 'A': + case 'a': + case 'N': + case 'n': + case 'X': + case 'x': + case '9': + case '0': + case 'D': + case 'd': + case '#': + case 'H': + case 'h': + case 'B': + case 'b': + s = false; + break; + case '\\': + escape = true; + break; + default: + s = true; + break; + } + + if (!escape) { + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + } + } + } +} + +QCoeFepInputMaskHandler::~QCoeFepInputMaskHandler() +{ + if (m_maskData) + delete[] m_maskData; +} + +bool QCoeFepInputMaskHandler::canPasteClipboard(const QString &text) +{ + if (!m_maskData) + return true; + + if (text.length() > m_maxLength) + return false; + int limit = qMin(m_maxLength, text.length()); + for (int i = 0; i < limit; ++i) { + if (m_maskData[i].separator) { + if (text.at(i) != m_maskData[i].maskChar) + return false; + } else { + if (!isValidInput(text.at(i), m_maskData[i].maskChar)) + return false; + } + } + return true; +} + +bool QCoeFepInputMaskHandler::isValidInput(QChar key, QChar mask) const +{ + switch (mask.unicode()) { + case 'A': + if (key.isLetter()) + return true; + break; + case 'a': + if (key.isLetter() || key == m_blank) + return true; + break; + case 'N': + if (key.isLetterOrNumber()) + return true; + break; + case 'n': + if (key.isLetterOrNumber() || key == m_blank) + return true; + break; + case 'X': + if (key.isPrint()) + return true; + break; + case 'x': + if (key.isPrint() || key == m_blank) + return true; + break; + case '9': + if (key.isNumber()) + return true; + break; + case '0': + if (key.isNumber() || key == m_blank) + return true; + break; + case 'D': + if (key.isNumber() && key.digitValue() > 0) + return true; + break; + case 'd': + if ((key.isNumber() && key.digitValue() > 0) || key == m_blank) + return true; + break; + case '#': + if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank) + return true; + break; + case 'B': + if (key == QLatin1Char('0') || key == QLatin1Char('1')) + return true; + break; + case 'b': + if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank) + return true; + break; + case 'H': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F'))) + return true; + break; + case 'h': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank) + return true; + break; + default: + break; + } + return false; +} + Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) { S60->partial_keyboard = enable; @@ -116,7 +376,8 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_pointerHandler(0), m_hasTempPreeditString(false), m_splitViewResizeBy(0), - m_splitViewPreviousWindowStates(Qt::WindowNoState) + m_splitViewPreviousWindowStates(Qt::WindowNoState), + m_ccpu(0) { m_fepState->SetObjectProvider(this); int defaultFlags = EAknEditorFlagDefault; @@ -133,6 +394,29 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_fepState->SetPermittedCases( EAknEditorAllCaseModes ); m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap); + enableSymbianCcpuSupport(); + + //adding softkeys + QString copyLabel = QLatin1String("Copy"); + QString pasteLabel = QLatin1String("Paste"); + TRAP_IGNORE( + CEikonEnv* coe = CEikonEnv::Static(); + if (coe) { + HBufC* copyBuf = coe->AllocReadResourceLC(R_TEXT_SOFTKEY_COPY); + copyLabel = qt_TDesC2QString(*copyBuf); + CleanupStack::PopAndDestroy(copyBuf); + HBufC* pasteBuf = coe->AllocReadResourceLC(R_TEXT_SOFTKEY_PASTE); + pasteLabel = qt_TDesC2QString(*pasteBuf); + CleanupStack::PopAndDestroy(pasteBuf); + } + ) + + m_copyAction = new QAction(copyLabel, QApplication::desktop()); + m_pasteAction = new QAction(pasteLabel, QApplication::desktop()); + m_copyAction->setSoftKeyRole(QAction::PositiveSoftKey); + m_pasteAction->setSoftKeyRole(QAction::NegativeSoftKey); + connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copy())); + connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste())); } QCoeFepInputContext::~QCoeFepInputContext() @@ -145,8 +429,8 @@ QCoeFepInputContext::~QCoeFepInputContext() // but is synchronous, rather than asynchronous. CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus(); - if (m_fepState) - delete m_fepState; + delete m_fepState; + delete m_ccpu; } void QCoeFepInputContext::reset() @@ -347,6 +631,12 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl); Q_ASSERT(sControl); + // Store last focused widget and object in case of fullscreen VKB + QObject *focusObject = 0; + m_lastFocusedEditor = getQWidgetFromQGraphicsView(focusWidget(), &focusObject); + m_lastFocusedObject = focusObject; // Can be null + Q_ASSERT(m_lastFocusedEditor); + // The FEP UI temporarily steals focus when it shows up the first time, causing // all sorts of weird effects on the focused widgets. Since it will immediately give // back focus to us, we temporarily disable focus handling until the job's done. @@ -369,28 +659,66 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event) { Q_UNUSED(keyWidget); + if (event->type() == QSymbianEvent::WindowServerEvent) { + const TWsEvent* wsEvent = event->windowServerEvent(); + TInt eventType = 0; + if (wsEvent) + eventType = wsEvent->Type(); + + if (eventType == EEventKey) { + TKeyEvent* keyEvent = wsEvent->Key(); + if (keyEvent) { + switch (keyEvent->iScanCode) { + case EEikCmdEditCopy: + CcpuCopyL(); + break; + case EEikCmdEditCut: + CcpuCutL(); + break; + case EEikCmdEditPaste: + CcpuPasteL(); + break; + case EStdKeyF21: + changeCBA(true); + break; + default: + break; + } + switch (keyEvent->iCode) { + case EKeyLeftArrow: + case EKeyRightArrow: + case EKeyUpArrow: + case EKeyDownArrow: + if (CcpuCanCopy() && ((keyEvent->iModifiers & EModifierShift) == EModifierShift)) + changeCBA(true); + break; + default: + break; + } + } + } else if (eventType == EEventKeyUp) { + if (wsEvent->Key() && wsEvent->Key()->iScanCode == EStdKeyLeftShift) + changeCBA(false); + } else if (eventType == EEventWindowVisibilityChanged && S60->splitViewLastWidget) { + QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); + const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); + + if (alwaysResize) { + TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags; + if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible) + ensureFocusWidgetVisible(S60->splitViewLastWidget); + if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) + resetSplitViewWidget(true); + } + } + } + if (event->type() == QSymbianEvent::CommandEvent) // A command basically means the same as a button being pushed. With Qt buttons // that would normally result in a reset of the input method due to the focus change. // This should also happen for commands. reset(); - if (event->type() == QSymbianEvent::WindowServerEvent - && event->windowServerEvent() - && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged - && S60->splitViewLastWidget) { - - QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); - const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); - - if (alwaysResize) { - TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags; - if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible) - ensureFocusWidgetVisible(S60->splitViewLastWidget); - if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) - resetSplitViewWidget(true); - } - } if (event->type() == QSymbianEvent::ResourceChangeEvent && (event->resourceChangeType() == KEikMessageFadeAllWindows @@ -1231,6 +1559,71 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin aAscent = metrics.ascent(); } +void QCoeFepInputContext::enableSymbianCcpuSupport() +{ + if (!m_ccpu) { + QT_TRAP_THROWING( + m_ccpu = new (ELeave) CAknCcpuSupport(this); + m_ccpu->SetMopParent(this); + CleanupStack::PushL(m_ccpu); + m_ccpu->ConstructL(); + CleanupStack::Pop(m_ccpu); + ); + Q_ASSERT(m_fepState); + if (m_fepState) + m_fepState->SetCcpuState(this); + } +} + +void QCoeFepInputContext::changeCBA(bool showCopyAndOrPaste) +{ + QWidget *w = focusWidget(); + if (!w) + w = m_lastFocusedEditor; + + if (w) { + if (showCopyAndOrPaste) { + if (CcpuCanCopy()) + w->addAction(m_copyAction); + if (CcpuCanPaste()) + w->addAction(m_pasteAction); + } else { + w->removeAction(m_copyAction); + w->removeAction(m_pasteAction); + } + } +} + +void QCoeFepInputContext::copyOrCutTextToClipboard(const char *operation) +{ + bool hasText = false; + + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + + if (w) { + int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); + + if (cursor != anchor) { + if (ccpuInvokeSlot(w, focusObject, operation)) { + TRAP_IGNORE( + CAknDiscreetPopup::ShowGlobalPopupL( + R_AVKON_DISCREET_POPUP_TEXT_COPIED, + KAvkonResourceFile); + ) + } + } + } +} + + void QCoeFepInputContext::DoCommitFepInlineEditL() { commitCurrentString(false); @@ -1295,6 +1688,142 @@ MCoeFepAwareTextEditor_Extension1::CState* QCoeFepInputContext::State(TUid /*aTy return m_fepState; } +TBool QCoeFepInputContext::CcpuIsFocused() const +{ + return focusWidget() != 0; +} + +TBool QCoeFepInputContext::CcpuCanCut() const +{ + bool retval = false; + QWidget *w = focusWidget(); + if (!w) + w = m_lastFocusedEditor; + else + w = getQWidgetFromQGraphicsView(w); + if (w) { + int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); + retval = cursor != anchor; + } + return retval; +} + +void QCoeFepInputContext::CcpuCutL() +{ + copyOrCutTextToClipboard("cut"); +} + +TBool QCoeFepInputContext::CcpuCanCopy() const +{ + return CcpuCanCut(); +} + +void QCoeFepInputContext::CcpuCopyL() +{ + copyOrCutTextToClipboard("copy"); +} + +TBool QCoeFepInputContext::CcpuCanPaste() const +{ + bool canPaste = false; + QString textToPaste = QApplication::clipboard()->text(); + if (!textToPaste.isEmpty()) { + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + if (w) { + // First, check if we are dealing with standard Qt editors (QLineEdit, QTextEdit, or QPlainTextEdit), + // as they do not have queryable property. + if (QTextEdit* tedit = qobject_cast<QTextEdit *>(w)) { + canPaste = tedit->canPaste(); + } else if (QPlainTextEdit* ptedit = qobject_cast<QPlainTextEdit *>(w)) { + canPaste = ptedit->canPaste(); + } else if (QLineEdit* ledit = qobject_cast<QLineEdit *>(w)) { + QString fullText = ledit->text(); + if (ledit->hasSelectedText()) { + fullText.remove(ledit->selectionStart(), ledit->selectedText().length()); + fullText.insert(ledit->selectionStart(), textToPaste); + } else { + fullText.insert(ledit->cursorPosition(), textToPaste); + } + + if (fullText.length() > ledit->maxLength()) { + canPaste = false; + } else { + const QValidator* validator = ledit->validator(); + if (validator) { + int pos = 0; + if (validator->validate(fullText, pos) == QValidator::Invalid) + canPaste = false; + else + canPaste = true; + } else { + QString mask(ledit->inputMask()); + if (!mask.isEmpty()) { + QCoeFepInputMaskHandler maskhandler(mask); + if (maskhandler.canPasteClipboard(fullText)) + canPaste = true; + else + canPaste = false; + } else { + canPaste = true; + } + } + } + } else { + // Unknown editor (probably a QML one); Request the "canPaste" property. + QObject *invokeTarget = w; + if (focusObject) + invokeTarget = focusObject; + + canPaste = invokeTarget->property("canPaste").toBool(); + } + } + } + return canPaste; +} + +void QCoeFepInputContext::CcpuPasteL() +{ + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + if (w) + ccpuInvokeSlot(w, focusObject, "paste"); +} + +TBool QCoeFepInputContext::CcpuCanUndo() const +{ + //not supported + return EFalse; +} + +void QCoeFepInputContext::CcpuUndoL() +{ + //not supported +} + +void QCoeFepInputContext::copy() +{ + QT_TRAP_THROWING(CcpuCopyL()); +} + +void QCoeFepInputContext::paste() +{ + QT_TRAP_THROWING(CcpuPasteL()); +} + TTypeUid::Ptr QCoeFepInputContext::MopSupplyObject(TTypeUid /*id*/) { return TTypeUid::Null(); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 2b51aaa..e06b625 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -84,21 +84,6 @@ CEikButtonGroupContainer *QS60Data::cba = 0; int qt_symbian_create_desktop_on_screen = -1; -static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b) -{ - if ( a.count() != b.count()) - return false; - int index=0; - while (index<a.count()) { - if (a.at(index)->softKeyRole() != b.at(index)->softKeyRole()) - return false; - if (a.at(index)->text().compare(b.at(index)->text())!=0) - return false; - index++; - } - return true; -} - void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { // Note: based on x11 implementation @@ -231,7 +216,6 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QPoint oldPos(q->pos()); QSize oldSize(q->size()); - QRect oldGeom(data.crect); bool checkExtra = true; if (q->isWindow() && (data.window_state & (Qt::WindowFullScreen | Qt::WindowMaximized))) { @@ -348,11 +332,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de bool topLevel = (flags & Qt::Window); bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet - || (flags & Qt::MSWindowsFixedSizeDialogHint)); bool desktop = (type == Qt::Desktop); - //bool tool = (type == Qt::Tool || type == Qt::Drawer); if (popup) flags |= Qt::WindowStaysOnTopHint; // a popup stays on top @@ -1075,7 +1055,7 @@ void QWidgetPrivate::registerTouchWindow() int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); - int val; + int val = 0; if (m == PdmWidth) { val = data->crect.width(); } else if (m == PdmHeight) { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index e9f7a86..eec2d15 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -101,12 +101,9 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106,30,30}, -{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106,30,30}, -{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,3,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135,30,30}, -{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,3,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135,30,30}, -{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106,30,30}, -{9,0,-909,0,0,2,0,5,-1,30,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,2,2,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184,30,30} +{7,0,-909,0,0,2,5,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,3,3,6,8,19,-909,7,74,19,7,0,5,5,8,5,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135,30,30}, +{7,0,-909,0,0,2,5,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,3,3,6,8,19,-909,7,74,22,7,0,5,5,8,5,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135,30,30}, +{9,0,-909,0,0,2,5,5,-1,30,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,2,2,9,1,25,-909,9,101,24,9,0,7,7,7,7,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184,30,30} // *** End of generated data *** }; @@ -845,6 +842,7 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) webPalette.setColor(QPalette::WindowText, Qt::black); webPalette.setColor(QPalette::Text, Qt::black); webPalette.setBrush(QPalette::Base, Qt::white); + webPalette.setBrush(QPalette::Window, Qt::white); QApplication::setPalette(webPalette, "QWebView"); QApplication::setPalette(webPalette, "QGraphicsWebView"); @@ -1520,9 +1518,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (tabOverlap > borderThickness) tabOverlap -= borderThickness; - const bool usesScrollButtons = + const bool usesScrollButtons = (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false; - const int roomForScrollButton = + const int roomForScrollButton = usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0; // adjust for overlapping tabs and scrollbuttons, if necessary @@ -1563,9 +1561,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, int tabOverlap = pixelMetric(PM_TabBarTabOverlap); if (tabOverlap > borderThickness) tabOverlap -= borderThickness; - const bool usesScrollButtons = + const bool usesScrollButtons = (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false; - const int roomForScrollButton = + const int roomForScrollButton = usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0; switch (tab->shape) { @@ -1771,7 +1769,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, //highlight and then it needs one to separate it whatever is shown after it (text/icon/both). const int moveByX = optionCheckBox.rect.width() + 2 * vSpacing; optionCheckBox.rect.moveCenter(QPoint( - optionCheckBox.rect.center().x() + moveByX >> 1, + optionCheckBox.rect.center().x() + moveByX >> 1, menuItem->rect.center().y())); if (optionMenuItem.direction != Qt::LeftToRight) @@ -1785,11 +1783,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const int end = optionMenuItem.rect.right() - spacing; //-1 adjustment to avoid highlight being on top of possible separator item const QRect highlightRect = QRect( - QPoint(start, option->rect.top()), + QPoint(start, option->rect.top()), QPoint(end, option->rect.bottom() - 1)); QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); } - + if (checkable && !ignoreCheckMark) drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); @@ -2072,8 +2070,8 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) && (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget)))) QS60StylePrivate::drawSkinElement( - QS60StylePrivate::isWidgetPressed(widget) ? - QS60StylePrivate::SE_ListItemPressed : + QS60StylePrivate::isWidgetPressed(widget) ? + QS60StylePrivate::SE_ListItemPressed : QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); } else { commonStyleDraws = true; @@ -2506,11 +2504,13 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin); } - if (widget && (metric == PM_LayoutTopMargin || metric == PM_LayoutLeftMargin || metric == PM_LayoutRightMargin)) - if (widget->windowType() == Qt::Dialog) - //double the layout margins (except bottom) for dialogs, it is very close to real value + if (widget && (metric == PM_LayoutTopMargin || metric == PM_LayoutBottomMargin + || metric == PM_LayoutRightMargin || metric == PM_LayoutLeftMargin)) + if (widget->windowType() == Qt::Dialog) { + //double the layout margins for dialogs, it is very close to real value //without having to define custom pixel metric metricValue *= 2; + } #if defined(Q_WS_S60) if (metric == PM_TabBarTabOverlap && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_2)) @@ -2537,13 +2537,17 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, //Make toolbuttons in toolbar stretch the whole screen area if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) { const QToolBar *tb = qobject_cast<const QToolBar *>(widget->parentWidget()); - const bool parentCanGrowHorizontally = !(tb->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed || - tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) && tb->orientation() == Qt::Horizontal; + bool parentCanGrowHorizontally = false; + if (tb) { + parentCanGrowHorizontally = !(tb->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed + || tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) + && tb->orientation() == Qt::Horizontal; + } if (parentCanGrowHorizontally) { int buttons = 0; //Make the auto-stretch to happen only for horizontal orientation - if (tb && tb->orientation() == Qt::Horizontal) { + if (tb->orientation() == Qt::Horizontal) { QList<QAction*> actionList = tb->actions(); for (int i = 0; i < actionList.count(); i++) { buttons++; @@ -2603,7 +2607,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, break; case CT_LineEdit: if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) - sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); + sz += QSize(2 * f->lineWidth, 4 * f->lineWidth + 2 * pixelMetric(PM_FocusFrameHMargin)); break; case CT_TabBarTab: { sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); @@ -2648,6 +2652,12 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, } break; #endif +#ifndef QT_NO_SPINBOX + case CT_SpinBox: + // Add margin to the spinbox height + sz.setHeight(sz.height() + 2 * pixelMetric(PM_SpinBoxFrameWidth)); + break; +#endif default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; @@ -2821,7 +2831,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple // Thus, side-by-side buttons would take half of the total width. const int maxSize = qMax(spinbox->rect.width() / 4, buttonContentWidth); QSize buttonSize; - buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - frameThickness))); + buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - 2 * frameThickness))); //width should at least be equal to height buttonSize.setWidth(qMax(buttonSize.height(), buttonContentWidth)); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); @@ -2829,9 +2839,9 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple // Normally spinbuttons should be side-by-side, but if spinbox grows very big // and spinbuttons reach their maximum size, they can be deployed one top of the other. const bool sideBySide = (buttonSize.height() * 2 < spinbox->rect.height()) ? false : true; - const int y = frameThickness + spinbox->rect.y() + + const int y = spinbox->rect.y() + (spinbox->rect.height() - (sideBySide ? 1 : 2) * buttonSize.height()) / 2; - const int x = spinbox->rect.x() + + const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - (sideBySide ? 2 : 1) * buttonSize.width(); switch (scontrol) { @@ -2843,8 +2853,8 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x + (sideBySide ? buttonSize.width() : 0), - y + (sideBySide ? 0 : buttonSize.height()), + ret = QRect(x + (sideBySide ? buttonSize.width() : 0), + y + (sideBySide ? 0 : buttonSize.height()), buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: @@ -3778,7 +3788,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QS60StylePrivate::SkinElementFlags flags = adjustedFlags; const int iconDimension = QS60StylePrivate::pixelMetric(metric); - const QRect iconSize = (!option) ? + const QRect iconSize = (!option) ? QRect(0, 0, iconDimension * iconWidthMultiplier, iconDimension * iconHeightMultiplier) : option->rect; const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), 0, flags)); return cachedPixMap.isNull() ? diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 33619d6..cfb10fa 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -110,7 +110,7 @@ typedef struct { TDrawType drawType; // Determines which native drawing routine is used to draw this item. int supportInfo; // Defines the S60 versions that use the default graphics. // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases. - // In general, these are given in numeric form to allow style compilation in earlier + // In general, these are given in numeric form to allow style compilation in earlier // native releases that do not contain the new graphics. int newMajorSkinId; int newMinorSkinId; @@ -929,6 +929,16 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( fallbackGraphicID , fallbackGraphicsMaskID); + // If drawing fails, re-try without a mask. + if (!icon) { + AknsUtils::CreateIconL( + skinInstance, + skinId, + icon, + (fallbackGraphicID != KErrNotFound ? AknIconUtils::AvkonIconFileName() : KNullDesC), + fallbackGraphicID); + } + result = fromFbsBitmap(icon, iconMask, flags, targetSize); delete icon; delete iconMask; @@ -961,17 +971,22 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( targetSize, drawParam); - if (drawn) + if (drawn) { result = fromFbsBitmap(background, NULL, flags, targetSize); - // if drawing fails in skin server, just ignore the background (probably OOM case) + } else { + // if drawing fails in skin server, draw background as white + QPixmap defaultBg = QPixmap(targetSize.iWidth, targetSize.iHeight); + defaultBg.fill(Qt::white); + result = defaultBg; + } CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext // QS60WindowSurface::lockBitmapHeap(); break; } case EDrawAnimation: { - CFbsBitmap* animationFrame; - CFbsBitmap* frameMask; + CFbsBitmap* animationFrame = 0; + CFbsBitmap* frameMask = 0; CAknBitmapAnimation* aknAnimation = 0; TBool constructedFromTheme = ETrue; @@ -1225,6 +1240,9 @@ TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameEl bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease) { + if (supportedRelease == ES60_All) + return true; + const QSysInfo::S60Version currentRelease = QSysInfo::s60Version(); return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) || (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) || diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 61bc63e..7c7d4eb 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -238,7 +238,8 @@ 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() */ diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 4886006..2fc1dbd 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1386,6 +1386,7 @@ QTextEngine::~QTextEngine() if (!stackEngine) delete layoutData; delete specialData; + resetFontEngineCache(); } const HB_CharAttributes *QTextEngine::attributes() const @@ -1446,6 +1447,13 @@ static inline void releaseCachedFontEngine(QFontEngine *fontEngine) } } +void QTextEngine::resetFontEngineCache() +{ + releaseCachedFontEngine(feCache.prevFontEngine); + releaseCachedFontEngine(feCache.prevScaledFontEngine); + feCache.reset(); +} + void QTextEngine::invalidate() { freeMemory(); @@ -1454,9 +1462,7 @@ void QTextEngine::invalidate() if (specialData) specialData->resolvedFormatIndices.clear(); - releaseCachedFontEngine(feCache.prevFontEngine); - releaseCachedFontEngine(feCache.prevScaledFontEngine); - feCache.reset(); + resetFontEngineCache(); } void QTextEngine::clearLineData() diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 0a86886..9362022 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -629,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/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 4595ef5..a86cf05 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(); } /*! @@ -2507,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); @@ -2609,6 +2612,9 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const x += eng->offsetInLigature(si, pos, end, glyph_pos); } + if (eng->option.wrapMode() != QTextOption::NoWrap && x > line.width) + x = line.width; + *cursorPos = pos + si->position; return x.toReal(); } diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index e79819e..05a1292 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -177,6 +177,9 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) Unicode-aware, the user may have configured their client without these features. Also, certain e-mail clients (e.g., Lotus Notes) have problems with long URLs. + \note On Symbian OS, \c SwEvent capability is required to open the given \a url + if the Web browser is already running. + \sa setUrlHandler() */ bool QDesktopServices::openUrl(const QUrl &url) diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index ab88f38..c0be3e1 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -59,6 +59,10 @@ #include <qaccessible.h> #endif +#ifdef Q_OS_SYMBIAN +#include "qt_s60_p.h" +#endif + QT_BEGIN_NAMESPACE /*! @@ -698,7 +702,11 @@ QSize QLabelPrivate::sizeForWidth(int w) const bool tryWidth = (w < 0) && (align & Qt::TextWordWrap); if (tryWidth) +#ifdef Q_OS_SYMBIAN + w = qMin(S60->clientRect().Width(), q->maximumSize().width()); +#else w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width()); +#endif else if (w < 0) w = 2000; w -= (hextra + contentsMargin.width()); |