From e8510d79520c433c745dd46a156a118313448352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 May 2014 17:25:49 +0200 Subject: qpa: Merge qapplication_qpa.cpp into qapplication.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable 'appFont' was removed as it was not used. Change-Id: I8dfa8382b3f30b72490fd22b4e0a27e991318a9c Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qapplication.cpp | 425 +++++++++++++++++++++++++++++++++++- 1 file changed, 419 insertions(+), 6 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 703b748a56..4ebcfc45f9 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -57,6 +57,7 @@ #include "qstyleoption.h" #include "qstylefactory.h" #include "qtextcodec.h" +#include "qtooltip.h" #include "qtranslator.h" #include "qvariant.h" #include "qwidget.h" @@ -97,6 +98,10 @@ #include "qlibrary.h" #endif +#ifdef Q_OS_WIN +#include // for qt_win_display_dc() +#endif + #include "qdatetime.h" #ifdef Q_OS_WINCE @@ -174,6 +179,11 @@ QApplicationPrivate::~QApplicationPrivate() self = 0; } +void QApplicationPrivate::createEventDispatcher() +{ + QGuiApplicationPrivate::createEventDispatcher(); +} + /*! \class QApplication \brief The QApplication class manages the GUI application's control @@ -351,6 +361,21 @@ QApplicationPrivate::~QApplicationPrivate() Returns the top-level widget at the given \a point; returns 0 if there is no such widget. */ +QWidget *QApplication::topLevelAt(const QPoint &pos) +{ + QList screens = QGuiApplication::screens(); + QList::const_iterator screen = screens.constBegin(); + QList::const_iterator end = screens.constEnd(); + + while (screen != end) { + if ((*screen)->geometry().contains(pos)) { + QWidgetWindow *w = qobject_cast((*screen)->handle()->topLevelAt(pos)); + return w ? w->widget() : 0; + } + ++screen; + } + return 0; +} /*! \fn QWidget *QApplication::topLevelAt(int x, int y) @@ -361,12 +386,6 @@ QApplicationPrivate::~QApplicationPrivate() 0 if there is no such widget. */ - -/* - The qt_init() and qt_cleanup() functions are implemented in the - qapplication_xyz.cpp file. -*/ - void qt_init(QApplicationPrivate *priv, int type ); void qt_init_tooltip_palette(); @@ -591,6 +610,26 @@ void QApplicationPrivate::construct() #endif } +void qt_init(QApplicationPrivate *priv, int type) +{ + Q_UNUSED(priv); + Q_UNUSED(type); + + QColormap::initialize(); + + qt_init_tooltip_palette(); + + QApplicationPrivate::initializeWidgetFontHash(); +} + +void qt_init_tooltip_palette() +{ +#ifndef QT_NO_TOOLTIP + if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) + QToolTip::setPalette(*toolTipPalette); +#endif +} + #ifndef QT_NO_STATEMACHINE void qRegisterGuiStateMachine(); void qUnregisterGuiStateMachine(); @@ -647,6 +686,91 @@ void QApplicationPrivate::initialize() is_app_running = true; // no longer starting up } +static void setPossiblePalette(const QPalette *palette, const char *className) +{ + if (palette == 0) + return; + QApplicationPrivate::setPalette_helper(*palette, className, false); +} + +void QApplicationPrivate::initializeWidgetPaletteHash() +{ + QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme(); + if (!platformTheme) + return; + qt_app_palettes_hash()->clear(); + + setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::CheckBoxPalette), "QCheckBox"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit"); +} + +void QApplicationPrivate::initializeWidgetFontHash() +{ + const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); + if (!theme) + return; + FontHash *fontHash = qt_app_fonts_hash(); + fontHash->clear(); + + if (const QFont *font = theme->font(QPlatformTheme::MenuFont)) + fontHash->insert(QByteArrayLiteral("QMenu"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont)) + fontHash->insert(QByteArrayLiteral("QMenuBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont)) + fontHash->insert(QByteArrayLiteral("QMenuItem"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont)) + fontHash->insert(QByteArrayLiteral("QMessageBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::LabelFont)) + fontHash->insert(QByteArrayLiteral("QLabel"), *font); + if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont)) + fontHash->insert(QByteArrayLiteral("QTipLabel"), *font); + if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont)) + fontHash->insert(QByteArrayLiteral("QTitleBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont)) + fontHash->insert(QByteArrayLiteral("QStatusBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont)) + fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont)) + fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font); + if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont)) + fontHash->insert(QByteArrayLiteral("QPushButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::CheckBoxFont)) + fontHash->insert(QByteArrayLiteral("QCheckBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::RadioButtonFont)) + fontHash->insert(QByteArrayLiteral("QRadioButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont)) + fontHash->insert(QByteArrayLiteral("QToolButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont)) + fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ListViewFont)) + fontHash->insert(QByteArrayLiteral("QListViewFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont)) + fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont)) + fontHash->insert(QByteArrayLiteral("QListBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont)) + fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont)) + fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::SmallFont)) + fontHash->insert(QByteArrayLiteral("QSmallFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MiniFont)) + fontHash->insert(QByteArrayLiteral("QMiniFont"), *font); +} + /***************************************************************************** Functions returning the active popup and modal widgets. *****************************************************************************/ @@ -770,6 +894,32 @@ QApplication::~QApplication() #endif } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +// #fixme: Remove. +static HDC displayDC = 0; // display device context + +Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC +{ + Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); + if (!displayDC) + displayDC = GetDC(0); + return displayDC; +} +#endif + +void qt_cleanup() +{ + QPixmapCache::clear(); + QColormap::cleanup(); + + QApplicationPrivate::active_window = 0; //### this should not be necessary +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + if (displayDC) { + ReleaseDC(0, displayDC); + displayDC = 0; + } +#endif +} /*! \fn QWidget *QApplication::widgetAt(const QPoint &point) @@ -2071,6 +2221,39 @@ void QApplication::setActiveWindow(QWidget* act) } } +QWidget *qt_tlw_for_window(QWindow *wnd) +{ + // QTBUG-32177, wnd might be a QQuickView embedded via window container. + while (wnd && !wnd->isTopLevel()) { + QWindow *parent = wnd->parent(); + // Don't end up in windows not belonging to this application + if (parent && parent->type() != Qt::ForeignWindow) + wnd = wnd->parent(); + else + break; + } + if (wnd) + foreach (QWidget *tlw, qApp->topLevelWidgets()) + if (tlw->windowHandle() == wnd) + return tlw; + return 0; +} + +void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) +{ + Q_UNUSED(previous); + QWindow *wnd = QGuiApplicationPrivate::focus_window; + if (inPopupMode()) // some delayed focus event to ignore + return; + QWidget *tlw = qt_tlw_for_window(wnd); + QApplication::setActiveWindow(tlw); + // QTBUG-37126, Active X controls may set the focus on native child widgets. + if (wnd && tlw && wnd != tlw->windowHandle()) { + if (QWidgetWindow *widgetWindow = qobject_cast(wnd)) + widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); + } +} + /*!internal * Helper function that returns the new focus widget, but does not set the focus reason. * Returns 0 if a new focus widget could not be found. @@ -2439,6 +2622,44 @@ bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop) return !isBlockedByModal(widget->window()); } +bool qt_try_modal(QWidget *widget, QEvent::Type type) +{ + QWidget * top = 0; + + if (QApplicationPrivate::tryModalHelper(widget, &top)) + return true; + + bool block_event = false; + + switch (type) { +#if 0 + case QEvent::Focus: + if (!static_cast(event)->simpleData.get_focus) + break; + // drop through +#endif + case QEvent::MouseButtonPress: // disallow mouse/key events + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + block_event = true; + break; + default: + break; + } + + if (block_event && top && top->parentWidget() == 0) + top->raise(); + + return !block_event; +} + +bool QApplicationPrivate::modalState() +{ + return !self->modalWindowList.isEmpty(); +} + /* \internal */ @@ -3514,6 +3735,123 @@ bool QApplicationPrivate::inPopupMode() return QApplicationPrivate::popupWidgets != 0; } +static void ungrabKeyboardForPopup(QWidget *popup) +{ + if (QWidget::keyboardGrabber()) + qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true); + else + qt_widget_private(popup)->stealKeyboardGrab(false); +} + +static void ungrabMouseForPopup(QWidget *popup) +{ + if (QWidget::mouseGrabber()) + qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true); + else + qt_widget_private(popup)->stealMouseGrab(false); +} + +static bool popupGrabOk; + +static void grabForPopup(QWidget *popup) +{ + Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); + popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true); + if (popupGrabOk) { + popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true); + if (!popupGrabOk) { + // transfer grab back to the keyboard grabber if any + ungrabKeyboardForPopup(popup); + } + } +} + +extern QWidget *qt_button_down; +extern QWidget *qt_popup_down; +extern bool qt_replay_popup_mouse_event; + +void QApplicationPrivate::closePopup(QWidget *popup) +{ + if (!popupWidgets) + return; + popupWidgets->removeAll(popup); + + if (popup == qt_popup_down) { + qt_button_down = 0; + qt_popup_down = 0; + } + + if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup + delete QApplicationPrivate::popupWidgets; + QApplicationPrivate::popupWidgets = 0; + + if (popupGrabOk) { + popupGrabOk = false; + + if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX, + QGuiApplicationPrivate::mousePressY)) + || popup->testAttribute(Qt::WA_NoMouseReplay)) { + // mouse release event or inside + qt_replay_popup_mouse_event = false; + } else { // mouse press event + qt_replay_popup_mouse_event = true; + } + + // transfer grab back to mouse grabber if any, otherwise release the grab + ungrabMouseForPopup(popup); + + // transfer grab back to keyboard grabber if any, otherwise release the grab + ungrabKeyboardForPopup(popup); + } + + if (active_window) { + if (QWidget *fw = active_window->focusWidget()) { + if (fw != QApplication::focusWidget()) { + fw->setFocus(Qt::PopupFocusReason); + } else { + QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); + QCoreApplication::sendEvent(fw, &e); + } + } + } + + } else { + // A popup was closed, so the previous popup gets the focus. + QWidget* aw = QApplicationPrivate::popupWidgets->last(); + if (QWidget *fw = aw->focusWidget()) + fw->setFocus(Qt::PopupFocusReason); + + if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard + grabForPopup(aw); + } + +} + +int openPopupCount = 0; + +void QApplicationPrivate::openPopup(QWidget *popup) +{ + openPopupCount++; + if (!popupWidgets) // create list + popupWidgets = new QWidgetList; + popupWidgets->append(popup); // add to end of list + + if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard + grabForPopup(popup); + + // popups are not focus-handled by the window system (the first + // popup grabbed the keyboard), so we have to do that manually: A + // new popup gets the focus + if (popup->focusWidget()) { + popup->focusWidget()->setFocus(Qt::PopupFocusReason); + } else if (popupWidgets->count() == 1) { // this was the first popup + if (QWidget *fw = QApplication::focusWidget()) { + QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); + QApplication::sendEvent(fw, &e); + } + } +} + #ifdef QT_KEYPAD_NAVIGATION /*! Sets the kind of focus navigation Qt should use to \a mode. @@ -3618,6 +3956,18 @@ bool QApplication::keypadNavigationEnabled() window must not be hidden (i.e. not have hide() called on it, but be visible in some sort of way) in order for this to work. */ +void QApplication::alert(QWidget *widget, int duration) +{ + if (widget) { + if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized)) + return; + if (QWindow *window= QApplicationPrivate::windowForWidget(widget)) + window->alert(duration); + } else { + foreach (QWidget *topLevel, topLevelWidgets()) + QApplication::alert(topLevel, duration); + } +} /*! \property QApplication::cursorFlashTime @@ -3705,6 +4055,38 @@ int QApplication::keyboardInputInterval() By default, this property has a value of 3. */ +#ifndef QT_NO_WHEELEVENT +int QApplication::wheelScrollLines() +{ + return QApplicationPrivate::wheel_scroll_lines; +} + +void QApplication::setWheelScrollLines(int lines) +{ + QApplicationPrivate::wheel_scroll_lines = lines; +} +#endif + +static inline int uiEffectToFlag(Qt::UIEffect effect) +{ + switch (effect) { + case Qt::UI_General: + return QPlatformTheme::GeneralUiEffect; + case Qt::UI_AnimateMenu: + return QPlatformTheme::AnimateMenuUiEffect; + case Qt::UI_FadeMenu: + return QPlatformTheme::FadeMenuUiEffect; + case Qt::UI_AnimateCombo: + return QPlatformTheme::AnimateComboUiEffect; + case Qt::UI_AnimateTooltip: + return QPlatformTheme::AnimateTooltipUiEffect; + case Qt::UI_FadeTooltip: + return QPlatformTheme::FadeTooltipUiEffect; + case Qt::UI_AnimateToolBox: + return QPlatformTheme::AnimateToolBoxUiEffect; + } + return 0; +} /*! \fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) @@ -3717,6 +4099,19 @@ int QApplication::keyboardInputInterval() \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware() */ +void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) +{ + int effectFlags = uiEffectToFlag(effect); + if (enable) { + if (effectFlags & QPlatformTheme::FadeMenuUiEffect) + effectFlags |= QPlatformTheme::AnimateMenuUiEffect; + if (effectFlags & QPlatformTheme::FadeTooltipUiEffect) + effectFlags |= QPlatformTheme::AnimateTooltipUiEffect; + QApplicationPrivate::enabledAnimations |= effectFlags; + } else { + QApplicationPrivate::enabledAnimations &= ~effectFlags; + } +} /*! \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect) @@ -3731,6 +4126,12 @@ int QApplication::keyboardInputInterval() \sa setEffectEnabled(), Qt::UIEffect */ +bool QApplication::isEffectEnabled(Qt::UIEffect effect) +{ + return QColormap::instance().depth() >= 16 + && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect) + && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect)); +} /*! \fn void QApplication::beep() @@ -3738,6 +4139,10 @@ int QApplication::keyboardInputInterval() Sounds the bell, using the default volume and sound. The function is \e not available in Qt for Embedded Linux. */ +void QApplication::beep() +{ + QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep"); +} /*! \macro qApp @@ -3850,11 +4255,19 @@ void QApplicationPrivate::initializeMultitouch() initializeMultitouch_sys(); } +void QApplicationPrivate::initializeMultitouch_sys() +{ +} + void QApplicationPrivate::cleanupMultitouch() { cleanupMultitouch_sys(); } +void QApplicationPrivate::cleanupMultitouch_sys() +{ +} + QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos) { int closestTouchPointId = -1; -- cgit v1.2.3