X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Feventmanager.cpp;h=fd3cf9bdbc655a44e5e8bd2b8fed03eb40570b84;hp=7303ea5af55fcbb874ab82f0dcf676de4801fba4;hb=d9588ab4fff449eeb77ebb03a6cb1c5c91d1449d;hpb=712781ef33198acb7267e02ee6f8f9bfc8598d5a diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp index 7303ea5a..fd3cf9bd 100644 --- a/src/common/eventmanager.cpp +++ b/src/common/eventmanager.cpp @@ -193,6 +193,8 @@ void EventManager::dispatchEvent(Event *event) { QSet ignored; uint type = event->type(); + bool checkDupes = false; + // special handling for numeric IrcEvents if((type & ~IrcEventNumericMask) == IrcEventNumeric) { ::IrcEventNumeric *numEvent = static_cast< ::IrcEventNumeric *>(event); @@ -201,19 +203,20 @@ void EventManager::dispatchEvent(Event *event) { else { int num = numEvent->number(); if(num > 0) { - insertHandlers(registeredHandlers().value(type + num), handlers); + insertHandlers(registeredHandlers().value(type + num), handlers, false); insertFilters(registeredFilters().value(type + num), filters); + checkDupes = true; } } } // exact type - insertHandlers(registeredHandlers().value(type), handlers); + insertHandlers(registeredHandlers().value(type), handlers, checkDupes); insertFilters(registeredFilters().value(type), filters); // check if we have a generic handler for the event group if((type & EventGroupMask) != type) { - insertHandlers(registeredHandlers().value(type & EventGroupMask), handlers); + insertHandlers(registeredHandlers().value(type & EventGroupMask), handlers, true); insertFilters(registeredFilters().value(type & EventGroupMask), filters); } @@ -222,18 +225,18 @@ void EventManager::dispatchEvent(Event *event) { for(it = handlers.begin(); it != handlers.end() && !event->isStopped(); ++it) { QObject *obj = it->object; - if(ignored.contains(obj)) // we only deliver an event once to any given object + if(ignored.contains(obj)) // object has filtered the event continue; - ignored.insert(obj); - if(filters.contains(obj)) { // we have a filter, so let's check if we want to deliver the event Handler filter = filters.value(obj); bool result = false; void *param[] = {Q_RETURN_ARG(bool, result).data(), Q_ARG(Event *, event).data() }; obj->qt_metacall(QMetaObject::InvokeMetaMethod, filter.methodIndex, param); - if(!result) + if(!result) { + ignored.insert(obj); continue; // mmmh, event filter told us to not accept + } } // finally, deliverance! @@ -245,19 +248,27 @@ void EventManager::dispatchEvent(Event *event) { delete event; } -void EventManager::insertHandlers(const QList &newHandlers, QList &existing) { +void EventManager::insertHandlers(const QList &newHandlers, QList &existing, bool checkDupes) { foreach(const Handler &handler, newHandlers) { if(existing.isEmpty()) existing.append(handler); else { - // need to insert it at the proper position + // need to insert it at the proper position, but only if we don't yet have a handler for this event and object! + bool insert = true; + QList::iterator insertpos = existing.end(); QList::iterator it = existing.begin(); while(it != existing.end()) { - if(handler.priority > it->priority) + if(checkDupes && handler.object == it->object) { + insert = false; break; + } + if(insertpos == existing.end() && handler.priority > it->priority) + insertpos = it; + ++it; } - existing.insert(it, handler); + if(insert) + existing.insert(it, handler); } } }