KDevelop API Documentation

buildtools/pascal/pascalproject_part.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2003 Alexander Dymo * 00003 * cloudtemple@mksat.net * 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 #include <qdom.h> 00012 #include <qfileinfo.h> 00013 #include <qdir.h> 00014 #include <qvaluestack.h> 00015 #include <qregexp.h> 00016 #include <qvbox.h> 00017 #include <qlabel.h> 00018 00019 #include <kiconloader.h> 00020 #include <klocale.h> 00021 #include <kaction.h> 00022 #include <kdevgenericfactory.h> 00023 #include <kdebug.h> 00024 #include <kdialogbase.h> 00025 #include <kmessagebox.h> 00026 #include <klibloader.h> 00027 #include <kservice.h> 00028 #include <kconfig.h> 00029 #include <kdeversion.h> 00030 #include <kprocess.h> 00031 00032 #include "domutil.h" 00033 #include "kdevcore.h" 00034 #include "kdevmainwindow.h" 00035 #include "kdevmakefrontend.h" 00036 #include "kdevappfrontend.h" 00037 #include "kdevpartcontroller.h" 00038 #include "kdevlanguagesupport.h" 00039 #include "kdevcompileroptions.h" 00040 #include "runoptionswidget.h" 00041 #include "envvartools.h" 00042 00043 #include "pascalproject_widget.h" 00044 #include "pascalproject_part.h" 00045 #include "pascalprojectoptionsdlg.h" 00046 #include "pascalglobaloptionsdlg.h" 00047 00048 typedef KDevGenericFactory<PascalProjectPart> PascalProjectFactory; 00049 static const KAboutData data("kdevpascalproject", I18N_NOOP("Build Tool"), "1.0"); 00050 K_EXPORT_COMPONENT_FACTORY( libkdevpascalproject, PascalProjectFactory( &data ) ) 00051 00052 PascalProjectPart::PascalProjectPart(QObject *parent, const char *name, const QStringList& ) 00053 :KDevProject("PascalProject", "pascalproject", parent, name ? name : "PascalProjectPart" ) 00054 { 00055 setInstance(PascalProjectFactory::instance()); 00056 setXMLFile("kdevpascalproject.rc"); 00057 00058 KAction *action; 00059 action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, 00060 this, SLOT(slotBuild()), 00061 actionCollection(), "build_build" ); 00062 action->setToolTip(i18n("Build project")); 00063 action->setWhatsThis(i18n("<b>Build project</b><p>Runs the compiler on a main source file of the project. " 00064 "The compiler and the main source file can be set in project settings, <b>Pascal Compiler</b> tab.")); 00065 action = new KAction( i18n("Execute Program"), "exec", 0, 00066 this, SLOT(slotExecute()), 00067 actionCollection(), "build_execute" ); 00068 action->setToolTip(i18n("Execute program")); 00069 action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run options</b> tab. " 00070 "If nothing is set, the binary file with the same name as the main source file name is executed.")); 00071 00072 connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), 00073 this, SLOT(projectConfigWidget(KDialogBase*)) ); 00074 00075 connect( core(), SIGNAL(configWidget(KDialogBase*)), 00076 this, SLOT(configWidget(KDialogBase*)) ); 00077 00078 // m_widget = new PascalProjectWidget(this); 00079 00080 // QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?")); 00081 00082 // now you decide what should happen to the widget. Take a look at kdevcore.h 00083 // or at other plugins how to embed it. 00084 00085 // if you want to embed your widget as an outputview, simply uncomment 00086 // the following line. 00087 00088 // mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" ); 00089 00090 } 00091 00092 PascalProjectPart::~PascalProjectPart() 00093 { 00094 // delete m_widget; 00095 } 00096 00101 static bool matchesPattern(const QString &fileName, const QStringList &patternList) 00102 { 00103 QStringList::ConstIterator it; 00104 for (it = patternList.begin(); it != patternList.end(); ++it) { 00105 QRegExp re(*it, true, true); 00106 if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) 00107 return true; 00108 } 00109 00110 return false; 00111 } 00112 00113 void PascalProjectPart::openProject(const QString &dirName, const QString &projectName) 00114 { 00115 m_buildDir = dirName; 00116 m_projectDir = dirName; 00117 m_projectName = projectName; 00118 00119 QDomDocument &dom = *projectDom(); 00120 // Set the default directory radio to "executable" 00121 if (DomUtil::readEntry(dom, "/kdevpascalproject/run/directoryradio") == "" ) { 00122 DomUtil::writeEntry(dom, "/kdevpascalproject/run/directoryradio", "executable"); 00123 } 00124 00125 loadProjectConfig(); 00126 00127 // Put all files from all subdirectories into file list 00128 QValueStack<QString> s; 00129 int prefixlen = m_projectDir.length()+1; 00130 s.push(m_projectDir); 00131 00132 QStringList includepatternList; 00133 if ( languageSupport() ) 00134 { 00135 KMimeType::List list = languageSupport()->mimeTypes(); 00136 KMimeType::List::Iterator it = list.begin(); 00137 while( it != list.end() ){ 00138 includepatternList += (*it)->patterns(); 00139 ++it; 00140 } 00141 } 00142 QString excludepatterns = "*~"; 00143 QStringList excludepatternList = QStringList::split(",", excludepatterns); 00144 00145 QDir dir; 00146 do { 00147 dir.setPath(s.pop()); 00148 kdDebug(9033) << "Examining: " << dir.path() << endl; 00149 const QFileInfoList *dirEntries = dir.entryInfoList(); 00150 QPtrListIterator<QFileInfo> it(*dirEntries); 00151 for (; it.current(); ++it) { 00152 QString fileName = it.current()->fileName(); 00153 if (fileName == "." || fileName == "..") 00154 continue; 00155 QString path = it.current()->absFilePath(); 00156 if (it.current()->isDir()) { 00157 kdDebug(9033) << "Pushing: " << path << endl; 00158 s.push(path); 00159 } 00160 else { 00161 if (matchesPattern(path, includepatternList) 00162 && !matchesPattern(path, excludepatternList)) { 00163 kdDebug(9033) << "Adding: " << path << endl; 00164 m_sourceFiles.append(path.mid(prefixlen)); 00165 } else { 00166 kdDebug(9033) << "Ignoring: " << path << endl; 00167 } 00168 } 00169 } 00170 } while (!s.isEmpty()); 00171 00172 KDevProject::openProject( dirName, projectName ); 00173 } 00174 00175 void PascalProjectPart::closeProject() 00176 { 00177 } 00178 00180 DomUtil::PairList PascalProjectPart::runEnvironmentVars() const 00181 { 00182 return DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); 00183 } 00184 00185 00195 QString PascalProjectPart::runDirectory() const 00196 { 00197 QDomDocument &dom = *projectDom(); 00198 00199 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevpascalproject/run/directoryradio"); 00200 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevpascalproject/run/mainprogram"); 00201 00202 if ( directoryRadioString == "build" ) 00203 return buildDirectory(); 00204 00205 if ( directoryRadioString == "custom" ) 00206 return DomUtil::readEntry(dom, "/kdevpascalproject/run/customdirectory"); 00207 00208 int pos = DomMainProgram.findRev('/'); 00209 if (pos != -1) 00210 return buildDirectory() + "/" + DomMainProgram.left(pos); 00211 00212 return buildDirectory() + "/" + DomMainProgram; 00213 00214 } 00215 00216 00226 QString PascalProjectPart::mainProgram(bool relative) const 00227 { 00228 QDomDocument &dom = *projectDom(); 00229 QString configMainProg = DomUtil::readEntry(dom, "/kdevpascalproject/run/mainprogram", ""); 00230 if (configMainProg.isEmpty()) 00231 { 00232 QFileInfo fi(mainSource()); 00233 return buildDirectory() + "/" + fi.baseName(); 00234 } 00235 else 00236 return QDir::cleanDirPath(projectDirectory() + "/" + configMainProg); 00237 00239 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevpascalproject/run/directoryradio"); 00240 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevpascalproject/run/mainprogram"); 00241 00242 if ( directoryRadioString == "custom" ) 00243 return DomMainProgram; 00244 00245 if ( relative == false ) 00246 return buildDirectory() + "/" + DomMainProgram; 00247 00248 if ( directoryRadioString == "executable" ) { 00249 int pos = DomMainProgram.findRev('/'); 00250 if (pos != -1) 00251 return DomMainProgram.mid(pos+1); 00252 return DomMainProgram; 00253 } 00254 else 00255 return DomMainProgram; 00256 } 00257 00258 00260 QString PascalProjectPart::runArguments() const 00261 { 00262 return DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); 00263 } 00264 00265 QString PascalProjectPart::mainSource() const 00266 { 00267 return projectDirectory() + "/" + m_mainSource; 00268 } 00269 00270 void PascalProjectPart::setMainSource(QString fullPath) 00271 { 00272 m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); 00273 } 00274 00275 QString PascalProjectPart::projectDirectory() const 00276 { 00277 return m_projectDir; 00278 } 00279 00280 QString PascalProjectPart::projectName() const 00281 { 00282 return m_projectName; 00283 } 00284 00285 QString PascalProjectPart::activeDirectory() const 00286 { 00287 QFileInfo fi(mainSource()); 00288 return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); 00289 } 00290 00291 QString PascalProjectPart::buildDirectory() const 00292 { 00293 QFileInfo fi(mainSource()); 00294 return fi.dirPath(true); 00295 } 00296 00297 void PascalProjectPart::listOfFiles(QStringList &result, QString path) const 00298 { 00299 QDir d(path); 00300 if (!d.exists()) 00301 return; 00302 QFileInfoList *entries = const_cast<QFileInfoList*>(d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden)); 00303 for (QFileInfo *it = entries->first(); it; it = entries->next()) 00304 { 00305 if ((it->isDir()) && (it->filePath() != path)) 00306 { 00307 // qWarning("entering dir %s", it->dirPath().latin1()); 00308 listOfFiles(result, it->dirPath()); 00309 } 00310 else 00311 { 00312 // qWarning("adding to result: %s", it->filePath().latin1()); 00313 result << it->filePath(); 00314 } 00315 } 00316 } 00317 00318 QStringList PascalProjectPart::allFiles() const 00319 { 00320 // QStringList files; 00321 00322 // listOfFiles(files, projectDirectory()); 00323 00324 // return files; 00325 return m_sourceFiles; 00326 } 00327 00328 void PascalProjectPart::addFile(const QString& /*fileName*/) 00329 { 00330 } 00331 00332 void PascalProjectPart::addFiles(const QStringList& /*fileList*/) 00333 { 00334 } 00335 00336 void PascalProjectPart::removeFile(const QString& /*fileName*/) 00337 { 00338 } 00339 00340 void PascalProjectPart::removeFiles(const QStringList& /*fileList*/) 00341 { 00342 } 00343 00344 void PascalProjectPart::slotBuild() 00345 { 00346 partController()->saveAllFiles(); 00347 00348 QString cmdline = m_compilerExec + " " + m_compilerOpts + " "; 00349 00350 if (cmdline.isEmpty()) 00351 { 00352 KMessageBox::sorry(0, i18n("Could not find pascal compiler.\nCheck if your compiler settings are correct.")); 00353 return; 00354 } 00355 00356 QFileInfo fi(mainSource()); 00357 cmdline += fi.fileName(); 00358 00359 QString dircmd = "cd "; 00360 dircmd += buildDirectory(); 00361 dircmd += " && "; 00362 00363 makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline); 00364 } 00365 00366 void PascalProjectPart::slotExecute() 00367 { 00368 partController()->saveAllFiles(); 00369 00370 QDomDocument &dom = *(projectDom()); 00371 bool runInTerminal = DomUtil::readBoolEntry(dom, "/kdevpascalproject/run/terminal", true); 00372 00373 // Get the run environment variables pairs into the environstr string 00374 // in the form of: "ENV_VARIABLE=ENV_VALUE" 00375 // Note that we quote the variable value due to the possibility of 00376 // embedded spaces 00377 DomUtil::PairList envvars = 00378 DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); 00379 00380 QString environstr; 00381 DomUtil::PairList::ConstIterator it; 00382 for (it = envvars.begin(); it != envvars.end(); ++it) { 00383 environstr += (*it).first; 00384 environstr += "="; 00385 /* 00386 #if (KDE_VERSION > 305) 00387 environstr += KProcess::quote((*it).second); 00388 #else 00389 environstr += KShellProcess::quote((*it).second); 00390 #endif 00391 */ 00392 environstr += EnvVarTools::quote((*it).second); 00393 environstr += " "; 00394 } 00395 00396 QString program = mainProgram(); 00397 program.prepend(environstr); 00398 program += " " + DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); 00399 00400 appFrontend()->startAppCommand(buildDirectory(), program, runInTerminal); 00401 } 00402 00403 void PascalProjectPart::changedFiles( const QStringList & fileList ) 00404 { 00405 KDevProject::changedFiles(fileList); 00406 } 00407 00408 void PascalProjectPart::changedFile( const QString & fileName ) 00409 { 00410 KDevProject::changedFile(fileName); 00411 } 00412 00413 void PascalProjectPart::projectConfigWidget( KDialogBase * dlg ) 00414 { 00415 QVBox *vbox; 00416 vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); 00417 PascalProjectOptionsDlg *w = new PascalProjectOptionsDlg(this, vbox); 00418 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); 00419 connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) ); 00420 00421 vbox = dlg->addVBoxPage(i18n("Run Options")); 00422 RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevpascalproject", buildDirectory(), vbox); 00423 w3->mainprogram_label->setText(i18n("Main program (relative to project directory):")); 00424 connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) ); 00425 00426 } 00427 00428 void PascalProjectPart::loadProjectConfig( ) 00429 { 00430 QDomDocument &dom = *(projectDom()); 00431 00432 QString config = DomUtil::readEntry(dom, "/kdevpascalproject/general/useconfiguration", "default"); 00433 m_mainSource = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/mainsource") ); 00434 m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compileroptions")); 00435 m_compilerExec = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compilerexec")); 00436 00437 if (m_compilerExec.isEmpty()) 00438 { 00439 KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); 00440 QValueList<KService::Ptr>::ConstIterator it; 00441 for (it = offers.begin(); it != offers.end(); ++it) { 00442 if ((*it)->property("X-KDevelop-Default").toBool()) { 00443 m_compilerExec = (*it)->exec(); 00444 break; 00445 } 00446 } 00447 } 00448 } 00449 00450 void PascalProjectPart::configWidget( KDialogBase * dlg ) 00451 { 00452 QVBox *vbox; 00453 vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); 00454 PascalGlobalOptionsDlg *w = new PascalGlobalOptionsDlg(this, vbox); 00455 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); 00456 } 00457 00458 KDevCompilerOptions *PascalProjectPart::createCompilerOptions(const QString &name) 00459 { 00460 KService::Ptr service = KService::serviceByDesktopName(name); 00461 if (!service) { 00462 kdDebug() << "Can't find service " << name; 00463 return 0; 00464 } 00465 00466 KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); 00467 if (!factory) { 00468 QString errorMessage = KLibLoader::self()->lastErrorMessage(); 00469 KMessageBox::error(0, i18n("There was an error loading the module %1.\n" 00470 "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); 00471 exit(1); 00472 } 00473 00474 QStringList args; 00475 QVariant prop = service->property("X-KDevelop-Args"); 00476 if (prop.isValid()) 00477 args = QStringList::split(" ", prop.toString()); 00478 00479 QObject *obj = factory->create(this, service->name().latin1(), 00480 "KDevCompilerOptions", args); 00481 00482 if (!obj->inherits("KDevCompilerOptions")) { 00483 kdDebug() << "Component does not inherit KDevCompilerOptions" << endl; 00484 return 0; 00485 } 00486 KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; 00487 00488 return dlg; 00489 } 00490 00491 QString PascalProjectPart::defaultOptions( const QString compiler ) const 00492 { 00493 KConfig *config = KGlobal::config(); 00494 config->setGroup("Pascal Compiler"); 00495 return config->readPathEntry(compiler); 00496 } 00497 00498 #include "pascalproject_part.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:38:54 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003