~ubuntu-branches/ubuntu/intrepid/kdesdk/intrepid-updates

« back to all changes in this revision

Viewing changes to kate/plugins/kjswrapper/plugin_katekjswrapper.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-05-28 10:11:43 UTC
  • mto: This revision was merged to the branch mainline in revision 37.
  • Revision ID: james.westby@ubuntu.com-20080528101143-gzc3styjz1b70zxu
Tags: upstream-4.0.80
ImportĀ upstreamĀ versionĀ 4.0.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright (C) 2004 Joseph Wenninger <jowenn@kde.org>
 
3
 
 
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.
 
7
 
 
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.
 
12
 
 
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.
 
17
*/
 
18
//BEGIN includes
 
19
#include "plugin_katekjswrapper.h"
 
20
#include "plugin_katekjswrapper.moc"
 
21
#include "bindings.h"
 
22
 
 
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>
 
31
#include <kdebug.h>
 
32
#include <qlayout.h>
 
33
#include <kstandarddirs.h>
 
34
#include <kate/mainwindow.h>
 
35
#include <kate/toolviewmanager.h>
 
36
#include <k3dockwidget.h>
 
37
#include <qvbox.h>
 
38
//END includes
 
39
 
 
40
K_EXPORT_COMPONENT_FACTORY( katekjswrapperplugin, KGenericFactory<PluginKateKJSWrapper>( "katekjswrapper" ) )
 
41
 
 
42
PluginKateKJSWrapperView::~PluginKateKJSWrapperView() {
 
43
}
 
44
 
 
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);
 
50
                toolviews.remove(it);
 
51
                win->toolViewManager()->removeToolView (tva);
 
52
      }
 
53
      win->guiFactory()->removeClient (this);
 
54
    }
 
55
 
 
56
PluginKateKJSWrapper::PluginKateKJSWrapper( QObject* parent, const char* name, const QStringList& list)
 
57
    : Kate::Plugin ( (Kate::Application *)parent, name ) {
 
58
    m_views.setAutoDelete(true);
 
59
    m_scriptname=list[0];
 
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();
 
64
 
 
65
    KJSEmbed::JSFactory *factory=m_part->factory();
 
66
 
 
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);
 
77
/* toplevel objects*/
 
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 )));   
 
84
 
 
85
/*    KJSEmbed::JSConsoleWidget *w=m_part->view();
 
86
    w->show();
 
87
    //w->show();*/
 
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");
 
91
}
 
92
 
 
93
PluginKateKJSWrapper::~PluginKateKJSWrapper()
 
94
{
 
95
        delete m_part;
 
96
        m_part=0;
 
97
}
 
98
 
 
99
 
 
100
uint PluginKateKJSWrapper::configPages () const {
 
101
        KJS::Interpreter *js = m_part->interpreter();
 
102
        KJS::ExecState *exec=js->globalExec();
 
103
 
 
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";
 
113
                        }
 
114
                        else  return size;
 
115
                } else return 1;
 
116
        }
 
117
    }
 
118
        exec->clearException();
 
119
        return 0;
 
120
}
 
121
 
 
122
 
 
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);
 
126
        KJS::Value constr;
 
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;
 
132
        
 
133
        }
 
134
        return constr.toObject(js->globalExec());
 
135
}
 
136
 
 
137
QString PluginKateKJSWrapper::configPageName(uint id) const {
 
138
        if (id>=configPages()) return "";
 
139
        KJS::Interpreter *js = m_part->interpreter();
 
140
 
 
141
        KJS::Object constr=getObj(js,m_configPageFactories,id);
 
142
 
 
143
        KJS::Value o=constr.get(js->globalExec(),KJS::Identifier("name"));
 
144
        QString retVal( o.toString(js->globalExec()).qstring() );
 
145
 
 
146
        kDebug()<<"==============================================================================================";
 
147
        kDebug()<<"PluginKateKJSWrapper::configPageName: "<<retVal;
 
148
        kDebug()<<"==============================================================================================";
 
149
        js->globalExec()->clearException();
 
150
        return retVal;
 
151
}
 
152
 
 
153
QString PluginKateKJSWrapper::configPageFullName(uint id) const {
 
154
        if (id>=configPages()) return "";
 
155
        KJS::Interpreter *js = m_part->interpreter();
 
156
 
 
157
        KJS::Object constr=getObj(js,m_configPageFactories,id);
 
158
 
 
159
        KJS::Value o=constr.get(js->globalExec(),KJS::Identifier("fullName"));
 
160
        QString retVal( o.toString(js->globalExec()).qstring() );
 
161
 
 
162
        kDebug()<<"==============================================================================================";
 
163
        kDebug()<<"PluginKateKJSWrapper::configPageFullName: "<<retVal;
 
164
        kDebug()<<"==============================================================================================";
 
165
        js->globalExec()->clearException();
 
166
        return retVal;
 
167
}
 
168
 
 
169
QPixmap PluginKateKJSWrapper::configPagePixmap (uint /*number = 0*/,
 
170
                              int /*size = KIconLoader::SizeSmall*/) const {
 
171
        return 0;
 
172
}
 
173
 
 
174
 
 
175
Kate::PluginConfigPage* PluginKateKJSWrapper::configPage (uint id, 
 
176
                                  QWidget *w, const char */*name*/) {
 
177
        kDebug()<<"PluginKateKJSWrapper::configPage";
 
178
 
 
179
        if (id>=configPages()) return 0;
 
180
        KJS::Interpreter *js = m_part->interpreter();
 
181
 
 
182
        KJS::Object constr=getObj(js,m_configPageFactories,id);
 
183
 
 
184
        if (js->globalExec()->hadException()) {
 
185
                kDebug()<<"PluginKateKJSWrapper::configPage: exit 1";
 
186
                js->globalExec()->clearException();
 
187
                return 0;
 
188
        }
 
189
        
 
190
        if (!constr.implementsConstruct()) {
 
191
                kWarning()<<"config page factory has to be an object constructor";
 
192
                return 0;
 
193
        }
 
194
 
 
195
        KateKJSWrapperConfigPage *p=new KateKJSWrapperConfigPage(constr,this,w);        
 
196
        return (Kate::PluginConfigPage*)p;
 
197
/*
 
198
  KateKJSWrapperConfigPage* p = new KateKJSWrapperConfigPage(this, w);
 
199
  //init
 
200
  connect( p, SIGNAL(configPageApplyRequest(KateKJSWrapperConfigPage*)), 
 
201
           this, SLOT(applyConfig(KateKJSWrapperConfigPage*)) );
 
202
  return (Kate::PluginConfigPage*);*/
 
203
}
 
204
 
 
205
 
 
206
 
 
207
 
 
208
static KMDI::ToolViewAccessor *createToolView(KJSEmbed::JSFactory *factory,KJS::Interpreter *js, Kate::MainWindow *winN,KJS::Object win,KJS::Object viewConstructor) {
 
209
        KJS::List params;
 
210
        KJS::ExecState *exec = js->globalExec();
 
211
        params.append(win);                             
 
212
        exec->clearException();
 
213
        int dockPos;
 
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();
 
219
        } else {
 
220
                dockPos=dockPosV.toInteger(exec);
 
221
                if (exec->hadException()) {
 
222
                        dockPos=KDockWidget::DockLeft;
 
223
                        exec->clearException();
 
224
                }
 
225
        }
 
226
        QString viewName;
 
227
        KJS::Value viewNameV=viewConstructor.get(exec,KJS::Identifier("name"));
 
228
        if (exec->hadException()) {
 
229
                viewName="kjs_unknown";
 
230
                exec->clearException();
 
231
        } else {
 
232
                viewName=QString( viewNameV.toString(exec).qstring() );
 
233
                if (exec->hadException()) {
 
234
                        viewName="kjs_unknown";
 
235
                        exec->clearException();
 
236
                }
 
237
        }
 
238
 
 
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";
 
244
                delete tv;
 
245
                kDebug()<<exec->exception().toString(exec).qstring();
 
246
                exec->clearException();
 
247
                return 0;
 
248
        }
 
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()<<"****************************************************************************************";
 
254
        return tva;
 
255
 
 
256
}
 
257
 
 
258
PluginKateKJSWrapperView *PluginKateKJSWrapper::getViewObject(Kate::MainWindow *win) {
 
259
    PluginKateKJSWrapperView * view=m_views[win];
 
260
    if (!view) {
 
261
        view=new PluginKateKJSWrapperView();
 
262
        view->win=win;
 
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";
 
270
    return view;
 
271
}
 
272
 
 
273
void PluginKateKJSWrapper::addView(Kate::MainWindow *win)
 
274
{
 
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()) {
 
284
        KJS::List param;
 
285
        param.append(view->winObj);
 
286
        KJS::Object newWinFunc=m_newWindowHandler.toObject(exec);
 
287
        if (exec->hadException()) {
 
288
                exec->clearException();
 
289
        } else {
 
290
                if (newWinFunc.implementsCall()) {
 
291
                        newWinFunc.call(exec,js->globalObject(),param);
 
292
                        if (exec->hadException()) {
 
293
                                kDebug()<<"Error while calling newWindowHandler";
 
294
                                exec->clearException();
 
295
                        }
 
296
                }
 
297
        }
 
298
    }
 
299
    if (exec->hadException()) kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): exec had an exception - 1";
 
300
 
 
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";
 
311
                        }
 
312
                        else {
 
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();
 
317
                                        } else {
 
318
                                                KMDI::ToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrO);
 
319
                                                if (w) {
 
320
                                                        view->toolviews.append(QGuardedPtr<KMDI::ToolViewAccessor>(w));
 
321
                                                }
 
322
                                                exec->clearException();
 
323
                                        }
 
324
                                }
 
325
                        }
 
326
                } else {
 
327
                        kDebug()<<"Single toolview constructor detected";
 
328
                        if (!constrs.implementsConstruct()) {
 
329
                                kWarning()<<"wrong object type";
 
330
                        } else {
 
331
                                KMDI::ToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrs);
 
332
                                if (w) {
 
333
                                        view->toolviews.append(QGuardedPtr<KMDI::ToolViewAccessor>(w));
 
334
                                }
 
335
                                exec->clearException();
 
336
                        }
 
337
                }
 
338
        
 
339
        }
 
340
    } else kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): no toolview constructors";
 
341
 
 
342
 
 
343
    if (exec->hadException()) kDebug()<<"void PluginKateKJSWrapper::addView(Kate::MainWindow *win): exec had an exception - 2";
 
344
 
 
345
    view->setComponentData (KComponentData("kate"));
 
346
    view->setXMLFile(QString("plugins/%1/%2.rc").arg(m_scriptname).arg(m_scriptname));
 
347
    win->guiFactory()->addClient (view);
 
348
}
 
349
 
 
350
 
 
351
void PluginKateKJSWrapper::slotWindowDestroyed() {
 
352
        m_views.remove((void*)sender());
 
353
}
 
354
 
 
355
void PluginKateKJSWrapper::removeView(Kate::MainWindow *win)
 
356
{
 
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();
 
359
}
 
360
 
 
361
 
 
362
 
 
363
void PluginKateKJSWrapper::applyConfig( KateKJSWrapperConfigPage *p )
 
364
{
 
365
#if 0
 
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()) );
 
369
  config->sync();
 
370
#endif
 
371
}
 
372
 
 
373
KateKJSWrapperConfigPage::KateKJSWrapperConfigPage(KJS::Object pageConstructor,PluginKateKJSWrapper* parent, 
 
374
                                                 QWidget *parentWidget)
 
375
  : Kate::PluginConfigPage( parentWidget ),m_plugin(parent)
 
376
{
 
377
        QVBoxLayout *l=new QVBoxLayout(this);
 
378
        l->setAutoAdd(true);
 
379
        l->activate();
 
380
        KJS::Interpreter *js = parent->m_part->interpreter();
 
381
        KJS::ExecState *exec = js->globalExec();
 
382
        exec->clearException();
 
383
        KJS::List param;
 
384
        param.append(parent->m_part->factory()->createProxy(exec,this,0));
 
385
        m_pageObject=pageConstructor.construct(exec,param);
 
386
}
 
387
 
 
388
 
 
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();
 
392
        KJS::List param;
 
393
        exec->clearException();
 
394
        KJS::Value funcV=o.get(exec,KJS::Identifier(funcName));
 
395
        if (exec->hadException()) {
 
396
#ifdef __GNUC__
 
397
#warning clear exception ?
 
398
#endif          
 
399
                return;
 
400
        }
 
401
        KJS::Object func=funcV.toObject(exec);
 
402
        if (exec->hadException()) {
 
403
#ifdef __GNUC__         
 
404
#warning clear exception ?
 
405
#endif          
 
406
                return;
 
407
        }
 
408
        if (func.implementsCall()) {
 
409
                func.call(exec,o,param);
 
410
                if (js->globalExec()->hadException()) {
 
411
#ifdef __GNUC__                 
 
412
#warning clear exception ?
 
413
#endif                  
 
414
                        return;
 
415
                }
 
416
        }
 
417
}
 
418
 
 
419
void KateKJSWrapperConfigPage::apply()
 
420
{
 
421
        callJS(m_plugin->m_part,m_pageObject,"apply");
 
422
}
 
423
 
 
424
void KateKJSWrapperConfigPage::reset()
 
425
{
 
426
        callJS(m_plugin->m_part,m_pageObject,"reset");
 
427
}
 
428
 
 
429
void KateKJSWrapperConfigPage::defaults()
 
430
{
 
431
        callJS(m_plugin->m_part,m_pageObject,"defaults");
 
432
}
 
433
 
 
434
 
 
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);
 
438
 
 
439
}
 
440
 
 
441
Kate::JS::ToolView::~ToolView() {
 
442
}
 
443