00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "perlsupportpart.h"
00013
00014 #include <qfileinfo.h>
00015 #include <qpopupmenu.h>
00016 #include <qstringlist.h>
00017 #include <qtextstream.h>
00018 #include <qtimer.h>
00019 #include <kaction.h>
00020 #include <kapplication.h>
00021 #include <kdebug.h>
00022 #include <kdevgenericfactory.h>
00023 #include <kinputdialog.h>
00024 #include <klocale.h>
00025 #include <qregexp.h>
00026 #include <codemodel.h>
00027 #include <qprogressbar.h>
00028 #include <kstatusbar.h>
00029 #include "kdevmainwindow.h"
00030
00031 #include <kprocess.h>
00032 #include <stdlib.h>
00033 #include <unistd.h>
00034
00035 #include "kdevcore.h"
00036 #include "kdevproject.h"
00037 #include "kdevpartcontroller.h"
00038 #include "kdevappfrontend.h"
00039
00040
00041
00042
00043 #include "domutil.h"
00044
00045
00046 typedef KDevGenericFactory<PerlSupportPart> PerlSupportFactory;
00047 static const KAboutData data("kdevperlsupport", I18N_NOOP("Language"), "1.0");
00048 K_EXPORT_COMPONENT_FACTORY( libkdevperlsupport, PerlSupportFactory( &data ) )
00049
00050 PerlSupportPart::PerlSupportPart(QObject *parent, const char *name, const QStringList &)
00051 : KDevLanguageSupport("PerlSupport", "perl", parent, name ? name : "PerlSupportPart")
00052 {
00053 setInstance(PerlSupportFactory::instance());
00054
00055 setXMLFile("kdevperlsupport.rc");
00056
00057 connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) );
00058 connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) );
00059 connect( partController(), SIGNAL(savedFile(const KURL&)),
00060 this, SLOT(savedFile(const KURL&)) );
00061
00062 KAction *action;
00063
00064 action = new KAction( i18n("Execute Program"), "exec", 0,
00065 this, SLOT(slotExecute()),
00066 actionCollection(), "build_exec" );
00067 action->setStatusText( i18n("Runs the Perl program") );
00068
00069 action = new KAction( i18n("Execute String..."), "exec", 0,
00070 this, SLOT(slotExecuteString()),
00071 actionCollection(), "build_execstring" );
00072 action->setStatusText( i18n("Executes a string as Perl code") );
00073
00074 action = new KAction( i18n("Start Perl Interpreter"), "exec", 0,
00075 this, SLOT(slotStartInterpreter()),
00076 actionCollection(), "build_runinterpreter" );
00077 action->setStatusText( i18n("Starts the Perl interpreter without a program") );
00078
00079 action = new KAction( i18n("Find Perl Function Documentation..."), 0,
00080 this, SLOT(slotPerldocFunction()),
00081 actionCollection(), "help_perldocfunction" );
00082 action->setStatusText( i18n("Show the documentation page of a Perl function") );
00083
00084 action = new KAction( i18n("Find Perl FAQ Entry..."), 0,
00085 this, SLOT(slotPerldocFAQ()),
00086 actionCollection(), "help_perldocfaq" );
00087 action->setStatusText( i18n("Show the FAQ entry for a keyword") );
00088
00089
00090 m_parser = new perlparser(core(),codeModel(),interpreter());
00091 }
00092
00093
00094 PerlSupportPart::~PerlSupportPart()
00095 {
00096 if (project())
00097 projectClosed();
00098
00099 delete m_parser;
00100 m_parser=0;
00101 }
00102
00103
00104 void PerlSupportPart::projectOpened()
00105 {
00106 kdDebug(9007) << "projectOpened()" << endl;
00107
00108 connect( project(), SIGNAL(addedFilesToProject(const QStringList &)),
00109 this, SLOT(addedFilesToProject(const QStringList &)) );
00110 connect( project(), SIGNAL(removedFilesFromProject(const QStringList &)),
00111 this, SLOT(removedFilesFromProject(const QStringList &)) );
00112
00113
00114
00115 QTimer::singleShot(0, this, SLOT(initialParse()));
00116 }
00117
00118
00119 void PerlSupportPart::projectClosed()
00120 {
00121 }
00122
00123 void PerlSupportPart::maybeParse(const QString fileName)
00124 {
00125 QFileInfo fi(fileName);
00126 QString path = fi.filePath();
00127 QString extension = fi.extension();
00128 if (extension == "pl" || extension == "pm") {
00129 kdDebug(9016) << "maybe " << fileName << endl;
00130 removeWithReference(fileName);
00131 m_parser->parse(fileName);
00132 emit addedSourceInfo( fileName);
00133 }
00134 }
00135
00136 void PerlSupportPart::addedFilesToProject(const QStringList &fileList)
00137 {
00138 kdDebug(9016) << "addedFilesToProject()" << endl;
00139
00140 QStringList::ConstIterator it;
00141
00142 for ( it = fileList.begin(); it != fileList.end(); ++it )
00143 {
00144 maybeParse(project()->projectDirectory() + "/" + ( *it ));
00145 }
00146 }
00147
00148
00149 void PerlSupportPart::removedFilesFromProject(const QStringList &fileList)
00150 {
00151 kdDebug(9016) << "removedFilesFromProject()" << endl;
00152 QStringList::ConstIterator it;
00153 for ( it = fileList.begin(); it != fileList.end(); ++it )
00154 {
00155 QString fileName = project()->projectDirectory() + "/" + ( *it );
00156 removeWithReference(fileName);
00157 }
00158 emit updatedSourceInfo();
00159 }
00160
00161
00162 void PerlSupportPart::savedFile(const KURL &fileName)
00163 {
00164 Q_UNUSED( fileName.path() );
00165 #if 0 // not needed anymore
00166 kdDebug(9016) << "savedFile()" << endl;
00167
00168 if (project()->allFiles().contains(fileName.mid ( project()->projectDirectory().length() + 1 ))) {
00169 maybeParse(fileName);
00170 emit updatedSourceInfo();
00171 }
00172 #endif
00173 }
00174
00175
00176 KDevLanguageSupport::Features PerlSupportPart::features()
00177 {
00178 return KDevLanguageSupport::Features(Classes | Functions | Variables | Namespaces | Scripts | NewClass | AddMethod | AddAttribute | NewScript);
00179
00180 }
00181
00182 QString PerlSupportPart::interpreter()
00183 {
00184 QString prog = DomUtil::readEntry(*projectDom(), "/kdevperlsupport/run/interpreter");
00185 if (prog.isEmpty())
00186 prog = "perl";
00187
00188 return prog;
00189 }
00190
00191
00192 void PerlSupportPart::startApplication(const QString &program)
00193 {
00194 bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevperlsupport/run/terminal");
00195 appFrontend()->startAppCommand(QString::QString(), program, inTerminal);
00196 }
00197
00198
00199 void PerlSupportPart::slotExecute()
00200 {
00201 QString program = project()->mainProgram();
00202 QString cmd = interpreter() + " " + program;
00203 startApplication(cmd);
00204 }
00205
00206
00207 void PerlSupportPart::slotStartInterpreter()
00208 {
00209 startApplication(interpreter());
00210 }
00211
00212
00213 void PerlSupportPart::slotExecuteString()
00214 {
00215 bool ok;
00216 QString cmd = KInputDialog::getText(i18n("String to Execute"), i18n("String to execute:"), QString::null, &ok, 0);
00217 if (ok) {
00218 cmd.prepend("'");
00219 cmd.append("'");
00220 startApplication(cmd);
00221 }
00222 }
00223
00224
00225 void PerlSupportPart::slotPerldocFunction()
00226 {
00227 bool ok;
00228 QString key = KInputDialog::getText(i18n("Show Perl Documentation"), i18n("Show Perl documentation for function:"), "", &ok, 0);
00229 if (ok && !key.isEmpty()) {
00230 QString url = "perldoc:functions/";
00231 url += key;
00232 partController()->showDocument(KURL(url));
00233 }
00234 }
00235
00236
00237 void PerlSupportPart::slotPerldocFAQ()
00238 {
00239 bool ok;
00240 QString key = KInputDialog::getText(i18n("Show FAQ Entry"), i18n("Show FAQ entry for keyword:"), "", &ok, 0);
00241 if (ok && !key.isEmpty()) {
00242 QString url = "perldoc:faq/";
00243 url += key;
00244 partController()->showDocument(KURL(url));
00245 }
00246 }
00247 KMimeType::List PerlSupportPart::mimeTypes( )
00248 {
00249 KMimeType::List list;
00250 KMimeType::Ptr mime = KMimeType::mimeType( "application/x-perl" );
00251 if( mime )
00252 list << mime;
00253 return list;
00254 }
00255
00256 void PerlSupportPart::initialParse()
00257 {
00258 kdDebug(9016) << "initialParse()" << endl;
00259
00260 if (project()) {
00261
00262 mainWindow()->statusBar()->message( i18n("Updating...") );
00263 kapp->processEvents( );
00264
00265 kapp->setOverrideCursor(waitCursor);
00266 QStringList files = project()->allFiles();
00267 m_parser->initialParse();
00268
00269
00270 QProgressBar* bar = new QProgressBar( files.count( ), mainWindow( )->statusBar( ) );
00271 bar->setMinimumWidth( 120 );
00272 bar->setCenterIndicator( true );
00273 mainWindow( )->statusBar( )->addWidget( bar );
00274 bar->show( );
00275 int n = 0;
00276 for (QStringList::Iterator it = files.begin(); it != files.end() ;++it) {
00277
00278 maybeParse(project()->projectDirectory() + "/" + *it);
00279
00280 bar->setProgress( n++ );
00281 if( (n%5) == 0 )
00282 kapp->processEvents();
00283 }
00284 parseUseFiles();
00285 emit updatedSourceInfo();
00286
00287
00288 mainWindow( )->statusBar( )->removeWidget( bar );
00289 delete bar;
00290 kapp->restoreOverrideCursor();
00291 mainWindow()->statusBar()->message( i18n("Done") );
00292
00293 } else {
00294 kdDebug(9016) << "No project" << endl;
00295 }
00296 }
00297
00298 void PerlSupportPart::removeWithReference( const QString & fileName )
00299 {
00300 kdDebug(9016) << "remove with references: " << fileName << endl;
00301
00302 if( !codeModel()->hasFile(fileName) )
00303 return;
00304
00305 emit aboutToRemoveSourceInfo( fileName );
00306 codeModel()->removeFile( codeModel()->fileByName(fileName) );
00307 }
00308
00309 void PerlSupportPart::parseUseFiles()
00310 {
00311 kdDebug(9016) << "parse addional libs" << endl;
00312 return;
00313 QString filename;
00314 QStringList m_usefiles = m_parser->UseFiles();
00315
00316
00317 for (QStringList::Iterator it = m_usefiles.begin(); it != m_usefiles.end() ;++it)
00318 {
00319 filename = m_parser->findLib(*it);
00320
00321 if (!filename.isEmpty()) {
00322
00323 maybeParse(filename);
00324 }
00325 }
00326 }
00327
00328 #include "perlsupportpart.moc"