File indexing completed on 2024-12-08 09:42:34
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 2003,2004,2005,2006 Ian Reinhart Geiser <geiseri@kde.org> 0003 Copyright (C) 2003,2004,2005,2006 Matt Broadstone <mbroadst@gmail.com> 0004 Copyright (C) 2003,2004,2005,2006 Richard J. Moore <rich@kde.org> 0005 Copyright (C) 2003,2004,2005,2006 Erik L. Bunce <kde@bunce.us> 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 #include "eventproxy.h" 0023 0024 #include <QCoreApplication> 0025 0026 #include "qobject_binding.h" 0027 #include <kjs/interpreter.h> 0028 0029 #include "kjseglobal.h" 0030 #include "jseventmapper.h" 0031 #include "jseventutils.h" 0032 0033 using namespace KJSEmbed; 0034 0035 EventProxy::EventProxy(QObjectBinding *watch, KJS::Interpreter *interpreter) : 0036 QObject(watch->object<QObject>()), m_watch(watch), m_interpreter(interpreter) 0037 { 0038 m_refcount = 0l; 0039 } 0040 0041 EventProxy::~EventProxy() 0042 { 0043 } 0044 0045 bool EventProxy::isFiltered(QEvent::Type t) const 0046 { 0047 if (m_eventMask.size() <= t) { 0048 return false; 0049 } 0050 return m_eventMask.testBit(t); 0051 } 0052 0053 void EventProxy::addFilter(QEvent::Type t) 0054 { 0055 if (t == QEvent::None) { 0056 return; 0057 } 0058 if (!m_refcount) { 0059 m_watch->object<QObject>()->installEventFilter(this); 0060 } 0061 0062 if (m_eventMask.size() <= t) { 0063 m_eventMask.resize(t + 1); 0064 } 0065 0066 if (!m_eventMask.testBit(t)) { 0067 m_refcount++; 0068 m_eventMask.setBit(t); 0069 } 0070 } 0071 0072 void EventProxy::removeFilter(QEvent::Type t) 0073 { 0074 if (t == QEvent::None) { 0075 return; 0076 } 0077 if (m_eventMask.size() <= t) { 0078 return; 0079 } 0080 m_eventMask.clearBit(t); 0081 m_refcount--; 0082 if (!m_refcount) { 0083 m_watch->object<QObject>()->removeEventFilter(this); 0084 deleteLater(); 0085 } 0086 } 0087 0088 bool EventProxy::eventFilter(QObject * /*watched*/, QEvent *e) 0089 { 0090 if (isFiltered(e->type())) { 0091 return !callHandler(e); 0092 } 0093 return false; 0094 } 0095 0096 bool EventProxy::callHandler(QEvent *e) 0097 { 0098 // Be careful enabling this as if there are a lot of events then the event loop times 0099 // out and the app crashes with 'Alarm Clock'. 0100 // qDebug("JSObjectEventProxy::callHandler() event type %d" , e->type() ); 0101 0102 KJS::ExecState *exec = m_interpreter->globalExec(); 0103 KJS::Identifier id = JSEventMapper::mapper()->findEventHandler(e->type()); 0104 0105 KJS::JSObject *jsobj(m_watch); 0106 KJS::JSObject *fun = jsobj->get(exec, id)->toObject(exec); 0107 0108 KJS::JSValue *retValue; 0109 if (!fun->implementsCall()) { 0110 QString msg = i18n("Bad event handler: Object %1 Identifier %2 Method %3 Type: %4.", 0111 jsobj->className().ascii(), 0112 id.ascii(), 0113 fun->className().ascii(), 0114 e->type()); 0115 retValue = throwError(exec, KJS::TypeError, msg); 0116 } else { 0117 // Process args 0118 KJS::List args; 0119 args.append(JSEventUtils::event(exec, e)); 0120 0121 // Call handler 0122 retValue = fun->call(exec, jsobj, args); 0123 } 0124 0125 if (exec->hadException()) { 0126 if (m_interpreter->shouldPrintExceptions()) { 0127 KJS::JSLock lock; 0128 KJS::JSObject *exceptObj = retValue->toObject(exec); 0129 QString message = toQString(exceptObj->toString(exec)); 0130 QString sourceURL = toQString(exceptObj->get(exec, "sourceURL")->toString(exec)); 0131 int sourceId = exceptObj->get(exec, "sourceId")->toUInt32(exec); 0132 int line = exceptObj->get(exec, "line")->toUInt32(exec); 0133 (*KJSEmbed::conerr()) << i18n("Exception calling '%1' function from %2:%3:%4", id.ascii(), !sourceURL.isEmpty() ? sourceURL : QString::number(sourceId), line, message) << Qt::endl; 0134 } 0135 0136 // clear it so it doesn't stop other things 0137 exec->clearException(); 0138 return false; 0139 } 0140 0141 return true; 0142 } 0143