summaryrefslogtreecommitdiffstats
path: root/kjsembed/kjsembedpart.h
blob: 676e27c2990b2e47d1142b5cccc580f44c99d88b (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*
 *  Copyright (C) 2001-2003, 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.
 */

#ifndef KJSEMBEDJSCONSOLEPART_H
#define KJSEMBEDJSCONSOLEPART_H
#include "global.h"
#include <tqstringlist.h>

#ifndef QT_ONLY
#include <tdeparts/part.h>
#endif

#include <kjs/interpreter.h>
#include <kjs/object.h>
#include <kjs/value.h>

#include <kjsembed/jsbinding.h>

#ifndef QT_ONLY
#include <kjsembed/xmlactionclient.h>
#else
#include <kjsembed/qtstubs.h>
#endif

class TQWidget;

#define KJSEMBED_VERSION_STRING "0.3"
#define KJSEMBED_VERSION_MAJOR 0
#define KJSEMBED_VERSION_MINOR 3

/**
 * Namespace containing the KJSEmbed library.
 */
namespace KJSEmbed {

class JSObjectProxy;
class JSConsoleWidget;
class JSFactory;
class JSBuiltIn;

/**
 * A KPart for embedding KJS in an application.
 *
 * @version $Id$
 * @author Richard Moore, rich@kde.org
 * This is the easiest class for interacting and embedding the interpreter.  To use KJSEmbed in yours
 * application you can simply create a new KJSEmbedPart.  Once you have this object you can expose your
 * TQObect based classes with a few simple methods.  The interface also allows for the manipulation of TQVariant data
 * structures between Javascript and C++.  Complex Javascript arrays are transparently converted to TQMaps and TQValueLists
 * depending on the type of the Array.  KJSEmbed also provides transparent access to most TQVariant datatypes between
 * C++ and Javascript.  The easiest way to integrate KJSEmbed into your application is to create a TQObject based class
 * that will be your interface between C++ and Javascript.  This object than can expose C++ methods via Qt slots, and
 * TQVariant datatypes via Qt properties.  This class will also have an interface where C++ objects can call Javascript
 * methods.
 */
class KJSEMBED_EXPORT KJSEmbedPart : public KParts::ReadOnlyPart
{
    TQ_OBJECT
    TQ_PROPERTY( TQStringList constructorNames READ constructorNames )
    TQ_PROPERTY( TQCString versionString READ versionString )
    TQ_PROPERTY( int versionMajor READ versionMajor )
    TQ_PROPERTY( int versionMinor READ versionMinor )

public:
    /** Create a KJSEmbedPart. */
    KJSEmbedPart( TQObject *parent=0, const char *name=0 );

    /**
     * Creates a KJSEmbedPart for which the parents of the view and part are different.
     *
     * Caution! you cannot use parent = [KQ]Application and wparent = 0L.
     * This will cause a crash on exit since the widget will not be destroyed
     * but the part will get destroyed at the end of the TQApplication
     * constructor.  This results in the widget trying to do GUI related things
     * after the TQPaint stuff is destroyed.
     */
    KJSEmbedPart( TQWidget *wparent, const char *wname=0, TQObject *parent=0, const char *name=0 );

    /**
     * Create a KJSEmbedPart with the specified interpreter.
     *
     * See warning above.
     */
    KJSEmbedPart( KJS::Interpreter *js, TQWidget *wparent, const char *wname=0,
		  TQObject *parent=0, const char *name=0 );

    /** Cleans up. */
    virtual ~KJSEmbedPart();

    //
    // Version information
    //

    /** Returns the version of KJSEmbed. */
    TQCString versionString() const;

    /** Returns the minor version number of KJSEmbed. */
    int versionMajor() const;

    /** Returns the major version number of KJSEmbed. */
    int versionMinor() const;

    //
    // Script environment.
    //

    /** Checks to see if a desired method is available in Javascript.
    * @code
    * if ( js->hasMethod( "javascriptFunction" ) )
    *   ... // do something with that function.
    * else
    *   ... // function not present.
    */
    bool hasMethod( const TQString &methodName );

    /** Calls a method from Javascript starting from the global context.
    * @code
    * KJS::List args;
    * args.append(KJS::String("String Arg") );
    * args.append(KJS::Number(10) );
    * args.append(KJSEmbed::convertToValue(js->globalExec(), TQColor("blue" ) ) );
    * KJS::Value val = js->callMethod("javascriptFunction", args );
    * TQString myString = val.toString().qstring();
    * @endcode
    */

    KJS::Value callMethod(const TQString &methodName, const KJS::List &args) const;
    /** Gets a value from Javascript starting from the global context.
    * @code
    * KJS::Value val = js->getValue("someValue");
    * TQString myString = val.toString().qstring();
    * @endcode
    */
    KJS::Value getValue( const TQString &valueName ) const;

    /** Sets a value in a Javascript starting from the global context.
    * Note if this value is not present in the javascript context it will
    * become defined once this method is called.
    * @code
    * KJS::Value val = KJSEmbed::convertToValue(js->globalExec(), TQColor("blue"));
    * js->putValue("myVar", val);
    * @endcode
    */
    void putValue( const TQString &valueName, const KJS::Value &value);

    /** Convinence method that wraps around @ref putValue that only handles values
    * that are supported by TQVariant.
    * @code
    * js->putVariant( "myVar", TQColor("blue") );
    * @endcode
    */
    void putVariant( const TQString &valueName, const TQVariant &value);

    /** Convinence method that wraps around @ref getValue that only handles values
    * that are supported by TQVariant.
    * @code
    * TQColor value = js->getVariant( "myVar").toColor();
    * @endcode
    */
    TQVariant getVariant( const TQString &valueName ) const;

    /** Returns the global object of the interpreter. */
    KJS::Object globalObject() const { return js->globalObject(); }

    /** Returns the completion object for the last script executed. */
    KJS::Completion completion() const { return res; }

    /** Returns the JS object of the part. */
    KJS::Object partObject() const { return partobj; }

    /**
     * Publishes 'obj' as property 'name' of the global object. If 'name' is
     * not specified then the name property of 'obj' is used instead.
     * @code
     * // In C++
     * TQObject *myClass = new TQObjectBasedClass(this, "jsObject");
     * js->addObject( myClass );
     * // In Javascript
     * jsObject.someProperty = "Test Property";
     * // In C++ again
     * kdDebug() << "New Value: " << myClass->someProperty() << endl;  // displays "Test Property"
     * @endcode
     */
    KJS::Object addObject( TQObject *obj, const char *name=0 );

    /**
     * Publishes 'obj' as property 'name' of object 'parent'. The binding is defined
     * using @ref JSObjectProxy, and is subject to the current default SecurityPolicy.
     */
    KJS::Object addObject( TQObject *obj, KJS::Object &parent, const char *name=0 );

    /** Returns a JS::Object that provides a binding to the specified TQObject. */
    KJS::Object bind( TQObject *obj );

    //
    // Query the supported types
    //

    /** Returns a list of the names of the constructors of this interpreter. */
    TQStringList constructorNames() const;

    /** Returns a JS Array of the constructors of this interpreter. */
    KJS::Value constructors() const;

    /** Returns a list of the constructors of this interpreter. */
    KJS::List constructorList() const;

public slots:
    //
    // Reimplement the KPart API.
    //

    /** Returns the view widget, creating one if required.*/
    virtual KJSEmbed::JSConsoleWidget *view();

    /** Opens a URL. If the URL has the protocol 'javascript' then it is executed. */
    virtual bool openURL( const KURL &url );

    //
    // XML Action Handling
    //

    /** Returns the current XMLActionClient. */
    KJSEmbed::XMLActionClient *actionClient() const { return xmlclient; }

    /** Loads the XML actions defined in the specified file to the default XMLActionClient. */
    bool loadActionSet( const TQString &file );

    //
    // Script environemnt
    //

    /** Returns the current interpreter. */
    KJS::Interpreter *interpreter() const { return js; }

    /** Returns the execution context of the interpreter. */
    KJS::ExecState *globalExec() const { return js->globalExec(); }

    /** Returns the current factory object. */
    JSFactory *factory() const { return jsfactory; }

    /** Evaluates the specified string, with the specified value as 'this'. */
    virtual KJS::Value evaluate( const TQString &script, const KJS::Value &self=KJS::Null() );

    /** Executes the specified string, with the specified value as 'this'. */
    bool execute( const TQString &script, const KJS::Value &self=KJS::Null() );

    /**
     * Executes the specified string, with the specified value as 'this' and sets
     * result to the completion object returned by the interpreter.
     */
    virtual bool execute( KJS::Completion &result, const TQString &script, const KJS::Value &self );

    /** Loads and runs the specified file. */
    virtual bool runFile( const TQString &filename, const KJS::Value &self=KJS::Null() );

    /**
     * Loads but does not execute the specified script file. If the
     * first line of the file starts with the string '#!' then that
     * line will be omitted from the returned string.
     */
    TQString loadFile( const TQString &file );

protected:
    /** Creates the interpreter. */
    void createInterpreter();

    /**
     * Creates the built-in objects and methods in the specified parent object
     * normally the global object of the interpreter. This method is called
     * automatically unless you create the part with a custom interpreter, if
     * you do then you have to call this method yourself if you want the
     * built-ins to be available.
     */
    void createBuiltIn( KJS::ExecState *exec, KJS::Object &parent );

    /** Sets up the XMLActionClient. */
    void createActionClient();

    /** Reimplemented to disable file support. */
    virtual bool openFile() { return false; }

    /** @internal Hook for virtual that cannot break compatibility. */
    virtual void virtual_hook( int id, void *data );

private:
    XMLActionClient *xmlclient;
    JSConsoleWidget *jsConsole;
    JSFactory *jsfactory;
    JSBuiltIn *builtins;
    TQWidget *widgetparent;
    TQCString widgetname;

    KJS::Object partobj;
    KJS::Completion res;
    KJS::Interpreter *js;
    bool deletejs;

    class KJSEmbedPartPrivate *d;
};


} // namespace KJSEmbed

#endif // KJSEMBEDJSCONSOLEPART_H