KDevelop API Documentation

buildtools/qmake/trollprojectpart.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2003 by Thomas Hasart * 00003 * thasart@gmx.de * 00004 * Copyright (C) 2001-2002 by Bernd Gehrmann * 00005 * bernd@kdevelop.org * 00006 * Copyright (C) 2002 by Jakob Simon-Gaarde * 00007 * jakob@jsg.dk * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include "trollprojectpart.h" 00017 00018 #include <qdir.h> 00019 #include <qfileinfo.h> 00020 #include <qwhatsthis.h> 00021 #include <kdeversion.h> 00022 #include <kdebug.h> 00023 #include <kdialogbase.h> 00024 #include <kiconloader.h> 00025 #include <klocale.h> 00026 #include <kmessagebox.h> 00027 #include <qmessagebox.h> 00028 #include <kdevgenericfactory.h> 00029 #include <kaction.h> 00030 #include <kparts/part.h> 00031 #include <kprocess.h> 00032 #include <makeoptionswidget.h> 00033 00034 00035 #include "domutil.h" 00036 #include "kdevcore.h" 00037 #include "kdevmainwindow.h" 00038 #include "kdevmakefrontend.h" 00039 #include "kdevappfrontend.h" 00040 #include "kdevpartcontroller.h" 00041 #include "trollprojectwidget.h" 00042 #include "runoptionswidget.h" 00043 #include "config.h" 00044 #include "envvartools.h" 00045 00046 00047 typedef KDevGenericFactory<TrollProjectPart> TrollProjectFactory; 00048 static const KAboutData data("kdevtrollproject", I18N_NOOP("QMake Manager"), "1.0"); 00049 K_EXPORT_COMPONENT_FACTORY( libkdevtrollproject, TrollProjectFactory( &data ) ) 00050 00051 TrollProjectPart::TrollProjectPart(QObject *parent, const char *name, const QStringList& args ) 00052 : KDevProject("TrollProject", "trollproject", parent, name ? name : "TrollProjectPart") 00053 { 00054 setInstance(TrollProjectFactory::instance()); 00055 00056 if ( args.count() == 1 && args[0] == "TMake" ) 00057 m_tmakeProject = true; 00058 else 00059 m_tmakeProject = false; 00060 00061 setXMLFile("kdevtrollproject.rc"); 00062 00063 m_executeAfterBuild = false; 00064 00065 m_widget = new TrollProjectWidget(this); 00066 m_widget->setIcon(SmallIcon("make")); 00067 m_widget->setCaption(i18n("QMake Manager")); 00068 QWhatsThis::add(m_widget, i18n("<b>QMake manager</b><p>" 00069 "The QMake manager project tree consists of two parts. The 'overview' " 00070 "in the upper half shows the subprojects, each one having a " 00071 ".pro file. The 'details' view in the lower half shows the " 00072 "list of files for the active subproject selected in the overview.")); 00073 00074 mainWindow()->embedSelectViewRight(m_widget, i18n("QMake Manager"), i18n("QMake manager")); 00075 00076 KAction *action; 00077 00078 const QIconSet icon(SmallIcon("compfile")); 00079 action = new KAction( i18n("Compile &File"), "compfile", 0, 00080 m_widget, SLOT(slotBuildFile()), 00081 actionCollection(),"build_compilefile" ); 00082 action->setToolTip(i18n("Compile file")); 00083 action->setWhatsThis(i18n("<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>" 00084 "Environment variables and make arguments can be specified " 00085 "in the project settings dialog, <b>Make Options</b> tab.")); 00086 00087 00088 action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, 00089 m_widget, SLOT(slotBuildProject()), 00090 actionCollection(), "build_build_project" ); 00091 action->setToolTip(i18n("Build project")); 00092 action->setWhatsThis(i18n("<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>" 00093 "Environment variables and make arguments can be specified " 00094 "in the project settings dialog, <b>Make Options</b> tab.")); 00095 00096 action = new KAction( i18n("&Rebuild Project"),"rebuild" , 0, 00097 m_widget, SLOT(slotRebuildProject()), 00098 actionCollection(),"build_rebuild_project" ); 00099 action->setToolTip(i18n("Rebuild project")); 00100 action->setWhatsThis(i18n("<b>Rebuild project</b><p>Runs <b>make clean</b> and then <b>make</b> from the project directory.<br>" 00101 "Environment variables and make arguments can be specified " 00102 "in the project settings dialog, <b>Make Options</b> tab.")); 00103 00104 action = new KAction( i18n("&Clean Project"), 0, 00105 m_widget, SLOT(slotCleanProject()), 00106 actionCollection(), "build_clean_project" ); 00107 action->setToolTip(i18n("Clean project")); 00108 action->setWhatsThis(i18n("<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>" 00109 "Environment variables and make arguments can be specified " 00110 "in the project settings dialog, <b>Make Options</b> tab.")); 00111 00112 action = new KAction( i18n("Execute Main Program"), "exec", SHIFT+Key_F9, 00113 m_widget, SLOT(slotExecuteProject()), 00114 actionCollection(), "build_execute_project" ); 00115 action->setToolTip(i18n("Execute main program")); 00116 action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab.")); 00117 00118 00119 00120 00121 00122 action = new KAction( i18n("&Build Subproject"), "make_kdevelop", Key_F7, 00123 m_widget, SLOT(slotBuildTarget()), 00124 actionCollection(), "build_build_target" ); 00125 action->setToolTip(i18n("Build subproject")); 00126 action->setWhatsThis(i18n("<b>Build subproject</b><p>Runs <b>make</b> from the current subproject directory. " 00127 "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" 00128 "Environment variables and make arguments can be specified " 00129 "in the project settings dialog, <b>Make Options</b> tab.")); 00130 00131 action = new KAction( i18n("&Rebuild Subproject"), "rebuild", 0, 00132 m_widget, SLOT(slotRebuildTarget()), 00133 actionCollection(),"build_rebuild_target" ); 00134 action->setToolTip(i18n("Rebuild subproject")); 00135 action->setWhatsThis(i18n("<b>Rebuild subproject</b><p>Runs <b>make clean</b> and then <b>make</b> from the current subproject directory. " 00136 "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" 00137 "Environment variables and make arguments can be specified " 00138 "in the project settings dialog, <b>Make Options</b> tab.")); 00139 00140 action = new KAction( i18n("&Clean Subproject"), 0, 00141 m_widget, SLOT(slotCleanTarget()), 00142 actionCollection(), "build_clean_target" ); 00143 action->setToolTip(i18n("Clean subproject")); 00144 action->setWhatsThis(i18n("<b>Clean subproject</b><p>Runs <b>make clean</b> from the current subproject directory. " 00145 "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" 00146 "Environment variables and make arguments can be specified " 00147 "in the project settings dialog, <b>Make Options</b> tab.")); 00148 00149 action = new KAction( i18n("Execute Subproject"), "exec", 0, 00150 m_widget, SLOT(slotExecuteTarget()), 00151 actionCollection(), "build_execute_target" ); 00152 action->setToolTip(i18n("Execute subproject")); 00153 action->setWhatsThis(i18n("<b>Execute subproject</b><p>Executes the target program for the currently selected subproject. " 00154 "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " 00155 "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu).")); 00156 00157 connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), 00158 this, SLOT(projectConfigWidget(KDialogBase*)) ); 00159 00160 connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), 00161 this, SLOT(slotCommandFinished(const QString&)) ); 00162 00163 m_qmakeHeader = i18n("# File generated by kdevelop's qmake manager. \n" 00164 "# ------------------------------------------- \n" 00165 "# Subdir relative project main directory: %s\n" 00166 "# Target is %s %s\n"); 00167 00168 m_availableQtDirList = availableQtDirList(); 00169 m_defaultQtDir = ::getenv( "QTDIR" ); 00170 if( m_defaultQtDir.isEmpty() && !m_availableQtDirList.isEmpty() ) 00171 m_defaultQtDir = m_availableQtDirList.front(); 00172 } 00173 00174 00175 TrollProjectPart::~TrollProjectPart() 00176 { 00177 if (m_widget) 00178 mainWindow()->removeView(m_widget); 00179 delete m_widget; 00180 } 00181 00182 QString TrollProjectPart::makeEnvironment() 00183 { 00184 // Get the make environment variables pairs into the environstr string 00185 // in the form of: "ENV_VARIABLE=ENV_VALUE" 00186 // Note that we quote the variable value due to the possibility of 00187 // embedded spaces 00188 DomUtil::PairList envvars = 00189 DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); 00190 00191 QString environstr; 00192 DomUtil::PairList::ConstIterator it; 00193 bool hasQtDir = false; 00194 for (it = envvars.begin(); it != envvars.end(); ++it) { 00195 if( (*it).first == "QTDIR" ) 00196 hasQtDir = true; 00197 00198 environstr += (*it).first; 00199 environstr += "="; 00200 /* 00201 #if (KDE_VERSION > 305) 00202 environstr += KProcess::quote((*it).second); 00203 #else 00204 environstr += KShellProcess::quote((*it).second); 00205 #endif 00206 */ 00207 environstr += EnvVarTools::quote((*it).second); 00208 environstr += " "; 00209 } 00210 00211 if( !hasQtDir && !m_defaultQtDir.isEmpty() ) 00212 { 00213 environstr += QString( "QTDIR=" ) + EnvVarTools::quote( m_defaultQtDir ) + QString( " " ); 00214 } 00215 00216 return environstr; 00217 } 00218 00219 void TrollProjectPart::projectConfigWidget(KDialogBase *dlg) 00220 { 00221 QVBox *vbox; 00222 vbox = dlg->addVBoxPage(i18n("Run Options")); 00223 RunOptionsWidget *optdlg = new RunOptionsWidget(*projectDom(), "/kdevtrollproject", buildDirectory(), vbox); 00224 00225 vbox = dlg->addVBoxPage(i18n("Make Options")); 00226 MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevtrollproject", vbox); 00227 connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) ); 00228 00229 connect( dlg, SIGNAL(okClicked()), optdlg, SLOT(accept()) ); 00230 } 00231 00232 00233 void TrollProjectPart::openProject(const QString &dirName, const QString &projectName) 00234 { 00235 m_widget->openProject(dirName); 00236 m_projectName = projectName; 00237 00238 QDomDocument &dom = *projectDom(); 00239 // Set the default directory radio to "executable" 00240 if (DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio") == "" ) { 00241 DomUtil::writeEntry(dom, "/kdevtrollproject/run/directoryradio", "executable"); 00242 } 00243 00244 KDevProject::openProject( dirName, projectName ); 00245 } 00246 00247 00248 void TrollProjectPart::closeProject() 00249 { 00250 m_widget->closeProject(); 00251 } 00252 00253 00254 QString TrollProjectPart::projectDirectory() const 00255 { 00256 return m_widget->projectDirectory(); 00257 } 00258 00259 00260 QString TrollProjectPart::buildDirectory() const 00261 { 00262 return m_widget->projectDirectory(); 00263 } 00264 00265 QString TrollProjectPart::projectName() const 00266 { 00267 return m_projectName; 00268 } 00269 00270 00272 DomUtil::PairList TrollProjectPart::runEnvironmentVars() const 00273 { 00274 return DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/run/envvars", "envvar", "name", "value"); 00275 } 00276 00277 00287 QString TrollProjectPart::runDirectory() const 00288 { 00289 QDomDocument &dom = *projectDom(); 00290 00291 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio"); 00292 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevtrollproject/run/mainprogram"); 00293 00294 if ( directoryRadioString == "build" ) 00295 return buildDirectory(); 00296 00297 if ( directoryRadioString == "custom" ) 00298 return DomUtil::readEntry(dom, "/kdevtrollproject/run/customdirectory"); 00299 00300 int pos = DomMainProgram.findRev('/'); 00301 if (pos != -1) 00302 return buildDirectory() + "/" + DomMainProgram.left(pos); 00303 00304 if ( DomMainProgram.isEmpty() ) 00305 { 00306 return m_widget->subprojectDirectory(); 00307 } 00308 return buildDirectory() + "/" + DomMainProgram; 00309 00310 } 00311 00312 00322 QString TrollProjectPart::mainProgram(bool relative) const 00323 { 00324 QDomDocument &dom = *projectDom(); 00325 00326 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio"); 00327 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevtrollproject/run/mainprogram"); 00328 00329 if ( directoryRadioString == "custom" ) 00330 return DomMainProgram; 00331 00332 if ( relative == false && !DomMainProgram.isEmpty() ) 00333 return buildDirectory() + "/" + DomMainProgram; 00334 00335 if ( directoryRadioString == "executable" ) { 00336 int pos = DomMainProgram.findRev('/'); 00337 if (pos != -1) 00338 return DomMainProgram.mid(pos+1); 00339 00340 if ( DomMainProgram.isEmpty() ) 00341 { 00342 return runDirectory() + "/" + m_widget->getCurrentOutputFilename(); 00343 } 00344 return DomMainProgram; 00345 } 00346 else 00347 return DomMainProgram; 00348 } 00349 00350 00352 QString TrollProjectPart::runArguments() const 00353 { 00354 return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/programargs"); 00355 } 00356 00357 00358 QString TrollProjectPart::activeDirectory() const 00359 { 00360 QDomDocument &dom = *projectDom(); 00361 00362 return DomUtil::readEntry(dom, "/kdevtrollproject/general/activedir"); 00363 } 00364 00365 00366 QStringList TrollProjectPart::allFiles() const 00367 { 00368 return m_widget->allFiles(); 00369 } 00370 00371 00372 void TrollProjectPart::addFile(const QString &fileName) 00373 { 00374 QStringList fileList; 00375 fileList.append ( fileName ); 00376 00377 this->addFiles ( fileList ); 00378 } 00379 00380 void TrollProjectPart::addFiles ( const QStringList &fileList ) 00381 { 00382 QStringList files = fileList; 00383 for (QStringList::iterator it = files.begin(); it != files.end(); ++it) 00384 if (!isProjectFile(projectDirectory() + "/" + (*it))) 00385 // if (!(*it).contains(projectDirectory())) 00386 *it = projectDirectory() + "/" + (*it); 00387 00388 m_widget->addFiles(files); 00389 00390 // emit addedFilesToProject ( files ); 00391 } 00392 00393 void TrollProjectPart::removeFile(const QString & /* fileName */) 00394 { 00396 /* QStringList fileList; 00397 fileList.append ( fileName ); 00398 00399 this->removeFiles ( fileList );*/ 00400 } 00401 00402 void TrollProjectPart::removeFiles ( const QStringList& fileList ) 00403 { 00405 // QStringList::ConstIterator it; 00406 // 00407 // it = fileList.begin(); 00408 // 00409 // for ( ; it != fileList.end(); ++it ) 00410 // { 00411 // FIXME 00412 // } 00413 00414 emit removedFilesFromProject ( fileList ); 00415 } 00416 /* 00417 void TrollProjectPart::startMakeCommand(const QString &dir, const QString &target) 00418 { 00419 partController()->saveAllFiles(); 00420 00421 QFileInfo fi(dir + "/Makefile"); 00422 if (!fi.exists()) { 00423 int r = KMessageBox::questionYesNo(m_widget, i18n("There is no Makefile in this directory. Run qmake first?")); 00424 if (r == KMessageBox::No) 00425 return; 00426 startQMakeCommand(dir); 00427 } 00428 QDomDocument &dom = *projectDom(); 00429 00430 if (target=="clean") 00431 { 00432 QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); 00433 if (cmdline.isEmpty()) 00434 cmdline = MAKE_COMMAND; 00435 cmdline += " clean"; 00436 QString dircmd = "cd "; 00437 dircmd += dir; 00438 dircmd += " && "; 00439 cmdline.prepend(makeEnvironment()); 00440 makeFrontend()->queueCommand(dir, dircmd + cmdline); 00441 } 00442 00443 QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); 00444 if (cmdline.isEmpty()) 00445 cmdline = MAKE_COMMAND; 00446 if (!DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/abortonerror")) 00447 cmdline += " -k"; 00448 int jobs = DomUtil::readIntEntry(dom, "/kdevtrollproject/make/numberofjobs"); 00449 if (jobs != 0) { 00450 cmdline += " -j"; 00451 cmdline += QString::number(jobs); 00452 } 00453 if (DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/dontact")) 00454 cmdline += " -n"; 00455 00456 cmdline += " "; 00457 cmdline += target; 00458 00459 QString dircmd = "cd "; 00460 dircmd += dir; 00461 dircmd += " && "; 00462 00463 cmdline.prepend(makeEnvironment()); 00464 makeFrontend()->queueCommand(dir, dircmd + cmdline); 00465 } 00466 */ 00467 00468 void TrollProjectPart::startQMakeCommand(const QString &dir) 00469 { 00470 QFileInfo fi(dir); 00471 00472 QString cmdline = QString::fromLatin1( isTMakeProject() ? "tmake " : "qmake " ); 00473 // cmdline += fi.baseName() + ".pro"; 00474 QDir d(dir); 00475 QStringList l = d.entryList("*.pro"); 00476 00477 cmdline += l.count()?l[0]:(fi.baseName() + ".pro"); 00478 00479 // cmdline += QString::fromLatin1( " -o Makefile" ); 00480 00481 QString dircmd = "cd "; 00482 dircmd += dir; 00483 dircmd += " && "; 00484 00485 cmdline.prepend(makeEnvironment()); 00486 makeFrontend()->queueCommand(dir, dircmd + cmdline); 00487 } 00488 00489 void TrollProjectPart::queueCmd(const QString &dir, const QString &cmd) 00490 { 00491 makeFrontend()->queueCommand(dir, cmd); 00492 } 00493 00494 void TrollProjectPart::slotCommandFinished( const QString& command ) 00495 { 00496 Q_UNUSED( command ); 00497 00498 if( m_buildCommand != command ) 00499 return; 00500 00501 m_buildCommand = QString::null; 00502 00503 m_timestamp.clear(); 00504 QStringList fileList = allFiles(); 00505 QStringList::Iterator it = fileList.begin(); 00506 while( it != fileList.end() ){ 00507 QString fileName = *it; 00508 ++it; 00509 00510 m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); 00511 } 00512 00513 emit projectCompiled(); 00514 00515 if( m_executeAfterBuild ){ 00516 m_widget->slotExecuteProject(); 00517 m_executeAfterBuild = false; 00518 } 00519 } 00520 00521 bool TrollProjectPart::isDirty() 00522 { 00523 QStringList fileList = allFiles(); 00524 QStringList::Iterator it = fileList.begin(); 00525 while( it != fileList.end() ){ 00526 QString fileName = *it; 00527 ++it; 00528 00529 QMap<QString, QDateTime>::Iterator it = m_timestamp.find( fileName ); 00530 QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); 00531 if( it == m_timestamp.end() || *it != t ){ 00532 return true; 00533 } 00534 } 00535 00536 return false; 00537 } 00538 00539 KDevProject::Options TrollProjectPart::options( ) 00540 { 00541 return UsesQMakeBuildSystem; 00542 } 00543 00544 bool TrollProjectPart::isValidQtDir( const QString& path ) const 00545 { 00546 return QFile::exists( path + "/include/qt.h" ); 00547 } 00548 00549 QStringList TrollProjectPart::availableQtDirList() const 00550 { 00551 QStringList qtdirs, lst; 00552 qtdirs.push_back( ::getenv("QTDIR") ); 00553 qtdirs.push_back( "/usr/lib/qt3" ); 00554 qtdirs.push_back( "/usr/lib/qt" ); 00555 qtdirs.push_back( "/usr/share/qt3" ); 00556 00557 for( QStringList::Iterator it=qtdirs.begin(); it!=qtdirs.end(); ++it ) 00558 { 00559 QString qtdir = *it; 00560 if( !qtdir.isEmpty() && isValidQtDir(qtdir) ) 00561 lst.push_back( qtdir ); 00562 } 00563 return lst; 00564 } 00565 00566 #include "trollprojectpart.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 Tue Oct 19 08:01:37 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003