KDevelop API Documentation

buildtools/haskell/haskellproject_part.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 haskellproject_part.cpp - description 00003 ------------------- 00004 begin : Mon Aug 11 2003 00005 copyright : (C) 2003 Peter Robinson 00006 email : listener@thaldyron.com 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include <qdom.h> 00019 #include <qfileinfo.h> 00020 #include <qdir.h> 00021 #include <qvaluestack.h> 00022 #include <qregexp.h> 00023 #include <qvbox.h> 00024 #include <qlabel.h> 00025 00026 #include <kiconloader.h> 00027 #include <klocale.h> 00028 #include <kaction.h> 00029 #include <kgenericfactory.h> 00030 #include <kdebug.h> 00031 #include <kdialogbase.h> 00032 #include <kmessagebox.h> 00033 #include <klibloader.h> 00034 #include <kservice.h> 00035 #include <kconfig.h> 00036 #include <kdeversion.h> 00037 #include <kprocess.h> 00038 #include <ktrader.h> 00039 00040 #include "domutil.h" 00041 #include "kdevcore.h" 00042 #include "kdevmainwindow.h" 00043 #include "kdevmakefrontend.h" 00044 #include "kdevappfrontend.h" 00045 #include "kdevpartcontroller.h" 00046 #include "kdevlanguagesupport.h" 00047 #include "kdevcompileroptions.h" 00048 #include "runoptionswidget.h" 00049 #include "haskellprojectoptionsdlg.h" 00050 #include "haskellproject_part.h" 00051 00052 typedef KGenericFactory<HaskellProjectPart> HaskellProjectFactory; 00053 K_EXPORT_COMPONENT_FACTORY( libkdevhaskellproject, HaskellProjectFactory( "kdevhaskellproject" ) ) 00054 00055 00056 HaskellProjectPart::HaskellProjectPart(QObject *parent, const char *name, const QStringList& ) 00057 : KDevProject("KDevPart", "kdevpart", parent, name ? name : "HaskellProjectPart" ) 00058 { 00059 setInstance(HaskellProjectFactory::instance()); 00060 setXMLFile("kdevhaskellproject.rc"); 00061 00062 // _widget = new HaskellProjectWidget(this); 00063 00064 _buildAction = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, 00065 this, SLOT(slotBuild()), 00066 actionCollection(), "build_build" ); 00067 _runAction = new KAction( i18n("Execute Program"), "exec", 0, 00068 this, SLOT(slotExecute()), 00069 actionCollection(), "build_execute" ); 00070 00071 connect( core(), SIGNAL( projectConfigWidget( KDialogBase* ) ), 00072 this, SLOT( projectConfigWidget( KDialogBase* ) ) ); 00073 00074 connect( core(), SIGNAL( configWidget( KDialogBase* ) ), 00075 this, SLOT( configWidget( KDialogBase* ) ) ); 00076 } 00077 00078 00079 HaskellProjectPart::~HaskellProjectPart() 00080 { 00081 //delete _widget; 00082 } 00083 00084 00085 void HaskellProjectPart::openProject(const QString &dirName, const QString &projectName) 00086 { 00087 _buildDir = dirName; 00088 _projectDir = dirName; 00089 _projectName = projectName; 00090 loadProjectConfig(); 00091 QDomDocument &dom = *projectDom(); 00092 QString directoryRadioString = DomUtil::readEntry( dom, 00093 "/kdevhaskellproject/run/directoryradio" ); 00094 QString mainProgram = DomUtil::readEntry( dom, 00095 "/kdevhaskellproject/run/mainprogram" ); 00096 QString customDir = DomUtil::readEntry( dom, 00097 "/kdevhaskellproject/run/customdirectory" ); 00098 } 00099 00100 void HaskellProjectPart::closeProject() 00101 { 00102 } 00103 00104 00105 QString HaskellProjectPart::projectDirectory() const 00106 { 00107 return _projectDir; 00108 } 00109 00110 QString HaskellProjectPart::projectName() const 00111 { 00112 return _projectName; 00113 } 00114 00116 DomUtil::PairList HaskellProjectPart::runEnvironmentVars() const 00117 { 00118 return DomUtil::readPairListEntry(*projectDom(), 00119 "/kdevhaskellproject/run/envvars", 00120 "envvar", "name", "value"); 00121 } 00122 00132 QString HaskellProjectPart::mainProgram( bool relative ) const 00133 { 00134 QString progName; 00135 QDomDocument &dom = *projectDom(); 00136 QString directoryRadioString = DomUtil::readEntry( dom, 00137 "/kdevhaskellproject/run/directoryradio" ); 00138 QString mainProgram = DomUtil::readEntry( dom, 00139 "/kdevhaskellproject/run/mainprogram" ); 00140 00141 if( mainProgram.isEmpty() ) { 00142 QFileInfo fileInfo( mainSource() ); 00143 progName = buildDirectory() + "/" + fileInfo.baseName(); 00144 if( relative ) { 00145 return fileInfo.baseName(); 00146 } 00147 else { 00148 return buildDirectory() + "/" + fileInfo.baseName(); 00149 } 00150 } 00151 else { 00152 if( directoryRadioString == "custom" ) { 00153 if( relative ) { 00154 return( mainProgram ); 00155 } 00156 else { 00157 QString customDir = DomUtil::readEntry( dom, 00158 "/kdevhaskellproject/run/customdirectory" ); 00159 return( customDir + '/' + mainProgram ); 00160 } 00161 } 00162 else if( directoryRadioString == "build" ) { 00163 if( relative ) { 00164 return( mainProgram ); 00165 } 00166 } 00167 } 00168 return QString::fromLatin1(""); 00169 } 00170 00171 QString HaskellProjectPart::runDirectory() const 00172 { 00173 QDomDocument &dom = *projectDom(); 00174 00175 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevhaskellproject/run/directoryradio"); 00176 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevhaskellproject/run/mainprogram"); 00177 00178 if ( directoryRadioString == "build" ) 00179 return buildDirectory(); 00180 00181 if ( directoryRadioString == "custom" ) 00182 return DomUtil::readEntry(dom, "/kdevhaskellproject/run/customdirectory"); 00183 00184 int pos = DomMainProgram.findRev('/'); 00185 if (pos != -1) 00186 return buildDirectory() + "/" + DomMainProgram.left(pos); 00187 00188 return buildDirectory() + "/" + DomMainProgram; 00189 } 00190 00192 QString HaskellProjectPart::runArguments() const 00193 { 00194 return DomUtil::readEntry(*projectDom(), "/kdevhaskellproject/run/programargs"); 00195 } 00196 00197 QString HaskellProjectPart::activeDirectory() const 00198 { 00199 QFileInfo fi(mainSource()); 00200 // @todo shouldn't that be false = relative path? 00201 return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); 00202 } 00203 00204 QString HaskellProjectPart::buildDirectory() const 00205 { 00206 QFileInfo fi(mainSource()); 00207 return fi.dirPath(true); 00208 } 00209 00210 QStringList HaskellProjectPart::allFiles() const 00211 { 00212 return _sourceFiles; 00213 } 00214 00215 void HaskellProjectPart::addFiles(const QStringList& /*fileList*/) 00216 { 00217 } 00218 00219 00220 void HaskellProjectPart::addFile(const QString& /*fileName*/) 00221 { 00222 } 00223 00224 void HaskellProjectPart::removeFiles(const QStringList& /*fileList*/) 00225 { 00226 } 00227 00228 void HaskellProjectPart::removeFile(const QString& /*fileName*/) 00229 { 00230 } 00231 00232 00233 /*QString HaskellProjectPart::mainProgram() 00234 { 00235 QDomDocument &dom = *projectDom(); 00236 QString configMainProg = DomUtil::readEntry(dom, "/kdevhaskellproject/run/mainprogram", ""); 00237 if (configMainProg.isEmpty()) 00238 { 00239 QFileInfo fi(mainSource()); 00240 return buildDirectory() + "/" + fi.baseName(); 00241 } 00242 else 00243 return QDir::cleanDirPath(projectDirectory() + "/" + configMainProg); 00244 }*/ 00245 00246 QString HaskellProjectPart::mainSource() const 00247 { 00248 return projectDirectory() + "/" + _mainSource; 00249 } 00250 00251 void HaskellProjectPart::setMainSource(QString fullPath) 00252 { 00253 _mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); 00254 } 00255 00256 00257 00258 void HaskellProjectPart::listOfFiles(QStringList &result, QString path) 00259 { 00260 QDir d(path); 00261 if (!d.exists()) 00262 return; 00263 00264 QFileInfoList *entries = const_cast<QFileInfoList*>(d.entryInfoList(QDir::Dirs | 00265 QDir::Files | QDir::Hidden)); 00266 for (QFileInfo *it = entries->first(); it; it = entries->next()) { 00267 if ((it->isDir()) && (!(it->filePath() == path))) { 00268 listOfFiles(result, it->dirPath()); 00269 } 00270 else 00271 { 00272 result << it->filePath(); 00273 } 00274 } 00275 } 00276 00277 QString HaskellProjectPart::createPackageString() 00278 { 00279 // @todo create "-package network -package concurrent" etc. 00280 return ""; 00281 } 00282 00283 QString HaskellProjectPart::createCmdLine( QString srcFile) 00284 { 00285 // @todo test which haskell comp/interpreter is used and build cmdLine accordingly 00286 // at the moment only ghc is supported 00287 QString cmdLine = _compilerExec + " " + createPackageString() + " " + srcFile + " " 00288 + _compilerOpts + " -o " + mainProgram(); 00289 QString dirCmd = "cd "; 00290 dirCmd += buildDirectory(); 00291 dirCmd += " && "; 00292 return dirCmd + cmdLine; 00293 } 00294 00295 void HaskellProjectPart::slotBuild() 00296 { 00297 partController()->saveAllFiles(); 00298 00299 if (_compilerExec.isEmpty()) { 00300 KMessageBox::sorry(0, i18n("Could not find the Haskell Translator.\nCheck if your settings are correct.")); 00301 return; 00302 } 00303 00304 QString cmdline = createCmdLine( QFileInfo( mainSource() ).fileName() ); 00305 makeFrontend()->queueCommand( buildDirectory(), cmdline ); 00306 } 00307 00308 void HaskellProjectPart::slotExecute() 00309 { 00310 partController()->saveAllFiles(); 00311 00312 QDomDocument &dom = *(projectDom()); 00313 bool runInTerminal = DomUtil::readBoolEntry(dom, "/kdevhaskellproject/run/terminal", true); 00314 00315 // Get the run environment variables pairs into the environstr string 00316 // in the form of: "ENV_VARIABLE=ENV_VALUE" 00317 // Note that we quote the variable value due to the possibility of 00318 // embedded spaces 00319 DomUtil::PairList envvars = DomUtil::readPairListEntry( *projectDom(), 00320 "/kdevhaskellproject/run/envvars", 00321 "envvar", "name", "value"); 00322 QString environstr; 00323 DomUtil::PairList::ConstIterator it; 00324 for (it = envvars.begin(); it != envvars.end(); ++it) { 00325 environstr += (*it).first; 00326 environstr += "="; 00327 #if (KDE_VERSION > 305) 00328 environstr += KProcess::quote((*it).second); 00329 #else 00330 environstr += KShellProcess::quote((*it).second); 00331 #endif 00332 environstr += " "; 00333 } 00334 00335 QString program = mainProgram(); 00336 program.prepend( environstr ); 00337 program += " " + DomUtil::readEntry(*projectDom(), 00338 "/kdevhaskellproject/run/programargs" ); 00339 00340 appFrontend()->startAppCommand(buildDirectory(), program, runInTerminal); 00341 } 00342 00343 void HaskellProjectPart::changedFiles( const QStringList & fileList ) 00344 { 00345 KDevProject::changedFiles( fileList ); 00346 } 00347 00348 void HaskellProjectPart::changedFile( const QString & fileName ) 00349 { 00350 KDevProject::changedFile( fileName ); 00351 } 00352 00353 void HaskellProjectPart::projectConfigWidget( KDialogBase * dlg ) 00354 { 00355 QVBox *vbox; 00356 vbox = dlg->addVBoxPage( i18n("Haskell Options") ); 00357 HaskellProjectOptionsDlg *optionsDlg = new HaskellProjectOptionsDlg( this, vbox ); 00358 00359 connect( dlg, SIGNAL( okClicked() ), 00360 optionsDlg, SLOT( accept() ) ); 00361 00362 connect( dlg, SIGNAL( okClicked() ), 00363 this, SLOT( loadProjectConfig() ) ); 00364 00365 vbox = dlg->addVBoxPage( i18n( "Run Options" ) ); 00366 RunOptionsWidget *w3 = new RunOptionsWidget( *projectDom(), 00367 "/kdevhaskellproject", buildDirectory(), vbox ); 00368 w3->mainprogram_label->setText( i18n( "Main program (relative to project directory):" ) ); 00369 connect( dlg, SIGNAL(okClicked()), 00370 w3, SLOT( accept() ) ); 00371 } 00372 00373 void HaskellProjectPart::loadProjectConfig() 00374 { 00375 QDomDocument &dom = *(projectDom()); 00376 00377 QString config = DomUtil::readEntry(dom, 00378 "/kdevhaskellproject/general/useconfiguration", 00379 "default"); 00380 _mainSource = DomUtil::readEntry(dom, 00381 QString("/kdevhaskellproject/configurations/") + 00382 config + QString("/mainsource") ); 00383 _compilerOpts = DomUtil::readEntry(dom, 00384 QString("/kdevhaskellproject/configurations/") + 00385 config + QString("/compileroptions")); 00386 _compilerExec = DomUtil::readEntry(dom, 00387 QString("/kdevhaskellproject/configurations/") + 00388 config + QString("/compilerexec")); 00389 00390 if ( _compilerExec.isEmpty() ) { 00391 KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Haskell'"); 00392 QValueList<KService::Ptr>::ConstIterator it; 00393 for (it = offers.begin(); it != offers.end(); ++it) { 00394 if ( (*it)->property( "X-KDevelop-Default" ).toBool() ) { 00395 _compilerExec = (*it)->exec(); 00396 break; 00397 } 00398 } 00399 } 00400 // no entries found set standard to Glasgow Haskell Compiler 00401 // if( _compilerExec.isEmpty() ) { 00402 // _compilerExec = "ghc"; 00403 // _compilerOpts = "--make"; 00404 // } 00405 } 00406 00407 void HaskellProjectPart::configWidget( KDialogBase * dlg ) 00408 { 00409 // @todo create config page for KDevelop Settings 00410 /*QVBox *vbox; 00411 vbox = dlg->addVBoxPage( i18n( "Haskell Options" ) ); 00412 HaskellGlobalOptionsDlg *w = new HaskellGlobalOptionsDlg( this, vbox ); 00413 connect( dlg, SIGNAL( okClicked() ), w, SLOT( accept() ) );*/ 00414 } 00415 00416 KDevCompilerOptions *HaskellProjectPart::createCompilerOptions(const QString &name) 00417 { 00418 KService::Ptr service = KService::serviceByName( name ); 00419 if ( !service ) { 00420 kdDebug() << "Can't find service " << name; 00421 return 0; 00422 } 00423 00424 KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); 00425 if (!factory) { 00426 QString errorMessage = KLibLoader::self()->lastErrorMessage(); 00427 KMessageBox::error(0, i18n("There was an error loading the module %1.\n" 00428 "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); 00429 exit(1); 00430 } 00431 00432 QStringList args; 00433 QVariant prop = service->property("X-KDevelop-Args"); 00434 if (prop.isValid()) 00435 args = QStringList::split(" ", prop.toString()); 00436 00437 QObject *obj = factory->create(this, service->name().latin1(), 00438 "KDevCompilerOptions", args); 00439 00440 if (!obj->inherits("KDevCompilerOptions")) { 00441 kdDebug() << "Component does not inherit KDevCompilerOptions" << endl; 00442 return 0; 00443 } 00444 KDevCompilerOptions *dlg = (KDevCompilerOptions*)obj; 00445 00446 return dlg; 00447 } 00448 00449 QString HaskellProjectPart::defaultOptions( const QString compiler ) 00450 { 00451 KConfig *config = KGlobal::config(); 00452 config->setGroup("Haskell Compiler"); 00453 kdDebug(9000) << "*********** " << config->readPathEntry( compiler ) << "::" << endl; 00454 return config->readPathEntry(compiler); 00455 } 00456 00457 QString HaskellProjectPart::mainProgram() 00458 { 00459 QDomDocument &dom = *projectDom(); 00460 QString configMainProg = DomUtil::readEntry(dom, "/kdevhaskellproject/run/mainprogram", ""); 00461 if (configMainProg.isEmpty()) 00462 { 00463 QFileInfo fi(mainSource()); 00464 return buildDirectory() + "/" + fi.baseName(); 00465 } 00466 else 00467 return QDir::cleanDirPath(projectDirectory() + "/" + configMainProg); 00468 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:37 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003