summaryrefslogtreecommitdiffstats
path: root/languages/kjssupport
diff options
context:
space:
mode:
Diffstat (limited to 'languages/kjssupport')
-rw-r--r--languages/kjssupport/Makefile.am22
-rw-r--r--languages/kjssupport/jscodecompletion.cpp174
-rw-r--r--languages/kjssupport/jscodecompletion.h53
-rw-r--r--languages/kjssupport/kdevkjssupport.desktop54
-rw-r--r--languages/kjssupport/kdevkjssupport.rc11
-rw-r--r--languages/kjssupport/kjsproblems.cpp78
-rw-r--r--languages/kjssupport/kjsproblems.h43
-rw-r--r--languages/kjssupport/kjssupport_part.cpp448
-rw-r--r--languages/kjssupport/kjssupport_part.h85
-rw-r--r--languages/kjssupport/subclassing_template/Makefile.am3
-rw-r--r--languages/kjssupport/subclassing_template/subclass_template.js2
-rw-r--r--languages/kjssupport/subclassingdlg.cpp461
-rw-r--r--languages/kjssupport/subclassingdlg.h85
-rw-r--r--languages/kjssupport/subclassingdlgbase.ui253
-rw-r--r--languages/kjssupport/template/Makefile.am20
-rw-r--r--languages/kjssupport/template/app.js18
-rw-r--r--languages/kjssupport/template/app.kdevelop45
-rw-r--r--languages/kjssupport/template/jshello6
-rw-r--r--languages/kjssupport/template/script13
-rw-r--r--languages/kjssupport/x-javascript-source.desktop4
20 files changed, 1878 insertions, 0 deletions
diff --git a/languages/kjssupport/Makefile.am b/languages/kjssupport/Makefile.am
new file mode 100644
index 00000000..d61fc67c
--- /dev/null
+++ b/languages/kjssupport/Makefile.am
@@ -0,0 +1,22 @@
+INCLUDES = -I$(kde_includes)/kdevelop $(all_includes)
+
+kde_module_LTLIBRARIES = libkdevkjssupport.la
+libkdevkjssupport_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
+libkdevkjssupport_la_LIBADD = -lkjsembed -lkdevelop
+libkdevkjssupport_la_SOURCES = kjssupport_part.cpp kjsproblems.cpp jscodecompletion.cpp subclassingdlg.cpp subclassingdlgbase.ui
+
+METASOURCES = AUTO
+
+servicedir = $(kde_servicesdir)
+service_DATA = kdevkjssupport.desktop
+
+mimesrcdir = $(kde_mimedir)/text
+mimesrc_DATA = x-javascript-source.desktop
+
+EXTRA_DIST = $(mimesrc_DATA)
+
+rcdir = $(kde_datadir)/kdevkjssupport
+rc_DATA = kdevkjssupport.rc
+
+SUBDIRS = template subclassing_template
+noinst_HEADERS = kjsproblems.h
diff --git a/languages/kjssupport/jscodecompletion.cpp b/languages/kjssupport/jscodecompletion.cpp
new file mode 100644
index 00000000..8fd59f57
--- /dev/null
+++ b/languages/kjssupport/jscodecompletion.cpp
@@ -0,0 +1,174 @@
+//
+// C++ Implementation: jscodecompletion
+//
+// Description:
+//
+//
+// Author: ian reinhart geiser <geiseri@kde.org>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "jscodecompletion.h"
+#include <qwhatsthis.h>
+
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <kapplication.h>
+#include <qregexp.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <kdebug.h>
+#include <kaction.h>
+#include <kparts/part.h>
+#include <kdialogbase.h>
+
+
+#include <kdevelop/kdevcore.h>
+#include <kdevelop/kdevmainwindow.h>
+#include <kdevelop/kdevlanguagesupport.h>
+#include <kdevelop/kdevpartcontroller.h>
+#include <kdevelop/kdevproject.h>
+#include <kdevelop/kdevappfrontend.h>
+#include <kdevelop/domutil.h>
+#include <kdevelop/codemodel.h>
+
+JSCodeCompletion::JSCodeCompletion(QObject *parent, const char *name)
+ : QObject(parent, name)
+{
+ m_argWidgetShow = false;
+ m_completionBoxShow=false;
+}
+
+
+JSCodeCompletion::~JSCodeCompletion()
+{}
+
+void JSCodeCompletion::setActiveEditorPart( KParts::Part * part )
+{
+ if (!part || !part->widget())
+ return;
+
+ kdDebug() << "JSCodeCompletion::setActiveEditorPart" << endl;
+
+ // We need to think about this
+ // if(!(m_config->getCodeCompletion() || m_config->getCodeHinting())){
+ // return; // no help
+ // }
+
+ m_editInterface = dynamic_cast<KTextEditor::EditInterface*>(part);
+ if (!m_editInterface)
+ {
+ kdDebug() << "editor doesn't support the EditDocumentIface" << endl;
+ return;
+ }
+
+ m_cursorInterface = dynamic_cast<KTextEditor::ViewCursorInterface*>(part->widget());
+ if (!m_cursorInterface)
+ {
+ kdDebug() << "editor does not support the ViewCursorInterface" << endl;
+ return;
+ }
+
+ m_codeInterface = dynamic_cast<KTextEditor::CodeCompletionInterface*>(part->widget());
+ if (!m_codeInterface)
+ { // no CodeCompletionDocument available
+ kdDebug() << "editor doesn't support the CodeCompletionDocumentIface" << endl;
+ return;
+ }
+
+ disconnect(part->widget(), 0, this, 0 ); // to make sure that it is't connected twice
+ connect(part->widget(), SIGNAL(cursorPositionChanged()),
+ this, SLOT(cursorPositionChanged()));
+ connect(part->widget(), SIGNAL(argHintHidden()), this, SLOT(argHintHidden()));
+ connect(part->widget(), SIGNAL(completionAborted()), this, SLOT(completionBoxAbort()));
+ connect(part->widget(), SIGNAL(completionDone()), this, SLOT(completionBoxHidden()));
+}
+
+QValueList< KTextEditor::CompletionEntry > JSCodeCompletion::getVars( const QString & startText )
+{
+ kdDebug() << "getVars for " << startText << endl;
+ QValueList<KTextEditor::CompletionEntry> varList;
+ /*
+ QValueList<QString>::ConstIterator it;
+ for (it = m_vars.begin(); it != m_vars.end(); ++it)
+ {
+ QString var = "$" + (*it);
+ kdDebug() << "Compair " << var << endl;
+ if( var.startsWith( startText ))
+ {
+ KTextEditor::CompletionEntry e;
+ e.text = var;
+ //e.postfix ="";
+ //e.prefix ="";
+ kdDebug() << "getVar: " << var << endl;
+ varList.append(e);
+ }
+ }
+ */
+ return varList;
+}
+
+void JSCodeCompletion::cursorPositionChanged( )
+{
+ uint line, col;
+ m_cursorInterface->cursorPositionReal(&line, &col);
+ kdDebug() << "JSCodeCompletion::cursorPositionChanged:" << line << ":" << col << endl;
+
+ QString lineStr = m_editInterface->textLine(line);
+ if(lineStr.isNull() || lineStr.isEmpty())
+ {
+ kdDebug() << "No Text..." << endl;
+ return; // nothing to do
+ }
+ // if(m_config->getCodeCompletion())
+ // {
+ QString restLine = lineStr.mid(col);
+ QString prevText = lineStr.mid(0,col);
+
+ if(restLine.left(1) != " " && restLine.left(1) != "\t" && !restLine.isNull())
+ {
+ kdDebug() << "no codecompletion because no empty character after cursor:" << restLine << ":" << endl;
+ return;
+ }
+
+ QRegExp prevReg("([\\d\\w]*)[.]$");
+
+ if (prevReg.search( prevText ) != -1 )
+ {
+ // We are in completion mode
+ QString startMatch = prevReg.cap(0);
+ kdDebug() << "Matching: " << startMatch << endl;
+ m_completionBoxShow=true;
+ m_codeInterface->showCompletionBox(getVars(startMatch),2);
+ }
+ else
+ {
+ kdDebug() << "no vars in: " << prevText << endl;
+ return;
+ }
+
+ // }
+
+
+}
+
+void JSCodeCompletion::completionBoxHidden( )
+{
+ kdDebug() << "Complete..." << endl;
+ m_completionBoxShow=false;
+}
+
+void JSCodeCompletion::completionBoxAbort( )
+{
+ kdDebug() << "aborted..." << endl;
+ m_completionBoxShow=false;
+
+}
+
+
+#include "jscodecompletion.moc"
diff --git a/languages/kjssupport/jscodecompletion.h b/languages/kjssupport/jscodecompletion.h
new file mode 100644
index 00000000..0cceb1e0
--- /dev/null
+++ b/languages/kjssupport/jscodecompletion.h
@@ -0,0 +1,53 @@
+//
+// C++ Interface: jscodecompletion
+//
+// Description:
+//
+//
+// Author: ian reinhart geiser <geiseri@kde.org>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef JSCODECOMPLETION_H
+#define JSCODECOMPLETION_H
+
+#include <qobject.h>
+#include <kdevelop/codemodel.h>
+#include <kdevelop/kdevplugin.h>
+#include <kdevelop/kdevlanguagesupport.h>
+
+#include <ktexteditor/editinterface.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/codecompletioninterface.h>
+
+/**
+The code completion engine for Javascript.
+
+@author ian reinhart geiser
+*/
+class JSCodeCompletion : public QObject
+{
+ Q_OBJECT
+ public:
+ JSCodeCompletion(QObject *parent = 0, const char *name = 0);
+
+ ~JSCodeCompletion();
+ void setActiveEditorPart(KParts::Part* editorPart);
+ QValueList<KTextEditor::CompletionEntry> getVars(const QString& textHint);
+
+ public slots:
+ void cursorPositionChanged();
+ void completionBoxHidden();
+ void completionBoxAbort();
+
+ private:
+ bool m_argWidgetShow;
+ bool m_completionBoxShow;
+ KTextEditor::EditInterface *m_editInterface;
+ KTextEditor::CodeCompletionInterface *m_codeInterface;
+ KTextEditor::ViewCursorInterface *m_cursorInterface;
+
+};
+
+#endif
diff --git a/languages/kjssupport/kdevkjssupport.desktop b/languages/kjssupport/kdevkjssupport.desktop
new file mode 100644
index 00000000..d60863b8
--- /dev/null
+++ b/languages/kjssupport/kdevkjssupport.desktop
@@ -0,0 +1,54 @@
+[Desktop Entry]
+Type=Service
+Exec=blubb
+Comment=kjsSupport
+Comment[da]=kjs-understøttelse
+Comment[et]=kjs toetus
+Comment[fa]=پشتیبانی kjs
+Comment[nds]=KDE-Ünnerstütten för JavaScript
+Comment[pl]=Obsługakjs
+Comment[sk]=kjs podpora
+Comment[sv]=Javaskript-stöd
+Comment[zh_TW]=kjs 支援
+Name=KDevkjsSupport
+Name[da]=KDevelop Bash-understøttelse
+Name[nds]=KJS-Ünnerstütten för KDevelop
+Name[pl]=KDevObsługakjs
+Name[sk]=KDev kjs podpora
+Name[sv]=KDevelop Javaskript-stöd
+Name[zh_TW]=KDevelop kjs 支援
+GenericName=KDE JavaScript Support
+GenericName[ca]=Suport per a JavaScript per al KDE
+GenericName[da]=KDE JavaScript-understøttelse
+GenericName[de]=Unterstützung für KDE-JavaScript
+GenericName[el]=Υποστήριξη KDE JavaScript
+GenericName[es]=Soporte para JavaScript de KDE
+GenericName[et]=KDE JavaScripti toetus
+GenericName[eu]=KDE JavaScript euskarria
+GenericName[fa]=پشتیبانی جاوااسکریپت KDE
+GenericName[fr]=Prise en charge du JavaScript pour KDE
+GenericName[ga]=Tacaíocht JavaScript KDE
+GenericName[gl]=Soporte para JavaScript de KDE
+GenericName[hu]=KDE Javascript-támogatás
+GenericName[it]=Supporto JavaScript di KDE
+GenericName[ja]=KDE JavaScript サポート
+GenericName[nds]=KDE-Ünnerstütten för JavaScript
+GenericName[ne]=केडीई जाभास्क्रिप्ट समर्थन
+GenericName[nl]=KDE ondersteuning voor JavaScript
+GenericName[pl]=Obsługa JavaScriptu KDE
+GenericName[pt]=Suporte KDE a JavaScript
+GenericName[pt_BR]=Suporte ao JavaScript do KDE
+GenericName[ru]=Поддержка языка JavaScript
+GenericName[sk]=KDE JavaScript podpora
+GenericName[sl]=Podpora javascriptu v KDE
+GenericName[sr]=KDE-ова подршка за Javascript
+GenericName[sr@Latn]=KDE-ova podrška za Javascript
+GenericName[sv]=KDE Javaskript-stöd
+GenericName[tr]=KDE JavaScript Desteği
+GenericName[zh_CN]=KDE JavaScript 支持
+GenericName[zh_TW]=KDE JavaScript 支援
+Icon=kdevelop
+ServiceTypes=KDevelop/LanguageSupport
+X-KDevelop-Language=Javascript
+X-KDE-Library=libkdevkjssupport
+X-KDevelop-Version=3
diff --git a/languages/kjssupport/kdevkjssupport.rc b/languages/kjssupport/kdevkjssupport.rc
new file mode 100644
index 00000000..e48fc863
--- /dev/null
+++ b/languages/kjssupport/kdevkjssupport.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="KDevkjsSupport" version="1">
+<MenuBar>
+ <Menu name="build" >
+ <Action name="build_execute" />
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar">
+ <Action name="build_execute" group="build_operations" />
+</ToolBar>
+</kpartgui>
diff --git a/languages/kjssupport/kjsproblems.cpp b/languages/kjssupport/kjsproblems.cpp
new file mode 100644
index 00000000..39084169
--- /dev/null
+++ b/languages/kjssupport/kjsproblems.cpp
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2003 ian reinhart geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ version 2, License 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.
+*/
+
+#include "kjsproblems.h"
+#include "kjssupport_part.h"
+#include <kiconloader.h>
+
+class KJSProblemItem: public KListViewItem
+{
+ public:
+ KJSProblemItem( QListView* parent, const QString& level, const QString& problem,
+ const QString& file, const QString& line, const QString& column )
+ : KListViewItem( parent, level, problem, file, line, column )
+ {}
+
+ KJSProblemItem( QListViewItem* parent, const QString& level, const QString& problem,
+ const QString& file, const QString& line, const QString& column )
+ : KListViewItem( parent, level, problem, file, line, column )
+ {}
+
+ int compare( QListViewItem* item, int column, bool ascending ) const
+ {
+ if( column == 2 || column == 3 )
+ {
+ int a = text( column ).toInt();
+ int b = item->text( column ).toInt();
+ if( a == b )
+ return 0;
+ return( a > b ? 1 : -1 );
+ }
+ return KListViewItem::compare( item, column, ascending );
+ }
+
+};
+
+KJSProblems::KJSProblems(kjsSupportPart *part, QWidget *parent, const char *name) : KListView(parent,name), m_part(part)
+{
+ addColumn ("File");
+ addColumn ("Line #");
+ addColumn ("Problem:");
+ setIcon( SmallIcon("info") );
+}
+
+
+KJSProblems::~KJSProblems()
+{
+
+}
+
+void KJSProblems::clearItems()
+{
+ clear();
+ setIcon( SmallIcon("info") );
+}
+
+void KJSProblems::addLine(const QString &file, int lineNo, const QString &message)
+{
+ new QListViewItem( this, file, QString::number( lineNo ), message);
+ setIcon( SmallIcon("error") );
+}
+
+
+#include "kjsproblems.moc"
diff --git a/languages/kjssupport/kjsproblems.h b/languages/kjssupport/kjsproblems.h
new file mode 100644
index 00000000..d7d47c63
--- /dev/null
+++ b/languages/kjssupport/kjsproblems.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2003 ian reinhart geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ version 2, License 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.
+*/
+
+#ifndef KJSPROBLEMS_H
+#define KJSPROBLEMS_H
+
+#include <klistview.h>
+class kjsSupportPart;
+
+/**
+@author ian reinhart geiser
+*/
+class KJSProblems : public KListView
+{
+Q_OBJECT
+public:
+
+ KJSProblems(kjsSupportPart *part, QWidget *parent = 0L, const char *name = 0L);
+ ~KJSProblems();
+
+ void clearItems();
+ void addLine(const QString &file, int lineNo, const QString &message);
+
+private:
+ kjsSupportPart *m_part;
+};
+
+#endif
diff --git a/languages/kjssupport/kjssupport_part.cpp b/languages/kjssupport/kjssupport_part.cpp
new file mode 100644
index 00000000..c4907991
--- /dev/null
+++ b/languages/kjssupport/kjssupport_part.cpp
@@ -0,0 +1,448 @@
+/*
+ Copyright (C) 2003 ian reinhart geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ version 2, License 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.
+*/
+
+#include <qwhatsthis.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qpopupmenu.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <kdevcore.h>
+#include <kdevpartcontroller.h>
+#include <kdevmainwindow.h>
+#include <domutil.h>
+#include <codemodel.h>
+#include <kparts/part.h>
+
+
+#include <kdevproject.h>
+#include <kaction.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+#include <kjsembed/kjsembedpart.h>
+#include <kjsembed/jsconsolewidget.h>
+
+#include <kdevplugininfo.h>
+
+#include "kjssupport_part.h"
+#include "kjsproblems.h"
+#include "jscodecompletion.h"
+#include "subclassingdlg.h"
+
+typedef KDevGenericFactory<kjsSupportPart> kjsSupportFactory;
+static const KDevPluginInfo data("kdevkjssupport");
+K_EXPORT_COMPONENT_FACTORY( libkdevkjssupport, kjsSupportFactory( data ) );
+
+
+class typeProperty
+{
+ public:
+ QString type;
+ QString name;
+ int depth;
+};
+
+kjsSupportPart::kjsSupportPart(QObject *parent, const char *name, const QStringList& )
+: KDevLanguageSupport(&data, parent, name ? name : "kjsSupportPart" )
+{
+ setInstance(kjsSupportFactory::instance());
+ setXMLFile("kdevkjssupport.rc");
+
+
+ m_build = new KAction( i18n("&Run"), "exec",Key_F9,this, SLOT(slotRun()),actionCollection(), "build_execute" );
+ m_build->setStatusText( i18n("Test the active script.") );
+
+ kdDebug() << "Creating kjssupport Part" << endl;
+
+ connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)),
+ this, SLOT(projectConfigWidget(KDialogBase*)) );
+ connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) );
+ connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) );
+ connect( partController(), SIGNAL(savedFile(const QString&)), this, SLOT(savedFile(const QString&)) );
+ connect(partController(), SIGNAL(activePartChanged(KParts::Part*)),
+ this, SLOT(slotActivePartChanged(KParts::Part *)));
+ connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
+ this, SLOT(contextMenu(QPopupMenu *, const Context *)));
+
+
+ // Building kjs interpreter.
+ m_js = new KJSEmbed::KJSEmbedPart();
+ mainWindow()->embedOutputView( m_js->view() , i18n("KJS Console"),i18n("KJS Embed Console") );
+
+ // get the problem reporter
+ m_problemReporter = new KJSProblems( this, 0, "problems" );
+ mainWindow( )->embedOutputView( m_problemReporter, i18n("Problems"), i18n("Problem reporter"));
+ m_cc = new JSCodeCompletion();
+ }
+
+
+kjsSupportPart::~kjsSupportPart()
+{
+ delete m_problemReporter;
+ delete m_cc;
+ delete m_build;
+ delete m_js;
+}
+
+KDevLanguageSupport::Features kjsSupportPart::features()
+{
+ return Features(Classes | Variables | Functions);
+}
+
+KMimeType::List kjsSupportPart::mimeTypes()
+{
+ KMimeType::List list;
+
+ KMimeType::Ptr mime = KMimeType::mimeType( "application/x-javascript" );
+ if( mime )
+ list << mime;
+
+ return list;
+}
+void kjsSupportPart::slotRun()
+{
+ // Execute the application here.
+
+ KParts::ReadOnlyPart * ro_part = dynamic_cast<KParts::ReadOnlyPart*>( partController()->activePart() );
+ if ( ro_part )
+ {
+ m_js->runFile( ro_part->url().path() );
+ }
+
+}
+
+void kjsSupportPart::projectConfigWidget(KDialogBase *dlg)
+{
+ Q_UNUSED( dlg );
+ // Create your config dialog here.
+}
+void kjsSupportPart::projectOpened()
+{
+ kdDebug(9014) << "projectOpened()" << endl;
+
+ connect( project(), SIGNAL(addedFilesToProject(const QStringList &)),
+ this, SLOT(addedFilesToProject(const QStringList &)) );
+ connect( project(), SIGNAL(removedFilesFromProject(const QStringList &)),
+ this, SLOT(removedFilesFromProject(const QStringList &)) );
+
+ // We want to parse only after all components have been
+ // properly initialized
+ QTimer::singleShot(0, this, SLOT(parse()));
+}
+void kjsSupportPart::projectClosed()
+{
+
+}
+void kjsSupportPart::savedFile(const QString &fileName)
+{
+
+
+ if (project()->allFiles().contains(fileName.mid ( project()->projectDirectory().length() + 1 )))
+ {
+ kdDebug(9014) << "parse file " << fileName << endl;
+ parse( fileName );
+ emit addedSourceInfo( fileName );
+ }
+}
+void kjsSupportPart::addedFilesToProject(const QStringList &fileList)
+{
+ kdDebug(9014) << "addedFilesToProject()" << endl;
+
+ QStringList::ConstIterator it;
+
+ for ( it = fileList.begin(); it != fileList.end(); ++it )
+ {
+ kdDebug(9014) << "maybe parse " << project()->projectDirectory() + "/" + ( *it ) << endl;
+ parse( project()->projectDirectory() + "/" + (*it) );
+ }
+
+ emit updatedSourceInfo();
+}
+void kjsSupportPart::removedFilesFromProject(const QStringList &fileList)
+{
+
+
+ QStringList::ConstIterator it;
+
+ for ( it = fileList.begin(); it != fileList.end(); ++it )
+ {
+ QString fileName = project()->projectDirectory() + "/" + ( *it );
+ if( codeModel()->hasFile(fileName) )
+ {
+ kdDebug(9014) << "removed " << fileName << endl;
+ emit aboutToRemoveSourceInfo( fileName );
+ codeModel()->removeFile( codeModel()->fileByName(fileName) );
+ }
+ }
+
+}
+void kjsSupportPart::parse()
+{
+ kdDebug(9014) << "initialParse()" << endl;
+
+ if (project())
+ {
+ kapp->setOverrideCursor(waitCursor);
+ QStringList files = project()->allFiles();
+ m_problemReporter->clear();
+
+ for (QStringList::Iterator it = files.begin(); it != files.end() ;++it)
+ {
+ kdDebug(9014) << "maybe parse " << project()->projectDirectory() + "/" + (*it) << endl;
+
+ parse( project()->projectDirectory() + "/" + (*it) );
+
+ }
+ emit updatedSourceInfo();
+ kapp->restoreOverrideCursor();
+ } else {
+ kdDebug(9014) << "No project" << endl;
+ }
+}
+void kjsSupportPart::slotActivePartChanged(KParts::Part *part)
+{
+ kdDebug() << "Changeing active part..." << endl;
+ m_cc->setActiveEditorPart(part);
+}
+
+/*!
+ \fn kjsSupportPart::parse(const QString &fileName)
+ */
+void kjsSupportPart::parse(const QString &fileName)
+{
+ QFileInfo fi(fileName);
+ if (fi.extension() == "js")
+ {
+ if( codeModel()->hasFile(fileName) )
+ {
+ emit aboutToRemoveSourceInfo( fileName );
+ codeModel()->removeFile( codeModel()->fileByName(fileName) );
+ }
+
+ FileDom m_file = codeModel()->create<FileModel>();
+ m_file->setName( fileName );
+ m_file->setFileName( fileName );
+
+ QFile f(QFile::encodeName(fileName));
+ if (!f.open(IO_ReadOnly))
+ return;
+ QString rawline;
+ QString line;
+ uint lineNo = 0;
+ QTextStream stream(&f);
+ int depth = 0;
+ bool inFunction = false;
+ QString lastFunction = "";
+ int lastLineNo = 0;
+ ClassDom currentClass;
+
+ QRegExp varRx("var[\\s]([_a-zA-Z\\d]+)");
+ QRegExp classVarRx("this\\.([_a-zA-Z\\d]+)");
+ QRegExp classMethRx("this\\.([_a-zA-Z\\d]+)[\\s]*=[\\s]*function(\\([^){}\\n\\r]*\\))");
+ QRegExp methRx("function[\\s]+([_a-zA-Z\\d]+[\\s]*\\([^){}\\n\\r]*\\))");
+ QRegExp allocRx("([_\\d\\w]+)[\\s]*=[\\s]*new[\\s]*([_\\d\\w]+)");
+ QRegExp assnRx("var[\\s]+([_\\d\\w]+)[\\s]+[=][\\s]+([_\\d\\w]+)[;]");
+
+ while (!stream.atEnd())
+ {
+ rawline = stream.readLine();
+ line = rawline.stripWhiteSpace().local8Bit();
+ kdDebug() << "Trying line: " << line << endl;
+
+ if (methRx.search(line) != -1 && depth == 0)
+ {
+ if (lastFunction != "" )
+ addMethod(lastFunction, m_file, lastLineNo);
+ lastFunction = methRx.cap(1);
+ lastLineNo = lineNo;
+ }
+ else if(varRx.search(line) != -1 && depth == 0)
+ {
+ addAttribute(varRx.cap(1), m_file, lineNo);
+ }
+ else if(classMethRx.search(line) != -1 && depth > 0)
+ {
+ if ( lastFunction != "" )
+ {
+ currentClass = addClass(lastFunction, m_file, lastLineNo );
+ lastFunction = "";
+ }
+ addMethod(classMethRx.cap(1)+classMethRx.cap(2), currentClass, lineNo);
+ }
+ else if(classVarRx.search(line) != -1 && depth > 0)
+ {
+ if ( lastFunction != "" )
+ {
+ currentClass = addClass(lastFunction, m_file, lastLineNo );
+ lastFunction = "";
+ }
+ addAttribute(classVarRx.cap(1), currentClass, lineNo);
+ }
+
+ if( allocRx.search(line) != -1 )
+ {
+ QString varName = allocRx.cap(1);
+ QString varType = allocRx.cap(2);
+
+ typeProperty *type = new typeProperty();
+ type->depth = depth;
+ type->name = varName;
+ type->type = varType;
+
+ m_typeMap.insert(varName, type);
+ kdDebug() << "Adding " << varName << " of type " << varType << " at scope " << depth << endl;
+
+ }
+
+
+ kdDebug() << "Syntax check..." << endl;
+ KJS::UString jsLine( line.latin1() );
+ int lineNumber = 0;
+ KJS::UString errorMessage;
+
+ if ( !m_js->interpreter()->checkSyntax( jsLine, &lineNumber, &errorMessage ) )
+ {
+ kdDebug() << errorMessage.qstring() << " on line " << lineNo << endl;
+ m_problemReporter->addLine(m_file->fileName(), lineNo, errorMessage.qstring());
+ }
+
+ if( line.contains("{") )
+ ++depth;
+
+ if( line.contains("}") )
+ --depth;
+
+ ++lineNo;
+ }
+
+ if (lastFunction != "" )
+ addMethod(lastFunction, m_file, lastLineNo);
+
+ f.close();
+
+ kdDebug() << "Trying to add list..." << endl;
+
+ codeModel()->addFile( m_file );
+
+
+ }
+}
+
+ClassDom kjsSupportPart::addClass(const QString &name, FileDom file, uint lineNo)
+{
+ ClassDom clazz = codeModel()->create<ClassModel>();
+ clazz->setName(name);
+ clazz->setFileName(file->fileName());
+ clazz->setStartPosition(lineNo, 0);
+
+ if( !file->hasClass(clazz->name()) ){
+ kdDebug() << "Add global class " << clazz->name() << endl;
+ file->addClass( clazz );
+ }
+ return clazz;
+}
+
+void kjsSupportPart::addMethod(const QString &name, ClassDom clazz, uint lineNo)
+{
+ FunctionDom method = codeModel()->create<FunctionModel>();
+ method->setName(name);
+ method->setFileName(clazz->fileName());
+ method->setStartPosition(lineNo, 0);
+
+ if( !clazz->hasFunction(method->name()) ){
+ kdDebug() << "Add class method " << method->name() << endl;
+ clazz->addFunction( method );
+ }
+}
+
+void kjsSupportPart::addAttribute(const QString &name, ClassDom clazz, uint lineNo)
+{
+ VariableDom var = codeModel()->create<VariableModel>();
+ var->setName(name);
+ var->setFileName(clazz->fileName());
+ var->setStartPosition( lineNo, 0 );
+ var->setType(i18n("Variable"));
+
+ if( !clazz->hasVariable(var->name()) ){
+ kdDebug() << "Add class attribute " << var->name() << endl;
+ clazz->addVariable(var);
+ }
+}
+
+void kjsSupportPart::addMethod(const QString &name, FileDom file, uint lineNo)
+{
+ FunctionDom method = codeModel()->create<FunctionModel>();
+ method->setName(name);
+ method->setFileName(file->fileName());
+ method->setStartPosition(lineNo, 0);
+
+ if( !file->hasFunction(method->name()) ){
+ kdDebug() << "Add global method " << method->name() << endl;
+ file->addFunction( method );
+ }
+}
+
+void kjsSupportPart::addAttribute(const QString &name, FileDom file, uint lineNo)
+{
+ VariableDom var = codeModel()->create<VariableModel>();
+ var->setName(name);
+ var->setFileName(file->fileName());
+ var->setStartPosition( lineNo, 0 );
+ var->setType(i18n("Variable"));
+
+ if( !file->hasVariable(var->name()) ){
+ kdDebug() << "Add global attribute " << var->name() << endl;
+ file->addVariable(var);
+ }
+}
+
+void kjsSupportPart::contextMenu(QPopupMenu * popupMenu, const Context *context)
+{
+ kdDebug() << "1" << endl;
+ if (!context->hasType( Context::FileContext ))
+ return;
+
+ kdDebug() << "2" << endl;
+ const FileContext *fcontext = static_cast<const FileContext*>(context);
+ m_selectedUI = fcontext->fileName();
+ if (m_selectedUI.right(3).lower() == ".ui")
+ int id = popupMenu->insertItem(i18n("Implement Slots"),
+ this, SLOT(implementSlots()));
+ else
+ m_selectedUI = QString::null;
+}
+
+void kjsSupportPart::implementSlots()
+{
+ if (m_selectedUI.isEmpty())
+ return;
+
+ QStringList newFiles;
+ SubclassingDlg *sub = new SubclassingDlg(this, m_selectedUI, newFiles);
+ if (sub->exec())
+ project()->addFiles(newFiles);
+
+ delete sub;
+}
+
+#include "kjssupport_part.moc"
diff --git a/languages/kjssupport/kjssupport_part.h b/languages/kjssupport/kjssupport_part.h
new file mode 100644
index 00000000..67e35f07
--- /dev/null
+++ b/languages/kjssupport/kjssupport_part.h
@@ -0,0 +1,85 @@
+/*
+ Copyright (C) 2003 ian reinhart geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ version 2, License 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.
+*/
+
+
+#ifndef __KDEVPART_KJSSUPPORT_H__
+#define __KDEVPART_KJSSUPPORT_H__
+
+
+#include <kdevelop/kdevplugin.h>
+#include <kdevelop/codemodel.h>
+#include <kdevelop/kdevlanguagesupport.h>
+#include <kdialogbase.h>
+#include <qstringlist.h>
+#include <qdict.h>
+
+namespace KJSEmbed
+{
+class KJSEmbedPart;
+class KJSConsoleWidget;
+};
+
+class QPopupMenu;
+class KAction;
+class KJSProblems;
+class JSCodeCompletion;
+class Context;
+
+class typeProperty;
+
+
+class kjsSupportPart : public KDevLanguageSupport
+{
+ Q_OBJECT
+ public:
+ kjsSupportPart(QObject *parent, const char *name, const QStringList &);
+ ~kjsSupportPart();
+ protected:
+ virtual Features features();
+ virtual KMimeType::List mimeTypes();
+
+ private slots:
+ void slotRun();
+ void projectConfigWidget(KDialogBase *dlg);
+ void projectOpened();
+ void projectClosed();
+ void savedFile(const QString &fileName);
+ void addedFilesToProject(const QStringList &fileList);
+ void removedFilesFromProject(const QStringList &fileList);
+ void parse();
+ void slotActivePartChanged(KParts::Part *part);
+ void contextMenu(QPopupMenu *popupMenu, const Context *context);
+ void implementSlots();
+ private:
+ void parse(const QString &fileName);
+ void addAttribute(const QString &name, ClassDom clazz, uint lineNo);
+ void addMethod(const QString &name, ClassDom clazz, uint lineNo);
+ void addAttribute(const QString &name, FileDom file, uint lineNo);
+ void addMethod(const QString &name, FileDom file, uint lineNo);
+ ClassDom addClass(const QString &name, FileDom file, uint lineNo);
+ KAction *m_build;
+ KJSEmbed::KJSEmbedPart *m_js;
+ KJSProblems *m_problemReporter;
+ QDict<typeProperty> m_typeMap;
+ JSCodeCompletion *m_cc;
+
+ QString m_selectedUI;
+};
+
+
+#endif
diff --git a/languages/kjssupport/subclassing_template/Makefile.am b/languages/kjssupport/subclassing_template/Makefile.am
new file mode 100644
index 00000000..8c99d172
--- /dev/null
+++ b/languages/kjssupport/subclassing_template/Makefile.am
@@ -0,0 +1,3 @@
+kjssupportdatadir = ${kde_datadir}/kdevkjssupport
+subclassingdir = ${kjssupportdatadir}/subclassing
+subclassing_DATA = subclass_template.js
diff --git a/languages/kjssupport/subclassing_template/subclass_template.js b/languages/kjssupport/subclassing_template/subclass_template.js
new file mode 100644
index 00000000..568c5699
--- /dev/null
+++ b/languages/kjssupport/subclassing_template/subclass_template.js
@@ -0,0 +1,2 @@
+//Slot implementations and slot-signal connections for $BASEFILENAME$ form
+/*$SPECIALIZATION$*/
diff --git a/languages/kjssupport/subclassingdlg.cpp b/languages/kjssupport/subclassingdlg.cpp
new file mode 100644
index 00000000..be1ad83e
--- /dev/null
+++ b/languages/kjssupport/subclassingdlg.cpp
@@ -0,0 +1,461 @@
+/***************************************************************************
+ * Copyright (C) 2002 by Jakob Simon-Gaarde *
+ * jsgaarde@tdcspace.dk *
+ * Copyright (C) 2003 by Alexander Dymo *
+ * cloudtemple@mksat.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "subclassingdlg.h"
+#include "kjssupport_part.h"
+/*#include "backgroundparser.h"
+#include "store_walker.h"
+#include "cppsupportfactory.h"*/
+#include <kdevelop/kdevsourceformatter.h>
+#include <kdevelop/kdevproject.h>
+#include <kdevelop/filetemplate.h>
+#include <kdevelop/codemodel.h>
+
+#include <qradiobutton.h>
+#include <qstringlist.h>
+#include <qcheckbox.h>
+#include <qmessagebox.h>
+#include <kfiledialog.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <domutil.h>
+#include <qdom.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <kconfig.h>
+
+
+#define WIDGET_CAPTION_NAME "widget/property|name=caption/string"
+#define WIDGET_CLASS_NAME "class"
+#define WIDGET_SLOTS "slots"
+#define WIDGET_FUNCTIONS "functions"
+
+// All widgets
+#define SLOT_ACCEPT SlotItem(m_slotView,"accept()","virtual","protected","void",false,true)
+#define SLOT_REJECT SlotItem(m_slotView,"reject()","virtual","protected","void",false,true)
+
+// Wizards
+#define SLOT_BACK SlotItem(m_slotView,"back()","virtual","protected","void",false,true)
+#define SLOT_NEXT SlotItem(m_slotView,"next()","virtual","protected","void",false,true)
+#define SLOT_HELP SlotItem(m_slotView,"help()","virtual","protected","void",false,true)
+
+
+SlotItem::SlotItem(QListView *parent,const QString &methodName,
+ const QString &specifier,
+ const QString &access, const QString &returnType,
+ bool isFunc,bool callBaseClass)
+: QCheckListItem(parent,methodName,QCheckListItem::CheckBox)
+{
+ setOn(true);
+ m_methodName = methodName;
+ m_access = access.isEmpty() ? (const QString) "public" : access;
+ m_specifier = specifier.isEmpty() ? (const QString) "virtual" : specifier;
+ m_returnType = returnType.isEmpty() ? (const QString) "void" : returnType;
+ m_isFunc = isFunc;
+ m_callBaseClass = callBaseClass;
+ setText(0,m_methodName);
+ setText(1,m_access);
+ setText(2,m_specifier);
+ setText(3,m_returnType);
+ setText(4,m_isFunc ? "Function" : "Slot");
+ if (m_access=="private" ||
+ m_specifier=="non virtual")
+ {
+ setOn(false);
+ setEnabled(false);
+ }
+ if (m_specifier=="pure virtual")
+ {
+ setOn(true);
+ setEnabled(false);
+ }
+ m_alreadyInSubclass = false;
+}
+
+void SlotItem::setAllreadyInSubclass()
+{
+ setOn(true);
+ setEnabled(false);
+ m_alreadyInSubclass = true;
+}
+
+
+SubclassingDlg::SubclassingDlg(kjsSupportPart* kjsSupport, const QString &formFile,QStringList &newFileNames,
+ QWidget* parent, const char* name,bool modal, WFlags fl)
+: SubclassingDlgBase(parent,name,modal,fl),
+m_newFileNames(newFileNames), m_kjsSupport( kjsSupport )
+//=================================================
+{
+ m_formFile = formFile;
+ readUiFile();
+ m_creatingNewSubclass = true;
+
+/* KConfig *config = kjsSupportFactory::instance()->config();
+ if (config)
+ {
+ config->setGroup("Subclassing");
+ reformatDefault_box->setChecked(config->readBoolEntry("Reformat Source", 0));
+ if (reformatDefault_box->isChecked())
+ reformat_box->setChecked(true);
+ }*/
+// m_btnOk->setEnabled(true);
+}
+
+
+/*SubclassingDlg::SubclassingDlg(kjsSupportPart* kjsSupport, const QString &formFile,const QString &filename,QStringList &dummy,
+ QWidget* parent, const char* name,bool modal, WFlags fl)
+: SubclassingDlgBase(parent,name,modal,fl),
+m_newFileNames(dummy), m_kjsSupport( kjsSupport )
+//=================================================
+{
+ m_formFile = formFile;
+ m_creatingNewSubclass = false;
+ m_filename = filename;
+
+ KConfig *config = kjsSupportFactory::instance()->config();
+ if (config)
+ {
+ config->setGroup("Subclassing");
+ reformatDefault_box->setChecked(config->readBoolEntry("Reformat Source", 0));
+ if (reformatDefault_box->isChecked())
+ reformat_box->setChecked(true);
+ }
+
+ QStringList pathsplit(QStringList::split('/',filename));
+
+ QString baseClass = readBaseClassName();
+ if (!kjsSupport->codeModel()->hasFile(filename+QString(".h")))
+ return;
+ ClassList myClasses = kjsSupport->codeModel()->fileByName(filename+QString(".h"))->classList();
+ for (ClassList::const_iterator classIt = myClasses.begin(); classIt != myClasses.end(); ++classIt)
+ {
+ kdDebug() << "base class " << baseClass << " class " << (*classIt)->name()
+ << " parents " << (*classIt)->baseClassList().join(",") << endl;
+ if ( (*classIt)->baseClassList().findIndex(baseClass) != -1 )
+ {
+ kdDebug() << "base class matched " << endl;
+ m_edClassName->setText((*classIt)->name());
+ m_edFileName->setText(pathsplit[pathsplit.count()-1]);
+
+ FunctionList functionList = (*classIt)->functionList();
+ for (FunctionList::const_iterator methodIt = functionList.begin();
+ methodIt != functionList.end(); ++methodIt)
+ {
+ m_parsedMethods << (*methodIt)->name() + "(";
+ }
+ }
+ }
+ readUiFile();
+ m_btnOk->setEnabled(true);
+}
+*/
+bool SubclassingDlg::alreadyInSubclass(const QString &method)
+{
+ for (uint i=0;i<m_parsedMethods.count();i++)
+ if (method.find(m_parsedMethods[i])==0)
+ return true;
+ return false;
+}
+
+void SubclassingDlg::readUiFile()
+{
+ QStringList splitPath = QStringList::split('/',m_formFile);
+ m_formName = QStringList::split('.',splitPath[splitPath.count()-1])[0]; // "somedlg.ui" = "somedlg"
+ splitPath.pop_back();
+ m_formPath = "/" + splitPath.join("/"); // join path to ui-file
+
+ m_btnOk->setEnabled(false);
+ QDomDocument doc;
+
+ DomUtil::openDOMFile(doc,m_formFile);
+ m_baseClassName = DomUtil::elementByPathExt(doc,WIDGET_CLASS_NAME).text();
+
+ m_baseCaption = DomUtil::elementByPathExt(doc,WIDGET_CAPTION_NAME).text();
+ setCaption(i18n("Create Subclass of ")+m_baseClassName);
+
+ // Special widget specific slots
+ SlotItem *newSlot;
+ m_qtBaseClassName = DomUtil::elementByPathExt(doc,"widget").attribute("class","QDialog");
+
+ if ( (m_qtBaseClassName=="QMainWindow") || (m_qtBaseClassName=="QWidget") )
+ m_canBeModal = false;
+ else
+ m_canBeModal = true;
+ if (m_qtBaseClassName != "QWidget")
+ {
+ newSlot = new SLOT_ACCEPT;
+ newSlot->setOn(false);
+ if (alreadyInSubclass("accept()"))
+ newSlot->setAllreadyInSubclass();
+ m_slotView->insertItem(newSlot);
+ m_slots << newSlot;
+
+ newSlot = new SLOT_REJECT;
+ newSlot->setOn(false);
+ if (alreadyInSubclass("reject()"))
+ newSlot->setAllreadyInSubclass();
+ m_slotView->insertItem(newSlot);
+ m_slots << newSlot;
+ }
+
+ if (m_qtBaseClassName == "QWizard")
+ {
+ newSlot = new SLOT_NEXT;
+ m_slotView->insertItem(newSlot);
+ if (alreadyInSubclass("next()"))
+ newSlot->setAllreadyInSubclass();
+ m_slots << newSlot;
+ newSlot = new SLOT_BACK;
+ m_slotView->insertItem(newSlot);
+ if (alreadyInSubclass("back()"))
+ newSlot->setAllreadyInSubclass();
+ m_slots << newSlot;
+ newSlot = new SLOT_HELP;
+ newSlot->setOn(false);
+ if (alreadyInSubclass("help()"))
+ newSlot->setAllreadyInSubclass();
+ m_slotView->insertItem(newSlot);
+ m_slots << newSlot;
+ }
+
+ QDomElement slotsElem = DomUtil::elementByPathExt(doc,WIDGET_SLOTS);
+ QDomNodeList slotnodes = slotsElem.childNodes();
+
+ for (unsigned int i=0; i<slotnodes.count();i++)
+ {
+ QDomElement slotelem = slotnodes.item(i).toElement();
+ newSlot = new SlotItem(m_slotView,slotelem.text(),
+ slotelem.attributeNode("specifier").value(),
+ slotelem.attributeNode("access").value(),
+ slotelem.attributeNode("returnType").value(),false);
+ m_slotView->insertItem(newSlot);
+ if (alreadyInSubclass(slotelem.text()))
+ newSlot->setAllreadyInSubclass();
+ m_slots << newSlot;
+ }
+
+ QDomElement funcsElem = DomUtil::elementByPathExt(doc,WIDGET_FUNCTIONS);
+ QDomNodeList funcnodes = funcsElem.childNodes();
+ SlotItem *newFunc;
+ for (unsigned int i=0; i<funcnodes.count();i++)
+ {
+ QDomElement funcelem = funcnodes.item(i).toElement();
+ newFunc = new SlotItem(m_slotView,funcelem.text(),
+ funcelem.attributeNode("specifier").value(),
+ funcelem.attributeNode("access").value(),
+ funcelem.attributeNode("returnType").value(),true);
+ m_slotView->insertItem(newFunc);
+ if (alreadyInSubclass(funcelem.text()))
+ newFunc->setAllreadyInSubclass();
+ m_slots << newFunc;
+ }
+
+ QDomElement connElem = DomUtil::elementByPathExt(doc,"connections");
+ QDomNodeList connnodes = connElem.childNodes();
+ for (unsigned int i=0; i<connnodes.count();i++)
+ {
+ QDomElement connelem = connnodes.item(i).toElement();
+ connections += "$NEWCLASS$.connect(";
+ if (connelem.namedItem("sender").toElement().text() == m_baseClassName)
+ connections += "this";
+ else
+ connections += "$NEWCLASS$.child('" + connelem.namedItem("sender").toElement().text() + "')";
+ connections += ", '" + connelem.namedItem("signal").toElement().text() + "', ";
+ if (connelem.namedItem("receiver").toElement().text() == m_baseClassName)
+ connections += "this";
+ else
+ connections += "$NEWCLASS$.child('" + connelem.namedItem("receiver").toElement().text() + "')";
+ connections += ", '" + connelem.namedItem("slot").toElement().text().remove("()") + "');\n";
+ }
+}
+
+SubclassingDlg::~SubclassingDlg()
+//===============================
+{
+}
+
+
+void SubclassingDlg::updateDlg()
+//==============================
+{
+}
+
+void SubclassingDlg::replace(QString &string, const QString& search, const QString& replace)
+//==========================================================================================
+{
+ int nextPos = string.find(search);
+ unsigned int searchLength = search.length();
+ while (nextPos>-1)
+ {
+ string = string.replace(nextPos,searchLength,replace);
+ nextPos = string.find(search,nextPos+replace.length());
+ }
+}
+
+bool SubclassingDlg::loadBuffer(QString &buffer, const QString& filename)
+//======================================================================
+{
+ // open file and buffer it
+ QFile dataFile(filename);
+ if (!dataFile.open(IO_ReadOnly))
+ return false;
+ char *temp = new char[dataFile.size()+1];
+ dataFile.readBlock(temp,dataFile.size());
+ temp[dataFile.size()]='\0';
+ buffer = temp;
+ delete [] temp;
+ dataFile.close();
+ return true;
+}
+
+bool SubclassingDlg::replaceKeywords(QString &buffer,bool canBeModal)
+//===================================================================
+{
+ replace(buffer,"$NEWFILENAMEUC$",m_edFileName->text().upper());
+ replace(buffer,"$BASEFILENAMELC$",m_formName.lower());
+ replace(buffer,"$BASEFILENAME$",m_formName);
+ replace(buffer,"$NEWCLASS$",m_edClassName->text());
+ replace(buffer,"$BASECLASS$",m_baseClassName);
+ replace(buffer,"$NEWFILENAMELC$",m_edFileName->text().lower());
+ if (canBeModal)
+ {
+ replace(buffer,"$CAN_BE_MODAL_H$",", bool modal = FALSE");
+ replace(buffer,"$CAN_BE_MODAL_CPP1$",", bool modal");
+ replace(buffer,"$CAN_BE_MODAL_CPP2$",", modal");
+ }
+ else
+ {
+ replace(buffer,"$CAN_BE_MODAL_H$","");
+ replace(buffer,"$CAN_BE_MODAL_CPP1$","");
+ replace(buffer,"$CAN_BE_MODAL_CPP2$","");
+ }
+
+ return true;
+}
+
+bool SubclassingDlg::saveBuffer(QString &buffer, const QString& filename)
+//=======================================================================
+{
+ // save buffer
+
+ QFile dataFile(filename);
+ if (!dataFile.open(IO_WriteOnly | IO_Truncate))
+ return false;
+ dataFile.writeBlock((buffer+"\n").ascii(),(buffer+"\n").length());
+ dataFile.close();
+ return true;
+}
+
+
+void SubclassingDlg::accept()
+//===========================
+{
+/* KConfig *config = kjsSupportFactory::instance()->config();
+ if (config)
+ {
+ config->setGroup("Subclassing");
+ config->writeEntry("Reformat Source", reformatDefault_box->isChecked());
+ }*/
+
+ unsigned int i;
+
+ // h - file
+
+ QString public_slot =
+ "/*$PUBLIC_SLOTS$*/\n ";
+
+ QString protected_slot =
+ "/*$PROTECTED_SLOTS$*/\n ";
+
+ QString public_func =
+ "/*$PUBLIC_FUNCTIONS$*/\n ";
+
+ QString protected_func =
+ "/*$PROTECTED_FUNCTIONS$*/\n ";
+
+ QString buffer;
+ if (m_creatingNewSubclass)
+ {
+ loadBuffer(buffer,::locate("data", "kdevkjssupport/subclassing/subclass_template.js"));
+ kdDebug() << "buffer: " << buffer << endl;
+ buffer = "var $NEWCLASS$ = Factory.loadui(\"$BASEFILENAME$.ui\", this);\n\n" + buffer;
+ buffer = FileTemplate::read(m_kjsSupport, "js") + buffer + connections;
+ kdDebug() << "buffer: " << buffer << endl;
+ QFileInfo fi(m_filename + ".js");
+ QString module = fi.baseName();
+ QString basefilename = fi.baseName(true);
+ buffer.replace(QRegExp("\\$MODULE\\$"),module);
+ buffer.replace(QRegExp("\\$FILENAME\\$"),basefilename);
+ }
+ else
+ loadBuffer(buffer,m_filename+".js");
+
+ // js - file
+
+ QString implementation =
+ "/*$SPECIALIZATION$*/\n"
+ "function $METHOD$\n"
+ "{\n"
+ "}\n";
+
+ replaceKeywords(buffer,m_canBeModal);
+ for (i=0; i<m_slots.count(); i++)
+ {
+ SlotItem *slitem = m_slots[i];
+ if (!slitem->isOn() ||
+ slitem->m_alreadyInSubclass)
+ continue;
+ QString impl = implementation;
+ replace(impl,"$RETURNTYPE$",slitem->m_returnType);
+ replace(impl,"$NEWCLASS$",m_edClassName->text());
+ replace(impl,"$METHOD$", slitem->m_methodName);
+ replace(impl,"$QTBASECLASS$", m_qtBaseClassName);
+ replace(buffer,"/*$SPECIALIZATION$*/",impl);
+ }
+ kdDebug() << buffer << endl;
+
+ if (reformat_box->isChecked())
+ buffer = m_kjsSupport->sourceFormatter()->formatSource(buffer);
+
+ if (m_creatingNewSubclass)
+ saveBuffer(buffer,m_formPath + "/" + m_edFileName->text()+".js");
+ else
+ saveBuffer(buffer,m_filename+".js");
+
+ if (m_creatingNewSubclass)
+ {
+ m_newFileNames.append(m_formPath + "/" + m_edFileName->text()+".js");
+ }
+ SubclassingDlgBase::accept();
+}
+
+void SubclassingDlg::onChangedClassName()
+//=======================================
+{
+ m_edFileName->setText(m_edClassName->text().lower());
+ if (m_edFileName->text().isEmpty() ||
+ m_edClassName->text().isEmpty())
+ m_btnOk->setEnabled(false);
+ else
+ m_btnOk->setEnabled(true);
+}
+
+QString SubclassingDlg::readBaseClassName( )
+{
+ QDomDocument doc;
+ DomUtil::openDOMFile(doc,m_formFile);
+ return DomUtil::elementByPathExt(doc,WIDGET_CLASS_NAME).text();
+}
diff --git a/languages/kjssupport/subclassingdlg.h b/languages/kjssupport/subclassingdlg.h
new file mode 100644
index 00000000..c727b648
--- /dev/null
+++ b/languages/kjssupport/subclassingdlg.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * Copyright (C) 2002 by Jakob Simon-Gaarde *
+ * jsgaarde@tdcspace.dk *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SUBCLASSINGDLG_H
+#define SUBCLASSINGDLG_H
+
+#include <qlistview.h>
+
+#include "subclassingdlgbase.h"
+
+class QStringList;
+class QDomDocument;
+class kjsSupportPart;
+
+class SlotItem : public QCheckListItem
+{
+ public:
+ SlotItem(QListView *parent,const QString &text,
+ const QString &specifier, const QString &Access,
+ const QString &returnType,bool isFunc,
+ bool callBaseClass=false);
+ void setAllreadyInSubclass();
+ QString m_access;
+ QString m_methodName;
+ QString m_returnType;
+ QString m_specifier;
+ bool m_isFunc;
+ bool m_callBaseClass;
+ bool m_alreadyInSubclass;
+};
+
+
+class SubclassingDlg : public SubclassingDlgBase
+{
+public:
+ SubclassingDlg(kjsSupportPart* kjsSupport, const QString &formFile,QStringList &newFileNames,
+ QWidget* parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );
+/* SubclassingDlg(CppSupportPart* kjsSupport, const QString &formFile,const QString &filename,QStringList &dummy,
+ QWidget* parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );*/
+ ~SubclassingDlg();
+
+private:
+ void readUiFile();
+ QString readBaseClassName();
+ void updateDlg();
+ bool replaceKeywords(QString &buffer, bool canBeModal=true);
+ void replace(QString &string, const QString& search, const QString& replace);
+ bool saveBuffer(QString &buffer, const QString& filename);
+ bool loadBuffer(QString &buffer, const QString& filename);
+ bool alreadyInSubclass(const QString &method);
+ bool m_creatingNewSubclass;
+
+public slots:
+ virtual void accept();
+ virtual void onChangedClassName();
+
+protected:
+ QStringList &m_newFileNames;
+ QString m_filename;
+ QString m_formFile;
+ QString m_baseClassName;
+ QString m_qtBaseClassName;
+ QString m_baseCaption;
+ QString m_formName;
+ QString m_formPath;
+ QStringList m_parsedMethods;
+ bool m_canBeModal;
+ QValueList<SlotItem*> m_slots;
+ QValueList<SlotItem*> m_functions;
+ kjsSupportPart* m_kjsSupport;
+ QString connections;
+};
+
+#endif
+
diff --git a/languages/kjssupport/subclassingdlgbase.ui b/languages/kjssupport/subclassingdlgbase.ui
new file mode 100644
index 00000000..fea5ef6d
--- /dev/null
+++ b/languages/kjssupport/subclassingdlgbase.ui
@@ -0,0 +1,253 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>SubclassingDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SubclassingDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>588</width>
+ <height>493</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Implement Slots</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>reformat_box</cstring>
+ </property>
+ <property name="text">
+ <string>Re&amp;format source</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="2">
+ <property name="name">
+ <cstring>reformatDefault_box</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reformat source by &amp;default</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="3" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string>Method</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Access</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Specifier</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Return Type</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>m_slotView</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Specialize following slots:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_slotView</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_edFileName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>F&amp;ile name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_edFileName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>C&amp;lass name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_edClassName</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_edClassName</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>m_btnOk</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;reate</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>m_btnCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>110</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>m_btnOk</sender>
+ <signal>clicked()</signal>
+ <receiver>SubclassingDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>m_btnCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>SubclassingDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>m_edClassName</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>SubclassingDlgBase</receiver>
+ <slot>onChangedClassName()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>m_edClassName</tabstop>
+ <tabstop>m_edFileName</tabstop>
+ <tabstop>m_slotView</tabstop>
+ <tabstop>reformat_box</tabstop>
+ <tabstop>reformatDefault_box</tabstop>
+ <tabstop>m_btnOk</tabstop>
+ <tabstop>m_btnCancel</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in implementation">kdialog.h</include>
+</includes>
+<slots>
+ <slot>onChangedClassName()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/languages/kjssupport/template/Makefile.am b/languages/kjssupport/template/Makefile.am
new file mode 100644
index 00000000..3244188a
--- /dev/null
+++ b/languages/kjssupport/template/Makefile.am
@@ -0,0 +1,20 @@
+appwizarddatadir = ${kde_datadir}/kdevappwizard
+commondatadir = ${appwizarddatadir}/template-common
+jshellodir = ${appwizarddatadir}/template-jshello
+templatedir = ${appwizarddatadir}/templates
+
+jshello_DATA = app.js app.kdevelop
+template_DATA = jshello
+
+DISTCLEANFILES = script.local
+EXTRA_DIST = script
+
+perl = perl
+
+script.local: ${srcdir}/script
+ cp ${srcdir}/script script.local ; \
+ perl -npi -e 's%^#\!.*$$%#!'${perl}' -I'${commondatadir}'%g;' script.local
+
+install-data-local: script.local
+ $(mkinstalldirs) $(DESTDIR)$(jshellodir)
+ $(INSTALL_DATA) script.local $(DESTDIR)$(jshellodir)/script
diff --git a/languages/kjssupport/template/app.js b/languages/kjssupport/template/app.js
new file mode 100644
index 00000000..aa564dd6
--- /dev/null
+++ b/languages/kjssupport/template/app.js
@@ -0,0 +1,18 @@
+#!/usr/bin/env kjscmd
+
+// Create main view
+var mw = new KMainWindow();
+var lv = new KListView( mw );
+mw.setCentralWidget(lv);
+
+lv.addColumn('One');
+lv.addColumn('Two');
+lv.addColumn('Three');
+
+lv.insertItem( 'Something', "Nothing", "Thing" );
+lv.insertItem( 'Something', "Nothing", "Thing" );
+lv.insertItem( 'Something', "Nothing", "Thing" );
+lv.insertItem( 'Something', "Nothing", "Thing" );
+
+mw.show();
+
diff --git a/languages/kjssupport/template/app.kdevelop b/languages/kjssupport/template/app.kdevelop
new file mode 100644
index 00000000..2bb39a0a
--- /dev/null
+++ b/languages/kjssupport/template/app.kdevelop
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<kdevelop>
+ <general>
+ <author>$AUTHOR$</author>
+ <email>$EMAIL$</email>
+ <version>$VERSION$</version>
+ <projectmanagement>KDevScriptProject</projectmanagement>
+ <primarylanguage>Javascript</primarylanguage>
+ <keywords>
+ <keyword>Javascript</keyword>
+ </keywords>
+ <ignoreparts>
+ <part>KDevFileView</part>
+ <part>KDevdistpart</part>
+ <part>KDevDebugger</part>
+ </ignoreparts>
+ </general>
+ <kdevscriptproject>
+ <general>
+ <activedir>src</activedir>
+ <includepatterns>*.js</includepatterns>
+ <excludepatterns>*~</excludepatterns>
+ </general>
+ </kdevscriptproject>
+ <kdevfileview>
+ <groups>
+ <group pattern="*.js" name="Scripts" />
+ </groups>
+ </kdevfileview>
+ <kdevdoctreeview>
+ <ignoretocs>
+ <toc>kde</toc>
+ <toc>gtk</toc>
+ <toc>gnustep</toc>
+ <toc>python</toc>
+ <toc>perl</toc>
+ <toc>php</toc>
+ </ignoretocs>
+ </kdevdoctreeview>
+ <kdevfilecreate>
+ <useglobaltypes>
+ <type ext="js"/>
+ </useglobaltypes>
+ </kdevfilecreate>
+</kdevelop>
diff --git a/languages/kjssupport/template/jshello b/languages/kjssupport/template/jshello
new file mode 100644
index 00000000..8013b033
--- /dev/null
+++ b/languages/kjssupport/template/jshello
@@ -0,0 +1,6 @@
+# KDE Config File
+[General]
+Name=Simple KJSEmbed Script
+Category=Script
+Comment=This generates a simplistic 'Hello world' program in KJSEmbed
+FileTemplates=js,Javascript
diff --git a/languages/kjssupport/template/script b/languages/kjssupport/template/script
new file mode 100644
index 00000000..d3a808c5
--- /dev/null
+++ b/languages/kjssupport/template/script
@@ -0,0 +1,13 @@
+#!perl -I/usr/kde/3.1/share/apps/kdevappwizard/template-common
+
+use gideon;
+
+initGideon();
+
+print "Installing project file\n";
+installHTML( "${src}/template-jshello/app.kdevelop", "${dest}/${APPNAMELC}.kdevelop" );
+
+print "Installing application sources\n";
+install( "${src}/template-jshello/app.js", "${dest}/${APPNAMELC}.js" );
+
+print "Finished\n";
diff --git a/languages/kjssupport/x-javascript-source.desktop b/languages/kjssupport/x-javascript-source.desktop
new file mode 100644
index 00000000..5beeb52a
--- /dev/null
+++ b/languages/kjssupport/x-javascript-source.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+MimeType=dummy
+Hidden=true
+