Logo Search packages:      
Sourcecode: kdeaddons version File versions

plugin_katekjswrapper.cpp

/* This file is part of the KDE project
   Copyright (C) 2004 Joseph Wenninger <jowenn@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 version 2 as published by the Free Software Foundation.

   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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/
//BEGIN includes
#include "plugin_katekjswrapper.h"
#include "plugin_katekjswrapper.moc"
#include "bindings.h"

#include <kjsembed/kjsembedpart.h>
#include <kjsembed/jssecuritypolicy.h>
#include <kjsembed/jsfactory.h>
#include <kjsembed/jsconsolewidget.h>
#include <kjs/interpreter.h>
#include <kjs/value.h>
#include <kjs/object.h>
#include <kgenericfactory.h>
#include <kdebug.h>
#include <qlayout.h>
#include <kstandarddirs.h>
#include <kate/mainwindow.h>
#include <kate/toolviewmanager.h>
#include <kdockwidget.h>
#include <qvbox.h>
//END includes

K_EXPORT_COMPONENT_FACTORY( katekjswrapperplugin, KGenericFactory<PluginKateKJSWrapper>( "katekjswrapper" ) )

//BEGIN obligatory stuff
class PluginKateKJSWrapperView : public KXMLGUIClient
{
  friend class KateKJSWrapper;;
 
  public:
    virtual ~PluginKateKJSWrapperView(){
      kdDebug()<<"PluginKateKJSWrapperView::~PluginKateKJSWrapperView"<<endl;
      for (QValueList<QGuardedPtr<KMdiToolViewAccessor> >::iterator it=toolviews.begin();it!=toolviews.end();it=toolviews.begin()) {
            kdDebug()<<"~PluginKateKJSWrapperView: removing a toolview"<<endl;
            KMdiToolViewAccessor* tva=(*it);
            toolviews.remove(it);
            win->toolViewManager()->removeToolView (tva);
      }
      win->guiFactory()->removeClient (this);
    }
    Kate::MainWindow *win;
    KJS::Object winObj;
    QValueList<QGuardedPtr<KMdiToolViewAccessor> > toolviews;
};
//END

PluginKateKJSWrapper::PluginKateKJSWrapper( QObject* parent, const char* name, const QStringList& list)
    : Kate::Plugin ( (Kate::Application *)parent, name ) {
    m_views.setAutoDelete(true);
    m_scriptname=list[0];
    m_kateAppBindings=new Kate::JS::Bindings(this);
    KJSEmbed::JSSecurityPolicy::setDefaultPolicy( KJSEmbed::JSSecurityPolicy::CapabilityAll );
    m_part = new KJSEmbed::KJSEmbedPart();
    KJS::Interpreter *js = m_part->interpreter();
    KJS::ExecState *exec = js->globalExec();
    KJSEmbed::JSFactory *factory=m_part->factory();

/* factories for kate app classes */
    factory->addQObjectPlugin("Kate::Application",m_kateAppBindings);
    factory->addQObjectPlugin("Kate::DocumentManager",m_kateAppBindings);
    factory->addQObjectPlugin("Kate::MainWindow",m_kateAppBindings);
    factory->addQObjectPlugin("Kate::PluginManager",m_kateAppBindings);
    factory->addQObjectPlugin("Kate::InitPluginManager",m_kateAppBindings);
    factory->addQObjectPlugin("Kate::ProjectManager",m_kateAppBindings);
    factory->addType("Kate::JS::ToolView");
/* toplevel objects*/
    KJS::Object appobj=m_part->addObject(Kate::application(),"KATE");
    js->globalObject().put( js->globalExec(),  "addConfigPage", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::AddConfigPage,this )));   
    js->globalObject().put( js->globalExec(),  "removeConfigPage", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::RemoveConfigPage,this )));   
    js->globalObject().put( js->globalExec(),  "setWindowConfiguration", KJS::Object(new Kate::JS::Management(js->globalExec(),Kate::JS::Management::SetWindowConfiguration,this )));   

    KJSEmbed::JSConsoleWidget *w=m_part->view();
    w->show();
    //w->show();
    kdDebug()<<"m_scriptname="<<m_scriptname<<endl;
    m_part->runFile(locate("appdata",QString("plugins/%1/%2.js").arg(m_scriptname).arg(m_scriptname)));
//"/home/jowenn/development/kde/cvs/kdeaddons/kate/kjswrapper/samples/test1.js");
}

PluginKateKJSWrapper::~PluginKateKJSWrapper()
{
      delete m_part;
      m_part=0;
}


uint PluginKateKJSWrapper::configPages () const {
      return m_configPageFactories.size();
}

QString PluginKateKJSWrapper::configPageName(uint id) const {
      if (id>=m_configPageFactories.size()) return "";
        KJS::Interpreter *js = m_part->interpreter();
      KJS::Value o=m_configPageFactories[id].toObject(js->globalExec()).get(js->globalExec(),KJS::Identifier("name"));
      QString retVal( o.toString(js->globalExec()).qstring() );
      kdDebug()<<"=============================================================================================="<<endl;
      kdDebug()<<"PluginKateKJSWrapper::configPageName: "<<retVal<<endl;
      kdDebug()<<"=============================================================================================="<<endl;
      js->globalExec()->clearException();
      return retVal;
}

QString PluginKateKJSWrapper::configPageFullName(uint id) const {
      if (id>=m_configPageFactories.size()) return "";
        KJS::Interpreter *js = m_part->interpreter();
      js->globalExec()->clearException();
      KJS::Value o=m_configPageFactories[id].toObject(js->globalExec()).get(js->globalExec(),KJS::Identifier("fullName"));
      QString retVal( o.toString(js->globalExec()).qstring() );
      js->globalExec()->clearException();
      return retVal;
}

QPixmap PluginKateKJSWrapper::configPagePixmap (uint /*number = 0*/,
                              int /*size = KIcon::SizeSmall*/) const {
      return 0;
}


Kate::PluginConfigPage* PluginKateKJSWrapper::configPage (uint id, 
                                  QWidget *w, const char */*name*/) {
      kdDebug()<<"PluginKateKJSWrapper::configPage"<<endl;
      if (id>=m_configPageFactories.size()) return 0;
      KJS::Interpreter *js = m_part->interpreter();
//    kdDebug()<<"PluginKateKJSWrapper::configPage: hadException on enter="<<js->globalExec()->hadException()<<endl;
      js->globalExec()->clearException();
      KJS::Value funcV=m_configPageFactories[id].toObject(js->globalExec()).get(js->globalExec(),KJS::Identifier("createPage"));
      if (js->globalExec()->hadException()) {
            kdDebug()<<"PluginKateKJSWrapper::configPage: exit 1"<<endl;
            js->globalExec()->clearException();
            return 0;
      }
      KJS::Object func=funcV.toObject(js->globalExec());
      if (js->globalExec()->hadException()) {
            kdDebug()<<"PluginKateKJSWrapper::configPage: exit 2"<<endl;
            js->globalExec()->clearException();
            return 0;
      }
      
      if (!func.implementsConstruct()) {
            kdWarning()<<"createPage property has to be an object constructor"<<endl;
            return 0;
      }

      KateKJSWrapperConfigPage *p=new KateKJSWrapperConfigPage(func,this,w);  
      return (Kate::PluginConfigPage*)p;
/*
  KateKJSWrapperConfigPage* p = new KateKJSWrapperConfigPage(this, w);
  //init
  connect( p, SIGNAL(configPageApplyRequest(KateKJSWrapperConfigPage*)), 
           this, SLOT(applyConfig(KateKJSWrapperConfigPage*)) );
  return (Kate::PluginConfigPage*);*/
}




static KMdiToolViewAccessor *createToolView(KJSEmbed::JSFactory *factory,KJS::Interpreter *js, Kate::MainWindow *winN,KJS::Object win,KJS::Object viewConstructor) {
      KJS::List params;
        KJS::ExecState *exec = js->globalExec();
      params.append(win);                       
      exec->clearException();
      int dockPos;
      if (!viewConstructor.implementsConstruct()) return 0;
      KJS::Value dockPosV=viewConstructor.get(exec,KJS::Identifier("startPosition"));
      if (exec->hadException()) {
            dockPos=KDockWidget::DockLeft;
            exec->clearException();
      } else {
            dockPos=dockPosV.toInteger(exec);
            if (exec->hadException()) {
                  dockPos=KDockWidget::DockLeft;
                  exec->clearException();
            }
      }
      QString viewName;
      KJS::Value viewNameV=viewConstructor.get(exec,KJS::Identifier("name"));
      if (exec->hadException()) {
            viewName="kjs_unknown";
            exec->clearException();
      } else {
            viewName=QString( viewNameV.toString(exec).qstring() );
            if (exec->hadException()) {
                  viewName="kjs_unknown";
                  exec->clearException();
            }
      }

      Kate::JS::ToolView *tv=new Kate::JS::ToolView(viewConstructor,exec,factory,params,viewName.utf8());
      //params.append(factory->createProxy(exec,tv));
      //KJS::Object otv=viewConstructor.construct(exec,params);
      if (exec->hadException()) {
            kdDebug()<<"Error while calling constructor"<<endl;
            delete tv;
            kdDebug()<<exec->exception().toString(exec).qstring()<<endl;
            exec->clearException();
            return 0;
      }
      KMdiToolViewAccessor *tva=winN->toolViewManager()->addToolView((KDockWidget::DockPosition)dockPos,tv,
            tv->icon()?(*(tv->icon())):QPixmap(),tv->caption());
      kdDebug()<<"****************************************************************************************"<<endl;
      kdDebug()<<"PluginKateKJSWrapper: Toolview has been added"<<endl;
      kdDebug()<<"****************************************************************************************"<<endl;
      return tva;

}


void PluginKateKJSWrapper::addView(Kate::MainWindow *win)
{
    PluginKateKJSWrapperView * view=new PluginKateKJSWrapperView();
    view->win=win;
    m_views.append(view);
    KJS::Interpreter *js = m_part->interpreter();
    KJS::ExecState *exec = js->globalExec();
    view->winObj=m_part->factory()->createProxy(exec,win);
    exec->clearException();
    kdDebug()<<"****************************************************************************************"<<endl;
    kdDebug()<<"PluginKateKJSWrapper::addView"<<endl;
    kdDebug()<<"****************************************************************************************"<<endl;
    kdDebug()<<"checking for newWindowHandler"<<endl;
    if (!m_newWindowHandler.isNull()) {
      KJS::List param;
      param.append(m_part->factory()->createProxy(exec,win));
      KJS::Object newWinFunc=m_newWindowHandler.toObject(exec);
      if (exec->hadException()) {
            exec->clearException();
      } else {
            if (newWinFunc.implementsCall()) {
                  newWinFunc.call(exec,js->globalObject(),param);
                  if (exec->hadException()) {
                        kdDebug()<<"Error while calling newWindowHandler"<<endl;
                        exec->clearException();
                  }
            }
      }
    }
    kdDebug()<<"checking for toolview constructors"<<endl;
    if (!m_toolViewConstructors.isNull()) {
      KJS::Object constrs=m_toolViewConstructors.toObject(exec);
      if (!exec->hadException()) {
            if (QString(constrs.classInfo()->className)=="Array") {
                  kdDebug()<<"Toolview constructor array detected"<<endl;
                  int size=constrs.get(exec,KJS::Identifier("length")).toInteger(exec);
                  if (exec->hadException()) {
                        exec->clearException(); 
                        kdDebug()<<"Error while retrieving array length"<<endl;
                  }
                  else {
                        for (int i=0;i<size;i++) {
                              KJS::Object constrO=constrs.get(exec,i).toObject(exec);
                              if (exec->hadException()) {
                                    exec->clearException();
                              } else {
                                    KMdiToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrO);
                                    if (w) {
                                          view->toolviews.append(QGuardedPtr<KMdiToolViewAccessor>(w));
                                    }
                                    exec->clearException();
                              }
                        }
                  }
            } else {
                  kdDebug()<<"Single toolview constructor detected"<<endl;
                  if (!constrs.implementsConstruct()) {
                        kdWarning()<<"wrong object type"<<endl;
                  } else {
                        KMdiToolViewAccessor *w=createToolView(m_part->factory(),js,win,view->winObj,constrs);
                        if (w) {
                              view->toolviews.append(QGuardedPtr<KMdiToolViewAccessor>(w));
                        }
                        exec->clearException();
                  }
            }
      
      }
    }

#if 0
    // TODO: doesn't this have to be deleted?
    PluginView *view = new PluginView ();
/*
    (void) new KAction ( i18n("Insert Command..."), "", 0, this,
                      SLOT( slotInsertCommand() ), view->actionCollection(),
                      "edit_insert_command" );
*/
    view->setInstance (new KInstance("kate"));
    view->setXMLFile("plugins/kateinsertcommand/ui.rc");
    win->guiFactory()->addClient (view);
    view->win = win;

   m_views.append (view);
#endif
}

void PluginKateKJSWrapper::removeView(Kate::MainWindow *win)
{
  for (uint z=0; z < m_views.count(); z++)
    if (m_views.at(z)->win == win)
    {
      PluginKateKJSWrapperView *view = m_views.at(z);
      m_views.remove (view);
//      delete view;
    }
}



void PluginKateKJSWrapper::applyConfig( KateKJSWrapperConfigPage *p )
{
#if 0
  config->writeEntry( "Command History Length", p->sb_cmdhistlen->value() );
  // truncate the cmd hist if nessecary?
  config->writeEntry( "Start In", p->rg_startin->id(p->rg_startin->selected()) );
  config->sync();
#endif
}

KateKJSWrapperConfigPage::KateKJSWrapperConfigPage(KJS::Object pageConstructor,PluginKateKJSWrapper* parent, 
                                                 QWidget *parentWidget)
  : Kate::PluginConfigPage( parentWidget ),m_plugin(parent)
{
      QVBoxLayout *l=new QVBoxLayout(this);
      l->setAutoAdd(true);
      l->activate();
      KJS::Interpreter *js = parent->m_part->interpreter();
      KJS::ExecState *exec = js->globalExec();
      exec->clearException();
      KJS::List param;
      param.append(parent->m_part->factory()->createProxy(exec,this,0));
      m_pageObject=pageConstructor.construct(exec,param);
}


static void callJS(KJSEmbed::KJSEmbedPart *p,KJS::Object o,const QString& funcName){
      KJS::Interpreter *js = p->interpreter();
      KJS::ExecState *exec = js->globalExec();
      KJS::List param;
      exec->clearException();
      KJS::Value funcV=o.get(exec,KJS::Identifier(funcName));
      if (exec->hadException()) {
#warning clear exception ?
            return;
      }
      KJS::Object func=funcV.toObject(exec);
      if (exec->hadException()) {
#warning clear exception ?
            return;
      }
      if (func.implementsCall()) {
            func.call(exec,o,param);
            if (js->globalExec()->hadException()) {
#warning clear exception ?
                  return;
            }
      }
}

00375 void KateKJSWrapperConfigPage::apply()
{
      callJS(m_plugin->m_part,m_pageObject,"apply");
}

void KateKJSWrapperConfigPage::reset()
{
      callJS(m_plugin->m_part,m_pageObject,"reset");
}

void KateKJSWrapperConfigPage::defaults()
{
      callJS(m_plugin->m_part,m_pageObject,"defaults");
}


Kate::JS::ToolView::ToolView(KJS::Object constr, KJS::ExecState *exec, KJSEmbed::JSFactory *factory, KJS::List parameters, const char *name):QVBox(0,name) {
      parameters.append(factory->createProxy(exec,this));
      handler=constr.construct(exec,parameters);

}

Kate::JS::ToolView::~ToolView() {
}


Generated by  Doxygen 1.6.0   Back to index