1
/* This file is part of the KDE project
2
Copyright (C) 2004 Joseph Wenninger <jowenn@kde.org>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Library General Public
6
License version 2 as published by the Free Software Foundation.
8
This library is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
Library General Public License for more details.
13
You should have received a copy of the GNU Library General Public License
14
along with this library; see the file COPYING.LIB. If not, write to
15
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16
Boston, MA 02110-1301, USA.
19
#include "plugin_katekjswrapper.h"
20
#include "plugin_katekjswrapper.moc"
23
#include <kjsembed/kjsembedpart.h>
24
#include <kjsembed/jssecuritypolicy.h>
25
#include <kjsembed/jsfactory.h>
26
#include <kjsembed/jsconsolewidget.h>
27
#include <kjs/interpreter.h>
28
#include <kjs/value.h>
29
#include <kjs/object.h>
30
#include <kgenericfactory.h>
33
#include <kstandarddirs.h>
34
#include <kate/mainwindow.h>
35
#include <kate/toolviewmanager.h>
36
#include <k3dockwidget.h>
40
K_EXPORT_COMPONENT_FACTORY( katekjswrapperplugin, KGenericFactory<PluginKateKJSWrapper>( "katekjswrapper" ) )
42
PluginKateKJSWrapperView::~PluginKateKJSWrapperView() {
45
void PluginKateKJSWrapperView::removeFromWindow() {
46
kDebug()<<"PluginKateKJSWrapperView::removeFromWindow";
47
for (QValueList<QGuardedPtr<KMDI::ToolViewAccessor> >::iterator it=toolviews.begin();it!=toolviews.end();it=toolviews.begin()) {
48
kDebug()<<"removeFromWindow: removing a toolview";
49
KMDI::ToolViewAccessor* tva=(*it);
51
win->toolViewManager()->removeToolView (tva);
53
win->guiFactory()->removeClient (this);
56
PluginKateKJSWrapper::PluginKateKJSWrapper( QObject* parent, const char* name, const QStringList& list)
57
: Kate::Plugin ( (Kate::Application *)parent, name ) {
58
m_views.setAutoDelete(true);
60
m_kateAppBindings=new Kate::JS::Bindings(this);
61
KJSEmbed::JSSecurityPolicy::setDefaultPolicy( KJSEmbed::JSSecurityPolicy::CapabilityAll );
62
m_part = new KJSEmbed::KJSEmbedPart(this);
63
KJS::Interpreter *js = m_part->interpreter();
65
KJSEmbed::JSFactory *factory=m_part->factory();
67
/* factories for kate app classes */
68
factory->addQObjectPlugin("Kate::Application",m_kateAppBindings);
69
factory->addQObjectPlugin("Kate::DocumentManager",m_kateAppBindings);
70
factory->addQObjectPlugin("Kate::MainWindow",m_kateAppBindings);
71
factory->addQObjectPlugin("Kate::PluginManager",m_kateAppBindings);
72
factory->addQObjectPlugin("Kate::InitPluginManager",m_kateAppBindings);
73
factory->addQObjectPlugin("Kate::ProjectManager",m_kateAppBindings);
74
factory->addQObjectPlugin("Kate::Project",m_kateAppBindings);
75
factory->addQObjectPlugin("Kate::ViewManager",m_kateAppBindings);
76
factory->addQObjectPlugin("Kate::View",m_kateAppBindings);
78
KJS::Object appobj=m_part->addObject(Kate::application(),"KATE");
79
js->globalObject().put( js->globalExec(), "addConfigPage", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::AddConfigPage,this )));
80
js->globalObject().put( js->globalExec(), "setConfigPages", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::SetConfigPages,this )));
81
js->globalObject().put( js->globalExec(), "removeConfigPage", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::RemoveConfigPage,this )));
82
js->globalObject().put( js->globalExec(), "setWindowConfiguration", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::SetWindowConfiguration,this )));
83
js->globalObject().put( js->globalExec(), "KJSConsole", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::KJSConsole,this )));
85
/* KJSEmbed::JSConsoleWidget *w=m_part->view();
88
kDebug()<<"m_scriptname="<<m_scriptname;
89
m_part->runFile(locate("appdata",QString("plugins/%1/%2.js").arg(m_scriptname).arg(m_scriptname)));
90
//"/home/jowenn/development/kde/cvs/kdeaddons/kate/kjswrapper/samples/test1.js");
93
PluginKateKJSWrapper::~PluginKateKJSWrapper()
100
uint PluginKateKJSWrapper::configPages () const {
101
KJS::Interpreter *js = m_part->interpreter();
102
KJS::ExecState *exec=js->globalExec();
104
if (! (m_configPageFactories.isNull() || (m_configPageFactories.type()==KJS::NullType))) {
105
KJS::Object constrs=m_configPageFactories.toObject(exec);
106
if (!exec->hadException()) {
107
if (QString(constrs.classInfo()->className)=="Array") {
108
kDebug()<<"config page constructor array detected";
109
uint size=constrs.get(exec,KJS::Identifier("length")).toInteger(exec);
110
if (exec->hadException()) {
111
exec->clearException();
112
kDebug()<<"Error while retrieving array length";
118
exec->clearException();
123
static KJS::Object getObj(KJS::Interpreter *js, KJS::Value mightBeArray, int id) {
124
KJS::ExecState *exec=js->globalExec();
125
KJS::Object constrs=mightBeArray.toObject(exec);
127
if (!exec->hadException()) {
128
if (QString(constrs.classInfo()->className)=="Array") {
129
kDebug()<<"config page constructor array detected";
130
constr=constrs.get(exec,id);
131
} else constr=mightBeArray;
134
return constr.toObject(js->globalExec());
137
QString PluginKateKJSWrapper::configPageName(uint id) const {
138
if (id>=configPages()) return "";
139
KJS::Interpreter *js = m_part->interpreter();
141
KJS::Object constr=getObj(js,m_configPageFactories,id);
143
KJS::Value o=constr.get(js->globalExec(),KJS::Identifier("name"));
144
QString retVal( o.toString(js->globalExec()).qstring() );
146
kDebug()<<"==============================================================================================";
147
kDebug()<<"PluginKateKJSWrapper::configPageName: "<<retVal;
148
kDebug()<<"==============================================================================================";
149
js->globalExec()->clearException();
153
QString PluginKateKJSWrapper::configPageFullName(uint id) const {
154
if (id>=configPages()) return "";
155
KJS::Interpreter *js = m_part->interpreter();
157
KJS::Object constr=getObj(js,m_configPageFactories,id);
159
KJS::Value o=constr.get(js->globalExec(),KJS::Identifier("fullName"));
160
QString retVal( o.toString(js->globalExec()).qstring() );
162
kDebug()<<"==============================================================================================";
163
kDebug()<<"PluginKateKJSWrapper::configPageFullName: "<<retVal;
164
kDebug()<<"==============================================================================================";
165
js->globalExec()->clearException();
169
QPixmap PluginKateKJSWrapper::configPagePixmap (uint /*number = 0*/,
170
int /*size = KIconLoader::SizeSmall*/) const {
175
Kate::PluginConfigPage* PluginKateKJSWrapper::configPage (uint id,
176
QWidget *w, const char */*name*/) {
177
kDebug()<<"PluginKateKJSWrapper::configPage";
179
if (id>=configPages()) return 0;
180
KJS::Interpreter *js = m_part->interpreter();
182
KJS::Object constr=getObj(js,m_configPageFactories,id);
184
if (js->globalExec()->hadException()) {
185
kDebug()<<"PluginKateKJSWrapper::configPage: exit 1";
186
js->globalExec()->clearException();
190
if (!constr.implementsConstruct()) {
191
kWarning()<<"config page factory has to be an object constructor";
195
KateKJSWrapperConfigPage *p=new KateKJSWrapperConfigPage(constr,this,w);
196
return (Kate::PluginConfigPage*)p;
198
KateKJSWrapperConfigPage* p = new KateKJSWrapperConfigPage(this, w);
200
connect( p, SIGNAL(configPageApplyRequest(KateKJSWrapperConfigPage*)),
201
this, SLOT(applyConfig(KateKJSWrapperConfigPage*)) );
202
return (Kate::PluginConfigPage*);*/
208
static KMDI::ToolViewAccessor *createToolView(KJSEmbed::JSFactory *factory,KJS::Interpreter *js, Kate::MainWindow *winN,KJS::Object win,KJS::Object viewConstructor) {
210
KJS::ExecState *exec = js->globalExec();
212
exec->clearException();
214
if (!viewConstructor.implementsConstruct()) return 0;
215
KJS::Value dockPosV=viewConstructor.get(exec,KJS::Identifier("startPosition"));
216
if (exec->hadException()) {
217
dockPos=KDockWidget::DockLeft;
218
exec->clearException();
220
dockPos=dockPosV.toInteger(exec);
221
if (exec->hadException()) {
222
dockPos=KDockWidget::DockLeft;
223
exec->clearException();
227
KJS::Value viewNameV=viewConstructor.get(exec,KJS::Identifier("name"));
228
if (exec->hadException()) {
229
viewName="kjs_unknown";
230
exec->clearException();
232
viewName=QString( viewNameV.toString(exec).qstring() );
233
if (exec->hadException()) {
234
viewName="kjs_unknown";
235
exec->clearException();
239
Kate::JS::ToolView *tv=new Kate::JS::ToolView(viewConstructor,exec,factory,params,viewName.utf8());
240
//params.append(factory->createProxy(exec,tv));
241
//KJS::Object otv=viewConstructor.construct(exec,params);
242
if (exec->hadException()) {
243
kDebug()<<"Error while calling constructor";
245
kDebug()<<exec->exception().toString(exec).qstring();
246
exec->clearException();
249
KMDI::ToolViewAccessor *tva=winN->toolViewManager()->addToolView((KDockWidget::DockPosition)dockPos,tv,
250
tv->icon()?(*(tv->icon())):QPixmap(),tv->caption());
251
kDebug()<<"****************************************************************************************";
252
kDebug()<<"PluginKateKJSWrapper: Toolview has been added";
253
kDebug()<<"****************************************************************************************";
258
PluginKateKJSWrapperView *PluginKateKJSWrapper::getViewObject(Kate::MainWindow *win) {
259
PluginKateKJSWrapperView * view=m_views[win];
261
view=new PluginKateKJSWrapperView();
263
connect(win,SIGNAL(destroyed()),this,SLOT(slotWindowDestroyed()));
264
m_views.insert(win,view);
265
KJS::Interpreter *js = m_part->interpreter();
266
KJS::ExecState *exec = js->globalExec();
267
view->actionCollectionObj=m_part->factory()->createProxy(exec,view->actionCollection());
268
view->winObj=m_part->factory()->createProxy(exec,win);
269
} else kDebug()<<"returning cached View/Window Object";
273
void PluginKateKJSWrapper::addView(Kate::MainWindow *win)
275
PluginKateKJSWrapperView * view=getViewObject(win); // this is needed to ensure correct caching the javascript object
276
KJS::Interpreter *js = m_part->interpreter();
277
KJS::ExecState *exec = js->globalExec();
278
exec->clearException();
279
kDebug()<<"****************************************************************************************";
280
kDebug()<<"PluginKateKJSWrapper::addView";
281
kDebug()<<"****************************************************************************************";
282
kDebug()<<"checking for newWindowHandler";
283
if (!m_newWindowHandler.isNull()) {
285
param.append(view->winObj);
286
KJS::Object newWinFunc=m_newWindowHandler.toObject(exec);
287
if (exec->hadException()) {
288
exec->clearException();
290
if (newWinFunc.implementsCall()) {
291
newWinFunc.call(exec,js->globalObject(),param);
292
if (exec->hadException()) {
293
kDebug()<<"Error while calling newWindowHandler";
294
exec->clearException();
299
if (exec->hadException()) kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): exec had an exception - 1";
301
kDebug()<<"checking for toolview constructors";
302
if (! (m_toolViewConstructors.isNull() || (m_toolViewConstructors.type()==KJS::NullType))) {
303
KJS::Object constrs=m_toolViewConstructors.toObject(exec);
304
if (!exec->hadException()) {
305
if (QString(constrs.classInfo()->className)=="Array") {
306
kDebug()<<"Toolview constructor array detected";
307
int size=constrs.get(exec,KJS::Identifier("length")).toInteger(exec);
308
if (exec->hadException()) {
309
exec->clearException();
310
kDebug()<<"Error while retrieving array length";
313
for (int i=0;i<size;i++) {
314
KJS::Object constrO=constrs.get(exec,i).toObject(exec);
315
if (exec->hadException()) {
316
exec->clearException();
318
KMDI::ToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrO);
320
view->toolviews.append(QGuardedPtr<KMDI::ToolViewAccessor>(w));
322
exec->clearException();
327
kDebug()<<"Single toolview constructor detected";
328
if (!constrs.implementsConstruct()) {
329
kWarning()<<"wrong object type";
331
KMDI::ToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrs);
333
view->toolviews.append(QGuardedPtr<KMDI::ToolViewAccessor>(w));
335
exec->clearException();
340
} else kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): no toolview constructors";
343
if (exec->hadException()) kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): exec had an exception - 2";
345
view->setComponentData (KComponentData("kate"));
346
view->setXMLFile(QString("plugins/%1/%2.rc").arg(m_scriptname).arg(m_scriptname));
347
win->guiFactory()->addClient (view);
351
void PluginKateKJSWrapper::slotWindowDestroyed() {
352
m_views.remove((void*)sender());
355
void PluginKateKJSWrapper::removeView(Kate::MainWindow *win)
357
//here toolviews must not be destroyed. Only cleanup functions called the view should be removed in the slot connected to the windows destroy signal only
358
m_views[win]->removeFromWindow();
363
void PluginKateKJSWrapper::applyConfig( KateKJSWrapperConfigPage *p )
366
config->writeEntry( "Command History Length", p->sb_cmdhistlen->value() );
367
// truncate the cmd hist if necessary?
368
config->writeEntry( "Start In", p->rg_startin->id(p->rg_startin->selected()) );
373
KateKJSWrapperConfigPage::KateKJSWrapperConfigPage(KJS::Object pageConstructor,PluginKateKJSWrapper* parent,
374
QWidget *parentWidget)
375
: Kate::PluginConfigPage( parentWidget ),m_plugin(parent)
377
QVBoxLayout *l=new QVBoxLayout(this);
380
KJS::Interpreter *js = parent->m_part->interpreter();
381
KJS::ExecState *exec = js->globalExec();
382
exec->clearException();
384
param.append(parent->m_part->factory()->createProxy(exec,this,0));
385
m_pageObject=pageConstructor.construct(exec,param);
389
static void callJS(KJSEmbed::KJSEmbedPart *p,KJS::Object o,const QString& funcName){
390
KJS::Interpreter *js = p->interpreter();
391
KJS::ExecState *exec = js->globalExec();
393
exec->clearException();
394
KJS::Value funcV=o.get(exec,KJS::Identifier(funcName));
395
if (exec->hadException()) {
397
#warning clear exception ?
401
KJS::Object func=funcV.toObject(exec);
402
if (exec->hadException()) {
404
#warning clear exception ?
408
if (func.implementsCall()) {
409
func.call(exec,o,param);
410
if (js->globalExec()->hadException()) {
412
#warning clear exception ?
419
void KateKJSWrapperConfigPage::apply()
421
callJS(m_plugin->m_part,m_pageObject,"apply");
424
void KateKJSWrapperConfigPage::reset()
426
callJS(m_plugin->m_part,m_pageObject,"reset");
429
void KateKJSWrapperConfigPage::defaults()
431
callJS(m_plugin->m_part,m_pageObject,"defaults");
435
Kate::JS::ToolView::ToolView(KJS::Object constr, KJS::ExecState *exec, KJSEmbed::JSFactory *factory, KJS::List parameters, const char *name):QVBox(0,name) {
436
parameters.append(factory->createProxy(exec,this));
437
handler=constr.construct(exec,parameters);
441
Kate::JS::ToolView::~ToolView() {