diff options
Diffstat (limited to 'src/gui')
24 files changed, 541 insertions, 120 deletions
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 96fe91c..8f6d9d9 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -310,7 +310,8 @@ namespace QAccessible2 TextInterface, EditableTextInterface, ValueInterface, - TableInterface + TableInterface, + ActionInterface }; } @@ -319,6 +320,7 @@ class QAccessibleTextInterface; class QAccessibleEditableTextInterface; class QAccessibleValueInterface; class QAccessibleTableInterface; +class QAccessibleActionInterface; class Q_GUI_EXPORT QAccessibleInterface : public QAccessible { @@ -376,6 +378,9 @@ public: inline QAccessibleTableInterface *tableInterface() { return reinterpret_cast<QAccessibleTableInterface *>(cast_helper(QAccessible2::TableInterface)); } + inline QAccessibleActionInterface *actionInterface() + { return reinterpret_cast<QAccessibleActionInterface *>(cast_helper(QAccessible2::ActionInterface)); } + private: QAccessible2Interface *cast_helper(QAccessible2::InterfaceType); }; diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp index f731962..0867368 100644 --- a/src/gui/accessible/qaccessible2.cpp +++ b/src/gui/accessible/qaccessible2.cpp @@ -108,6 +108,18 @@ QT_BEGIN_NAMESPACE \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink */ +/*! + \class QAccessibleActionInterface + \ingroup accessibility + \internal + \preliminary + + \brief The QAccessibleActionInterface class implements support for + the IAccessibleAction interface. + + \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink +*/ + QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface( QAccessibleInterface *accessibleInterface) : iface(accessibleInterface) diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 3281509..435c640 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -81,6 +81,7 @@ inline QAccessible2Interface *qAccessibleValueCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleTextCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; } +inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; } #define Q_ACCESSIBLE_OBJECT \ public: \ @@ -95,6 +96,8 @@ inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; } return qAccessibleValueCastHelper(); \ case QAccessible2::TableInterface: \ return qAccessibleTableCastHelper(); \ + case QAccessible2::ActionInterface: \ + return qAccessibleActionCastHelper(); \ } \ return 0; \ } \ @@ -208,6 +211,19 @@ public: int *columnSpan, bool *isSelected) = 0; }; +class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface +{ +public: + inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; } + + virtual int actionCount() = 0; + virtual void doAction(int actionIndex) = 0; + virtual QString description(int actionIndex) = 0; + virtual QString name(int actionIndex) = 0; + virtual QString localizedName(int actionIndex) = 0; + virtual QStringList keyBindings(int actionIndex) = 0; +}; + #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index b59c28b..8089b43 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -251,10 +251,10 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, ofn->nMaxFile = maxLen; ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16(); ofn->lpstrTitle = (wchar_t*)tTitle.utf16(); - ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER); + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST); if (mode == QFileDialog::ExistingFile || mode == QFileDialog::ExistingFiles) - ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); + ofn->Flags |= (OFN_FILEMUSTEXIST); if (mode == QFileDialog::ExistingFiles) ofn->Flags |= (OFN_ALLOWMULTISELECT); if (!(options & QFileDialog::DontConfirmOverwrite)) diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp index 8ee417f..ea6ed35 100644 --- a/src/gui/inputmethod/qinputcontext.cpp +++ b/src/gui/inputmethod/qinputcontext.cpp @@ -467,32 +467,32 @@ bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/) } #endif // Q_WS_X11 -#ifdef Q_WS_S60 +#ifdef Q_OS_SYMBIAN /*! \since 4.6 This function may be overridden only if input method is depending - on Symbian and you need raw TWsEvent. Otherwise, this function must not. + on Symbian and you need raw Symbian events. Otherwise, this function must not. - This function is designed to filter raw key events on S60, but + This function is designed to filter raw key events on Symbian, but other input methods may use this to implement some special features. Return true if the \a event has been consumed. Otherwise, the unfiltered \a event will be translated into QEvent and forwarded - to filterEvent(). Filtering at both s60FilterEvent() and + to filterEvent(). Filtering at both symbianFilterEvent() and filterEvent() in single input method is allowed. \a keywidget is a client widget into which a text is inputted. \a - event is inputted TWsEvent. + event is inputted QSymbianEvent. \sa filterEvent() */ -bool QInputContext::s60FilterEvent(QWidget * /*keywidget*/, TWsEvent * /*event*/) +bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/) { return false; } -#endif // Q_WS_S60 +#endif // Q_OS_SYMBIAN QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qinputcontext.h b/src/gui/inputmethod/qinputcontext.h index 73b05d8..14096e3 100644 --- a/src/gui/inputmethod/qinputcontext.h +++ b/src/gui/inputmethod/qinputcontext.h @@ -67,10 +67,6 @@ QT_BEGIN_HEADER -#ifdef Q_WS_S60 -class TWsEvent; -#endif - QT_BEGIN_NAMESPACE QT_MODULE(Gui) @@ -79,6 +75,9 @@ class QWidget; class QFont; class QPopupMenu; class QInputContextPrivate; +#ifdef Q_OS_SYMBIAN +class QSymbianEvent; +#endif class Q_GUI_EXPORT QInputContext : public QObject { @@ -108,9 +107,9 @@ public: #if defined(Q_WS_X11) virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event ); #endif // Q_WS_X11 -#if defined(Q_WS_S60) - virtual bool s60FilterEvent( QWidget *keywidget, TWsEvent *event ); -#endif // Q_WS_S60 +#if defined(Q_OS_SYMBIAN) + virtual bool symbianFilterEvent( QWidget *keywidget, const QSymbianEvent *event ); +#endif // Q_OS_SYMBIAN virtual bool filterEvent( const QEvent *event ); void sendEvent(const QInputMethodEvent &event); diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 12b398d..5a8e325 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -61,9 +61,6 @@ QT_BEGIN_HEADER -#if defined(Q_OS_SYMBIAN) -class TWsEvent; -#endif #if defined(Q_WS_S60) class CApaApplication; #endif @@ -83,6 +80,9 @@ class QLocale; #if defined(Q_WS_QWS) class QDecoration; #endif +#if defined(Q_OS_SYMBIAN) +class QSymbianEvent; +#endif class QApplication; class QApplicationPrivate; @@ -241,10 +241,8 @@ public: int x11ProcessEvent(XEvent*); #endif #if defined(Q_OS_SYMBIAN) - int s60ProcessEvent(TWsEvent *event); - virtual bool s60EventFilter(TWsEvent *aEvent); - void symbianHandleCommand(int command); - void symbianResourceChange(int type); + int symbianProcessEvent(const QSymbianEvent *event); + virtual bool symbianEventFilter(const QSymbianEvent *event); #endif #if defined(Q_WS_QWS) virtual bool qwsEventFilter(QWSEvent *); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 92b07c7..0fa7269 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -500,6 +500,11 @@ public: static void setNavigationMode(Qt::NavigationMode mode); static TUint resolveS60ScanCode(TInt scanCode, TUint keysym); QSet<WId> nativeWindows; + + int symbianProcessWsEvent(const TWsEvent *event); + int symbianHandleCommand(int command); + int symbianResourceChange(int type); + #endif #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) void sendSyntheticEnterLeave(QWidget *widget); diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 656bbc9..689429e 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -42,6 +42,7 @@ #include "qapplication_p.h" #include "qsessionmanager.h" #include "qevent.h" +#include "qsymbianevent.h" #include "qeventdispatcher_s60_p.h" #include "qwidget.h" #include "qdesktopwidget.h" @@ -1091,6 +1092,13 @@ void qt_init(QApplicationPrivate * /* priv */, int) err = HAL::Get(HALData::EPen, touch); if (err != KErrNone || touchIsUnsupportedOnSystem) touch = 0; +#ifdef __WINS__ + if(QSysInfo::symbianVersion() <= QSysInfo::SV_9_4) { + //for symbian SDK emulator, force values to match typical devices. + mouse = 0; + touch = touchIsUnsupportedOnSystem ? 0 : 1; + } +#endif if (mouse || machineUID == KMachineUidSamsungI8510) { S60->hasTouchscreen = false; S60->virtualMouseRequired = false; @@ -1426,43 +1434,47 @@ void QApplication::beep() \warning This function is only available on Symbian. \since 4.6 - This function processes an individual Symbian window server + This function processes an individual Symbian event \a event. It returns 1 if the event was handled, 0 if the \a event was not handled, and -1 if the event was - not handled because the event handle (\c{TWsEvent::Handle()}) - is not known to Qt. + not handled because the event is not known to Qt. */ -int QApplication::s60ProcessEvent(TWsEvent *event) + +int QApplication::symbianProcessEvent(const QSymbianEvent *event) { - bool handled = s60EventFilter(event); - if (handled) + Q_D(QApplication); + + QScopedLoopLevelCounter counter(d->threadData); + + QWidget *w = qApp ? qApp->focusWidget() : 0; + if (w) { + QInputContext *ic = w->inputContext(); + if (ic && ic->symbianFilterEvent(w, event)) + return 1; + } + + if (symbianEventFilter(event)) return 1; + switch (event->type()) { + case QSymbianEvent::WindowServerEvent: + return d->symbianProcessWsEvent(event->windowServerEvent()); + case QSymbianEvent::CommandEvent: + return d->symbianHandleCommand(event->command()); + case QSymbianEvent::ResourceChangeEvent: + return d->symbianResourceChange(event->resourceChangeType()); + default: + return -1; + } +} + +int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) +{ // Qt event handling. Handle some events regardless of if the handle is in our // widget map or not. CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle()); const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control); switch (event->Type()) { -#if !defined(QT_NO_IM) && defined(Q_WS_S60) - case EEventKey: - case EEventKeyUp: - case EEventKeyDown: - { - // The control doesn't seem to be any of our widgets, so rely on the focused - // widget instead. If the user needs the control, it can be found inside the - // event structure. - QWidget *w = qApp ? qApp->focusWidget() : 0; - if (w) { - QInputContext *ic = w->inputContext(); - if (ic && ic->s60FilterEvent(w, event)) { - return 1; - } else { - return 0; - } - } - break; - } -#endif case EEventPointerEnter: if (controlInMap) return 1; // Qt::Enter will be generated in HandlePointerL @@ -1551,15 +1563,15 @@ int QApplication::s60ProcessEvent(TWsEvent *event) If you create an application that inherits QApplication and reimplement this function, you get direct access to events that the are received - from the Symbian window server. The events are passed in the TWsEvent - \a aEvent parameter. + from Symbian. The events are passed in the \a event parameter. Return true if you want to stop the event from being processed. Return - false for normal event dispatching. The default implementation - false, and does nothing with \a aEvent. + false for normal event dispatching. The default implementation returns + false, and does nothing with \a event. */ -bool QApplication::s60EventFilter(TWsEvent * /* aEvent */) +bool QApplication::symbianEventFilter(const QSymbianEvent *event) { + Q_UNUSED(event); return false; } @@ -1574,32 +1586,39 @@ bool QApplication::s60EventFilter(TWsEvent * /* aEvent */) \sa s60EventFilter(), s60ProcessEvent() */ -void QApplication::symbianHandleCommand(int command) +int QApplicationPrivate::symbianHandleCommand(int command) { - QScopedLoopLevelCounter counter(d_func()->threadData); + Q_Q(QApplication); + int ret = 0; + switch (command) { #ifdef Q_WS_S60 case EAknSoftkeyExit: { QCloseEvent ev; - QApplication::sendSpontaneousEvent(this, &ev); - if (ev.isAccepted()) - quit(); + QApplication::sendSpontaneousEvent(q, &ev); + if (ev.isAccepted()) { + q->quit(); + ret = 1; + } break; } #endif case EEikCmdExit: - quit(); + q->quit(); + ret = 1; break; default: bool handled = QSoftKeyManager::handleCommand(command); + if (handled) + ret = 1; #ifdef Q_WS_S60 - if (!handled) - QMenuBarPrivate::symbianCommands(command); -#else - Q_UNUSED(handled); + else + ret = QMenuBarPrivate::symbianCommands(command); #endif break; } + + return ret; } /*! @@ -1611,8 +1630,10 @@ void QApplication::symbianHandleCommand(int command) Currently, KEikDynamicLayoutVariantSwitch and KAknsMessageSkinChange are handled. */ -void QApplication::symbianResourceChange(int type) +int QApplicationPrivate::symbianResourceChange(int type) { + int ret = 0; + switch (type) { #ifdef Q_WS_S60 case KEikDynamicLayoutVariantSwitch: @@ -1631,22 +1652,28 @@ void QApplication::symbianResourceChange(int type) #endif s60Style = qobject_cast<QS60Style*>(QApplication::style()); - if (s60Style) + if (s60Style) { s60Style->d_func()->handleDynamicLayoutVariantSwitch(); + ret = 1; + } #endif } break; #ifndef QT_NO_STYLE_S60 case KAknsMessageSkinChange: - if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) + if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) { s60Style->d_func()->handleSkinChange(); + ret = 1; + } break; #endif #endif // Q_WS_S60 default: break; } + + return ret; } #ifndef QT_NO_WHEELEVENT diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index be207df..f95efa2 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -438,10 +438,10 @@ static const Qt::KeyboardModifiers ModsTbl[] = { */ inline int winceKeyBend(int keyCode) { -#ifdef Q_OS_WINCE_WM +#if defined(Q_OS_WINCE_WM) && defined(QT_KEYPAD_NAVIGATION) // remap return or action key to select key for windows mobile. // will be changed to a table remapping function in the next version (4.6/7). - if (keyCode == 13) + if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled()) return Qt::Key_Select; else return KeyTbl[keyCode]; diff --git a/src/gui/kernel/symbian.pri b/src/gui/kernel/symbian.pri index 5497ccb..69422dd 100644 --- a/src/gui/kernel/symbian.pri +++ b/src/gui/kernel/symbian.pri @@ -1,4 +1,7 @@ symbian { contains(QT_CONFIG, s60): LIBS+= $$QMAKE_LIBS_S60 RESOURCES += symbian/symbianresources.qrc + + HEADERS += symbian/qsymbianevent.h + SOURCES += symbian/qsymbianevent.cpp } diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index e630253..4ad78f9 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -50,6 +50,7 @@ #include "qs60mainappui.h" #include <QtGui/qapplication.h> +#include <QtGui/qsymbianevent.h> #include <QtGui/qmenu.h> #include <private/qmenu_p.h> #include <private/qt_s60_p.h> @@ -134,8 +135,10 @@ QS60MainAppUi::~QS60MainAppUi() */ void QS60MainAppUi::HandleCommandL(TInt command) { - if (qApp) - QT_TRYCATCH_LEAVING(qApp->symbianHandleCommand(command)); + if (qApp) { + QSymbianEvent event(QSymbianEvent::CommandEvent, command); + QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event)); + } } /*! @@ -151,8 +154,10 @@ void QS60MainAppUi::HandleResourceChangeL(TInt type) { CAknAppUi::HandleResourceChangeL(type); - if (qApp) - QT_TRYCATCH_LEAVING(qApp->symbianResourceChange(type)); + if (qApp) { + QSymbianEvent event(QSymbianEvent::ResourceChangeEvent, type); + QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event)); + } } /*! @@ -164,16 +169,18 @@ void QS60MainAppUi::HandleResourceChangeL(TInt type) * If you override this function, you should call the base class implementation if you do not * handle the event. */ -void QS60MainAppUi::HandleWsEventL(const TWsEvent& event, CCoeControl *destination) +void QS60MainAppUi::HandleWsEventL(const TWsEvent& wsEvent, CCoeControl *destination) { int result = 0; - if (qApp) + if (qApp) { + QSymbianEvent event(&wsEvent); QT_TRYCATCH_LEAVING( - result = qApp->s60ProcessEvent(const_cast<TWsEvent*>(&event)) + result = qApp->symbianProcessEvent(&event) ); + } if (result <= 0) - CAknAppUi::HandleWsEventL(event, destination); + CAknAppUi::HandleWsEventL(wsEvent, destination); } diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 6d95336..4c6bc46 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1844,8 +1844,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, //todo: update to horizontal table graphic QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest); } - } else if (qobject_cast<const QFrame *>(widget)) { - QCommonStyle::drawControl(element, option, painter, widget); + } else if (qobject_cast<const QFrame *>(widget)) { + QCommonStyle::drawControl(element, option, painter, widget); } break; case CE_MenuScroller: @@ -2216,6 +2216,12 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) sz += QSize(2*f->lineWidth, 4*f->lineWidth); break; + case CT_TabBarTab: + QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); + sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); + if (naviPaneSize.height() > sz.height()) + sz.setHeight(naviPaneSize.height()); + break; default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; @@ -2425,8 +2431,8 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_ComboBoxArrow: ret.setRect( ret.x() + ret.width() - buttonMargin - buttonWidth, - ret.y() + buttonMargin, - buttonWidth, + ret.y() + buttonMargin, + buttonWidth, height - 2*buttonMargin); break; case SC_ComboBoxEditField: { diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index 6be3197..ab10792 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -101,7 +101,7 @@ protected Q_SLOTS: private: Q_DISABLE_COPY(QS60Style) friend class QStyleFactory; - friend class QApplication; + friend class QApplicationPrivate; }; #endif // QT_NO_STYLE_S60 diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 5422ff6..8e53eee 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -460,6 +460,8 @@ public: void handleSkinChange(); #endif // Q_WS_S60 + static QSize naviPaneSize(); + private: static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter, const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index d760016..9765066 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -61,6 +61,7 @@ #include <AknFontAccess.h> #include <AknLayoutFont.h> #include <aknutils.h> +#include <aknnavi.h> #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) @@ -104,6 +105,7 @@ public: static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part); static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame); static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QSize naviPaneSize(); private: static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, @@ -1388,6 +1390,24 @@ void QS60StylePrivate::handleSkinChange() topLevelWidget->ensurePolished(); } } + +QSize QS60StylePrivate::naviPaneSize() +{ + return QS60StyleModeSpecifics::naviPaneSize(); +} + +QSize QS60StyleModeSpecifics::naviPaneSize() +{ + CAknNavigationControlContainer* naviContainer; + if (S60->statusPane()) + naviContainer = static_cast<CAknNavigationControlContainer*> + (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi))); + if (naviContainer) + return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight); + else + return QSize(0,0); +} + #endif // Q_WS_S60 QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index 89a9158..8a2616d 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -326,6 +326,10 @@ QPixmap QS60StylePrivate::backgroundTexture() return *m_background; } +QSize QS60StylePrivate::naviPaneSize() +{ + return QSize(0, 0); +} bool QS60StylePrivate::isTouchSupported() { diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index a617102..5fa6251 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -5592,8 +5592,43 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption painter->drawLine(rect.bottomLeft(), rect.bottomRight()); } #endif // QT_NO_SCROLLAREA - break; } - + break; + } +#ifndef QT_NO_COMBOBOX + case CE_ComboBoxLabel: + // This is copied from qcommonstyle.cpp with the difference, that + // the editRect isn't adjusted when calling drawItemText. + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget); + painter->save(); + painter->setClipRect(editRect); + if (!cb->currentIcon.isNull()) { + QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal + : QIcon::Disabled; + QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode); + QRect iconRect(editRect); + iconRect.setWidth(cb->iconSize.width() + 4); + iconRect = alignedRect(cb->direction, + Qt::AlignLeft | Qt::AlignVCenter, + iconRect.size(), editRect); + if (cb->editable) + painter->fillRect(iconRect, option->palette.brush(QPalette::Base)); + proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); + + if (cb->direction == Qt::RightToLeft) + editRect.translate(-4 - cb->iconSize.width(), 0); + else + editRect.translate(cb->iconSize.width() + 4, 0); + } + if (!cb->currentText.isEmpty() && !cb->editable) { + proxy()->drawItemText(painter, editRect, + visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter), + cb->palette, cb->state & State_Enabled, cb->currentText); + } + painter->restore(); + } + break; +#endif // QT_NO_COMBOBOX #ifndef QT_NO_DOCKWIDGET case CE_DockWidgetTitle: if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { @@ -6154,24 +6189,24 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget), &editBrush); else painter->fillRect(option->rect, editBrush); - State flags = State_None; - QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); - if ((option->state & State_On)) { - painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow)); - } - if (d->doubleControls) - ar.adjust(5, 0, 5, 0); - else - ar.adjust(2, 0, -2, 0); - if (option->state & State_Enabled) - flags |= State_Enabled; - if (option->state & State_On) - flags |= State_Sunken; - QStyleOption arrowOpt(0); - arrowOpt.rect = ar; - arrowOpt.palette = cmb->palette; - arrowOpt.state = flags; - proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget); + State flags = State_None; + QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); + if ((option->state & State_On)) { + painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow)); + } + if (d->doubleControls) + ar.adjust(5, 0, 5, 0); + else + ar.adjust(2, 0, -2, 0); + if (option->state & State_Enabled) + flags |= State_Enabled; + if (option->state & State_On) + flags |= State_Sunken; + QStyleOption arrowOpt(0); + arrowOpt.rect = ar; + arrowOpt.palette = cmb->palette; + arrowOpt.state = flags; + proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget); if (cmb->subControls & SC_ComboBoxEditField) { QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget); if (cmb->state & State_HasFocus && !cmb->editable) @@ -6335,7 +6370,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio case CT_ComboBox: if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { int fw = comboBox->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0; - newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw-4); //Nine is a magic Number - See CommonStyle for real magic (23) + newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw); //Nine is a magic Number - See CommonStyle for real magic (23) } break; #endif @@ -6618,14 +6653,21 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp switch (subControl) { case SC_ComboBoxArrow: rect.setRect(xpos, y + bmarg, he - 2*bmarg, he - 2*bmarg); - rect.setRect(xpos, y + bmarg, int((he - 2*bmarg)), he - 2*bmarg); break; - case SC_ComboBoxEditField: - rect.setRect(x + margin+4, y + margin+2, wi - 4 * margin - int((he - 2*bmarg) * 0.84f) -2, he - 2 * margin-4); - break; - case SC_ComboBoxFrame: - rect = comboBox->rect; - break; + case SC_ComboBoxEditField: + rect.setRect(x + margin, y + margin, wi - 2 * margin - int((he - 2*bmarg) * 0.84f), he - 2 * margin); + if (d->doubleControls) { + if (comboBox->editable) + rect.adjust(2, 0, 0, 0); + else + rect.adjust(4, 2, 0, -2); + } else if (!comboBox->editable) { + rect.adjust(2, 1, 0, -1); + } + break; + case SC_ComboBoxFrame: + rect = comboBox->rect; + break; default: break; } @@ -6999,7 +7041,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co } else { d->doubleControls ? ret = 36 : ret = 18; } - break; + break; case PM_ScrollBarExtent: { if (d->smartphone) @@ -7055,7 +7097,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co break; case PM_TextCursorWidth: ret = 2; - break; + break; case PM_TabBar_ScrollButtonOverlap: ret = 0; break; @@ -7089,7 +7131,7 @@ int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, cons #endif case SH_ToolBar_Movable: ret = false; - break; + break; case SH_ScrollBar_ContextMenu: ret = false; break; diff --git a/src/gui/symbian/qsymbianevent.cpp b/src/gui/symbian/qsymbianevent.cpp new file mode 100644 index 0000000..af2c861 --- /dev/null +++ b/src/gui/symbian/qsymbianevent.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsymbianevent.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QSymbianEvent + \brief The QSymbianEvent class contains a Symbian event of any type. + \since 4.6 + + The class is used as a generic container type for all types of Symbian + events. + + \note This class is only available on Symbian. + + \sa QApplication::symbianEventFilter() +*/ + +/*! + \enum QSymbianEvent::Type + + \value InvalidEvent The event is not valid. + \value WindowServerEvent Indicates an event of type \c TWsEvent. + \value CommandEvent Indicates that the event is a Symbian command. + \value ResourceChangeEvent Indicates that the event is a Symbian resource change type. +*/ + +/*! + \fn QSymbianEvent::type() + + Returns the event type contained in the QSymbianEvent instance. +*/ + +/*! + \fn QSymbianEvent::isValid() + + Returns whether this QSymbianEvent instance contains a valid event. +*/ + +/*! + Constructs a QSymbianEvent containing the given window server event + \a windowServerEvent. +*/ +QSymbianEvent::QSymbianEvent(const TWsEvent *windowServerEvent) + : m_type(WindowServerEvent) + , m_eventPtr(windowServerEvent) +{ +} + +/*! + Constructs a QSymbianEvent containing the given event value + \a value. The type of event is controlled by the \a eventType parameter. +*/ +QSymbianEvent::QSymbianEvent(QSymbianEvent::Type eventType, int value) +{ + switch (eventType) { + case CommandEvent: + case ResourceChangeEvent: + m_type = eventType; + m_eventValue = value; + break; + default: + m_type = InvalidEvent; + m_eventValue = 0; + break; + } +} + +/*! + Destroys the QSymbianEvent. +*/ +QSymbianEvent::~QSymbianEvent() +{ +} + +/*! + Returns the window server event contained in the class instance, or 0 if the event type + is not \c WindowServerEvent. +*/ +const TWsEvent *QSymbianEvent::windowServerEvent() const +{ + return (m_type == WindowServerEvent) ? static_cast<const TWsEvent *>(m_eventPtr) : 0; +} + +/*! + Returns the command contained in the class instance, or 0 if the event type + is not \c CommandEvent. +*/ +int QSymbianEvent::command() const +{ + return (m_type == CommandEvent) ? m_eventValue : 0; +} + +/*! + Returns the resource change type contained in the class instance, or 0 if the event type + is not \c ResourceChangeEvent. +*/ +int QSymbianEvent::resourceChangeType() const +{ + return (m_type == ResourceChangeEvent) ? m_eventValue : 0; +} + +QT_END_NAMESPACE diff --git a/src/gui/symbian/qsymbianevent.h b/src/gui/symbian/qsymbianevent.h new file mode 100644 index 0000000..74aa5d0 --- /dev/null +++ b/src/gui/symbian/qsymbianevent.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSYMBIANEVENT_H +#define QSYMBIANEVENT_H + +#include <QtCore/qglobal.h> + +#ifdef Q_OS_SYMBIAN + +class TWsEvent; + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class Q_GUI_EXPORT QSymbianEvent +{ +public: + enum Type { + InvalidEvent, + WindowServerEvent, + CommandEvent, + ResourceChangeEvent + }; + + QSymbianEvent(const TWsEvent *windowServerEvent); + QSymbianEvent(Type eventType, int value); + ~QSymbianEvent(); + + Type type() const; + bool isValid() const; + + const TWsEvent *windowServerEvent() const; + int command() const; + int resourceChangeType() const; + +private: + Type m_type; + union { + const void *m_eventPtr; + int m_eventValue; + + qint64 m_reserved; + }; +}; + +inline QSymbianEvent::Type QSymbianEvent::type() const +{ + return m_type; +} + +inline bool QSymbianEvent::isValid() const +{ + return m_type != InvalidEvent; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q_OS_SYMBIAN + +#endif // QSYMBIANEVENT_H diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index cee38ee..b238faf 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1771,6 +1771,16 @@ QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action) actionItems.removeAll(action); } +bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget) +{ + // This function is different from q->isNativeMenuBar(), as + // it returns true only if a native menu bar is actually + // _created_. + if (!widget) + return false; + return menubars()->contains(widget->window()); +} + void QMenuBarPrivate::macCreateMenuBar(QWidget *parent) { @@ -1778,16 +1788,22 @@ QMenuBarPrivate::macCreateMenuBar(QWidget *parent) static int dontUseNativeMenuBar = -1; // We call the isNativeMenuBar function here // because that will make sure that local overrides - // are dealt with correctly. + // are dealt with correctly. q->isNativeMenuBar() will, if not + // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar: bool qt_mac_no_native_menubar = !q->isNativeMenuBar(); if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) { + // The menubar is set to be native. Let's check (one time only + // for all menubars) if this is OK with the rest of the environment. + // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application + // might still choose to not respect, or change, this flag. bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication); bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty(); dontUseNativeMenuBar = isPlugin || environmentSaysNo; QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar); qt_mac_no_native_menubar = !q->isNativeMenuBar(); } - if (!qt_mac_no_native_menubar) { + if (qt_mac_no_native_menubar == false) { + // INVARIANT: Use native menubar. extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp qt_event_request_menubarupdate(); if (!parent && !fallback) { diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index d757f98..94c4177 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -243,11 +243,14 @@ void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id) } #endif // Q_WS_S60 -void QMenuBarPrivate::symbianCommands(int command) +int QMenuBarPrivate::symbianCommands(int command) { + int ret = 0; + if (command == contexMenuCommand && !widgetWithContextMenu.isNull()) { QContextMenuEvent* event = new QContextMenuEvent(QContextMenuEvent::Keyboard, QPoint(0,0)); QCoreApplication::postEvent(widgetWithContextMenu, event); + ret = 1; } int size = nativeMenuBars.size(); @@ -258,8 +261,11 @@ void QMenuBarPrivate::symbianCommands(int command) emit nativeMenuBars.at(i)->triggered(menu->action); menu->action->activate(QAction::Trigger); + ret = 1; break; } + + return ret; } void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 13e7de4..f2f0722 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -1370,8 +1370,13 @@ void QMenuBarPrivate::handleReparent() oldWindow = newWindow; #ifdef Q_WS_MAC - macDestroyMenuBar(); - macCreateMenuBar(newParent); + if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) { + // If the new parent got a native menubar from before, keep that + // menubar rather than replace it with this one (because a parents + // menubar has precedence over children menubars). + macDestroyMenuBar(); + macCreateMenuBar(newParent); + } #endif #ifdef Q_WS_WINCE diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 0b27b97..da2b8d7 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -196,6 +196,7 @@ public: return 0; } } *mac_menubar; + bool macWidgetHasNativeMenubar(QWidget *widget); void macCreateMenuBar(QWidget *); void macDestroyMenuBar(); OSMenuRef macMenu(); @@ -265,7 +266,7 @@ public: void insertNativeMenuItems(const QList<QAction*> &actions); } *symbian_menubar; - static void symbianCommands(int command); + static int symbianCommands(int command); #endif }; |