Logo Search packages:      
Sourcecode: qt4-x11 version File versions  Download package

bool QApplication::notify ( QObject receiver,
QEvent e 
) [virtual]

Reimplemented from QCoreApplication.

Definition at line 3065 of file qapplication.cpp.

References QEvent::accept(), QWidget::acceptDrops, QMouseEvent::button(), QMouseEvent::buttons(), QWheelEvent::buttons(), QWheelEvent::delta(), QTabletEvent::device(), event(), QObject::eventFilter(), QWidget::focusPolicy, QMouseEvent::globalPos(), QTabletEvent::globalPos(), QHelpEvent::globalPos(), QWheelEvent::globalPos(), QContextMenuEvent::globalPos(), QWidget::hasMouseTracking(), QTabletEvent::hiResGlobalPos(), QEvent::ignore(), QEvent::isAccepted(), QWidget::isEnabled(), QObject::isWidgetType(), QWidget::isWindow(), QKeyEvent::key(), QDropEvent::keyboardModifiers(), QReadWriteLock::lockForRead(), QWidget::mapFromGlobal(), QWidget::mapToParent(), QDropEvent::mimeData(), QKeyEvent::modifiers(), QInputEvent::modifiers(), QDropEvent::mouseButtons(), QWheelEvent::orientation(), QDropEvent::p, QWidget::parentWidget(), QTabletEvent::pointerType(), QMouseEvent::pos(), QContextMenuEvent::pos(), QWheelEvent::pos(), QHelpEvent::pos(), QDropEvent::pos(), QTabletEvent::pos(), QWidget::pos, QDropEvent::possibleActions(), QTabletEvent::pressure(), QContextMenuEvent::reason(), QDragMoveEvent::rect, QTabletEvent::rotation(), QCoreApplication::sendEvent(), QEvent::setAccepted(), QWidget::setAttribute(), QWidget::setFocus(), QRect::setTopLeft(), QEvent::spont, QEvent::spontaneous(), QTabletEvent::tangentialPressure(), QWidget::testAttribute(), QRect::topLeft(), QEvent::type(), QTabletEvent::uniqueId(), QReadWriteLock::unlock(), QWidget::window(), QTabletEvent::xTilt(), QTabletEvent::yTilt(), and QTabletEvent::z().

{
    Q_D(QApplication);
    // no events are delivered after ~QCoreApplication() has started
    if (QApplicationPrivate::is_app_closing)
        return true;

    if (receiver == 0) {                        // serious error
        qWarning("QApplication::notify: Unexpected null receiver");
        return true;
    }

#ifndef QT_NO_DEBUG
    d->checkReceiverThread(receiver);
#endif

#ifdef QT3_SUPPORT
    if (e->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
        receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(e)->child());
#endif // QT3_SUPPORT

    // capture the current mouse/keyboard state
    if(e->spontaneous()) {
        if(e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
            QKeyEvent *ke = static_cast<QKeyEvent*>(e);
            QApplicationPrivate::modifier_buttons = ke->modifiers();
        } else if(e->type() == QEvent::MouseButtonPress
                  || e->type() == QEvent::MouseButtonRelease) {
            QMouseEvent *me = static_cast<QMouseEvent*>(e);
            QApplicationPrivate::modifier_buttons = me->modifiers();
            if(me->type() == QEvent::MouseButtonPress)
                QApplicationPrivate::mouse_buttons |= me->button();
            else
                QApplicationPrivate::mouse_buttons &= ~me->button();
        }
    }

    // User input and window activation makes tooltips sleep
    switch (e->type()) {
    case QEvent::Wheel:
    case QEvent::ActivationChange:
    case QEvent::KeyPress:
    case QEvent::KeyRelease:
    case QEvent::FocusOut:
    case QEvent::FocusIn:
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
        d->toolTipFallAsleep.stop();
    case QEvent::Leave:
        d->toolTipWakeUp.stop();
    default:
        break;
    }

    bool res = false;
    if (!receiver->isWidgetType()) {
        res = d->notify_helper(receiver, e);
    } else switch (e->type()) {
#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
    case QEvent::Accel:
        {
            if (d->use_compat()) {
                QKeyEvent* key = static_cast<QKeyEvent*>(e);
                res = d->notify_helper(receiver, e);

                if (!res && !key->isAccepted())
                    res = d->qt_dispatchAccelEvent(static_cast<QWidget *>(receiver), key);

                // next lines are for compatibility with Qt <= 3.0.x: old
                // QAccel was listening on toplevel widgets
                if (!res && !key->isAccepted() && !static_cast<QWidget *>(receiver)->isWindow())
                    res = d->notify_helper(static_cast<QWidget *>(receiver)->window(), e);
            }
            break;
        }
#endif //QT3_SUPPORT && !QT_NO_SHORTCUT
    case QEvent::ShortcutOverride:
    case QEvent::KeyPress:
    case QEvent::KeyRelease:
        {
            if (!receiver->isWidgetType()) {
                res = d->notify_helper(receiver, e);
                break;
            }
            QWidget* w = static_cast<QWidget*>(receiver);
            QKeyEvent* key = static_cast<QKeyEvent*>(e);
#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
            if (d->use_compat() && d->qt_tryComposeUnicode(w, key))
                break;
#endif
            if (key->type()==QEvent::KeyPress) {
#ifndef QT_NO_SHORTCUT
                // Try looking for a Shortcut before sending key events
                if (res = qApp->d_func()->shortcutMap.tryShortcutEvent(w, key))
                    return res;
#endif
                qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
                                       || key->key() == Qt::Key_Tab
                                       || key->key() == Qt::Key_Left
                                       || key->key() == Qt::Key_Up
                                       || key->key() == Qt::Key_Right
                                       || key->key() == Qt::Key_Down);
            }
            bool def = key->isAccepted();
            QPointer<QWidget> pw = w;
            while (w) {
                if (def)
                    key->accept();
                else
                    key->ignore();
                res = d->notify_helper(w, e);
                if ((res && key->isAccepted())
                    /*
                       QLineEdit will emit a signal on Key_Return, but
                       ignore the event, and sometimes the connected
                       slot deletes the QLineEdit (common in itemview
                       delegates), so we have to check if the widget
                       was destroyed even if the event was ignored (to
                       prevent a crash)

                       note that we don't have to reset pw while
                       propagating (because the original receiver will
                       be destroyed if one of it's ancestors is)
                    */
                    || !pw
                    || w->isWindow() || !w->parentWidget()) {
                    break;
                }
                w = w->parentWidget();
            }
            qt_in_tab_key_event = false;
        }
        break;
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
    case QEvent::MouseMove:
        {
            QWidget* w = static_cast<QWidget *>(receiver);

            QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
            QPoint relpos = mouse->pos();

            if (e->spontaneous()) {

                if (e->type() == QEvent::MouseButtonPress) {
                    QWidget *fw = w;
                    while (fw) {
                        if (fw->isEnabled() && (fw->focusPolicy() & Qt::ClickFocus)) {
                            fw->setFocus(Qt::MouseFocusReason);
                            break;
                        }
                        if (fw->isWindow())
                            break;
                        fw = fw->parentWidget();
                    }
                }

                if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
                    d->toolTipWidget = w;
                    d->toolTipPos = relpos;
                    d->toolTipGlobalPos = mouse->globalPos();
                    d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
                }
            }

            bool eventAccepted = mouse->isAccepted();

            QPointer<QWidget> pw = w;
            while (w) {
                QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->buttons(),
                               mouse->modifiers());
                me.spont = mouse->spontaneous();
                // throw away any mouse-tracking-only mouse events
                if (!w->hasMouseTracking()
                    && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
                    // but still send them through all application event filters (normally done by notify_helper)
                    QReadWriteLock *lock = QObjectPrivate::readWriteLock();
                    if (lock)
                        lock->lockForRead();
                    for (int i = 0; i < d->eventFilters.size(); ++i) {
                        register QObject *obj = d->eventFilters.at(i);
                        if (lock)
                            lock->unlock();
                        if (obj && obj->eventFilter(w, w == receiver ? mouse : &me)) {
                            lock = 0;
                            break;
                        }
                        if (lock)
                            lock->lockForRead();
                    }
                    if (lock)
                        lock->unlock();
                    res = true;
                } else {
                    w->setAttribute(Qt::WA_NoMouseReplay, false);
                    res = d->notify_helper(w, w == receiver ? mouse : &me);
                    e->spont = false;
                }
                eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
                if (res && eventAccepted)
                    break;
                if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
                    break;
                relpos += w->pos();
                w = w->parentWidget();
            }

            mouse->setAccepted(eventAccepted);

            if (e->type() == QEvent::MouseMove) {
                if (!pw)
                    break;

                w = static_cast<QWidget *>(receiver);
                relpos = mouse->pos();
                QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
                while (w) {
                    if (w->testAttribute(Qt::WA_Hover) &&
                        (!qApp->activePopupWidget() || qApp->activePopupWidget() == w->window())) {
                        QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff);
                        d->notify_helper(w, &he);
                    }
                    if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
                        break;
                    relpos += w->pos();
                    w = w->parentWidget();
                }
            }

            d->hoverGlobalPos = mouse->globalPos();
        }
        break;
#ifndef QT_NO_WHEELEVENT
    case QEvent::Wheel:
        {
            QWidget* w = static_cast<QWidget *>(receiver);
            QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
            QPoint relpos = wheel->pos();
            bool eventAccepted = wheel->isAccepted();

            if (e->spontaneous()) {
                QWidget *fw = w;
                while (fw) {
                    if (fw->isEnabled() && (fw->focusPolicy() & Qt::WheelFocus) == Qt::WheelFocus) {
                        fw->setFocus(Qt::MouseFocusReason);
                        break;
                    }
                    if (fw->isWindow())
                        break;
                    fw = fw->parentWidget();
                }
            }

            while (w) {
                QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->buttons(),
                               wheel->modifiers(), wheel->orientation());
                we.spont = wheel->spontaneous();
                res = d->notify_helper(w, w == receiver ? wheel : &we);
                eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
                e->spont = false;
                if ((res && eventAccepted)
                    || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
                    break;

                relpos += w->pos();
                w = w->parentWidget();
            }
            wheel->setAccepted(eventAccepted);
        }
        break;
#endif
    case QEvent::ContextMenu:
        {
            QWidget* w = static_cast<QWidget *>(receiver);
            QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
            QPoint relpos = context->pos();
            bool eventAccepted = context->isAccepted();
            while (w) {
                QContextMenuEvent ce(context->reason(), relpos, context->globalPos());
                ce.spont = e->spontaneous();
                res = d->notify_helper(w, w == receiver ? context : &ce);
                eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
                e->spont = false;

                if ((res && eventAccepted)
                    || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
                    break;

                relpos += w->pos();
                w = w->parentWidget();
            }
            context->setAccepted(eventAccepted);
        }
        break;
#ifndef QT_NO_TABLETEVENT
    case QEvent::TabletMove:
    case QEvent::TabletPress:
    case QEvent::TabletRelease:
        {
            QWidget *w = static_cast<QWidget *>(receiver);
            QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
            QPoint relpos = tablet->pos();
            bool eventAccepted = tablet->isAccepted();
            while (w) {
                QTabletEvent te(tablet->type(), relpos, tablet->globalPos(),
                                tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(),
                                tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
                                tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
                                tablet->modifiers(), tablet->uniqueId());
                te.spont = e->spontaneous();
                res = d->notify_helper(w, w == receiver ? tablet : &te);
                eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
                e->spont = false;
                if ((res && eventAccepted)
                     || w->isWindow()
                     || w->testAttribute(Qt::WA_NoMousePropagation))
                    break;

                relpos += w->pos();
                w = w->parentWidget();
            }
            tablet->setAccepted(eventAccepted);
            qt_tabletChokeMouse = tablet->isAccepted();
        }
        break;
#endif // QT_NO_TABLETEVENT

#if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
    case QEvent::ToolTip:
    case QEvent::WhatsThis:
    case QEvent::QueryWhatsThis:
        {
            QWidget* w = static_cast<QWidget *>(receiver);
            QHelpEvent *help = static_cast<QHelpEvent*>(e);
            QPoint relpos = help->pos();
            bool eventAccepted = help->isAccepted();
            while (w) {
                QHelpEvent he(help->type(), relpos, help->globalPos());
                he.spont = e->spontaneous();
                res = d->notify_helper(w, w == receiver ? help : &he);
                e->spont = false;
                eventAccepted = (w == receiver ? help : &he)->isAccepted();
                if ((res && eventAccepted) || w->isWindow())
                    break;

                relpos += w->pos();
                w = w->parentWidget();
            }
            help->setAccepted(eventAccepted);
        }
        break;
#endif
#if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
    case QEvent::StatusTip:
    case QEvent::WhatsThisClicked:
        {
            QWidget *w = static_cast<QWidget *>(receiver);
            while (w) {
                res = d->notify_helper(w, e);
                if ((res && e->isAccepted()) || w->isWindow())
                    break;
                w = w->parentWidget();
            }
        }
        break;
#endif

#ifndef QT_NO_DRAGANDDROP
    case QEvent::DragEnter: {
            QWidget* w = static_cast<QWidget *>(receiver);
            QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
#ifdef Q_WS_MAC
            // HIView has a slight difference in how it delivers events to children and parents
            // It will not give a leave to a child's parent when it enters a child.
            QWidget *currentTarget = QDragManager::self()->currentTarget();
            if (currentTarget) {
                // Assume currentTarget did not get a leave
                QDragLeaveEvent event;
                QApplication::sendEvent(currentTarget, &event);
            }
#endif
            while (w) {
                if (w->isEnabled() && w->acceptDrops()) {
                    res = d->notify_helper(w, dragEvent);
                    if (res && dragEvent->isAccepted()) {
                        QDragManager::self()->setCurrentTarget(w);
                        break;
                    }
                }
                if (w->isWindow())
                    break;
                dragEvent->p = w->mapToParent(dragEvent->p);
                w = w->parentWidget();
            }
        }
        break;
    case QEvent::DragMove:
    case QEvent::Drop:
    case QEvent::DragLeave: {
            QWidget * w = QDragManager::self()->currentTarget();
            if (!w) {
#ifdef Q_WS_MAC
                // HIView has a slight difference in how it delivers events to children and parents
                // It will not give an enter to a child's parent when it leaves the child.
                if (e->type() == QEvent::DragLeave)
                    break;
                // Assume that w did not get an enter.
                QDropEvent *dropEvent = static_cast<QDropEvent *>(e);
                QDragEnterEvent dragEnterEvent(dropEvent->pos(), dropEvent->possibleActions(),
                                               dropEvent->mimeData(), dropEvent->mouseButtons(),
                                               dropEvent->keyboardModifiers());
                QApplication::sendEvent(receiver, &dragEnterEvent);
                w = QDragManager::self()->currentTarget();
                if (!w)
#endif
                    break;
            }
            if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
                QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
                QWidget *origReciver = static_cast<QWidget *>(receiver);
                while (origReciver && w != origReciver) {
                    dragEvent->p = origReciver->mapToParent(dragEvent->p);
                    origReciver = origReciver->parentWidget();
                }
            }
            res = d->notify_helper(w, e);
            if (e->type() != QEvent::DragMove) {
                QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
            } else {
                QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(e);
                moveEvent->rect.setTopLeft(static_cast<QWidget *>(receiver)->mapFrom(w, moveEvent->rect.topLeft()));
            }
        }
        break;
#endif

    default:
        res = d->notify_helper(receiver, e);
        break;
    }

    return res;
}


Generated by  Doxygen 1.6.0   Back to index