/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qapplication_p.h" #include "qcolormap.h" #include "qpalette.h" #include "qpixmapcache.h" #ifndef QT_NO_CURSOR #include "private/qcursor_p.h" #endif #include "qscreen.h" #include "private/qwidget_p.h" #include "private/qevent_p.h" #include "qgenericpluginfactory_qpa.h" #include "private/qplatformintegrationfactory_qpa_p.h" #include #include #include #include #include #include "private/qwindowsysteminterface_qpa_p.h" #include #include "qdesktopwidget_qpa_p.h" #include "qwidgetwindow_qpa_p.h" #include "qtooltip.h" #ifdef Q_OS_WIN # include // for qt_win_display_dc() #endif QT_BEGIN_NAMESPACE static QString appName; static QString appFont; static bool popupGrabOk; extern QWidget *qt_button_down; extern QWidget *qt_popup_down; extern bool qt_replay_popup_mouse_event; int openPopupCount = 0; QString QApplicationPrivate::appName() const { return QT_PREPEND_NAMESPACE(appName); } void QApplicationPrivate::createEventDispatcher() { QGuiApplicationPrivate::createEventDispatcher(); } bool qt_try_modal(QWidget *widget, QEvent::Type type) { QWidget * top = 0; if (QApplicationPrivate::tryModalHelper(widget, &top)) return true; bool block_event = false; bool paint_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 || paint_event) && top->parentWidget() == 0) top->raise(); return !block_event; } bool QApplicationPrivate::modalState() { return !self->modalWindowList.isEmpty(); } QWidget *qt_tlw_for_window(QWindow *wnd) { 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); } 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 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); } } } 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 QGuiApplicationPrivate::mousePressTime -= 10000; // avoid double click 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); } } 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); } } } void QApplicationPrivate::initializeMultitouch_sys() { } void QApplicationPrivate::cleanupMultitouch_sys() { } 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; setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton"); setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton"); setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView"); setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView"); setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPelette), "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(); 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::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); } #ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int lines) { QApplicationPrivate::wheel_scroll_lines = lines; } int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } #endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { switch (effect) { case Qt::UI_AnimateMenu: QApplicationPrivate::animate_menu = enable; break; case Qt::UI_FadeMenu: if (enable) QApplicationPrivate::animate_menu = true; QApplicationPrivate::fade_menu = enable; break; case Qt::UI_AnimateCombo: QApplicationPrivate::animate_combo = enable; break; case Qt::UI_AnimateTooltip: QApplicationPrivate::animate_tooltip = enable; break; case Qt::UI_FadeTooltip: if (enable) QApplicationPrivate::animate_tooltip = true; QApplicationPrivate::fade_tooltip = enable; break; case Qt::UI_AnimateToolBox: QApplicationPrivate::animate_toolbox = enable; break; default: QApplicationPrivate::animate_ui = enable; break; } } bool QApplication::isEffectEnabled(Qt::UIEffect effect) { if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui) return false; switch(effect) { case Qt::UI_AnimateMenu: return QApplicationPrivate::animate_menu; case Qt::UI_FadeMenu: return QApplicationPrivate::fade_menu; case Qt::UI_AnimateCombo: return QApplicationPrivate::animate_combo; case Qt::UI_AnimateTooltip: return QApplicationPrivate::animate_tooltip; case Qt::UI_FadeTooltip: return QApplicationPrivate::fade_tooltip; case Qt::UI_AnimateToolBox: return QApplicationPrivate::animate_toolbox; default: return QApplicationPrivate::animate_ui; } } 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; } void QApplication::beep() { } void QApplication::alert(QWidget *, int) { } void qt_init(QApplicationPrivate *priv, int type) { Q_UNUSED(priv); Q_UNUSED(type); qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QColormap::initialize(); if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) QToolTip::setPalette(*toolTipPalette); QApplicationPrivate::initializeWidgetFontHash(); qApp->setObjectName(appName); } #ifdef Q_OS_WIN // #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 #ifdef Q_OS_WIN if (displayDC) { ReleaseDC(0, displayDC); displayDC = 0; } #endif } QT_END_NAMESPACE