1
/* Copyright (C) 2003 Oliver Kellogg
2
* okellogg@users.sourceforge.net
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
10
#include <qfileinfo.h>
12
#include <qvaluestack.h>
16
#include <kiconloader.h>
19
#include <kgenericfactory.h>
21
#include <kdialogbase.h>
22
#include <kmessagebox.h>
23
#include <klibloader.h>
30
#include "kdevmainwindow.h"
31
#include "kdevmakefrontend.h"
32
#include "kdevappfrontend.h"
33
#include "kdevpartcontroller.h"
34
#include "kdevlanguagesupport.h"
35
#include "kdevcompileroptions.h"
36
#include "kdevgenericfactory.h"
37
#include <kdevplugininfo.h>
39
#include "adaproject_widget.h"
40
#include "adaproject_part.h"
41
#include "adaprojectoptionsdlg.h"
42
#include "adaglobaloptionsdlg.h"
44
typedef KDevGenericFactory<AdaProjectPart> AdaProjectFactory;
45
static const KDevPluginInfo data("kdevadaproject");
46
K_EXPORT_COMPONENT_FACTORY( libkdevadaproject, AdaProjectFactory( data ) )
48
AdaProjectPart::AdaProjectPart(QObject *parent, const char *name, const QStringList& )
49
:KDevBuildTool(&data, parent, name ? name : "AdaProjectPart" )
51
setInstance(AdaProjectFactory::instance());
52
setXMLFile("kdevadaproject.rc");
55
action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8,
56
this, SLOT(slotBuild()),
57
actionCollection(), "build_build" );
58
action = new KAction( i18n("Execute Program"), "exec", 0,
59
this, SLOT(slotExecute()),
60
actionCollection(), "build_execute" );
62
connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)),
63
this, SLOT(projectConfigWidget(KDialogBase*)) );
65
connect( core(), SIGNAL(configWidget(KDialogBase*)),
66
this, SLOT(configWidget(KDialogBase*)) );
68
// m_widget = new AdaProjectWidget(this);
70
// QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?"));
72
// now you decide what should happen to the widget. Take a look at kdevcore.h
73
// or at other plugins how to embed it.
75
// if you want to embed your widget as an outputview, simply uncomment
76
// the following line.
78
// mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" );
82
AdaProjectPart::~AdaProjectPart()
88
* This should really be merged with FileTreeWidget::matchesHidePattern()
89
* and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp
91
static bool matchesPattern(const QString &fileName, const QStringList &patternList)
93
QStringList::ConstIterator it;
94
for (it = patternList.begin(); it != patternList.end(); ++it) {
95
QRegExp re(*it, true, true);
96
if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length())
103
void AdaProjectPart::openProject(const QString &dirName, const QString &projectName)
105
m_buildDir = dirName;
106
m_projectDir = dirName;
107
m_projectName = projectName;
109
QDomDocument &dom = *projectDom();
110
// Set the default directory radio to "executable"
111
if (DomUtil::readEntry(dom, "/kdevadaproject/run/directoryradio") == "" ) {
112
DomUtil::writeEntry(dom, "/kdevadaproject/run/directoryradio", "executable");
117
// Put all files from all subdirectories into file list
118
QValueStack<QString> s;
119
int prefixlen = m_projectDir.length()+1;
120
s.push(m_projectDir);
122
QStringList includepatternList;
124
if ( languageSupport() )
126
KMimeType::List list = languageSupport()->mimeTypes();
127
KMimeType::List::Iterator it = list.begin();
128
while( it != list.end() ){
129
includepatternList += (*it)->patterns();
134
QString excludepatterns = "*~";
135
QStringList excludepatternList = QStringList::split(",", excludepatterns);
139
dir.setPath(s.pop());
140
kdDebug() << "AdaProjectPart::openProject examining: " << dir.path() << endl;
141
const QFileInfoList *dirEntries = dir.entryInfoList();
145
QPtrListIterator<QFileInfo> it(*dirEntries);
146
for (; it.current(); ++it) {
147
QString fileName = it.current()->fileName();
148
if (fileName == "." || fileName == "..")
150
QString path = it.current()->absFilePath();
151
if (it.current()->isDir()) {
152
kdDebug() << "AdaProjectPart::openProject pushing: " << path << endl;
156
if (matchesPattern(path, includepatternList)
157
&& !matchesPattern(path, excludepatternList)) {
158
kdDebug() << "AdaProjectPart::openProject adding: " << path << endl;
159
m_sourceFiles.append(path.mid(prefixlen));
161
kdDebug() << "AdaProjectPart::openProject ignoring: " << path << endl;
165
} while (!s.isEmpty());
167
KDevProject::openProject( dirName, projectName );
170
void AdaProjectPart::closeProject()
174
/** Retuns a PairList with the run environment variables */
175
DomUtil::PairList AdaProjectPart::runEnvironmentVars() const
177
return DomUtil::readPairListEntry(*projectDom(), "/kdevadaproject/run/envvars", "envvar", "name", "value");
181
/** Retuns the currently selected run directory
182
* The returned string can be:
183
* if run/directoryradio == executable
184
* The directory where the executable is
185
* if run/directoryradio == build
186
* The directory where the executable is relative to build directory
187
* if run/directoryradio == custom
188
* The custom directory absolute path
190
QString AdaProjectPart::runDirectory() const
192
return defaultRunDirectory("kdevadaproject");
196
/** Retuns the currently selected main program
197
* The returned string can be:
198
* if run/directoryradio == executable
199
* The executable name
200
* if run/directoryradio == build
201
* The path to executable relative to build directory
202
* if run/directoryradio == custom or relative == false
203
* The absolute path to executable
205
QString AdaProjectPart::mainProgram(bool relative) const
207
QFileInfo fi(mainSource());
208
return buildDirectory() + "/" + fi.baseName();
210
/// \FIXME put the code below into use!
211
QDomDocument &dom = *projectDom();
213
QString directoryRadioString = DomUtil::readEntry(dom, "/kdevadaproject/run/directoryradio");
214
QString DomMainProgram = DomUtil::readEntry(dom, "/kdevadaproject/run/mainprogram");
216
if ( directoryRadioString == "custom" )
217
return DomMainProgram;
219
if ( relative == false )
220
return buildDirectory() + "/" + DomMainProgram;
222
if ( directoryRadioString == "executable" ) {
223
int pos = DomMainProgram.findRev('/');
225
return DomMainProgram.mid(pos+1);
226
return DomMainProgram;
229
return DomMainProgram;
233
/** Retuns a QString with the run command line arguments */
234
QString AdaProjectPart::runArguments() const
236
return DomUtil::readEntry(*projectDom(), "/kdevadaproject/run/programargs");
239
QString AdaProjectPart::mainSource() const
241
return projectDirectory() + "/" + m_mainSource;
244
void AdaProjectPart::setMainSource(QString fullPath)
246
m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),"");
249
QString AdaProjectPart::projectDirectory() const
254
QString AdaProjectPart::projectName() const
256
return m_projectName;
259
QString AdaProjectPart::activeDirectory() const
261
QFileInfo fi(mainSource());
262
return fi.dirPath(true).replace(QRegExp(projectDirectory()),"");
265
QString AdaProjectPart::buildDirectory() const
267
QFileInfo fi(mainSource());
268
return fi.dirPath(true);
271
void AdaProjectPart::listOfFiles(QStringList &result, QString path) const
277
const QFileInfoList *entries = d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden);
281
QFileInfoListIterator it( *entries );
282
while( const QFileInfo* fileInfo = it.current() )
286
if (fileInfo->isDir() && fileInfo->filePath() != path)
288
kdDebug() << "entering dir " << fileInfo->dirPath() << endl;
289
listOfFiles(result, fileInfo->dirPath());
293
kdDebug() << "adding to result: " << fileInfo->filePath() << endl;
294
result << fileInfo->filePath();
299
QStringList AdaProjectPart::allFiles() const
301
// QStringList files;
303
// listOfFiles(files, projectDirectory());
306
return m_sourceFiles;
309
void AdaProjectPart::addFile(const QString& /*fileName*/)
313
void AdaProjectPart::addFiles(const QStringList& /*fileList*/)
317
void AdaProjectPart::removeFile(const QString& /*fileName*/)
321
void AdaProjectPart::removeFiles(const QStringList& /*fileList*/)
325
void AdaProjectPart::slotBuild()
327
if (partController()->saveAllFiles()==false)
328
return; //user cancelled
330
QString cmdline = m_compilerExec + " " + m_compilerOpts + " ";
332
if (cmdline.isEmpty())
334
KMessageBox::sorry(0, i18n("Could not find ada compiler.\nCheck if your compiler settings are correct."));
338
QFileInfo fi(mainSource());
339
cmdline += fi.fileName();
341
QString dircmd = "cd ";
342
dircmd += KProcess::quote(buildDirectory());
345
makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline);
348
void AdaProjectPart::slotExecute()
350
partController()->saveAllFiles();
351
QString program = "./";
352
appFrontend()->startAppCommand(buildDirectory(), mainProgram(), true);
355
void AdaProjectPart::changedFiles( const QStringList & fileList )
357
KDevProject::changedFiles(fileList);
360
void AdaProjectPart::changedFile( const QString & fileName )
362
KDevProject::changedFile(fileName);
365
void AdaProjectPart::projectConfigWidget( KDialogBase * dlg )
368
vbox = dlg->addVBoxPage(i18n("Ada Compiler"));
369
AdaProjectOptionsDlg *w = new AdaProjectOptionsDlg(this, vbox);
370
connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) );
371
connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) );
374
void AdaProjectPart::loadProjectConfig( )
376
QDomDocument &dom = *(projectDom());
378
QString config = DomUtil::readEntry(dom, "/kdevadaproject/general/useconfiguration", "default");
379
m_mainSource = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/mainsource") );
380
m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compileroptions"));
381
m_compilerExec = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compilerexec"));
383
if (m_compilerExec.isEmpty())
385
KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'");
386
QValueList<KService::Ptr>::ConstIterator it;
387
for (it = offers.begin(); it != offers.end(); ++it) {
388
if ((*it)->property("X-KDevelop-Default").toBool()) {
389
m_compilerExec = (*it)->exec();
396
void AdaProjectPart::configWidget( KDialogBase * dlg )
399
vbox = dlg->addVBoxPage(i18n("Ada Compiler"));
400
AdaGlobalOptionsDlg *w = new AdaGlobalOptionsDlg(this, vbox);
401
connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) );
404
KDevCompilerOptions *AdaProjectPart::createCompilerOptions(const QString &name)
406
KService::Ptr service = KService::serviceByDesktopName(name);
408
kdDebug() << "AdaProjectPart::createCompilerOptions can't find service " << name;
412
KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library()));
414
QString errorMessage = KLibLoader::self()->lastErrorMessage();
415
KMessageBox::error(0, i18n("There was an error loading the module %1.\n"
416
"The diagnostics are:\n%2").arg(service->name()).arg(errorMessage));
421
QVariant prop = service->property("X-KDevelop-Args");
423
args = QStringList::split(" ", prop.toString());
425
QObject *obj = factory->create(this, service->name().latin1(),
426
"KDevCompilerOptions", args);
428
if (!obj->inherits("KDevCompilerOptions")) {
429
kdDebug() << "AdaProjectPart::createCompilerOptions: component does not inherit KDevCompilerOptions" << endl;
432
KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj;
437
QString AdaProjectPart::defaultOptions( const QString compiler )
439
KConfig *config = KGlobal::config();
440
config->setGroup("Ada Compiler");
441
return config->readPathEntry(compiler);
444
#include "adaproject_part.moc"
448
\fn AdaProjectPart::distFiles() const
450
QStringList AdaProjectPart::distFiles() const
452
QStringList sourceList = allFiles();
453
// Scan current source directory for any .pro files.
454
QString projectDir = projectDirectory();
455
QDir dir(projectDir);
456
QStringList files = dir.entryList( "Makefile");
457
return sourceList + files;