It sometimes makes sense to deliver the same event to the same object
(but different event handlers), so we shouldn't prevent that. Instead,
make sure that generic handlers are not called if at least one specialized
handler is registered.
QSet<QObject *> ignored;
uint type = event->type();
QSet<QObject *> ignored;
uint type = event->type();
+ bool checkDupes = false;
+
// special handling for numeric IrcEvents
if((type & ~IrcEventNumericMask) == IrcEventNumeric) {
::IrcEventNumeric *numEvent = static_cast< ::IrcEventNumeric *>(event);
// special handling for numeric IrcEvents
if((type & ~IrcEventNumericMask) == IrcEventNumeric) {
::IrcEventNumeric *numEvent = static_cast< ::IrcEventNumeric *>(event);
else {
int num = numEvent->number();
if(num > 0) {
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);
insertFilters(registeredFilters().value(type + num), filters);
- 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) {
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);
}
insertFilters(registeredFilters().value(type & EventGroupMask), filters);
}
for(it = handlers.begin(); it != handlers.end() && !event->isStopped(); ++it) {
QObject *obj = it->object;
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
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(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) {
+ ignored.insert(obj);
continue; // mmmh, event filter told us to not accept
continue; // mmmh, event filter told us to not accept
}
// finally, deliverance!
}
// finally, deliverance!
-void EventManager::insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing) {
+void EventManager::insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing, bool checkDupes) {
foreach(const Handler &handler, newHandlers) {
if(existing.isEmpty())
existing.append(handler);
else {
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<Handler>::iterator insertpos = existing.end();
QList<Handler>::iterator it = existing.begin();
while(it != existing.end()) {
QList<Handler>::iterator it = existing.begin();
while(it != existing.end()) {
- if(handler.priority > it->priority)
+ if(checkDupes && handler.object == it->object) {
+ insert = false;
+ }
+ if(insertpos == existing.end() && handler.priority > it->priority)
+ insertpos = it;
+
- existing.insert(it, handler);
+ if(insert)
+ existing.insert(it, handler);
inline HandlerHash ®isteredFilters() { return _registeredFilters; }
//! Add handlers to an existing sorted (by priority) handler list
inline HandlerHash ®isteredFilters() { return _registeredFilters; }
//! Add handlers to an existing sorted (by priority) handler list
- void insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing);
+ void insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing, bool checkDupes = false);
//! Add filters to an existing filter hash
void insertFilters(const QList<Handler> &newFilters, QHash<QObject *, Handler> &existing);
//! Add filters to an existing filter hash
void insertFilters(const QList<Handler> &newFilters, QHash<QObject *, Handler> &existing);