1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* Copyright (C) 2003-2004, Richard J. Moore <rich@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <qvariant.h>
#include "global.h"
#include "jsfactory.h"
#include "jseventmapper.h"
#include "jsobjectproxy.h"
#include "kjsembedpart.h"
#include "jsbinding.h"
#include "jsobjecteventproxy.h"
#ifndef QT_ONLY
#include "jsobjecteventproxy.moc"
#endif // QT_ONLY
namespace KJSEmbed {
// We'll need to increase this if we need to support any custom events
static const QEvent::Type QEVENT_TYPE_MAX = QEvent::TabletRelease;
JSObjectEventProxy::JSObjectEventProxy( JSObjectProxy *parent, const char *name )
: QObject( parent->object(), name ? name : "jsobjecteventproxy" ),
proxy( parent ), eventMask( QEVENT_TYPE_MAX ), refcount(0)
{
eventMask.fill( false );
}
JSObjectEventProxy::~JSObjectEventProxy()
{
}
bool JSObjectEventProxy::isFiltered( QEvent::Type t ) const
{
return eventMask.testBit( t );
}
void JSObjectEventProxy::addFilter( QEvent::Type t )
{
if ( !refcount )
proxy->object()->installEventFilter( this );
if ( !eventMask.testBit(t) ) {
refcount++;
eventMask.setBit( t );
}
kdDebug(80001) << "JSObjectEventProxy::addFilter done" << endl;
}
void JSObjectEventProxy::removeFilter( QEvent::Type t )
{
eventMask.clearBit( t );
refcount--;
if ( !refcount ) {
proxy->object()->removeEventFilter( this );
deleteLater();
}
kdDebug(80001) << "JSObjectEventProxy::removeFilter done" << endl;
}
bool JSObjectEventProxy::eventFilter( QObject * /*watched*/, QEvent *e )
{
if ( isFiltered(e->type()) )
callHandler( e );
return false;
}
KJS::Value JSObjectEventProxy::callHandler( QEvent *e )
{
// Be careful enabling this as if there are a lot of events then the event loop times
// out and the app crashes with 'Alarm Clock'.
// kdDebug(80001) << "JSObjectEventProxy::callHandler() event type " << e->type() << endl;
KJS::ExecState *exec = proxy->interpreter()->globalExec();
KJS::Identifier *id = proxy->part()->factory()->eventMapper()->findEventHandler( e->type() );
KJS::Object jsobj( proxy );
KJS::Object fun = jsobj.get(exec, *id ).toObject( exec );
if ( !fun.implementsCall() ) {
QString msg = i18n( "Bad event handler: Object %1 Identifier %2 Method %3 Type: %4." )
.arg(jsobj.className().ascii()).arg(id->ascii()).arg(fun.className().ascii()).arg(e->type());
return throwError(exec, msg, KJS::TypeError );
}
// Process args
KJS::List args;
KJS::Object obj = proxy->part()->factory()->createProxy( exec, e, proxy );
args.append( obj );
// Call handler
KJS::Value result = fun.call( exec, jsobj, args );
if ( exec->hadException() ) {
kdWarning( 80001 ) << "Exception in event handler '" << id->qstring() << "', "
<< exec->exception().toString(exec).qstring() << endl;
exec->clearException();
}
return result;
}
} // KJSEmbed
|