KDevelop API Documentation

languages/python/pythonsupportpart.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2001-2002 by Bernd Gehrmann * 00003 * bernd@kdevelop.org * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 * * 00010 ***************************************************************************/ 00011 00012 #include "pythonsupportpart.h" 00013 #include "pythonconfigwidget.h" 00014 00015 #include <kdevcore.h> 00016 #include <kdevproject.h> 00017 #include <kdevappfrontend.h> 00018 #include <kdevpartcontroller.h> 00019 #include <codemodel.h> 00020 #include <domutil.h> 00021 00022 #include <qfileinfo.h> 00023 #include <qpopupmenu.h> 00024 #include <qstringlist.h> 00025 #include <qtextstream.h> 00026 #include <qtimer.h> 00027 #include <qvbox.h> 00028 #include <kaction.h> 00029 #include <kapplication.h> 00030 #include <kdebug.h> 00031 #include <kdialogbase.h> 00032 #include <kdevgenericfactory.h> 00033 #include <klineeditdlg.h> 00034 #include <klocale.h> 00035 #include <qregexp.h> 00036 00037 00038 typedef KDevGenericFactory<PythonSupportPart> PythonSupportFactory; 00039 static const KAboutData data("kdevpythonsupport", I18N_NOOP("Language"), "1.0"); 00040 K_EXPORT_COMPONENT_FACTORY( libkdevpythonsupport, PythonSupportFactory( &data ) ) 00041 00042 PythonSupportPart::PythonSupportPart(QObject *parent, const char *name, const QStringList &) 00043 : KDevLanguageSupport("PythonSupport", "python", parent, name ? name : "PythonSupportPart") 00044 { 00045 setInstance(PythonSupportFactory::instance()); 00046 00047 setXMLFile("kdevpythonsupport.rc"); 00048 00049 connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) ); 00050 connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) ); 00051 connect( partController(), SIGNAL(savedFile(const QString&)), 00052 this, SLOT(savedFile(const QString&)) ); 00053 connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), 00054 this, SLOT(projectConfigWidget(KDialogBase*)) ); 00055 00056 KAction *action; 00057 00058 action = new KAction( i18n("Execute Program"), "exec", 0, 00059 this, SLOT(slotExecute()), 00060 actionCollection(), "build_exec" ); 00061 action->setToolTip( i18n("Execute program") ); 00062 action->setWhatsThis(i18n("<b>Execute program</b><p>Runs the Python program.")); 00063 00064 action = new KAction( i18n("Execute String..."), "exec", 0, 00065 this, SLOT(slotExecuteString()), 00066 actionCollection(), "build_execstring" ); 00067 action->setToolTip( i18n("Execute string") ); 00068 action->setWhatsThis(i18n("<b>Execute String</b><p>Executes a string as Python code.")); 00069 00070 action = new KAction( i18n("Start Python Interpreter"), "exec", 0, 00071 this, SLOT(slotStartInterpreter()), 00072 actionCollection(), "build_runinterpreter" ); 00073 action->setToolTip( i18n("Start python interpreter") ); 00074 action->setWhatsThis(i18n("<b>Start python interpreter</b><p>Starts the Python interpreter without a program")); 00075 00076 action = new KAction( i18n("Python Documentation..."), 0, 00077 this, SLOT(slotPydoc()), 00078 actionCollection(), "help_pydoc" ); 00079 action->setToolTip( i18n("Python documentation") ); 00080 action->setWhatsThis(i18n("<b>Python documentation</b><p>Shows a Python documentation page.")); 00081 } 00082 00083 00084 PythonSupportPart::~PythonSupportPart() 00085 {} 00086 00087 00088 void PythonSupportPart::projectConfigWidget(KDialogBase *dlg) 00089 { 00090 QVBox *vbox = dlg->addVBoxPage(i18n("Python")); 00091 PythonConfigWidget *w = new PythonConfigWidget(*projectDom(), vbox, "python config widget"); 00092 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); 00093 } 00094 00095 00096 void PythonSupportPart::projectOpened() 00097 { 00098 kdDebug(9014) << "projectOpened()" << endl; 00099 00100 connect( project(), SIGNAL(addedFilesToProject(const QStringList &)), 00101 this, SLOT(addedFilesToProject(const QStringList &)) ); 00102 connect( project(), SIGNAL(removedFilesFromProject(const QStringList &)), 00103 this, SLOT(removedFilesFromProject(const QStringList &)) ); 00104 00105 // We want to parse only after all components have been 00106 // properly initialized 00107 QTimer::singleShot(0, this, SLOT(initialParse())); 00108 } 00109 00110 00111 void PythonSupportPart::projectClosed() 00112 { 00113 } 00114 00115 00116 void PythonSupportPart::maybeParse(const QString fileName) 00117 { 00118 QFileInfo fi(fileName); 00119 if (fi.extension() == "py") { 00120 00121 if( codeModel()->hasFile(fileName) ){ 00122 emit aboutToRemoveSourceInfo( fileName ); 00123 codeModel()->removeFile( codeModel()->fileByName(fileName) ); 00124 } 00125 00126 parse( fileName ); 00127 } 00128 } 00129 00130 00131 void PythonSupportPart::initialParse() 00132 { 00133 kdDebug(9014) << "initialParse()" << endl; 00134 00135 if (project()) { 00136 kapp->setOverrideCursor(waitCursor); 00137 QStringList files = project()->allFiles(); 00138 for (QStringList::Iterator it = files.begin(); it != files.end() ;++it) { 00139 kdDebug(9014) << "maybe parse " << project()->projectDirectory() + "/" + (*it) << endl; 00140 maybeParse(project()->projectDirectory() + "/" + *it); 00141 } 00142 00143 emit updatedSourceInfo(); 00144 kapp->restoreOverrideCursor(); 00145 } else { 00146 kdDebug(9014) << "No project" << endl; 00147 } 00148 } 00149 00150 00151 void PythonSupportPart::addedFilesToProject(const QStringList &fileList) 00152 { 00153 kdDebug(9014) << "addedFilesToProject()" << endl; 00154 00155 QStringList::ConstIterator it; 00156 00157 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00158 { 00159 QString fileName = project()->projectDirectory() + "/" + ( *it ); 00160 maybeParse( fileName ); 00161 emit addedSourceInfo( fileName ); 00162 } 00163 00164 //emit updatedSourceInfo(); 00165 } 00166 00167 00168 void PythonSupportPart::removedFilesFromProject(const QStringList &fileList) 00169 { 00170 kdDebug(9014) << "removedFilesFromProject()" << endl; 00171 00172 QStringList::ConstIterator it; 00173 00174 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00175 { 00176 QString fileName = project()->projectDirectory() + "/" + ( *it ); 00177 00178 if( codeModel()->hasFile(fileName) ){ 00179 emit aboutToRemoveSourceInfo( fileName ); 00180 codeModel()->removeFile( codeModel()->fileByName(fileName) ); 00181 } 00182 } 00183 00184 //emit updatedSourceInfo(); 00185 } 00186 00187 00188 void PythonSupportPart::savedFile(const QString &fileName) 00189 { 00190 kdDebug(9014) << "savedFile()" << endl; 00191 00192 if (project()->allFiles().contains(fileName.mid ( project()->projectDirectory().length() + 1 ))) { 00193 maybeParse(fileName); 00194 emit addedSourceInfo( fileName ); 00195 } 00196 } 00197 00198 00199 KDevLanguageSupport::Features PythonSupportPart::features() 00200 { 00201 return Features(Classes | Functions); 00202 } 00203 00204 00205 KMimeType::List PythonSupportPart::mimeTypes( ) 00206 { 00207 KMimeType::List list; 00208 KMimeType::Ptr mime = KMimeType::mimeType( "text/x-python" ); 00209 if( mime ) 00210 list << mime; 00211 00212 mime = KMimeType::mimeType( "application/x-python" ); 00213 if( mime ) 00214 list << mime; 00215 00216 return list; 00217 } 00218 00219 void PythonSupportPart::parse(const QString &fileName) 00220 { 00221 QFile f(QFile::encodeName(fileName)); 00222 if (!f.open(IO_ReadOnly)) 00223 return; 00224 QTextStream stream(&f); 00225 00226 QRegExp classre("^[ \t]*class[ \t]+([A-Za-z0-9_]+)[ \t]*(\\(([A-Za-z0-9_, \t]+)\\))?.*$"); 00227 QRegExp methodre("^[ \t]*def[ \t]+([A-Za-z0-9_]+).*$"); 00228 00229 FileDom m_file = codeModel()->create<FileModel>(); 00230 m_file->setName( fileName ); 00231 00232 ClassDom lastClass; 00233 QString rawline; 00234 QCString line; 00235 int lineNo = 0; 00236 while (!stream.atEnd()) { 00237 rawline = stream.readLine(); 00238 line = rawline.stripWhiteSpace().local8Bit(); 00239 if (classre.search(line) != -1) { 00240 00241 lastClass = codeModel()->create<ClassModel>(); 00242 lastClass->setName(classre.cap(1)); 00243 lastClass->setFileName( fileName ); 00244 lastClass->setStartPosition( lineNo, 0 ); 00245 00246 QStringList parentList = QStringList::split(",", classre.cap(3)); 00247 QStringList::ConstIterator it; 00248 for (it = parentList.begin(); it != parentList.end(); ++it) { 00249 QString baseName = (*it).stripWhiteSpace(); 00250 kdDebug(9014) << "Add parent" << baseName << endl; 00251 lastClass->addBaseClass( baseName ); 00252 } 00253 00254 if (m_file->hasClass(lastClass->name())) { 00255 ClassDom old = m_file->classByName( lastClass->name() )[ 0 ]; 00256 old->setFileName( lastClass->fileName() ); 00257 00258 int line, col; 00259 lastClass->getStartPosition( &line, &col ); 00260 old->setStartPosition( line, col ); 00261 00262 lastClass = old; 00263 } else { 00264 kdDebug(9014) << "Add class " << lastClass->name() << endl; 00265 m_file->addClass( lastClass ); 00266 } 00267 00268 } else if (methodre.search(line) != -1 ) { 00269 00270 FunctionDom method = codeModel()->create<FunctionModel>(); 00271 method->setName(methodre.cap(1)); 00272 method->setFileName( fileName ); 00273 method->setStartPosition( lineNo, 0 ); 00274 00275 if (lastClass && rawline.left(3) != "def") { 00276 if( !lastClass->hasFunction(method->name()) ) 00277 lastClass->addFunction( method ); 00278 } else if( !m_file->hasFunction(method->name()) ){ 00279 m_file->addFunction( method ); 00280 lastClass = 0; 00281 } 00282 } 00283 ++lineNo; 00284 } 00285 00286 f.close(); 00287 00288 codeModel()->addFile( m_file ); 00289 } 00290 00291 00292 QString PythonSupportPart::interpreter() 00293 { 00294 QString prog = DomUtil::readEntry(*projectDom(), "/kdevpythonsupport/run/interpreter"); 00295 if (prog.isEmpty()) 00296 prog = "python"; 00297 00298 return prog; 00299 } 00300 00301 00302 void PythonSupportPart::startApplication(const QString &program) 00303 { 00304 bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevpythonsupport/run/terminal"); 00305 appFrontend()->startAppCommand(QString::QString(), program, inTerminal); 00306 } 00307 00308 00309 void PythonSupportPart::slotExecute() 00310 { 00311 QString program = project()->mainProgram(); 00312 QString cmd = interpreter() + " " + program; 00313 startApplication(cmd); 00314 } 00315 00316 00317 void PythonSupportPart::slotStartInterpreter() 00318 { 00319 startApplication(interpreter()); 00320 } 00321 00322 00323 void PythonSupportPart::slotExecuteString() 00324 { 00325 bool ok; 00326 QString cmd = KLineEditDlg::getText(i18n("String to execute"), QString::null, &ok, 0); 00327 if (ok) { 00328 cmd.prepend("'"); 00329 cmd.append("'"); 00330 startApplication(cmd); 00331 } 00332 } 00333 00334 00335 void PythonSupportPart::slotPydoc() 00336 { 00337 bool ok; 00338 QString key = KLineEditDlg::getText(i18n("Show Python documentation on keyword:"), "", &ok, 0); 00339 if (ok && !key.isEmpty()) { 00340 QString url = "pydoc:"; 00341 url += key; 00342 partController()->showDocument(KURL(url)); 00343 } 00344 } 00345 00346 #include "pythonsupportpart.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:06 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003