KDevelop API Documentation

buildtools/ant/antprojectpart.cpp

Go to the documentation of this file.
00001 #include <qapplication.h> 00002 #include <qfile.h> 00003 #include <qfileinfo.h> 00004 #include <qpopupmenu.h> 00005 #include <qvbox.h> 00006 #include <qtable.h> 00007 #include <qtextstream.h> 00008 #include <qvaluestack.h> 00009 #include <qdir.h> 00010 00011 00012 #include <kdevgenericfactory.h> 00013 #include <kdebug.h> 00014 #include <kaction.h> 00015 #include <kpopupmenu.h> 00016 #include <kdialogbase.h> 00017 #include <klineedit.h> 00018 #include <kcombobox.h> 00019 #include <keditlistbox.h> 00020 #include <kurlrequester.h> 00021 00022 00023 #include <kdevcore.h> 00024 #include <kdevmakefrontend.h> 00025 00026 00027 #include "antoptionswidget.h" 00028 #include "classpathwidget.h" 00029 00030 00031 #include "antprojectpart.h" 00032 00033 00034 typedef KDevGenericFactory<AntProjectPart> AntProjectFactory; 00035 static const KAboutData data("kdevantproject", I18N_NOOP("Build Tool"), "1.0"); 00036 K_EXPORT_COMPONENT_FACTORY(libkdevantproject, AntProjectFactory( &data )) 00037 00038 00039 AntOptions::AntOptions() 00040 : m_buildXML("build.xml"), m_verbosity(AntOptions::Quiet) 00041 { 00042 } 00043 00044 00045 AntProjectPart::AntProjectPart(QObject *parent, const char *name, const QStringList &) 00046 : KDevProject("AntProject", "antproject", parent, name ? name : "AntProjectPart") 00047 { 00048 setInstance(AntProjectFactory::instance()); 00049 00050 setXMLFile("kdevantproject.rc"); 00051 00052 m_buildProjectAction = new KAction(i18n("&Build Project"), "make_kdevelop", Key_F8, 00053 this, SLOT(slotBuild()), 00054 actionCollection(), "build_build" ); 00055 m_buildProjectAction->setToolTip(i18n("Build project")); 00056 m_buildProjectAction->setWhatsThis(i18n("<b>Build project</b><p>Executes <b>ant dist</b> command to build the project.")); 00057 00058 KActionMenu *menu = new KActionMenu(i18n("Build &Target"), 00059 actionCollection(), "build_target" ); 00060 menu->setToolTip(i18n("Build target")); 00061 menu->setWhatsThis(i18n("<b>Build target</b><p>Executes <b>ant target_name</b> command to build the specified target.")); 00062 00063 m_targetMenu = menu->popupMenu(); 00064 00065 connect(m_targetMenu, SIGNAL(activated(int)), this, SLOT(slotTargetMenuActivated(int))); 00066 connect(core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*))); 00067 connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *))); 00068 00069 m_antOptionsWidget = 0; 00070 } 00071 00072 00073 AntProjectPart::~AntProjectPart() 00074 { 00075 } 00076 00077 00078 void AntProjectPart::openProject(const QString &dirName, const QString &projectName) 00079 { 00080 m_projectDirectory = dirName; 00081 m_projectName = projectName; 00082 00083 QDomDocument &dom = *projectDom(); 00084 // Set the default directory radio to "executable" 00086 if (DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio") == "" ) { 00087 DomUtil::writeEntry(dom, "/kdevantproject/run/directoryradio", "executable"); 00088 } 00089 00091 m_antOptions.m_buildXML = "build.xml"; 00092 00093 parseBuildXML(); 00094 00095 fillMenu(); 00096 00097 QFile f(dirName + "/" + projectName + ".filelist"); 00098 if (f.open(IO_ReadOnly)) 00099 { 00100 QTextStream stream(&f); 00101 while (!stream.atEnd()) 00102 { 00103 QString s = stream.readLine(); 00104 if (!s.startsWith("#")) 00105 m_sourceFiles << s; 00106 } 00107 } 00108 else 00109 populateProject(); 00110 00111 KDevProject::openProject( dirName, projectName ); 00112 } 00113 00114 00115 void AntProjectPart::populateProject() 00116 { 00117 QApplication::setOverrideCursor(Qt::waitCursor); 00118 00119 QValueStack<QString> s; 00120 int prefixlen = m_projectDirectory.length()+1; 00121 s.push(m_projectDirectory); 00122 00123 QDir dir; 00124 do 00125 { 00126 dir.setPath(s.pop()); 00127 kdDebug() << "Examining: " << dir.path() << endl; 00128 const QFileInfoList *dirEntries = dir.entryInfoList(); 00129 QPtrListIterator<QFileInfo> it(*dirEntries); 00130 for (; it.current(); ++it) 00131 { 00132 QString fileName = it.current()->fileName(); 00133 if (fileName == "." || fileName == "..") 00134 continue; 00135 QString path = it.current()->absFilePath(); 00136 if (it.current()->isDir()) 00137 { 00138 kdDebug() << "Pushing: " << path << endl; 00139 s.push(path); 00140 } 00141 else 00142 { 00143 kdDebug() << "Adding: " << path << endl; 00144 m_sourceFiles.append(path.mid(prefixlen)); 00145 } 00146 } 00147 } 00148 while (!s.isEmpty()); 00149 00150 QApplication::restoreOverrideCursor(); 00151 } 00152 00153 00154 void AntProjectPart::closeProject() 00155 { 00156 m_projectDirectory = ""; 00157 m_projectName = ""; 00158 m_buildProjectAction->setEnabled(false); 00159 00160 m_targetMenu->clear(); 00161 00162 m_antOptions = AntOptions(); 00163 00164 QFile f(m_projectDirectory + "/" + m_projectName + ".filelist"); 00165 if (!f.open(IO_WriteOnly)) 00166 return; 00167 00168 QTextStream stream(&f); 00169 stream << "# KDevelop Ant Project File List" << endl; 00170 00171 QStringList::ConstIterator it; 00172 for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) 00173 stream << (*it) << endl; 00174 f.close(); 00175 } 00176 00177 00178 QString AntProjectPart::projectDirectory() const 00179 { 00180 return m_projectDirectory; 00181 } 00182 00183 00184 QString AntProjectPart::buildDirectory() const 00185 { 00186 return m_projectDirectory; 00187 } 00188 00189 QString AntProjectPart::projectName() const 00190 { 00191 return m_projectName; 00192 } 00193 00194 00196 DomUtil::PairList AntProjectPart::runEnvironmentVars() const 00197 { 00199 return DomUtil::readPairListEntry(*projectDom(), "/kdevantproject/run/envvars", "envvar", "name", "value"); 00200 } 00201 00202 00212 QString AntProjectPart::runDirectory() const 00213 { 00214 return buildDirectory(); 00216 00217 QDomDocument &dom = *projectDom(); 00218 00220 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio"); 00221 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram"); 00222 00223 if ( directoryRadioString == "build" ) 00224 return buildDirectory(); 00225 00226 if ( directoryRadioString == "custom" ) 00227 return DomUtil::readEntry(dom, "/kdevantproject/run/customdirectory"); 00228 00229 int pos = DomMainProgram.findRev('/'); 00230 if (pos != -1) 00231 return buildDirectory() + "/" + DomMainProgram.left(pos); 00232 00233 return buildDirectory() + "/" + DomMainProgram; 00234 00235 } 00236 00237 00247 QString AntProjectPart::mainProgram(bool relative) const 00248 { 00249 return QString::null; 00250 00252 QDomDocument &dom = *projectDom(); 00253 00255 QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio"); 00256 QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram"); 00257 00258 if ( directoryRadioString == "custom" ) 00259 return DomMainProgram; 00260 00261 if ( relative == false ) 00262 return buildDirectory() + "/" + DomMainProgram; 00263 00264 if ( directoryRadioString == "executable" ) { 00265 int pos = DomMainProgram.findRev('/'); 00266 if (pos != -1) 00267 return DomMainProgram.mid(pos+1); 00268 return DomMainProgram; 00269 } 00270 else 00271 return DomMainProgram; 00272 } 00273 00274 00276 QString AntProjectPart::runArguments() const 00277 { 00279 return DomUtil::readEntry(*projectDom(), "/kdevantproject/run/programargs"); 00280 } 00281 00282 00283 QString AntProjectPart::activeDirectory() const 00284 { 00286 00287 // return m_projectDirectory; 00288 00289 // returning m_projectDirectory is wrong, the path returned should be _relative_ to the project dir 00290 // returning an empty string until antproject supports the idea of an active directory 00291 return QString(""); 00292 } 00293 00294 00295 QStringList AntProjectPart::allFiles() const 00296 { 00297 /* QStringList res; 00298 00299 QStringList::ConstIterator it; 00300 for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) 00301 { 00302 QString fileName = *it; 00303 if (!fileName.startsWith("/")) 00304 { 00305 fileName.prepend("/"); 00306 fileName.prepend(m_projectDirectory); 00307 } 00308 res += fileName; 00309 } 00310 00311 return res;*/ 00312 00313 // return all files relative to the project directory! 00314 return m_sourceFiles; 00315 } 00316 00317 00318 void AntProjectPart::addFile(const QString &fileName) 00319 { 00320 QStringList fileList; 00321 fileList.append ( fileName ); 00322 00323 this->addFiles ( fileList ); 00324 } 00325 00326 void AntProjectPart::addFiles ( const QStringList& fileList ) 00327 { 00328 QStringList::ConstIterator it; 00329 00330 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00331 { 00332 m_sourceFiles.append (*it ); 00333 } 00334 00335 kdDebug() << "Emitting addedFilesToProject" << endl; 00336 emit addedFilesToProject(fileList); 00337 } 00338 00339 void AntProjectPart::removeFile(const QString &fileName) 00340 { 00341 QStringList fileList; 00342 fileList.append ( fileName ); 00343 00344 this->removeFiles ( fileList ); 00345 } 00346 00347 void AntProjectPart::removeFiles ( const QStringList& fileList ) 00348 { 00349 kdDebug() << "Emitting removedFilesFromProject" << endl; 00350 emit removedFilesFromProject(fileList); 00351 00352 QStringList::ConstIterator it; 00353 00354 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00355 { 00356 m_sourceFiles.remove ( *it ); 00357 } 00358 } 00359 00360 void AntProjectPart::parseBuildXML() 00361 { 00362 m_antOptions.m_targets.clear(); 00363 m_antOptions.m_properties.clear(); 00364 m_antOptions.m_defineProperties.clear(); 00365 00366 // open build file 00367 QFile bf(m_projectDirectory + "/" + m_antOptions.m_buildXML); 00368 if (!bf.open(IO_ReadOnly)) 00369 return; 00370 00371 // parse build file 00372 QDomDocument dom; 00373 if (!dom.setContent(&bf)) 00374 { 00375 bf.close(); 00376 return; 00377 } 00378 bf.close(); 00379 00380 m_projectName = dom.documentElement().attribute("name", m_projectName); 00381 m_antOptions.m_defaultTarget = dom.documentElement().attribute("default", ""); 00382 00383 QDomNode node = dom.documentElement().firstChild(); 00384 while (!node.isNull()) 00385 { 00386 if (node.toElement().tagName() == "target") 00387 { 00388 if (m_antOptions.m_defaultTarget.isEmpty()) 00389 m_antOptions.m_defaultTarget = node.toElement().attribute("name"); 00390 m_antOptions.m_targets.append(node.toElement().attribute("name")); 00391 } 00392 else if (node.toElement().tagName() == "property") 00393 { 00394 m_antOptions.m_properties.insert(node.toElement().attribute("name"), node.toElement().attribute("value")); 00395 m_antOptions.m_defineProperties.insert(node.toElement().attribute("name"), false); 00396 } 00397 00400 00401 node = node.nextSibling(); 00402 } 00403 } 00404 00405 00406 void AntProjectPart::fillMenu() 00407 { 00408 m_buildProjectAction->setEnabled(!m_antOptions.m_defaultTarget.isEmpty()); 00409 00410 m_targetMenu->clear(); 00411 int id = 0; 00412 QStringList::ConstIterator it; 00413 for (it = m_antOptions.m_targets.begin(); it != m_antOptions.m_targets.end(); ++it) 00414 m_targetMenu->insertItem(*it, id++); 00415 } 00416 00417 00418 void AntProjectPart::slotBuild() 00419 { 00420 ant(m_antOptions.m_defaultTarget); 00421 } 00422 00423 00424 void AntProjectPart::slotTargetMenuActivated(int id) 00425 { 00426 ant(m_antOptions.m_targets[id]); 00427 } 00428 00429 00430 void AntProjectPart::ant(const QString &target) 00431 { 00432 QString cmd = "%0 cd %1 && ant %2 -buildfile %3 %4 %5"; 00433 00434 QString verb = ""; 00435 switch (m_antOptions.m_verbosity) 00436 { 00437 case AntOptions::Quiet: 00438 verb = "-quiet"; 00439 break; 00440 case AntOptions::Verbose: 00441 verb = "-verbose"; 00442 break; 00443 default: 00444 verb = "-debug"; 00445 break; 00446 } 00447 00448 QString options = ""; 00449 QMap<QString,QString>::Iterator it; 00450 for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) 00451 if (m_antOptions.m_defineProperties[it.key()]) 00452 options += "-D" + it.key() + "=\"" + it.data() + "\" "; 00453 00454 QString cp; 00455 if (!m_classPath.count() == 0) 00456 cp = "CLASSPATH="+m_classPath.join(":"); 00457 00458 makeFrontend()->queueCommand(m_projectDirectory, cmd.arg(cp).arg(m_projectDirectory).arg(target).arg(m_antOptions.m_buildXML).arg(verb).arg(options)); 00459 } 00460 00461 00462 void AntProjectPart::projectConfigWidget(KDialogBase *dlg) 00463 { 00464 QVBox *vbox = dlg->addVBoxPage(i18n("Ant Options")); 00465 m_antOptionsWidget = new AntOptionsWidget(vbox); 00466 00467 m_antOptionsWidget->BuildXML->setURL(m_antOptions.m_buildXML); 00468 00469 switch (m_antOptions.m_verbosity) 00470 { 00471 case AntOptions::Quiet: 00472 m_antOptionsWidget->Verbosity->setCurrentItem(0); 00473 break; 00474 case AntOptions::Verbose: 00475 m_antOptionsWidget->Verbosity->setCurrentItem(1); 00476 break; 00477 default: 00478 m_antOptionsWidget->Verbosity->setCurrentItem(2); 00479 break; 00480 } 00481 00482 m_antOptionsWidget->Properties->setNumRows(m_antOptions.m_properties.count()); 00483 m_antOptionsWidget->Properties->setNumCols(2); 00484 00485 QMap<QString,QString>::Iterator it; 00486 int i=0; 00487 for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) 00488 { 00489 QCheckTableItem *citem = new QCheckTableItem(m_antOptionsWidget->Properties, it.key()); 00490 citem->setChecked(m_antOptions.m_defineProperties[it.key()]); 00491 m_antOptionsWidget->Properties->setItem(i,0, citem); 00492 QTableItem *item = new QTableItem(m_antOptionsWidget->Properties, QTableItem::WhenCurrent, it.data()); 00493 m_antOptionsWidget->Properties->setItem(i,1, item); 00494 ++i; 00495 } 00496 00497 connect(dlg, SIGNAL(okClicked()), this, SLOT(optionsAccepted())); 00498 00499 vbox = dlg->addVBoxPage(i18n("Classpath")); 00500 m_classPathWidget = new ClassPathWidget(vbox); 00501 00502 m_classPathWidget->ClassPath->insertStringList(m_classPath); 00503 } 00504 00505 00506 void AntProjectPart::optionsAccepted() 00507 { 00508 if (!m_antOptionsWidget || !m_classPathWidget) 00509 return; 00510 00511 m_antOptions.m_buildXML = m_antOptionsWidget->BuildXML->url(); 00512 00513 switch (m_antOptionsWidget->Verbosity->currentItem()) 00514 { 00515 case 1: 00516 m_antOptions.m_verbosity = AntOptions::Verbose; 00517 break; 00518 case 2: 00519 m_antOptions.m_verbosity = AntOptions::Debug; 00520 break; 00521 default: 00522 m_antOptions.m_verbosity = AntOptions::Quiet; 00523 break; 00524 } 00525 00526 for (int i=0; i<m_antOptionsWidget->Properties->numRows(); ++i) 00527 { 00528 QString key = m_antOptionsWidget->Properties->text(i,0); 00529 m_antOptions.m_properties.replace(key, m_antOptionsWidget->Properties->text(i,1)); 00530 kdDebug() << "PROP: " << key << " = " << m_antOptionsWidget->Properties->text(i,1); 00531 00532 QCheckTableItem *item =(QCheckTableItem*) m_antOptionsWidget->Properties->item(i,0); 00533 m_antOptions.m_defineProperties.replace(key, item->isChecked()); 00534 } 00535 00536 m_classPath = m_classPathWidget->ClassPath->items(); 00537 00538 m_antOptionsWidget = 0; 00539 m_classPathWidget = 0; 00540 } 00541 00542 00543 void AntProjectPart::contextMenu(QPopupMenu *popup, const Context *context) 00544 { 00545 if (!context->hasType( Context::FileContext )) 00546 return; 00547 00548 const FileContext *fcontext = static_cast<const FileContext*>(context); 00549 if (fcontext->isDirectory()) 00550 return; 00551 00552 m_contextFileName = fcontext->fileName(); 00553 bool inProject = project()->allFiles().contains(m_contextFileName.mid ( project()->projectDirectory().length() + 1 ) ); 00554 QString popupstr = QFileInfo(m_contextFileName).fileName(); 00555 if (m_contextFileName.startsWith(projectDirectory()+ "/")) 00556 m_contextFileName.remove(0, projectDirectory().length()+1); 00557 00558 popup->insertSeparator(); 00559 if (inProject) 00560 { 00561 int id = popup->insertItem( i18n("Remove %1 From Project").arg(popupstr), 00562 this, SLOT(slotRemoveFromProject()) ); 00563 popup->setWhatsThis(id, i18n("<b>Remove from project</b><p>Removes current file from the project.")); 00564 } 00565 else 00566 { 00567 int id = popup->insertItem( i18n("Add %1 to Project").arg(popupstr), 00568 this, SLOT(slotAddToProject()) ); 00569 popup->setWhatsThis(id, i18n("<b>Add to project</b><p>Adds current file from the project.")); 00570 } 00571 } 00572 00573 00574 void AntProjectPart::slotAddToProject() 00575 { 00576 QStringList fileList; 00577 fileList.append ( m_contextFileName ); 00578 addFiles ( fileList ); 00579 } 00580 00581 00582 void AntProjectPart::slotRemoveFromProject() 00583 { 00584 QStringList fileList; 00585 fileList.append ( m_contextFileName ); 00586 removeFiles ( fileList ); 00587 } 00588 00589 00590 #include "antprojectpart.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:52 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003