#include "bindings.h" #include "bindings.moc" #include "plugin_katekjswrapper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kate::JS; Bindings::Bindings(TQObject *parent): KJSEmbed::Bindings::JSBindingPlugin(parent,"KateAppBindings",TQStringList()) { } Bindings::~Bindings() { } KJS::Object Bindings::createBinding(KJSEmbed::KJSEmbedPart *jspart, KJS::ExecState *exec, const KJS::List &args) const { /* kdDebug() << "Loading a custom object" << endl; DocumentManager *obj = new DocumentManager(); JSOpaqueProxy *prx = new JSOpaqueProxy( (void *) obj, "Kate::JS::DocumentManager" ); KJS::Object proxyObj(prx); DocumentManagerImp::addBindings( exec, proxyObj ); return proxyObj; */ return KJS::Object(); } void Bindings::addBindings(KJS::ExecState *exec, KJS::Object &target) const { kdDebug()<<"Kate::JS::Bindings:: ADDING CUSTOM BINDINGS"<(proxy->object()); if (dm) { DocumentManager::addBindings(exec,proxy,target); } else { Kate::Application *app=dynamic_cast(proxy->object()); if (app) { Application::addBindings(exec,proxy,target); } else { Kate::MainWindow *win=dynamic_cast(proxy->object()); if (win) { MainWindow::addBindings(exec,proxy,target); } } } General::addBindings(exec,proxy,target); } void DocumentManager::addBindings(KJS::ExecState *exec, KJSEmbed::JSObjectProxy *proxy,KJS::Object &object){ RefCountedObjectDict *dict=new RefCountedObjectDict(100); object.put(exec, "document", KJS::Object(new DocumentManager( exec, Document, proxy,dict ))); object.put(exec, "activeDocument", KJS::Object(new DocumentManager( exec, ActiveDocument, proxy,dict ))); object.put(exec, "documentForID", KJS::Object(new DocumentManager( exec, DocumentWithID, proxy,dict ))); object.put(exec, "documentForURL", KJS::Object(new DocumentManager( exec, FindDocument, proxy,dict ))); object.put(exec, "openURL", KJS::Object(new DocumentManager( exec, OpenURL, proxy,dict ))); object.put(exec, "isOpen", KJS::Object(new DocumentManager( exec, IsOpen, proxy,dict ))); object.put(exec, "documentCount", KJS::Object(new DocumentManager( exec, Documents, proxy,dict ))); object.put(exec, "closeDocument", KJS::Object(new DocumentManager( exec, CloseDocument, proxy,dict ))); object.put(exec, "closeAllDocument", KJS::Object(new DocumentManager( exec, CloseAllDocuments, proxy,dict ))); } DocumentManager::DocumentManager( KJS::ExecState *exec, int id, KJSEmbed::JSObjectProxy *parent, RefCountedObjectDict *dict ):KJSEmbed::JSProxyImp(exec) { m_dict=dict; m_dict->incRef(); m_id=id; m_proxy=parent; } DocumentManager::~DocumentManager() { m_dict->decRef(); } KJS::Value DocumentManager::call( KJS::ExecState *exec, KJS::Object &self, const KJS::List &args ) { TQObject *o=m_proxy->object(); Kate::DocumentManager *dm=dynamic_cast(o); if (!dm) { kdWarning()<<"Object died"<setException( err ); return KJS::Undefined(); } TQString mdesc; switch (m_id) { case Document: { mdesc="document(int)"; if (args.size()!=1) break; uint index=args[0].toUInt32(exec); if (exec->hadException()) break; TQObject *doc=dynamic_cast(dm->document(index)); if (!doc) return KJS::Null(); return m_dict->jsObject(exec,doc,m_proxy); } break; case ActiveDocument: { mdesc="activeDocument()"; if (args.size()!=0) break; TQObject *doc=dynamic_cast(dm->activeDocument()); if (!doc) return KJS::Null(); return m_dict->jsObject(exec,doc,m_proxy); } break; case DocumentWithID: { mdesc="documentForID(int)"; if (args.size()!=1) break; uint id=args[0].toUInt32(exec); if (exec->hadException()) break; TQObject *doc=dynamic_cast(dm->documentWithID(id)); if (!doc) return KJS::Null(); return m_dict->jsObject(exec,doc,m_proxy); } break; case FindDocument: { mdesc="documentForURL(KURL)"; if (args.size()!=1) break; KURL url = TQString( args[0].toString(exec).qstring() ); if (exec->hadException()) break; return KJS::Number(dm->findDocument(url)); } break; case IsOpen: { mdesc="isOpen(KURL)"; if (args.size()!=0) break; KURL url = TQString( args[0].toString(exec).qstring() ); if (exec->hadException()) break; return KJS::Boolean(dm->isOpen(url));} break; case OpenURL: { mdesc="openURL(KURL[,String encoding])"; uint docID; if (args.size()==1) { KURL url = TQString( args[0].toString(exec).qstring() ); if (exec->hadException()) break; (void)dm->openURL(url,TQString::null,&docID); return KJS::Number(docID); } else if (args.size()==2) { KURL url = TQString( args[0].toString(exec).qstring() ); if (exec->hadException()) break; TQString encoding=TQString( args[1].toString(exec).qstring() ); (void)dm->openURL(url,encoding,&docID); return KJS::Number(docID); } } break; case Documents: { mdesc="documentCount()"; if (args.size()!=0) break; return KJS::Number(dm->documents()); } break; case CloseDocument: { mdesc="closeDocument(Kate::Document)"; if (args.size()!=1) break; KJSEmbed::JSObjectProxy *proxy = KJSEmbed::JSProxy::toObjectProxy( args[0].imp() ); if (!proxy) break; TQObject *tmp=proxy->object(); Kate::Document *tmpdoc=dynamic_cast(tmp); if (!tmpdoc) break; return KJS::Boolean(dm->closeDocument(tmpdoc)); } break; case CloseAllDocuments: { mdesc="closeAllDocuments()"; if (args.size()!=0) break; return KJS::Boolean(dm->closeAllDocuments()); } break; default: kdDebug()<<"calling illegal method of DocumentManager"<setException( err ); return KJS::Undefined(); } Kate::JS::Management::Management(KJS::ExecState *exec, int id, PluginKateKJSWrapper *kateplug):KJSEmbed::JSProxyImp(exec) { m_id=id; m_wrapper=kateplug; } KJS::Value Kate::JS::Management::call( KJS::ExecState *exec, KJS::Object &self, const KJS::List &args ) { if (m_id==AddConfigPage) { if (args.size()!=1) { TQString msg = i18n("One parameter expected"); KJS::Object err = KJS::Error::create( exec, KJS::GeneralError, msg.utf8() ); exec->setException( err ); return KJS::Undefined(); } KJS::Value v=args[0]; // m_wrapper->m_configPageFactories.append(v); #warning implement me } else if (m_id==SetConfigPages) { if (args.size()>1) { TQString msg=i18n("One or no parameter expected"); KJS::Object err = KJS::Error::create( exec, KJS::GeneralError, msg.utf8() ); exec->setException( err ); return KJS::Undefined(); } m_wrapper->m_configPageFactories=(args.size()>0)?args[0]:KJS::Value(); } else if (m_id==SetWindowConfiguration) { if (args.size()>3) { TQString msg = i18n("A maximum of three parameters expected"); KJS::Object err = KJS::Error::create( exec, KJS::GeneralError, msg.utf8() ); exec->setException( err ); return KJS::Undefined(); } kdDebug()<<"***********************************************************************************"<m_toolViewConstructors=(args.size()>0)?args[0]:KJS::Value(); kdDebug()<<"Kate::JS::Management::call: Object type for m_toolViewConstructors (2):"<m_toolViewConstructors.type()<m_newWindowHandler=(args.size()>1)?args[1]:KJS::Value(); m_wrapper->m_removeWindowHandler=(args.size()>2)?args[2]:KJS::Value(); } else if (m_id==KJSConsole) { m_wrapper->m_part->view()->show(); } else kdDebug()<<"Remove not implemented yet"<(proxy->part()->parent()); KJS::Object ToolView(new Application( exec, ToolView, proxy ,wrap)); ToolView.put(exec,KJS::Identifier("Left"),KJS::Number(KDockWidget::DockLeft) ,KJS::ReadOnly | KJS::DontDelete); ToolView.put(exec,KJS::Identifier("Top"),KJS::Number(KDockWidget::DockTop) ,KJS::ReadOnly | KJS::DontDelete); ToolView.put(exec,KJS::Identifier("Right"),KJS::Number(KDockWidget::DockRight) ,KJS::ReadOnly | KJS::DontDelete); ToolView.put(exec,KJS::Identifier("Bottom"),KJS::Number(KDockWidget::DockBottom), KJS::ReadOnly | KJS::DontDelete); General::addBindings(exec,proxy,ToolView); object.put(exec, "ToolView",ToolView); object.put(exec, KJS::Identifier("DocumentManager"),proxy->part()->bind(::Kate::documentManager()),KJS::ReadOnly | KJS::DontDelete); object.put(exec, "windowCount", KJS::Object(new Application( exec, WindowCount, proxy,wrap))); object.put(exec, "activeWindow", KJS::Object(new Application( exec, ActiveWindow, proxy,wrap))); object.put(exec, "window", KJS::Object(new Application( exec, Window, proxy,wrap ))); // object.put(exec, "ProjectManager",proxy->part()->bind(::Kate::projectManager()); /* obbject.put(exec, KJS::Identifier("WindowManager"),proxy->part KJS::Object*/ /* Kate::PluginManager *pluginManager (); Kate::InitPluginManager *initPluginManager (); Kate::MainWindow *activeMainWindow ();*/ // uint mainWindows (); // Kate::MainWindow *mainWindow (uint n = 0); } Kate::JS::Application::Application( KJS::ExecState *exec, int id, KJSEmbed::JSObjectProxy *parent,PluginKateKJSWrapper *plugin):KJSEmbed::JSProxyImp(exec) { kdDebug()<<"Kate::JS::Application::Application"<object(); Kate::Application *ka=dynamic_cast(o); if (!ka) { kdWarning()<<"Object died"<setException( err ); return KJS::Undefined(); } TQString mdesc; switch (m_id) { case WindowCount: { mdesc="windowCount()"; if (args.size()!=0) break; return KJS::Number(ka->mainWindows()); } break; case Window: { mdesc="window(int)"; if (args.size()!=1) break; uint index=args[0].toUInt32(exec); if (exec->hadException()) break; Kate::MainWindow *mw=ka->mainWindow(index); if (!mw) return KJS::Null(); return m_plugin->getViewObject(mw)->winObj; } break; case ActiveWindow: { mdesc="activeWindow()"; if (args.size()!=0) break; Kate::MainWindow *mw=ka->activeMainWindow(); if (!mw) return KJS::Null(); return m_plugin->getViewObject(mw)->winObj; } break; } TQString msg = i18n("Method %1 called with wrong signature").arg(mdesc); KJS::Object err = KJS::Error::create( exec, KJS::GeneralError, msg.utf8() ); exec->setException( err ); return KJS::Undefined(); } void Kate::JS::General::addBindings(KJS::ExecState *exec, KJSEmbed::JSObjectProxy *proxy,KJS::Object &object){ #warning "try to find a way to make the function implementations static, right now this doesn't work because of the need to retrieve the interpreter" KJS::Object methods= KJS::Object(new General( exec,proxy->interpreter(),MethodMethods)); KJS::Object fields= KJS::Object(new General( exec,proxy->interpreter(),MethodFields)); object.put(exec, "methods", methods); object.put(exec, "fields", fields); } Kate::JS::General::General( KJS::ExecState *exec, KJS::Interpreter *interpreter, int id):KJSEmbed::JSProxyImp(exec) { m_id=id; m_interpreter=interpreter; } KJS::Value Kate::JS::General::call( KJS::ExecState *exec, KJS::Object &self, const KJS::List &args ) { switch (m_id) { case MethodMethods: return methodz(exec,self,args); case MethodFields: return fieldz(exec,self,args); default: return KJS::Null(); } } KJS::Value Kate::JS::General::methodz(KJS::ExecState *exec, KJS::Object &obj, const KJS::List &) { KJS::List items; KJS::ReferenceList list=obj.propList(exec, /*bool recursive*/ false); for (KJS::ReferenceListIterator it=list.begin();it!=list.end();it++) { if (it->getValue(exec).toObject(exec).implementsCall()) items.append(KJS::String(it->getPropertyName(exec).qstring())); } return KJS::Object(m_interpreter->builtinArray().construct(exec,items) ); } KJS::Value Kate::JS::General::fieldz(KJS::ExecState *exec, KJS::Object &obj, const KJS::List &) { KJS::List items; KJS::ReferenceList list=obj.propList(exec, /*bool recursive*/ false); for (KJS::ReferenceListIterator it=list.begin();it!=list.end();it++) { if (!(it->getValue(exec).toObject(exec).implementsCall())) items.append(KJS::String(it->getPropertyName(exec).qstring())); } return KJS::Object(m_interpreter->builtinArray().construct(exec,items) ); } Kate::JS::RefCountedObjectDict::RefCountedObjectDict(int size): TQObject(), TQPtrDict(size) { m_usageCount=0; setAutoDelete(true); } void Kate::JS::RefCountedObjectDict::incRef() { m_usageCount++; } void Kate::JS::RefCountedObjectDict::decRef() { kdDebug()<<"Kate::JS:RefCountedObjectDict::decCount()"<obj=proxy->part()->factory()->createProxy(exec,obj,proxy); connect(obj,TQT_SIGNAL(destroyed()),this,TQT_SLOT(removeSender())); insert(obj,oe); return oe->obj; } else return oe->obj; } void Kate::JS::RefCountedObjectDict::removeSender() { kdDebug()<<"Trying to remove object from dict"<(proxy->object()); if (!mw) return; kdDebug()<<"Kate::JS::MainWindow::addBindings - 3"<(proxy->part()->parent()); if (!wrap) return; kdDebug()<<"Kate::JS::MainWindow::addBindings - 4"<object(); Kate::MainWindow *mw=dynamic_cast(o); if (!mw) { kdWarning()<<"Object died"<setException( err ); return KJS::Undefined(); } TQString mdesc; switch (m_id) { case ActionCollection: { mdesc="actionCollection()"; if (args.size()!=0) break; return m_plugin->getViewObject(mw)->actionCollectionObj; } break; default: return KJS::Undefined(); } TQString msg = i18n("Method %1 called with wrong signature").arg(mdesc); KJS::Object err = KJS::Error::create( exec, KJS::GeneralError, msg.utf8() ); exec->setException( err ); return KJS::Undefined(); }