KDevelop API Documentation

rubysupport_part.cpp

Go to the documentation of this file.
00001 #include <qwhatsthis.h>
00002 #include <qtimer.h>
00003 #include <qfileinfo.h>
00004 
00005 
00006 #include <kiconloader.h>
00007 #include <klocale.h>
00008 #include <kdevgenericfactory.h>
00009 #include <kprocess.h>
00010 #include <kdebug.h>
00011 #include <kaction.h>
00012 #include <kparts/part.h>
00013 #include <kdialogbase.h>
00014 #include <kapplication.h>
00015 #include <qregexp.h>
00016 
00017 
00018 #include "kdevcore.h"
00019 #include "kdevmainwindow.h"
00020 #include "kdevlanguagesupport.h"
00021 #include "kdevpartcontroller.h"
00022 #include "kdevproject.h"
00023 #include "kdevappfrontend.h"
00024 
00025 #include "rubysupport_part.h"
00026 #include "rubyconfigwidget.h"
00027 #include "domutil.h"
00028 
00029 typedef KDevGenericFactory<RubySupportPart> RubySupportFactory;
00030 static const KAboutData data("kdevrubysupport", I18N_NOOP("Language"), "1.0");
00031 K_EXPORT_COMPONENT_FACTORY( libkdevrubysupport, RubySupportFactory( &data ) )
00032 
00033 RubySupportPart::RubySupportPart(QObject *parent, const char *name, const QStringList& )
00034   : KDevLanguageSupport ("KDevPart", "kdevpart", parent, name ? name : "RubySupportPart" )
00035 {
00036   setInstance(RubySupportFactory::instance());
00037   setXMLFile("kdevrubysupport.rc");
00038 
00039   KAction *action;
00040   action = new KAction( i18n("&Run"), "exec",Key_F9,this, SLOT(slotRun()),actionCollection(), "build_execute" );
00041   action->setToolTip(i18n("Run"));
00042   action->setWhatsThis(i18n("<b>Run</b><p>Starts an application."));
00043 
00044   kdDebug() << "Creating RubySupportPart" << endl;
00045 
00046   connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) );
00047   connect( partController(), SIGNAL(savedFile(const KURL&)),
00048     this, SLOT(savedFile(const KURL&)) );
00049   connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)),
00050              this, SLOT(projectConfigWidget(KDialogBase*)) );
00051 }
00052 
00053 
00054 RubySupportPart::~RubySupportPart() {
00055 }
00056 
00057 
00058 void RubySupportPart::projectConfigWidget(KDialogBase *dlg) {
00059     QVBox *vbox = dlg->addVBoxPage(i18n("Ruby"));
00060     RubyConfigWidget *w = new RubyConfigWidget(*projectDom(), (QWidget *)vbox, "ruby config widget");
00061     connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) );
00062 }
00063 
00064 void RubySupportPart::projectOpened()
00065 {
00066   kdDebug() << "projectOpened()" << endl;
00067 
00068   connect( project(), SIGNAL(addedFilesToProject(const QStringList &)),
00069     this, SLOT(addedFilesToProject(const QStringList &)) );
00070   connect( project(), SIGNAL(removedFilesFromProject(const QStringList &)),
00071     this, SLOT(removedFilesFromProject(const QStringList &)) );
00072 
00073   // We want to parse only after all components have been
00074   // properly initialized
00075   QTimer::singleShot(0, this, SLOT(initialParse()));
00076 }
00077 
00078 void RubySupportPart::maybeParse(const QString fileName)
00079 {
00080   QFileInfo fi(fileName);
00081 
00082   if (fi.extension() == "rb") {
00083     if (codeModel()->hasFile(fileName)) {
00084       emit aboutToRemoveSourceInfo(fileName);
00085       codeModel()->removeFile(codeModel()->fileByName(fileName));
00086     }
00087 
00088     parse(fileName);
00089   }
00090 }
00091 
00092 void RubySupportPart::initialParse()
00093 {
00094   kdDebug() << "initialParse()" << endl;
00095 
00096   if (project()) {
00097     kapp->setOverrideCursor(waitCursor);
00098     QStringList files = project()->allFiles();
00099     for (QStringList::Iterator it = files.begin(); it != files.end() ;++it) {
00100       kdDebug() << "maybe parse " << project()->projectDirectory() + "/" + (*it) << endl;
00101       maybeParse(project()->projectDirectory() + "/" + *it);
00102     }
00103 
00104     emit updatedSourceInfo();
00105     kapp->restoreOverrideCursor();
00106   } else {
00107     kdDebug() << "No project" << endl;
00108   }
00109 }
00110 
00111 void RubySupportPart::addedFilesToProject(const QStringList &fileList)
00112 {
00113   kdDebug() << "addedFilesToProject()" << endl;
00114 
00115   QStringList::ConstIterator it;
00116 
00117   for ( it = fileList.begin(); it != fileList.end(); ++it )
00118   {
00119     QString fileName = project()->projectDirectory() + "/" + ( *it );
00120     maybeParse( fileName );
00121     emit addedSourceInfo( fileName );
00122   }
00123 }
00124 
00125 void RubySupportPart::removedFilesFromProject(const QStringList &fileList)
00126 {
00127   kdDebug() << "removedFilesFromProject()" << endl;
00128 
00129   QStringList::ConstIterator it;
00130 
00131   for ( it = fileList.begin(); it != fileList.end(); ++it )
00132   {
00133     QString fileName = project()->projectDirectory() + "/" + ( *it );
00134 
00135     if( codeModel()->hasFile(fileName) ){
00136       emit aboutToRemoveSourceInfo( fileName );
00137       codeModel()->removeFile( codeModel()->fileByName(fileName) );
00138     }
00139   }
00140 }
00141 
00142 void RubySupportPart::savedFile(const KURL &fileName)
00143 {
00144   kdDebug() << "savedFile()" << endl;
00145 
00146   if (project()->allFiles().contains(fileName.path().mid ( project()->projectDirectory().length() + 1 ))) {
00147     maybeParse(fileName.path());
00148     emit addedSourceInfo( fileName.path() );
00149   }
00150 }
00151 
00152 KDevLanguageSupport::Features RubySupportPart::features()
00153 {
00154   return Features(Classes | Functions);
00155 }
00156 
00157 void RubySupportPart::parse(const QString &fileName)
00158 {
00159   QFile f(QFile::encodeName(fileName));
00160   if (!f.open(IO_ReadOnly))
00161     return;
00162   QTextStream stream(&f);
00163 
00164   QRegExp classre("^\\s*class\\s+([A-Z][A-Za-z0-9_]+)\\s*(<\\s*([A-Z][A-Za-z0-9_:]+))?$");
00165   QRegExp methodre("^\\s*def\\s+([A-Za-z0-9_]+).*$");
00166 
00167   FileDom m_file = codeModel()->create<FileModel>();
00168   m_file->setName(fileName);
00169 
00170   ClassDom lastClass;
00171   QString rawline;
00172   QCString line;
00173   int lineNo = 0;
00174 
00175   while (!stream.atEnd()) {
00176     rawline = stream.readLine();
00177     line = rawline.stripWhiteSpace().local8Bit();
00178     if (classre.search(line) != -1) {
00179       lastClass = codeModel()->create<ClassModel>();
00180       lastClass->setName(classre.cap(1));
00181       lastClass->setFileName( fileName );
00182       lastClass->setStartPosition( lineNo, 0 );
00183 
00184       QString parent = classre.cap(3);//.stripWhiteSpace()?
00185       if (!parent.isEmpty())
00186       {
00187         kdDebug() << "Add parent " << parent << endl;
00188         lastClass->addBaseClass( parent );
00189       }
00190 
00191       if (m_file->hasClass(lastClass->name())) {
00192         ClassDom old = m_file->classByName( lastClass->name() )[ 0 ];
00193         old->setFileName( lastClass->fileName() );
00194 
00195         int line, col;
00196         lastClass->getStartPosition( &line, &col );
00197         old->setStartPosition( line, col );
00198 
00199         lastClass = old;
00200       } else {
00201           kdDebug() << "Add class " << lastClass->name() << endl;
00202           m_file->addClass( lastClass );
00203       }
00204     } else if (methodre.search(line) != -1) {
00205       FunctionDom method = codeModel()->create<FunctionModel>();
00206       method->setName(methodre.cap(1));
00207       kdDebug() << "Add method: " << method->name() << endl;
00208       method->setFileName( fileName );
00209       method->setStartPosition( lineNo, 0 );
00210 
00211       if (lastClass && rawline.left(3) != "def") {
00212         if( !lastClass->hasFunction(method->name()) ) 
00213           lastClass->addFunction( method );
00214       } else if( !m_file->hasFunction(method->name()) ){
00215         m_file->addFunction( method );
00216         lastClass = 0;
00217       }
00218     }
00219     ++lineNo;
00220   }
00221 
00222   f.close();
00223 
00224   codeModel()->addFile( m_file );
00225 }
00226 
00227 
00228 void RubySupportPart::slotRun () {
00229   QString file;
00230 KParts::ReadOnlyPart *ro_part = dynamic_cast<KParts::ReadOnlyPart*>(partController()->activePart());
00231   if(ro_part) file = ro_part->url().path();
00232 //  file = project()->mainProgram();
00233 
00234   QString cmd = interpreter() + " " + file;
00235   startApplication(cmd);
00236 }
00237 
00238 QString RubySupportPart::interpreter() {
00239     QString prog = DomUtil::readEntry(*projectDom(), "/kdevrubysupport/run/interpreter");
00240     if (prog.isEmpty()) prog = "ruby";
00241     return prog;
00242 }
00243 
00244 
00245 void RubySupportPart::startApplication(const QString &program) {
00246         bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevrubysupport/run/terminal");
00247     appFrontend()->startAppCommand(project()->projectDirectory(), program, inTerminal);
00248 }
00249 
00250 
00251 KMimeType::List RubySupportPart::mimeTypes( )
00252 {
00253     KMimeType::List list;
00254     KMimeType::Ptr mime = KMimeType::mimeType( "text/x-ruby" );
00255     if( mime )
00256     list << mime;
00257     return list;
00258 }
00259 
00260 #include "rubysupport_part.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:34 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003