diff options
| author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 | 
|---|---|---|
| committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 | 
| commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
| tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /buildtools/ant/antprojectpart.cpp | |
| download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip | |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'buildtools/ant/antprojectpart.cpp')
| -rw-r--r-- | buildtools/ant/antprojectpart.cpp | 608 | 
1 files changed, 608 insertions, 0 deletions
| diff --git a/buildtools/ant/antprojectpart.cpp b/buildtools/ant/antprojectpart.cpp new file mode 100644 index 00000000..a7f0ea25 --- /dev/null +++ b/buildtools/ant/antprojectpart.cpp @@ -0,0 +1,608 @@ +#include "antprojectpart.h" + +#include <qapplication.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qpopupmenu.h> +#include <qvbox.h> +#include <qtable.h> +#include <qtextstream.h> +#include <qvaluestack.h> +#include <qdir.h> + + +#include <kdevgenericfactory.h> +#include <kdebug.h> +#include <kaction.h> +#include <kpopupmenu.h> +#include <kdialogbase.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <keditlistbox.h> +#include <kurlrequester.h> + +#include <kdevplugininfo.h> + +#include <kdevcore.h> +#include <kdevmakefrontend.h> +#include <urlutil.h> + + +#include "antoptionswidget.h" +#include "classpathwidget.h" + + + + +typedef KDevGenericFactory<AntProjectPart> AntProjectFactory; +static const KDevPluginInfo data("kdevantproject"); +K_EXPORT_COMPONENT_FACTORY(libkdevantproject, AntProjectFactory( data )) + + +AntOptions::AntOptions() +  : m_buildXML("build.xml"), m_verbosity(AntOptions::Quiet) +{ +} + + +AntProjectPart::AntProjectPart(QObject *parent, const char *name, const QStringList &) +  : KDevBuildTool(&data, parent, name ? name : "AntProjectPart") +{ +  setInstance(AntProjectFactory::instance()); + +  setXMLFile("kdevantproject.rc"); + +  m_buildProjectAction = new KAction(i18n("&Build Project"), "make_kdevelop", Key_F8, +		                     this, SLOT(slotBuild()), +				     actionCollection(), "build_build" ); +  m_buildProjectAction->setToolTip(i18n("Build project")); +  m_buildProjectAction->setWhatsThis(i18n("<b>Build project</b><p>Executes <b>ant dist</b> command to build the project.")); + +  KActionMenu *menu = new KActionMenu(i18n("Build &Target"), +                                      actionCollection(), "build_target" ); +  menu->setToolTip(i18n("Build target")); +  menu->setWhatsThis(i18n("<b>Build target</b><p>Executes <b>ant target_name</b> command to build the specified target.")); + +  m_targetMenu = menu->popupMenu(); + +  connect(m_targetMenu, SIGNAL(activated(int)), this, SLOT(slotTargetMenuActivated(int))); +  connect(core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*))); +  connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *))); + +  m_antOptionsWidget = 0; +} + + +AntProjectPart::~AntProjectPart() +{ +} + + +void AntProjectPart::openProject(const QString &dirName, const QString &projectName) +{ +  m_projectDirectory = dirName; +  m_projectName = projectName; + +  QDomDocument &dom = *projectDom(); +  // Set the default directory radio to "executable" +  /// \FIXME there is no kdevantproject so this will not work ! +  if (DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio") == "" ) { +    DomUtil::writeEntry(dom, "/kdevantproject/run/directoryradio", "executable"); +  } + +  /// @todo read alternative build file from properties +  m_antOptions.m_buildXML = "build.xml"; + +  parseBuildXML(); + +  fillMenu(); + +  QFile f(dirName + "/" + projectName.lower() + ".kdevelop" + ".filelist"); +  if (f.open(IO_ReadOnly)) +  { +    QTextStream stream(&f); +    while (!stream.atEnd()) +    { +      QString s = stream.readLine(); +      if (!s.startsWith("#")) +        m_sourceFiles << s; +    } +  } +  else +    populateProject(); + +  KDevProject::openProject( dirName, projectName ); +} + + +void AntProjectPart::populateProject() +{ +  QApplication::setOverrideCursor(Qt::waitCursor); + +  QValueStack<QString> s; +  int prefixlen = m_projectDirectory.length()+1; +  s.push(m_projectDirectory); + +  QDir dir; +  do +  { +    dir.setPath(s.pop()); +    kdDebug() << "Examining: " << dir.path() << endl; +    const QFileInfoList *dirEntries = dir.entryInfoList(); +    QPtrListIterator<QFileInfo> it(*dirEntries); +    for (; it.current(); ++it) +    { +      QString fileName = it.current()->fileName(); +      if (fileName == "." || fileName == "..") +        continue; +      QString path = it.current()->absFilePath(); +      if (it.current()->isDir()) +      { +        kdDebug() << "Pushing: " << path << endl; +        s.push(path); +      } +      else +      { +        kdDebug() << "Adding: " << path << endl; +        m_sourceFiles.append(path.mid(prefixlen)); +      } +    } +  } +  while (!s.isEmpty()); + +  QApplication::restoreOverrideCursor(); +} + + +void AntProjectPart::closeProject() +{ +  m_projectDirectory = ""; +  m_projectName = ""; +  m_buildProjectAction->setEnabled(false); + +  m_targetMenu->clear(); + +  m_antOptions = AntOptions(); + +  QFile f(m_projectDirectory + "/" + m_projectName.lower() + ".kdevelop" + ".filelist"); +  if (!f.open(IO_WriteOnly)) +    return; + +  QTextStream stream(&f); +  stream << "# KDevelop Ant Project File List" << endl; + +  QStringList::ConstIterator it; +  for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) +    stream << (*it) << endl; +  f.close(); +} + + +QString AntProjectPart::projectDirectory() const +{ +  return m_projectDirectory; +} + + +QString AntProjectPart::buildDirectory() const +{ +  return m_projectDirectory; +} + +QString AntProjectPart::projectName() const +{ +  return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AntProjectPart::runEnvironmentVars() const +{ +    /// \FIXME there is no kdevantproject so this will not work ! +    return DomUtil::readPairListEntry(*projectDom(), "/kdevantproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory +  * The returned string can be: +  *   if run/directoryradio == executable +  *        The directory where the executable is +  *   if run/directoryradio == build +  *        The directory where the executable is relative to build directory +  *   if run/directoryradio == custom +  *        The custom directory absolute path +  */ +QString AntProjectPart::runDirectory() const +{ +    return buildDirectory(); +    /// \FIXME put the code below into use! + +    QDomDocument &dom = *projectDom(); + +    /// \FIXME there is no kdevantproject so this will not work ! +    QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio"); +    QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram"); + +    if ( directoryRadioString == "build" ) +        return buildDirectory(); + +    if ( directoryRadioString == "custom" ) +        return DomUtil::readEntry(dom, "/kdevantproject/run/customdirectory"); + +    int pos = DomMainProgram.findRev('/'); +    if (pos != -1) +        return buildDirectory() + "/" + DomMainProgram.left(pos); + +    return buildDirectory() + "/" + DomMainProgram; + +} + + +/** Retuns the currently selected main program +  * The returned string can be: +  *   if run/directoryradio == executable +  *        The executable name +  *   if run/directoryradio == build +  *        The path to executable relative to build directory +  *   if run/directoryradio == custom or relative == false +  *        The absolute path to executable +  */ +QString AntProjectPart::mainProgram() const +{ +    QDomDocument * dom = projectDom(); + +    if ( !dom ) return QString(); + +    QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevantproject/run/mainprogram"); + +    if ( DomMainProgram.isEmpty() ) return QString(); + +    if ( DomMainProgram.startsWith("/") )   // assume absolute path +    { +        return DomMainProgram;     +    } +    else // assume project relative path +    { +        return projectDirectory() + "/" + DomMainProgram; +    } + +    return QString(); +} + + +QString AntProjectPart::debugArguments() const +{ +    return QString(""); +} + +/** Retuns a QString with the run command line arguments */ +QString AntProjectPart::runArguments() const +{ +    /// \FIXME there is no kdevantproject so this will not work ! +    return DomUtil::readEntry(*projectDom(), "/kdevantproject/run/programargs"); +} + + +QString AntProjectPart::activeDirectory() const +{ +  /// \FIXME + +//  return m_projectDirectory; + +	// returning m_projectDirectory is wrong, the path returned should be _relative_ to the project dir +	// returning an empty string until antproject supports the idea of an active directory +	return QString(""); +} + + +QStringList AntProjectPart::allFiles() const +{ +/* QStringList res; + +  QStringList::ConstIterator it; +  for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) +  { +    QString fileName = *it; +    if (!fileName.startsWith("/")) +    { +      fileName.prepend("/"); +      fileName.prepend(m_projectDirectory); +    } +    res += fileName; +  } + +  return res;*/ + +	// return all files relative to the project directory! +	return m_sourceFiles; +} + + +void AntProjectPart::addFile(const QString &fileName) +{ +	QStringList fileList; +	fileList.append ( fileName ); + +	this->addFiles ( fileList ); +} + +void AntProjectPart::addFiles ( const QStringList& fileList ) +{ +	QStringList::ConstIterator it; + +	for ( it = fileList.begin(); it != fileList.end(); ++it ) +	{ +		m_sourceFiles.append (*it ); +	} + +	kdDebug() << "Emitting addedFilesToProject" << endl; +	emit addedFilesToProject(fileList); +} + +void AntProjectPart::removeFile(const QString &fileName) +{ +	QStringList fileList; +	fileList.append ( fileName ); + +	this->removeFiles ( fileList ); +} + +void AntProjectPart::removeFiles ( const QStringList& fileList ) +{ +	kdDebug() << "Emitting removedFilesFromProject" << endl; +	emit removedFilesFromProject(fileList); + +	QStringList::ConstIterator it; + +	for ( it = fileList.begin(); it != fileList.end(); ++it ) +	{ +		m_sourceFiles.remove ( *it ); +	} +} + +void AntProjectPart::parseBuildXML() +{ +  m_antOptions.m_targets.clear(); +  m_antOptions.m_properties.clear(); +  m_antOptions.m_defineProperties.clear(); + +  // open build file +  QFile bf(m_projectDirectory + "/" + m_antOptions.m_buildXML); +  if (!bf.open(IO_ReadOnly)) +    return; + +  // parse build file +  QDomDocument dom; +  if (!dom.setContent(&bf)) +  { +    bf.close(); +    return; +  } +  bf.close(); + +  m_projectName = dom.documentElement().attribute("name", m_projectName); +  m_antOptions.m_defaultTarget = dom.documentElement().attribute("default", ""); + +  QDomNode node = dom.documentElement().firstChild(); +  while (!node.isNull()) +  { +    if (node.toElement().tagName() == "target") +    { +      if (m_antOptions.m_defaultTarget.isEmpty()) +        m_antOptions.m_defaultTarget = node.toElement().attribute("name"); +      m_antOptions.m_targets.append(node.toElement().attribute("name")); +    } +    else if (node.toElement().tagName() == "property") +    { +      m_antOptions.m_properties.insert(node.toElement().attribute("name"), node.toElement().attribute("value")); +      m_antOptions.m_defineProperties.insert(node.toElement().attribute("name"), false); +    } + +    /// @todo Handle property files +    /// @todo evaluate properties' values + +    node = node.nextSibling(); +  } +} + + +void AntProjectPart::fillMenu() +{ +  m_buildProjectAction->setEnabled(!m_antOptions.m_defaultTarget.isEmpty()); + +  m_targetMenu->clear(); +  int id = 0; +  QStringList::ConstIterator it; +  for (it = m_antOptions.m_targets.begin(); it != m_antOptions.m_targets.end(); ++it) +    m_targetMenu->insertItem(*it, id++); +} + + +void AntProjectPart::slotBuild() +{ +  ant(m_antOptions.m_defaultTarget); +} + + +void AntProjectPart::slotTargetMenuActivated(int id) +{ +  ant(m_antOptions.m_targets[id]); +} + + +void AntProjectPart::ant(const QString &target) +{ +  QString cmd = "%0 cd %1 && ant %2 -buildfile %3 %4 %5"; + +  QString verb = ""; +  switch (m_antOptions.m_verbosity) +  { +  case AntOptions::Quiet: +    verb = "-quiet"; +    break; +  case AntOptions::Verbose: +    verb = "-verbose"; +    break; +  default: +    verb = "-debug"; +    break; +  } + +  QString options = ""; +  QMap<QString,QString>::Iterator it; +  for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) +    if (m_antOptions.m_defineProperties[it.key()]) +      options += "-D" + it.key() + "=\"" + it.data() + "\" "; + +  QString cp; +  if (!m_classPath.count() == 0) +    cp = "CLASSPATH="+m_classPath.join(":"); + +  makeFrontend()->queueCommand(m_projectDirectory, cmd.arg(cp).arg(m_projectDirectory).arg(target).arg(m_antOptions.m_buildXML).arg(verb).arg(options)); +} + + +void AntProjectPart::projectConfigWidget(KDialogBase *dlg) +{ +  QVBox *vbox = dlg->addVBoxPage(i18n("Ant Options")); +  m_antOptionsWidget = new AntOptionsWidget(vbox); + +  m_antOptionsWidget->BuildXML->setURL(m_antOptions.m_buildXML); + +  switch (m_antOptions.m_verbosity) +  { +  case AntOptions::Quiet: +    m_antOptionsWidget->Verbosity->setCurrentItem(0); +    break; +  case AntOptions::Verbose: +    m_antOptionsWidget->Verbosity->setCurrentItem(1); +    break; +  default: +    m_antOptionsWidget->Verbosity->setCurrentItem(2); +    break; +  } + +  m_antOptionsWidget->Properties->setNumRows(m_antOptions.m_properties.count()); +  m_antOptionsWidget->Properties->setNumCols(2); + +  QMap<QString,QString>::Iterator it; +  int i=0; +  for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) +  { +    QCheckTableItem *citem = new QCheckTableItem(m_antOptionsWidget->Properties, it.key()); +    citem->setChecked(m_antOptions.m_defineProperties[it.key()]); +    m_antOptionsWidget->Properties->setItem(i,0, citem); +    QTableItem *item = new QTableItem(m_antOptionsWidget->Properties, QTableItem::WhenCurrent, it.data()); +    m_antOptionsWidget->Properties->setItem(i,1, item); +    ++i; +  } + +  connect(dlg, SIGNAL(okClicked()), this, SLOT(optionsAccepted())); + +  vbox = dlg->addVBoxPage(i18n("Classpath")); +  m_classPathWidget = new ClassPathWidget(vbox); + +  m_classPathWidget->ClassPath->insertStringList(m_classPath); +} + + +void AntProjectPart::optionsAccepted() +{ +  if (!m_antOptionsWidget || !m_classPathWidget) +    return; + +  m_antOptions.m_buildXML = m_antOptionsWidget->BuildXML->url(); + +  switch (m_antOptionsWidget->Verbosity->currentItem()) +  { +  case 1: +    m_antOptions.m_verbosity = AntOptions::Verbose; +    break; +  case 2: +    m_antOptions.m_verbosity = AntOptions::Debug; +    break; +  default: +    m_antOptions.m_verbosity = AntOptions::Quiet; +    break; +  } + +  for (int i=0; i<m_antOptionsWidget->Properties->numRows(); ++i) +  { +    QString key = m_antOptionsWidget->Properties->text(i,0); +    m_antOptions.m_properties.replace(key, m_antOptionsWidget->Properties->text(i,1)); +    kdDebug() << "PROP: " << key << "  = " << m_antOptionsWidget->Properties->text(i,1); + +    QCheckTableItem *item =(QCheckTableItem*) m_antOptionsWidget->Properties->item(i,0); +    m_antOptions.m_defineProperties.replace(key, item->isChecked()); +  } + +  m_classPath = m_classPathWidget->ClassPath->items(); + +  m_antOptionsWidget = 0; +  m_classPathWidget = 0; +} + + +void AntProjectPart::contextMenu(QPopupMenu *popup, const Context *context) +{ +  if (!context->hasType( Context::FileContext )) +    return; + +  const FileContext *fcontext = static_cast<const FileContext*>(context); +  KURL url = fcontext->urls().first(); +  if (URLUtil::isDirectory(url)) +    return; + +  m_contextFileName = url.fileName(); +  bool inProject = project()->allFiles().contains(m_contextFileName.mid ( project()->projectDirectory().length() + 1 ) ); +  QString popupstr = QFileInfo(m_contextFileName).fileName(); +  if (m_contextFileName.startsWith(projectDirectory()+ "/")) +    m_contextFileName.remove(0, projectDirectory().length()+1); + +  popup->insertSeparator(); +  if (inProject) +  { +    int id = popup->insertItem( i18n("Remove %1 From Project").arg(popupstr), +                       this, SLOT(slotRemoveFromProject()) ); +    popup->setWhatsThis(id, i18n("<b>Remove from project</b><p>Removes current file from the project.")); +  } +  else +  { +    int id = popup->insertItem( i18n("Add %1 to Project").arg(popupstr), +                       this, SLOT(slotAddToProject()) ); +    popup->setWhatsThis(id, i18n("<b>Add to project</b><p>Adds current file from the project.")); +  } +} + + +void AntProjectPart::slotAddToProject() +{ +	QStringList fileList; +	fileList.append ( m_contextFileName ); +	addFiles ( fileList ); +} + + +void AntProjectPart::slotRemoveFromProject() +{ +	QStringList fileList; +	fileList.append ( m_contextFileName ); +	removeFiles ( fileList ); +} + + +#include "antprojectpart.moc" + + +/*! +    \fn AntProjectPart::distFiles() const + */ +QStringList AntProjectPart::distFiles() const +{ +	QStringList sourceList = allFiles(); +	// Scan current source directory for any .pro files. +	QString projectDir = projectDirectory(); +	QDir dir(projectDir); +	QStringList files = dir.entryList( "build.xml"); +	return sourceList + files; +} | 
