1
#include "antprojectpart.h"
3
#include <qapplication.h>
6
#include <qpopupmenu.h>
9
#include <qtextstream.h>
10
#include <qvaluestack.h>
14
#include <kdevgenericfactory.h>
17
#include <kpopupmenu.h>
18
#include <kdialogbase.h>
19
#include <klineedit.h>
20
#include <kcombobox.h>
21
#include <keditlistbox.h>
22
#include <kurlrequester.h>
24
#include <kdevplugininfo.h>
27
#include <kdevmakefrontend.h>
31
#include "antoptionswidget.h"
32
#include "classpathwidget.h"
37
typedef KDevGenericFactory<AntProjectPart> AntProjectFactory;
38
static const KDevPluginInfo data("kdevantproject");
39
K_EXPORT_COMPONENT_FACTORY(libkdevantproject, AntProjectFactory( data ))
42
AntOptions::AntOptions()
43
: m_buildXML("build.xml"), m_verbosity(AntOptions::Quiet)
48
AntProjectPart::AntProjectPart(QObject *parent, const char *name, const QStringList &)
49
: KDevBuildTool(&data, parent, name ? name : "AntProjectPart")
51
setInstance(AntProjectFactory::instance());
53
setXMLFile("kdevantproject.rc");
55
m_buildProjectAction = new KAction(i18n("&Build Project"), "make_kdevelop", Key_F8,
56
this, SLOT(slotBuild()),
57
actionCollection(), "build_build" );
58
m_buildProjectAction->setToolTip(i18n("Build project"));
59
m_buildProjectAction->setWhatsThis(i18n("<b>Build project</b><p>Executes <b>ant dist</b> command to build the project."));
61
KActionMenu *menu = new KActionMenu(i18n("Build &Target"),
62
actionCollection(), "build_target" );
63
menu->setToolTip(i18n("Build target"));
64
menu->setWhatsThis(i18n("<b>Build target</b><p>Executes <b>ant target_name</b> command to build the specified target."));
66
m_targetMenu = menu->popupMenu();
68
connect(m_targetMenu, SIGNAL(activated(int)), this, SLOT(slotTargetMenuActivated(int)));
69
connect(core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*)));
70
connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *)));
72
m_antOptionsWidget = 0;
76
AntProjectPart::~AntProjectPart()
81
void AntProjectPart::openProject(const QString &dirName, const QString &projectName)
83
m_projectDirectory = dirName;
84
m_projectName = projectName;
86
QDomDocument &dom = *projectDom();
87
// Set the default directory radio to "executable"
88
/// \FIXME there is no kdevantproject so this will not work !
89
if (DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio") == "" ) {
90
DomUtil::writeEntry(dom, "/kdevantproject/run/directoryradio", "executable");
93
/// @todo read alternative build file from properties
94
m_antOptions.m_buildXML = "build.xml";
100
QFile f(dirName + "/" + projectName.lower() + ".kdevelop" + ".filelist");
101
if (f.open(IO_ReadOnly))
103
QTextStream stream(&f);
104
while (!stream.atEnd())
106
QString s = stream.readLine();
107
if (!s.startsWith("#"))
114
KDevProject::openProject( dirName, projectName );
118
void AntProjectPart::populateProject()
120
QApplication::setOverrideCursor(Qt::waitCursor);
122
QValueStack<QString> s;
123
int prefixlen = m_projectDirectory.length()+1;
124
s.push(m_projectDirectory);
129
dir.setPath(s.pop());
130
kdDebug() << "Examining: " << dir.path() << endl;
131
const QFileInfoList *dirEntries = dir.entryInfoList();
132
QPtrListIterator<QFileInfo> it(*dirEntries);
133
for (; it.current(); ++it)
135
QString fileName = it.current()->fileName();
136
if (fileName == "." || fileName == "..")
138
QString path = it.current()->absFilePath();
139
if (it.current()->isDir())
141
kdDebug() << "Pushing: " << path << endl;
146
kdDebug() << "Adding: " << path << endl;
147
m_sourceFiles.append(path.mid(prefixlen));
151
while (!s.isEmpty());
153
QApplication::restoreOverrideCursor();
157
void AntProjectPart::closeProject()
159
m_projectDirectory = "";
161
m_buildProjectAction->setEnabled(false);
163
m_targetMenu->clear();
165
m_antOptions = AntOptions();
167
QFile f(m_projectDirectory + "/" + m_projectName.lower() + ".kdevelop" + ".filelist");
168
if (!f.open(IO_WriteOnly))
171
QTextStream stream(&f);
172
stream << "# KDevelop Ant Project File List" << endl;
174
QStringList::ConstIterator it;
175
for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it)
176
stream << (*it) << endl;
181
QString AntProjectPart::projectDirectory() const
183
return m_projectDirectory;
187
QString AntProjectPart::buildDirectory() const
189
return m_projectDirectory;
192
QString AntProjectPart::projectName() const
194
return m_projectName;
198
/** Retuns a PairList with the run environment variables */
199
DomUtil::PairList AntProjectPart::runEnvironmentVars() const
201
/// \FIXME there is no kdevantproject so this will not work !
202
return DomUtil::readPairListEntry(*projectDom(), "/kdevantproject/run/envvars", "envvar", "name", "value");
206
/** Retuns the currently selected run directory
207
* The returned string can be:
208
* if run/directoryradio == executable
209
* The directory where the executable is
210
* if run/directoryradio == build
211
* The directory where the executable is relative to build directory
212
* if run/directoryradio == custom
213
* The custom directory absolute path
215
QString AntProjectPart::runDirectory() const
217
return buildDirectory();
218
/// \FIXME put the code below into use!
220
QDomDocument &dom = *projectDom();
222
/// \FIXME there is no kdevantproject so this will not work !
223
QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio");
224
QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram");
226
if ( directoryRadioString == "build" )
227
return buildDirectory();
229
if ( directoryRadioString == "custom" )
230
return DomUtil::readEntry(dom, "/kdevantproject/run/customdirectory");
232
int pos = DomMainProgram.findRev('/');
234
return buildDirectory() + "/" + DomMainProgram.left(pos);
236
return buildDirectory() + "/" + DomMainProgram;
241
/** Retuns the currently selected main program
242
* The returned string can be:
243
* if run/directoryradio == executable
244
* The executable name
245
* if run/directoryradio == build
246
* The path to executable relative to build directory
247
* if run/directoryradio == custom or relative == false
248
* The absolute path to executable
250
QString AntProjectPart::mainProgram() const
252
QDomDocument * dom = projectDom();
254
if ( !dom ) return QString();
256
QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevantproject/run/mainprogram");
258
if ( DomMainProgram.isEmpty() ) return QString();
260
if ( DomMainProgram.startsWith("/") ) // assume absolute path
262
return DomMainProgram;
264
else // assume project relative path
266
return projectDirectory() + "/" + DomMainProgram;
273
QString AntProjectPart::debugArguments() const
278
/** Retuns a QString with the run command line arguments */
279
QString AntProjectPart::runArguments() const
281
/// \FIXME there is no kdevantproject so this will not work !
282
return DomUtil::readEntry(*projectDom(), "/kdevantproject/run/programargs");
286
QString AntProjectPart::activeDirectory() const
290
// return m_projectDirectory;
292
// returning m_projectDirectory is wrong, the path returned should be _relative_ to the project dir
293
// returning an empty string until antproject supports the idea of an active directory
298
QStringList AntProjectPart::allFiles() const
302
QStringList::ConstIterator it;
303
for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it)
305
QString fileName = *it;
306
if (!fileName.startsWith("/"))
308
fileName.prepend("/");
309
fileName.prepend(m_projectDirectory);
316
// return all files relative to the project directory!
317
return m_sourceFiles;
321
void AntProjectPart::addFile(const QString &fileName)
323
QStringList fileList;
324
fileList.append ( fileName );
326
this->addFiles ( fileList );
329
void AntProjectPart::addFiles ( const QStringList& fileList )
331
QStringList::ConstIterator it;
333
for ( it = fileList.begin(); it != fileList.end(); ++it )
335
m_sourceFiles.append (*it );
338
kdDebug() << "Emitting addedFilesToProject" << endl;
339
emit addedFilesToProject(fileList);
342
void AntProjectPart::removeFile(const QString &fileName)
344
QStringList fileList;
345
fileList.append ( fileName );
347
this->removeFiles ( fileList );
350
void AntProjectPart::removeFiles ( const QStringList& fileList )
352
kdDebug() << "Emitting removedFilesFromProject" << endl;
353
emit removedFilesFromProject(fileList);
355
QStringList::ConstIterator it;
357
for ( it = fileList.begin(); it != fileList.end(); ++it )
359
m_sourceFiles.remove ( *it );
363
void AntProjectPart::parseBuildXML()
365
m_antOptions.m_targets.clear();
366
m_antOptions.m_properties.clear();
367
m_antOptions.m_defineProperties.clear();
370
QFile bf(m_projectDirectory + "/" + m_antOptions.m_buildXML);
371
if (!bf.open(IO_ReadOnly))
376
if (!dom.setContent(&bf))
383
m_projectName = dom.documentElement().attribute("name", m_projectName);
384
m_antOptions.m_defaultTarget = dom.documentElement().attribute("default", "");
386
QDomNode node = dom.documentElement().firstChild();
387
while (!node.isNull())
389
if (node.toElement().tagName() == "target")
391
if (m_antOptions.m_defaultTarget.isEmpty())
392
m_antOptions.m_defaultTarget = node.toElement().attribute("name");
393
m_antOptions.m_targets.append(node.toElement().attribute("name"));
395
else if (node.toElement().tagName() == "property")
397
m_antOptions.m_properties.insert(node.toElement().attribute("name"), node.toElement().attribute("value"));
398
m_antOptions.m_defineProperties.insert(node.toElement().attribute("name"), false);
401
/// @todo Handle property files
402
/// @todo evaluate properties' values
404
node = node.nextSibling();
409
void AntProjectPart::fillMenu()
411
m_buildProjectAction->setEnabled(!m_antOptions.m_defaultTarget.isEmpty());
413
m_targetMenu->clear();
415
QStringList::ConstIterator it;
416
for (it = m_antOptions.m_targets.begin(); it != m_antOptions.m_targets.end(); ++it)
417
m_targetMenu->insertItem(*it, id++);
421
void AntProjectPart::slotBuild()
423
ant(m_antOptions.m_defaultTarget);
427
void AntProjectPart::slotTargetMenuActivated(int id)
429
ant(m_antOptions.m_targets[id]);
433
void AntProjectPart::ant(const QString &target)
435
QString cmd = "%0 cd %1 && ant %2 -buildfile %3 %4 %5";
438
switch (m_antOptions.m_verbosity)
440
case AntOptions::Quiet:
443
case AntOptions::Verbose:
451
QString options = "";
452
QMap<QString,QString>::Iterator it;
453
for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it)
454
if (m_antOptions.m_defineProperties[it.key()])
455
options += "-D" + it.key() + "=\"" + it.data() + "\" ";
458
if (!m_classPath.count() == 0)
459
cp = "CLASSPATH="+m_classPath.join(":");
461
makeFrontend()->queueCommand(m_projectDirectory, cmd.arg(cp).arg(m_projectDirectory).arg(target).arg(m_antOptions.m_buildXML).arg(verb).arg(options));
465
void AntProjectPart::projectConfigWidget(KDialogBase *dlg)
467
QVBox *vbox = dlg->addVBoxPage(i18n("Ant Options"));
468
m_antOptionsWidget = new AntOptionsWidget(vbox);
470
m_antOptionsWidget->BuildXML->setURL(m_antOptions.m_buildXML);
472
switch (m_antOptions.m_verbosity)
474
case AntOptions::Quiet:
475
m_antOptionsWidget->Verbosity->setCurrentItem(0);
477
case AntOptions::Verbose:
478
m_antOptionsWidget->Verbosity->setCurrentItem(1);
481
m_antOptionsWidget->Verbosity->setCurrentItem(2);
485
m_antOptionsWidget->Properties->setNumRows(m_antOptions.m_properties.count());
486
m_antOptionsWidget->Properties->setNumCols(2);
488
QMap<QString,QString>::Iterator it;
490
for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it)
492
QCheckTableItem *citem = new QCheckTableItem(m_antOptionsWidget->Properties, it.key());
493
citem->setChecked(m_antOptions.m_defineProperties[it.key()]);
494
m_antOptionsWidget->Properties->setItem(i,0, citem);
495
QTableItem *item = new QTableItem(m_antOptionsWidget->Properties, QTableItem::WhenCurrent, it.data());
496
m_antOptionsWidget->Properties->setItem(i,1, item);
500
connect(dlg, SIGNAL(okClicked()), this, SLOT(optionsAccepted()));
502
vbox = dlg->addVBoxPage(i18n("Classpath"));
503
m_classPathWidget = new ClassPathWidget(vbox);
505
m_classPathWidget->ClassPath->insertStringList(m_classPath);
509
void AntProjectPart::optionsAccepted()
511
if (!m_antOptionsWidget || !m_classPathWidget)
514
m_antOptions.m_buildXML = m_antOptionsWidget->BuildXML->url();
516
switch (m_antOptionsWidget->Verbosity->currentItem())
519
m_antOptions.m_verbosity = AntOptions::Verbose;
522
m_antOptions.m_verbosity = AntOptions::Debug;
525
m_antOptions.m_verbosity = AntOptions::Quiet;
529
for (int i=0; i<m_antOptionsWidget->Properties->numRows(); ++i)
531
QString key = m_antOptionsWidget->Properties->text(i,0);
532
m_antOptions.m_properties.replace(key, m_antOptionsWidget->Properties->text(i,1));
533
kdDebug() << "PROP: " << key << " = " << m_antOptionsWidget->Properties->text(i,1);
535
QCheckTableItem *item =(QCheckTableItem*) m_antOptionsWidget->Properties->item(i,0);
536
m_antOptions.m_defineProperties.replace(key, item->isChecked());
539
m_classPath = m_classPathWidget->ClassPath->items();
541
m_antOptionsWidget = 0;
542
m_classPathWidget = 0;
546
void AntProjectPart::contextMenu(QPopupMenu *popup, const Context *context)
548
if (!context->hasType( Context::FileContext ))
551
const FileContext *fcontext = static_cast<const FileContext*>(context);
552
KURL url = fcontext->urls().first();
553
if (URLUtil::isDirectory(url))
556
m_contextFileName = url.fileName();
557
bool inProject = project()->allFiles().contains(m_contextFileName.mid ( project()->projectDirectory().length() + 1 ) );
558
QString popupstr = QFileInfo(m_contextFileName).fileName();
559
if (m_contextFileName.startsWith(projectDirectory()+ "/"))
560
m_contextFileName.remove(0, projectDirectory().length()+1);
562
popup->insertSeparator();
565
int id = popup->insertItem( i18n("Remove %1 From Project").arg(popupstr),
566
this, SLOT(slotRemoveFromProject()) );
567
popup->setWhatsThis(id, i18n("<b>Remove from project</b><p>Removes current file from the project."));
571
int id = popup->insertItem( i18n("Add %1 to Project").arg(popupstr),
572
this, SLOT(slotAddToProject()) );
573
popup->setWhatsThis(id, i18n("<b>Add to project</b><p>Adds current file from the project."));
578
void AntProjectPart::slotAddToProject()
580
QStringList fileList;
581
fileList.append ( m_contextFileName );
582
addFiles ( fileList );
586
void AntProjectPart::slotRemoveFromProject()
588
QStringList fileList;
589
fileList.append ( m_contextFileName );
590
removeFiles ( fileList );
594
#include "antprojectpart.moc"
598
\fn AntProjectPart::distFiles() const
600
QStringList AntProjectPart::distFiles() const
602
QStringList sourceList = allFiles();
603
// Scan current source directory for any .pro files.
604
QString projectDir = projectDirectory();
605
QDir dir(projectDir);
606
QStringList files = dir.entryList( "build.xml");
607
return sourceList + files;