00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#include <qdom.h>
00019
#include <qfileinfo.h>
00020
#include <qdir.h>
00021
#include <qvaluestack.h>
00022
#include <qregexp.h>
00023
#include <qvbox.h>
00024
#include <qlabel.h>
00025
00026
#include <kiconloader.h>
00027
#include <klocale.h>
00028
#include <kaction.h>
00029
#include <kgenericfactory.h>
00030
#include <kdebug.h>
00031
#include <kdialogbase.h>
00032
#include <kmessagebox.h>
00033
#include <klibloader.h>
00034
#include <kservice.h>
00035
#include <kconfig.h>
00036
#include <kdeversion.h>
00037
#include <kprocess.h>
00038
#include <ktrader.h>
00039
00040
#include "domutil.h"
00041
#include "kdevcore.h"
00042
#include "kdevmainwindow.h"
00043
#include "kdevmakefrontend.h"
00044
#include "kdevappfrontend.h"
00045
#include "kdevpartcontroller.h"
00046
#include "kdevlanguagesupport.h"
00047
#include "kdevcompileroptions.h"
00048
#include "runoptionswidget.h"
00049
#include "haskellprojectoptionsdlg.h"
00050
#include "haskellproject_part.h"
00051
00052 typedef KGenericFactory<HaskellProjectPart> HaskellProjectFactory;
00053 K_EXPORT_COMPONENT_FACTORY( libkdevhaskellproject,
HaskellProjectFactory(
"kdevhaskellproject" ) )
00054
00055
00056
HaskellProjectPart::
HaskellProjectPart(
QObject *parent, const
char *name, const
QStringList& )
00057 :
KDevProject("KDevPart", "kdevpart", parent, name ? name : "
HaskellProjectPart" )
00058 {
00059 setInstance(HaskellProjectFactory::instance());
00060 setXMLFile(
"kdevhaskellproject.rc");
00061
00062
00063
00064 _buildAction =
new KAction( i18n(
"&Build Project"),
"make_kdevelop", Key_F8,
00065
this, SLOT(slotBuild()),
00066 actionCollection(),
"build_build" );
00067 _runAction =
new KAction( i18n(
"Execute Program"),
"exec", 0,
00068
this, SLOT(slotExecute()),
00069 actionCollection(),
"build_execute" );
00070
00071 connect( core(), SIGNAL( projectConfigWidget(
KDialogBase* ) ),
00072
this, SLOT( projectConfigWidget(
KDialogBase* ) ) );
00073
00074 connect( core(), SIGNAL( configWidget(
KDialogBase* ) ),
00075
this, SLOT( configWidget(
KDialogBase* ) ) );
00076 }
00077
00078
00079 HaskellProjectPart::~HaskellProjectPart()
00080 {
00081
00082 }
00083
00084
00085 void HaskellProjectPart::openProject(
const QString &dirName,
const QString &projectName)
00086 {
00087
_buildDir = dirName;
00088
_projectDir = dirName;
00089
_projectName = projectName;
00090
loadProjectConfig();
00091
QDomDocument &dom = *
projectDom();
00092
QString directoryRadioString = DomUtil::readEntry( dom,
00093
"/kdevhaskellproject/run/directoryradio" );
00094
QString mainProgram = DomUtil::readEntry( dom,
00095
"/kdevhaskellproject/run/mainprogram" );
00096
QString customDir = DomUtil::readEntry( dom,
00097
"/kdevhaskellproject/run/customdirectory" );
00098 }
00099
00100 void HaskellProjectPart::closeProject()
00101 {
00102 }
00103
00104
00105 QString HaskellProjectPart::projectDirectory()
const
00106
{
00107
return _projectDir;
00108 }
00109
00110 QString HaskellProjectPart::projectName()
const
00111
{
00112
return _projectName;
00113 }
00114
00116 DomUtil::PairList HaskellProjectPart::runEnvironmentVars()
const
00117
{
00118
return DomUtil::readPairListEntry(*
projectDom(),
00119
"/kdevhaskellproject/run/envvars",
00120
"envvar",
"name",
"value");
00121 }
00122
00132 QString HaskellProjectPart::mainProgram(
bool relative )
const
00133
{
00134
QString progName;
00135
QDomDocument &dom = *
projectDom();
00136
QString directoryRadioString = DomUtil::readEntry( dom,
00137
"/kdevhaskellproject/run/directoryradio" );
00138
QString mainProgram = DomUtil::readEntry( dom,
00139
"/kdevhaskellproject/run/mainprogram" );
00140
00141
if( mainProgram.isEmpty() ) {
00142
QFileInfo fileInfo(
mainSource() );
00143 progName =
buildDirectory() +
"/" + fileInfo.baseName();
00144
if( relative ) {
00145
return fileInfo.baseName();
00146 }
00147
else {
00148
return buildDirectory() +
"/" + fileInfo.baseName();
00149 }
00150 }
00151
else {
00152
if( directoryRadioString ==
"custom" ) {
00153
if( relative ) {
00154
return( mainProgram );
00155 }
00156
else {
00157
QString customDir = DomUtil::readEntry( dom,
00158
"/kdevhaskellproject/run/customdirectory" );
00159
return( customDir +
'/' + mainProgram );
00160 }
00161 }
00162
else if( directoryRadioString ==
"build" ) {
00163
if( relative ) {
00164
return( mainProgram );
00165 }
00166 }
00167 }
00168
return QString::fromLatin1(
"");
00169 }
00170
00171 QString HaskellProjectPart::runDirectory()
const
00172
{
00173
QDomDocument &dom = *
projectDom();
00174
00175
QString directoryRadioString = DomUtil::readEntry(dom,
"/kdevhaskellproject/run/directoryradio");
00176
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevhaskellproject/run/mainprogram");
00177
00178
if ( directoryRadioString ==
"build" )
00179
return buildDirectory();
00180
00181
if ( directoryRadioString ==
"custom" )
00182
return DomUtil::readEntry(dom,
"/kdevhaskellproject/run/customdirectory");
00183
00184
int pos = DomMainProgram.findRev(
'/');
00185
if (pos != -1)
00186
return buildDirectory() +
"/" + DomMainProgram.left(pos);
00187
00188
return buildDirectory() +
"/" + DomMainProgram;
00189 }
00190
00192 QString HaskellProjectPart::runArguments()
const
00193
{
00194
return DomUtil::readEntry(*
projectDom(),
"/kdevhaskellproject/run/programargs");
00195 }
00196
00197 QString HaskellProjectPart::activeDirectory()
const
00198
{
00199
QFileInfo fi(
mainSource());
00200
00201
return fi.dirPath(
true).replace(
QRegExp(
projectDirectory()),
"");
00202 }
00203
00204 QString HaskellProjectPart::buildDirectory()
const
00205
{
00206
QFileInfo fi(
mainSource());
00207
return fi.dirPath(
true);
00208 }
00209
00210 QStringList HaskellProjectPart::allFiles()
const
00211
{
00212
return _sourceFiles;
00213 }
00214
00215 void HaskellProjectPart::addFiles(
const QStringList& )
00216 {
00217 }
00218
00219
00220 void HaskellProjectPart::addFile(
const QString& )
00221 {
00222 }
00223
00224 void HaskellProjectPart::removeFiles(
const QStringList& )
00225 {
00226 }
00227
00228 void HaskellProjectPart::removeFile(
const QString& )
00229 {
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 QString HaskellProjectPart::mainSource()
const
00247
{
00248
return projectDirectory() +
"/" +
_mainSource;
00249 }
00250
00251 void HaskellProjectPart::setMainSource(
QString fullPath)
00252 {
00253
_mainSource = fullPath.replace(
QRegExp(
QString(
projectDirectory() +
QString(
"/"))),
"");
00254 }
00255
00256
00257
00258 void HaskellProjectPart::listOfFiles(
QStringList &result,
QString path)
00259 {
00260
QDir d(path);
00261
if (!d.exists())
00262
return;
00263
00264 QFileInfoList *entries = const_cast<QFileInfoList*>(d.entryInfoList(QDir::Dirs |
00265 QDir::Files | QDir::Hidden));
00266
for (
QFileInfo *it = entries->first(); it; it = entries->next()) {
00267
if ((it->isDir()) && (!(it->filePath() == path))) {
00268
listOfFiles(result, it->dirPath());
00269 }
00270
else
00271 {
00272 result << it->filePath();
00273 }
00274 }
00275 }
00276
00277 QString HaskellProjectPart::createPackageString()
00278 {
00279
00280
return "";
00281 }
00282
00283 QString HaskellProjectPart::createCmdLine(
QString srcFile)
00284 {
00285
00286
00287
QString cmdLine =
_compilerExec +
" " +
createPackageString() +
" " + srcFile +
" "
00288 +
_compilerOpts +
" -o " +
mainProgram();
00289
QString dirCmd =
"cd ";
00290 dirCmd +=
buildDirectory();
00291 dirCmd +=
" && ";
00292
return dirCmd + cmdLine;
00293 }
00294
00295 void HaskellProjectPart::slotBuild()
00296 {
00297
partController()->
saveAllFiles();
00298
00299
if (
_compilerExec.isEmpty()) {
00300 KMessageBox::sorry(0, i18n(
"Could not find the Haskell Translator.\nCheck if your settings are correct."));
00301
return;
00302 }
00303
00304
QString cmdline =
createCmdLine(
QFileInfo(
mainSource() ).fileName() );
00305
makeFrontend()->
queueCommand(
buildDirectory(), cmdline );
00306 }
00307
00308 void HaskellProjectPart::slotExecute()
00309 {
00310
partController()->
saveAllFiles();
00311
00312
QDomDocument &dom = *(
projectDom());
00313
bool runInTerminal = DomUtil::readBoolEntry(dom,
"/kdevhaskellproject/run/terminal",
true);
00314
00315
00316
00317
00318
00319
DomUtil::PairList envvars = DomUtil::readPairListEntry( *
projectDom(),
00320
"/kdevhaskellproject/run/envvars",
00321
"envvar",
"name",
"value");
00322
QString environstr;
00323 DomUtil::PairList::ConstIterator it;
00324
for (it = envvars.begin(); it != envvars.end(); ++it) {
00325 environstr += (*it).first;
00326 environstr +=
"=";
00327
#if (KDE_VERSION > 305)
00328
environstr += KProcess::quote((*it).second);
00329
#else
00330
environstr += KShellProcess::quote((*it).second);
00331
#endif
00332
environstr +=
" ";
00333 }
00334
00335
QString program =
mainProgram();
00336 program.prepend( environstr );
00337 program +=
" " + DomUtil::readEntry(*
projectDom(),
00338
"/kdevhaskellproject/run/programargs" );
00339
00340
appFrontend()->
startAppCommand(
buildDirectory(), program, runInTerminal);
00341 }
00342
00343 void HaskellProjectPart::changedFiles(
const QStringList & fileList )
00344 {
00345 KDevProject::changedFiles( fileList );
00346 }
00347
00348 void HaskellProjectPart::changedFile(
const QString & fileName )
00349 {
00350 KDevProject::changedFile( fileName );
00351 }
00352
00353 void HaskellProjectPart::projectConfigWidget(
KDialogBase * dlg )
00354 {
00355
QVBox *vbox;
00356 vbox = dlg->
addVBoxPage( i18n(
"Haskell Options") );
00357
HaskellProjectOptionsDlg *optionsDlg =
new HaskellProjectOptionsDlg(
this, vbox );
00358
00359 connect( dlg, SIGNAL( okClicked() ),
00360 optionsDlg, SLOT( accept() ) );
00361
00362 connect( dlg, SIGNAL( okClicked() ),
00363
this, SLOT(
loadProjectConfig() ) );
00364
00365 vbox = dlg->
addVBoxPage( i18n(
"Run Options" ) );
00366
RunOptionsWidget *w3 =
new RunOptionsWidget( *
projectDom(),
00367
"/kdevhaskellproject",
buildDirectory(), vbox );
00368 w3->
mainprogram_label->setText( i18n(
"Main program (relative to project directory):" ) );
00369 connect( dlg, SIGNAL(okClicked()),
00370 w3, SLOT( accept() ) );
00371 }
00372
00373 void HaskellProjectPart::loadProjectConfig()
00374 {
00375
QDomDocument &dom = *(
projectDom());
00376
00377
QString config = DomUtil::readEntry(dom,
00378
"/kdevhaskellproject/general/useconfiguration",
00379
"default");
00380
_mainSource = DomUtil::readEntry(dom,
00381
QString(
"/kdevhaskellproject/configurations/") +
00382 config +
QString(
"/mainsource") );
00383
_compilerOpts = DomUtil::readEntry(dom,
00384
QString(
"/kdevhaskellproject/configurations/") +
00385 config +
QString(
"/compileroptions"));
00386
_compilerExec = DomUtil::readEntry(dom,
00387
QString(
"/kdevhaskellproject/configurations/") +
00388 config +
QString(
"/compilerexec"));
00389
00390
if (
_compilerExec.isEmpty() ) {
00391 KTrader::OfferList offers = KTrader::self()->query(
"KDevelop/CompilerOptions",
"[X-KDevelop-Language] == 'Haskell'");
00392
QValueList<KService::Ptr>::ConstIterator it;
00393
for (it = offers.begin(); it != offers.end(); ++it) {
00394
if ( (*it)->property(
"X-KDevelop-Default" ).toBool() ) {
00395
_compilerExec = (*it)->exec();
00396
break;
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405 }
00406
00407 void HaskellProjectPart::configWidget(
KDialogBase * dlg )
00408 {
00409
00410
00411
00412
00413
00414 }
00415
00416 KDevCompilerOptions *
HaskellProjectPart::createCompilerOptions(
const QString &name)
00417 {
00418
KService::Ptr service = KService::serviceByName( name );
00419
if ( !service ) {
00420
kdDebug() <<
"Can't find service " << name;
00421
return 0;
00422 }
00423
00424
KLibFactory *factory =
KLibLoader::self()->
factory(QFile::encodeName(service->library()));
00425
if (!factory) {
00426
QString errorMessage =
KLibLoader::self()->
lastErrorMessage();
00427 KMessageBox::error(0, i18n(
"There was an error loading the module %1.\n"
00428
"The diagnostics is:\n%2").arg(service->name()).arg(errorMessage));
00429 exit(1);
00430 }
00431
00432
QStringList args;
00433
QVariant prop = service->property(
"X-KDevelop-Args");
00434
if (prop.isValid())
00435 args = QStringList::split(
" ", prop.toString());
00436
00437
QObject *obj = factory->
create(
this, service->name().latin1(),
00438
"KDevCompilerOptions", args);
00439
00440
if (!obj->inherits(
"KDevCompilerOptions")) {
00441
kdDebug() <<
"Component does not inherit KDevCompilerOptions" <<
endl;
00442
return 0;
00443 }
00444
KDevCompilerOptions *dlg = (
KDevCompilerOptions*)obj;
00445
00446
return dlg;
00447 }
00448
00449 QString HaskellProjectPart::defaultOptions(
const QString compiler )
00450 {
00451
KConfig *config =
KGlobal::config();
00452 config->
setGroup(
"Haskell Compiler");
00453
kdDebug(9000) <<
"*********** " << config->
readPathEntry( compiler ) <<
"::" <<
endl;
00454
return config->
readPathEntry(compiler);
00455 }
00456
00457 QString HaskellProjectPart::mainProgram()
00458 {
00459
QDomDocument &dom = *
projectDom();
00460
QString configMainProg = DomUtil::readEntry(dom,
"/kdevhaskellproject/run/mainprogram",
"");
00461
if (configMainProg.isEmpty())
00462 {
00463
QFileInfo fi(
mainSource());
00464
return buildDirectory() +
"/" + fi.baseName();
00465 }
00466
else
00467
return QDir::cleanDirPath(
projectDirectory() +
"/" + configMainProg);
00468 }