KDevelop API Documentation

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"
00591 
00592 
00596 QStringList AntProjectPart::distFiles() const
00597 {
00598     QStringList sourceList = allFiles();
00599     // Scan current source directory for any .pro files.
00600     QString projectDir = projectDirectory();
00601     QDir dir(projectDir);
00602     QStringList files = dir.entryList( "build.xml");
00603     return sourceList + files;
00604 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:20 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003