00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <config.h>
00016
00017
#include "autoprojectpart.h"
00018
#include "autolistviewitems.h"
00019
#include "configureoptionswidget.h"
00020
#include "addtranslationdlg.h"
00021
#include "addicondlg.h"
00022
#include "autoprojectwidget.h"
00023
00024
#include <qdom.h>
00025
#include <qdir.h>
00026
#include <qfileinfo.h>
00027
#include <qpopupmenu.h>
00028
#include <qstringlist.h>
00029
#include <qwhatsthis.h>
00030
#include <qregexp.h>
00031
#include <qgroupbox.h>
00032
00033
#include <kaction.h>
00034
#include <kdebug.h>
00035
#include <kdialogbase.h>
00036
#include <kiconloader.h>
00037
#include <klocale.h>
00038
#include <kmessagebox.h>
00039
#include <kparts/part.h>
00040
#include <kdeversion.h>
00041
#include <kprocess.h>
00042
00043
#include <domutil.h>
00044
#include <kdevcore.h>
00045
#include <kdevmakefrontend.h>
00046
#include <kdevappfrontend.h>
00047
#include <kdevmainwindow.h>
00048
#include <kdevpartcontroller.h>
00049
#include <makeoptionswidget.h>
00050
#include <runoptionswidget.h>
00051
#include <envvartools.h>
00052
00053
#include <configwidgetproxy.h>
00054
00055 #define CONFIGURE_OPTIONS 1
00056 #define RUN_OPTIONS 2
00057 #define MAKE_OPTIONS 3
00058
00059
static const KAboutData data(
"kdevautoproject",
I18N_NOOP(
"Automake Manager"),
"1.0");
00060
00061 K_EXPORT_COMPONENT_FACTORY( libkdevautoproject,
AutoProjectFactory( &data ) )
00062
00063
AutoProjectPart::
AutoProjectPart(
QObject *parent, const
char *name, const
QStringList &args)
00064 :
KDevProject("AutoProject", "autoproject", parent, name ? name : "
AutoProjectPart")
00065 , m_lastCompilationFailed(false)
00066 {
00067 setInstance(AutoProjectFactory::instance());
00068
00069 setXMLFile(
"kdevautoproject.rc");
00070
00071 m_executeAfterBuild =
false;
00072 m_isKDE = (args[0] ==
"kde");
00073 m_needMakefileCvs =
false;
00074
00075 m_widget =
new AutoProjectWidget(
this, m_isKDE);
00076 m_widget->setIcon(SmallIcon(
"make"));
00077 m_widget->setCaption(i18n(
"Automake Manager"));
00078 QWhatsThis::add(m_widget, i18n(
"<b>Automake manager</b><p>"
00079
"The project tree consists of two parts. The 'overview' "
00080
"in the upper half shows the subprojects, each one having a "
00081
"Makefile.am. The 'details' view in the lower half shows the "
00082
"targets and files for the subproject selected in the overview."));
00083
00084 mainWindow()->embedSelectViewRight(m_widget, i18n(
"Automake Manager"), i18n(
"Automake manager"));
00085
00086
KAction *action;
00087
00088 action =
new KAction( i18n(
"Add Translation..."), 0,
00089
this, SLOT(slotAddTranslation()),
00090 actionCollection(),
"project_addtranslation" );
00091 action->setToolTip(i18n(
"Add translation"));
00092 action->setWhatsThis(i18n(
"<b>Add translation</b><p>Creates .po file for the selected language."));
00093 action->setGroup(
"autotools");
00094
00095
00096
00097
00098
00099
00100
if (!m_isKDE)
00101 action->setEnabled(
false);
00102
00103 action =
new KAction( i18n(
"&Build Project"),
"make_kdevelop", Key_F8,
00104
this, SLOT(slotBuild()),
00105 actionCollection(),
"build_build" );
00106 action->setToolTip(i18n(
"Build project"));
00107 action->setWhatsThis(i18n(
"<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>"
00108
"Environment variables and make arguments can be specified "
00109
"in the project settings dialog, <b>Make Options</b> tab."));
00110 action->setGroup(
"autotools");
00111
00112 action =
new KAction( i18n(
"Build &Active Target"),
"make_kdevelop", Key_F7,
00113
this, SLOT(slotBuildActiveTarget()),
00114 actionCollection(),
"build_buildactivetarget" );
00115 action->setToolTip(i18n(
"Build active target"));
00116 action->setWhatsThis(i18n(
"<b>Build active target</b><p>Constructs a series of make commands to build an active target. "
00117
"Also builds dependent targets.<br>"
00118
"Environment variables and make arguments can be specified "
00119
"in the project settings dialog, <b>Make Options</b> tab."));
00120 action->setGroup(
"autotools");
00121
00122 action =
new KAction( i18n(
"Compile &File"),
"make_kdevelop",
00123
this, SLOT(slotCompileFile()),
00124 actionCollection(),
"build_compilefile" );
00125 action->setToolTip(i18n(
"Compile file"));
00126 action->setWhatsThis(i18n(
"<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>"
00127
"Environment variables and make arguments can be specified "
00128
"in the project settings dialog, <b>Make Options</b> tab."));
00129 action->setGroup(
"autotools");
00130
00131 action =
new KAction( i18n(
"Run Configure"), 0,
00132
this, SLOT(slotConfigure()),
00133 actionCollection(),
"build_configure" );
00134 action->setToolTip(i18n(
"Run configure"));
00135 action->setWhatsThis(i18n(
"<b>Run configure</b><p>Executes <b>configure</b> with flags, arguments "
00136
"and environment variables specified in the project settings dialog, "
00137
"<b>Configure Options</b> tab."));
00138 action->setGroup(
"autotools");
00139
00140 action =
new KAction( i18n(
"Run automake && friends"), 0,
00141
this, SLOT(slotMakefilecvs()),
00142 actionCollection(),
"build_makefilecvs" );
00143 action->setToolTip(i18n(
"Run automake && friends"));
00144 action->setWhatsThis(i18n(
"<b>Run automake && friends</b><p>Executes<br><b>make -f Makefile.cvs</b><br><b>./configure</b><br>commands from the project directory."));
00145 action->setGroup(
"autotools");
00146
00147 action =
new KAction( i18n(
"Install"), 0,
00148
this, SLOT(slotInstall()),
00149 actionCollection(),
"build_install" );
00150 action->setToolTip(i18n(
"Install"));
00151 action->setWhatsThis(i18n(
"<b>Install</b><p>Runs <b>make install</b> command from the project directory.<br>"
00152
"Environment variables and make arguments can be specified "
00153
"in the project settings dialog, <b>Make Options</b> tab."));
00154 action->setGroup(
"autotools");
00155
00156 action =
new KAction( i18n(
"Install (as root user)"), 0,
00157
this, SLOT(slotInstallWithKdesu()),
00158 actionCollection(),
"build_install_kdesu" );
00159 action->setToolTip(i18n(
"Install as root user"));
00160 action->setWhatsThis(i18n(
"<b>Install</b><p>Runs <b>make install</b> command from the project directory with root privileges.<br>"
00161
"It is executed via kdesu command.<br>"
00162
"Environment variables and make arguments can be specified "
00163
"in the project settings dialog, <b>Make Options</b> tab."));
00164 action->setGroup(
"autotools");
00165
00166 action =
new KAction( i18n(
"&Clean Project"), 0,
00167
this, SLOT(slotClean()),
00168 actionCollection(),
"build_clean" );
00169 action->setToolTip(i18n(
"Clean project"));
00170 action->setWhatsThis(i18n(
"<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>"
00171
"Environment variables and make arguments can be specified "
00172
"in the project settings dialog, <b>Make Options</b> tab."));
00173 action->setGroup(
"autotools");
00174
00175 action =
new KAction( i18n(
"&Distclean"), 0,
00176
this, SLOT(slotDistClean()),
00177 actionCollection(),
"build_distclean" );
00178 action->setToolTip(i18n(
"Distclean"));
00179 action->setWhatsThis(i18n(
"<b>Distclean</b><p>Runs <b>make distclean</b> command from the project directory.<br>"
00180
"Environment variables and make arguments can be specified "
00181
"in the project settings dialog, <b>Make Options</b> tab."));
00182 action->setGroup(
"autotools");
00183
00184 action =
new KAction( i18n(
"Make Messages && Merge"), 0,
00185
this, SLOT(slotMakeMessages()),
00186 actionCollection(),
"build_messages" );
00187 action->setToolTip(i18n(
"Make messages && merge"));
00188 action->setWhatsThis(i18n(
"<b>Make messages && merge</b><p>Runs <b>make package-messages</b> command from the project directory.<br>"
00189
"Environment variables and make arguments can be specified "
00190
"in the project settings dialog, <b>Make Options</b> tab."));
00191 action->setGroup(
"autotools");
00192
00193
if (!m_isKDE)
00194 action->setEnabled(
false);
00195
00196 buildConfigAction =
new KSelectAction( i18n(
"Build Configuration"), 0,
00197 actionCollection(),
"project_configuration" );
00198 buildConfigAction->setToolTip(i18n(
"Build configuration menu"));
00199 buildConfigAction->setWhatsThis(i18n(
"<b>Build configuration menu</b><p>Allows to switch between project build configurations.<br>"
00200
"Build configuration is a set of build and top source directory settings, "
00201
"configure flags and arguments, compiler flags, etc.<br>"
00202
"Modify build configurations in project settings dialog, <b>Configure Options</b> tab."));
00203 buildConfigAction->setGroup(
"autotools");
00204
00205
QDomDocument &dom = *projectDom();
00206
if (!DomUtil::readBoolEntry(dom,
"/kdevautoproject/run/disable_default")) {
00207
00208 action =
new KAction( i18n(
"Execute Program"),
"exec", SHIFT+Key_F9,
00209
this, SLOT(slotExecute()),
00210 actionCollection(),
"build_execute" );
00211 action->setToolTip(i18n(
"Execute program"));
00212 action->setWhatsThis(i18n(
"<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab. "
00213
"If it is not specified then the active target is used to determine the application to run."));
00214 action->setGroup(
"autotools");
00215 }
00216
00217 connect( buildConfigAction, SIGNAL(activated(
const QString&)),
00218
this, SLOT(slotBuildConfigChanged(
const QString&)) );
00219 connect( buildConfigAction->popupMenu(), SIGNAL(aboutToShow()),
00220
this, SLOT(slotBuildConfigAboutToShow()) );
00221
00222
00223
00224 _configProxy =
new ConfigWidgetProxy( core() );
00225 _configProxy->createProjectConfigPage( i18n(
"Configure Options"),
CONFIGURE_OPTIONS );
00226 _configProxy->createProjectConfigPage( i18n(
"Run Options"),
RUN_OPTIONS );
00227 _configProxy->createProjectConfigPage( i18n(
"Make Options"),
MAKE_OPTIONS );
00228 connect( _configProxy, SIGNAL(insertConfigWidget(
const KDialogBase*,
QWidget*,
unsigned int )),
this, SLOT(insertConfigWidget(
const KDialogBase*,
QWidget*,
unsigned int )) );
00229
00230
00231 connect( makeFrontend(), SIGNAL(commandFinished(
const QString&)),
00232
this, SLOT(slotCommandFinished(
const QString&)) );
00233 connect( makeFrontend(), SIGNAL(commandFailed(
const QString&)),
00234
this, SLOT(slotCommandFailed(
const QString&)) );
00235
00236 setWantautotools();
00237 }
00238
00239
00240 AutoProjectPart::~AutoProjectPart()
00241 {
00242
if (
m_widget)
00243
mainWindow()->
removeView(
m_widget);
00244
delete m_widget;
00245
delete _configProxy;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 void AutoProjectPart::insertConfigWidget(
const KDialogBase* dlg,
QWidget * page,
unsigned int pagenumber )
00274 {
00275
switch ( pagenumber )
00276 {
00277
case CONFIGURE_OPTIONS:
00278 {
00279
ConfigureOptionsWidget *w2 =
new ConfigureOptionsWidget(
this, page );
00280 connect( dlg, SIGNAL(okClicked()), w2, SLOT(accept()) );
00281 }
00282
break;
00283
00284
case RUN_OPTIONS:
00285 {
00286
QDomDocument &dom = *
projectDom();
00287
if (!DomUtil::readBoolEntry(dom,
"/kdevautoproject/run/disable_default")) {
00288
00289
RunOptionsWidget *w3 =
new RunOptionsWidget(*
projectDom(),
"/kdevautoproject",
buildDirectory(), page );
00290 w3->
programGroupBox->setTitle(i18n(
"Program (if empty automatically uses active target and active target's arguments)"));
00291 connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) );
00292 }
00293 }
00294
break;
00295
00296
case MAKE_OPTIONS:
00297 {
00298
MakeOptionsWidget *w4 =
new MakeOptionsWidget(*
projectDom(),
"/kdevautoproject", page );
00299 connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) );
00300 }
00301
break;
00302 }
00303 }
00304
00305 void AutoProjectPart::openProject(
const QString &dirName,
const QString &projectName)
00306 {
00307
m_projectName = projectName;
00308
m_projectPath =dirName;
00309
00310
m_widget->openProject(dirName);
00311
00312
QDomDocument &dom = *
projectDom();
00313
QString activeTarget = DomUtil::readEntry(dom,
"/kdevautoproject/general/activetarget");
00314
kdDebug(9020) <<
"activeTarget " << activeTarget <<
endl;
00315
if (!activeTarget.isEmpty())
00316
m_widget->setActiveTarget(activeTarget);
00317
00318
00319
if (!DomUtil::readBoolEntry(dom,
"/kdevautoproject/run/disable_default") && DomUtil::readEntry(dom,
"/kdevautoproject/run/directoryradio") ==
"" ) {
00320 DomUtil::writeEntry(dom,
"/kdevautoproject/run/directoryradio",
"executable");
00321 }
00322
00323 KDevProject::openProject( dirName, projectName );
00324 }
00325
00326
00327 void AutoProjectPart::closeProject()
00328 {
00329
m_widget->closeProject();
00330 }
00331
00332
00333 QString AutoProjectPart::projectDirectory()
const
00334
{
00335
return m_projectPath;
00336 }
00337
00338
00339 QString AutoProjectPart::projectName()
const
00340
{
00341
return m_projectName;
00342 }
00343
00344
00346 DomUtil::PairList AutoProjectPart::runEnvironmentVars()
const
00347
{
00348
return DomUtil::readPairListEntry(*
projectDom(),
"/kdevautoproject/run/envvars",
"envvar",
"name",
"value");
00349 }
00350
00351
00363 QString AutoProjectPart::runDirectory()
const
00364
{
00365
QDomDocument &dom = *
projectDom();
00366
00367
QString directoryRadioString = DomUtil::readEntry(dom,
"/kdevautoproject/run/directoryradio");
00368
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevautoproject/run/mainprogram");
00369
00370
if ( directoryRadioString ==
"build" )
00371
return buildDirectory();
00372
00373
if ( directoryRadioString ==
"custom" )
00374
return DomUtil::readEntry(dom,
"/kdevautoproject/run/customdirectory");
00375
00376
if ( DomMainProgram.isEmpty() )
00377
00378
return buildDirectory() +
"/" +
activeDirectory();
00379
00380
00381
int pos = DomMainProgram.findRev(
'/');
00382
if (pos != -1)
00383
return buildDirectory() +
"/" + DomMainProgram.left(pos);
00384
return buildDirectory() +
"/" + DomMainProgram;
00385 }
00386
00387
00399 QString AutoProjectPart::mainProgram(
bool relative)
const
00400
{
00401
QDomDocument &dom = *
projectDom();
00402
00403
QString directoryRadioString = DomUtil::readEntry(dom,
"/kdevautoproject/run/directoryradio");
00404
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevautoproject/run/mainprogram");
00405
00406
if ( DomMainProgram.isEmpty() ) {
00407
00408
00409
00410
TargetItem* titem =
m_widget->activeTarget();
00411
00412
if ( !titem ) {
00413
kdDebug ( 9000 ) <<
"Error! : No Main Program was specified and there's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" <<
endl;
00414
return QString::null;
00415 }
00416
00417
if ( titem->
primary !=
"PROGRAMS" ) {
00418
kdDebug ( 9000 ) <<
"Error! : No Main Program was specified and active target isn't binary (" << titem->
primary <<
") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" <<
endl;
00419
return QString::null;
00420 }
00421
00422
if (relative ==
false || directoryRadioString ==
"custom")
00423
return buildDirectory() +
"/" +
activeDirectory() +
"/" + titem->
name;
00424
00425
if ( directoryRadioString ==
"executable" )
00426
return titem->
name;
00427
00428
return activeDirectory() +
"/" + titem->
name;
00429
00430 }
00431
else {
00432
00433
if ( directoryRadioString ==
"custom" )
00434
return DomMainProgram;
00435
00436
if ( relative ==
false )
00437
return buildDirectory() +
"/" + DomMainProgram;
00438
00439
if ( directoryRadioString !=
"executable" )
00440
return DomMainProgram;
00441
00442
int pos = DomMainProgram.findRev(
'/');
00443
if (pos != -1)
00444
return DomMainProgram.mid(pos+1);
00445
return DomMainProgram;
00446 }
00447 }
00448
00449
00451 QString AutoProjectPart::runArguments()
const
00452
{
00453
QDomDocument &dom = *
projectDom();
00454
00455
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevautoproject/run/mainprogram");
00456
QString DomProgramArguments = DomUtil::readEntry(*
projectDom(),
"/kdevautoproject/run/programargs");
00457
00458
if ( DomMainProgram.isEmpty() && DomProgramArguments.isEmpty() )
00459
00460
if (
m_widget->activeTarget())
00461
return DomUtil::readEntry(*
projectDom(),
"/kdevautoproject/run/runarguments/" +
m_widget->activeTarget()->name);
00462
else
00463
return QString::null;
00464
else
00465
return DomProgramArguments;
00466 }
00467
00468
00469 QString AutoProjectPart::activeDirectory()
const
00470
{
00471
return m_widget->activeDirectory();
00472 }
00473
00474
00475 QStringList AutoProjectPart::allFiles()
const
00476
{
00477
return m_widget->allFiles();
00478 }
00479
00480
00481 void AutoProjectPart::setWantautotools()
00482 {
00483
QDomDocument &dom = *
projectDom();
00484
QDomElement el = DomUtil::elementByPath(dom,
"/kdevautoproject/make");
00485
if ( el.namedItem(
"envvars").isNull() ) {
00486
DomUtil::PairList list;
00487 list <<
DomUtil::Pair(
"WANT_AUTOCONF_2_5",
"1");
00488 list << DomUtil::Pair(
"WANT_AUTOMAKE_1_6",
"1");
00489 DomUtil::writePairListEntry(dom,
"/kdevautoproject/make/envvars",
"envvar",
"name",
"value", list);
00490 }
00491 }
00492
00493
00494 QString AutoProjectPart::makeEnvironment()
const
00495
{
00496
00497
00498
00499
00500
DomUtil::PairList envvars =
00501 DomUtil::readPairListEntry(*
projectDom(),
"/kdevautoproject/make/envvars",
"envvar",
"name",
"value");
00502
00503
QString environstr;
00504 DomUtil::PairList::ConstIterator it;
00505
for (it = envvars.begin(); it != envvars.end(); ++it) {
00506 environstr += (*it).first;
00507 environstr +=
"=";
00508
00509
00510
00511
00512
00513
00514
00515 environstr +=
EnvVarTools::quote((*it).second);
00516 environstr +=
" ";
00517 }
00518
return environstr;
00519 }
00520
00521
00522 void AutoProjectPart::addFile(
const QString &fileName)
00523 {
00524
QStringList fileList;
00525 fileList.append ( fileName );
00526
00527 this->
addFiles ( fileList );
00528 }
00529
00530 void AutoProjectPart::addFiles (
const QStringList& fileList )
00531 {
00532
QString directory, name;
00533 QStringList::ConstIterator it;
00534
bool messageBoxShown =
false;
00535
00536
for ( it = fileList.begin(); it != fileList.end(); ++it )
00537 {
00538
int pos = ( *it ).findRev(
'/');
00539
if (pos != -1)
00540 {
00541 directory = ( *it ).left(pos);
00542 name = ( *it ).mid(pos+1);
00543 }
00544
else
00545 {
00546 directory =
"";
00547 name = ( *it );
00548 }
00549
00550
if (directory !=
m_widget->activeDirectory() ||
00551 directory.isEmpty())
00552 {
00553
if ( !messageBoxShown )
00554 {
00555 KMessageBox::information(
m_widget, i18n(
"The directory you selected is not the active directory!\n"
00556
"You should 'activate' the target you're currently working on in Automake Manager.\n"
00557
"Just right-click a target and choose 'Make Target Active'."),
00558 i18n (
"No Active Target Found" ),
"No automake manager active target warning" );
00559 messageBoxShown =
true;
00560 }
00561 }
00562 }
00563
00564
m_widget->addFiles(fileList);
00565 }
00566
00567 void AutoProjectPart::removeFile(
const QString &fileName)
00568 {
00569
QStringList fileList;
00570 fileList.append ( fileName );
00571
00572 this->
removeFiles ( fileList );
00573 }
00574
00575 void AutoProjectPart::removeFiles (
const QStringList& fileList )
00576 {
00578
m_widget->removeFiles ( fileList );
00579
00580 emit removedFilesFromProject ( fileList );
00581 }
00582
00583 QStringList AutoProjectPart::allBuildConfigs()
const
00584
{
00585
QDomDocument &dom = *
projectDom();
00586
00587
QStringList allConfigs;
00588 allConfigs.append(
"default");
00589
00590
QDomNode node = dom.documentElement().namedItem(
"kdevautoproject").namedItem(
"configurations");
00591
QDomElement childEl = node.firstChild().toElement();
00592
while (!childEl.isNull()) {
00593
QString config = childEl.tagName();
00594
kdDebug(9020) <<
"Found config " << config <<
endl;
00595
if (config !=
"default")
00596 allConfigs.append(config);
00597 childEl = childEl.nextSibling().toElement();
00598 }
00599
00600
return allConfigs;
00601 }
00602
00603
00604 QString AutoProjectPart::currentBuildConfig()
const
00605
{
00606
QDomDocument &dom = *
projectDom();
00607
00608
QString config = DomUtil::readEntry(dom,
"/kdevautoproject/general/useconfiguration");
00609
if (config.isEmpty() || !
allBuildConfigs().contains(config))
00610 config =
"default";
00611
00612
return config;
00613 }
00614
00615
00616 QString AutoProjectPart::buildDirectory()
const
00617
{
00618
QString prefix =
"/kdevautoproject/configurations/" +
currentBuildConfig() +
"/";
00619
00620
QString builddir = DomUtil::readEntry(*
projectDom(), prefix +
"builddir");
00621
if (builddir.isEmpty())
00622
return topsourceDirectory();
00623
else if (builddir.startsWith(
"/"))
00624
return builddir;
00625
else
00626
return projectDirectory() +
"/" + builddir;
00627 }
00628
00629 QString AutoProjectPart::topsourceDirectory()
const
00630
{
00631
QString prefix =
"/kdevautoproject/configurations/" +
currentBuildConfig() +
"/";
00632
00633
QString topsourcedir = DomUtil::readEntry(*
projectDom(), prefix +
"topsourcedir");
00634
if (topsourcedir.isEmpty())
00635
return projectDirectory();
00636
else if (topsourcedir.startsWith(
"/"))
00637
return topsourcedir;
00638
else
00639
return projectDirectory() +
"/" + topsourcedir;
00640 }
00641
00642 QString AutoProjectPart::constructMakeCommandLine(
const QString &dir,
const QString &target)
const
00643
{
00644
00645
QString preCommand;
00646
QFileInfo fi1();
00647
if ( !QFile::exists(dir +
"/GNUmakefile") && !QFile::exists(dir +
"/makefile")
00648 && ! QFile::exists(dir +
"/Makefile") ) {
00649
if (!QFile::exists(
buildDirectory() +
"/configure")) {
00650
int r = KMessageBox::questionYesNo(
m_widget, i18n(
"There is no Makefile in this directory\n"
00651
"and no configure script for this project.\n"
00652
"Run automake & friends and configure first?"));
00653
if (r == KMessageBox::No)
00654
return 0;
00655 preCommand =
makefileCvsCommand();
00656
if (preCommand.isNull())
00657
return 0;
00658 preCommand +=
" && ";
00659 preCommand +=
configureCommand() +
" && ";
00660 }
else {
00661
int r = KMessageBox::questionYesNo(
m_widget, i18n(
"There is no Makefile in this directory. Run 'configure' first?"));
00662
if (r == KMessageBox::No)
00663
return 0;
00664 preCommand =
configureCommand() +
" && ";
00665 }
00666 }
00667
QDomDocument &dom = *
projectDom();
00668
00669
QString cmdline = DomUtil::readEntry(dom,
"/kdevautoproject/make/makebin");
00670
if (cmdline.isEmpty())
00671 cmdline = MAKE_COMMAND;
00672
if (!DomUtil::readBoolEntry(dom,
"/kdevautoproject/make/abortonerror"))
00673 cmdline +=
" -k";
00674
int jobs = DomUtil::readIntEntry(dom,
"/kdevautoproject/make/numberofjobs");
00675
if (jobs != 0) {
00676 cmdline +=
" -j";
00677 cmdline += QString::number(jobs);
00678 }
00679
if (DomUtil::readBoolEntry(dom,
"/kdevautoproject/make/dontact"))
00680 cmdline +=
" -n";
00681
00682 cmdline +=
" ";
00683 cmdline += target;
00684 cmdline.prepend(
makeEnvironment());
00685
00686
QString dircmd =
"cd \"";
00687 dircmd += dir;
00688 dircmd +=
"\" && ";
00689
00690
return preCommand + dircmd + cmdline;
00691 }
00692
00693
00694 void AutoProjectPart::startMakeCommand(
const QString &dir,
const QString &target,
bool withKdesu)
00695 {
00696
partController()->
saveAllFiles();
00697
00698
m_buildCommand =
constructMakeCommandLine(dir, target);
00699
00700
if (withKdesu)
00701
m_buildCommand =
"kdesu -t -c '" +
m_buildCommand +
"'";
00702
00703
if (!m_buildCommand.isNull())
00704
makeFrontend()->
queueCommand(dir, m_buildCommand);
00705 }
00706
00707
00710 void AutoProjectPart::queueInternalLibDependenciesBuild(
TargetItem* titem)
00711 {
00712
00713
QString addstr = (titem->
primary ==
"PROGRAMS")? titem->
ldadd : titem->
libadd;
00714
QStringList l2 = QStringList::split(
QRegExp(
"[ \t]"), addstr);
00715
QString tdir;
00716
QString tname;
00717
QString tcmd;
00718 QStringList::Iterator l2it;
00719
for (l2it = l2.begin(); l2it != l2.end(); ++l2it) {
00720
QString dependency = *l2it;
00721
if (dependency.startsWith(
"$(top_builddir)/")) {
00722
00723
#if KDE_VERSION > 305
00724
dependency.remove(
"$(top_builddir)/");
00725
#else
00726
QString topBuildDirStr(
"$(top_builddir)/");
00727
int i = dependency.find(topBuildDirStr);
00728
if (i != -1) {
00729 dependency.remove(i, i + topBuildDirStr.length() - 1);
00730 }
00731
#endif
00732
tdir =
buildDirectory();
00733
if (!tdir.endsWith(
"/") && !tdir.isEmpty())
00734 tdir +=
"/";
00735
int pos = dependency.findRev(
'/');
00736
if (pos == -1) {
00737 tname = dependency;
00738 }
else {
00739 tdir += dependency.left(pos+1);
00740 tname = dependency.mid(pos+1);
00741 }
00742
kdDebug(9020) <<
"Scheduling : <" << tdir <<
"> target <" << tname <<
">" <<
endl;
00743
00744
00745
SubprojectItem *spi =
m_widget->subprojectItemForPath( dependency.left(pos) );
00746
if (spi) {
00747
QPtrList< TargetItem > tl = spi->
targets;
00748
00749
TargetItem *ti = tl.first();
00750
do {
00751
if (ti->
name == tname) {
00752
00753
queueInternalLibDependenciesBuild(ti);
00754
break;
00755 }
00756 ti = tl.next();
00757 }
while (ti);
00758 }
00759
00760 tcmd =
constructMakeCommandLine(tdir, tname);
00761
if (!tcmd.isNull()) {
00762
makeFrontend()->
queueCommand( tdir, tcmd);
00763 }
00764 }
00765 }
00766 }
00767
00768
00769 void AutoProjectPart::slotBuild()
00770 {
00771
00772
00773
if(
m_needMakefileCvs ){
00774
slotMakefilecvs();
00775
slotConfigure();
00776
m_needMakefileCvs =
false;
00777 }
00778
00779
startMakeCommand(
buildDirectory(), QString::fromLatin1(
""));
00780 }
00781
00782
00783 void AutoProjectPart::buildTarget(
QString relpath,
TargetItem* titem)
00784 {
00785
00786
if ( !titem )
00787
return;
00788
00789
00790
00791
00792
QString name = titem->
name;
00793
if ( titem->
primary ==
"KDEDOCS" )
00794 name =
"index.cache.bz2";
00795
00796
00797
QString path =
buildDirectory();
00798
if (!path.endsWith(
"/") && !path.isEmpty())
00799 path +=
"/";
00800
if (relpath.at(0) ==
'/')
00801 path += relpath.mid(1);
00802
else
00803 path += relpath;
00804
00805
00806
partController()->
saveAllFiles();
00807
00808
00809
00810
queueInternalLibDependenciesBuild(titem);
00811
00812
00813
QString tcmd =
constructMakeCommandLine( path, name );
00814
00815
00816
if (!tcmd.isNull()) {
00817
m_buildCommand = tcmd;
00818
makeFrontend()->
queueCommand( path, tcmd);
00819 }
00820 }
00821
00822
00823 void AutoProjectPart::slotBuildActiveTarget()
00824 {
00825
00826
TargetItem* titem =
m_widget->activeTarget();
00827
00828
if ( !titem )
00829
return;
00830
00831
00832
buildTarget(
activeDirectory(), titem);
00833
00834
00835
mainWindow()->
lowerView(
m_widget );
00836 }
00837
00838
00839 void AutoProjectPart::slotCompileFile()
00840 {
00841
KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(
partController()->
activePart());
00842
if (!part || !part->
url().
isLocalFile())
00843
return;
00844
00845
QString fileName = part->
url().
path();
00846
QFileInfo fi(fileName);
00847
QString sourceDir = fi.dirPath();
00848
QString baseName = fi.baseName(
true);
00849
kdDebug(9020) <<
"Compiling " << fileName
00850 <<
" in dir " << sourceDir
00851 <<
" with baseName " << baseName <<
endl;
00852
00853
QString projectDir =
projectDirectory();
00854
if (!sourceDir.startsWith(projectDir)) {
00855 KMessageBox::sorry(
m_widget, i18n(
"Can only compile files in directories which belong to the project."));
00856
return;
00857 }
00858
00859
QString buildDir =
buildDirectory() + sourceDir.mid(projectDir.length());
00860
QString target = baseName +
".lo";
00861
kdDebug(9020) <<
"builddir " << buildDir <<
", target " << target <<
endl;
00862
00863
startMakeCommand(buildDir, target);
00864 }
00865
00866 QString AutoProjectPart::configureCommand()
const
00867
{
00868
QDomDocument &dom = *
projectDom();
00869
QString prefix =
"/kdevautoproject/configurations/" +
currentBuildConfig() +
"/";
00870
00871
QString cmdline =
"\"" +
topsourceDirectory();
00872 cmdline +=
"/configure\"";
00873
QString cc = DomUtil::readEntry(dom, prefix +
"ccompilerbinary");
00874
if (!cc.isEmpty())
00875 cmdline.prepend(
QString(
"CC=%1 ").arg(cc));
00876
QString cflags = DomUtil::readEntry(dom, prefix +
"cflags");
00877
if (!cflags.isEmpty())
00878 cmdline.prepend(
QString(
"CFLAGS=\"%1\" ").arg(cflags));
00879
QString cxx = DomUtil::readEntry(dom, prefix +
"cxxcompilerbinary");
00880
if (!cxx.isEmpty())
00881 cmdline.prepend(
QString(
"CXX=%1 ").arg(cxx));
00882
QString cxxflags = DomUtil::readEntry(dom, prefix +
"cxxflags");
00883
if (!cxxflags.isEmpty())
00884 cmdline.prepend(
QString(
"CXXFLAGS=\"%1\" ").arg(cxxflags));
00885
QString f77 = DomUtil::readEntry(dom, prefix +
"f77compilerbinary");
00886
if (!f77.isEmpty())
00887 cmdline.prepend(
QString(
"F77=%1 ").arg(f77));
00888
QString fflags = DomUtil::readEntry(dom, prefix +
"f77flags");
00889
if (!fflags.isEmpty())
00890 cmdline.prepend(
QString(
"FFLAGS=\"%1\" ").arg(fflags));
00891
QString cppflags = DomUtil::readEntry(dom, prefix +
"cppflags");
00892
if (!cppflags.isEmpty())
00893 cmdline.prepend(
QString(
"CPPFLAGS=\"%1\" ").arg(cppflags));
00894
QString ldflags = DomUtil::readEntry(dom, prefix +
"ldflags");
00895
if (!ldflags.isEmpty())
00896 cmdline.prepend(
QString(
"LDFLAGS=\"%1\" ").arg(ldflags));
00897
00898
QString configargs = DomUtil::readEntry(dom, prefix +
"configargs");
00899
if (!configargs.isEmpty()) {
00900 cmdline +=
" ";
00901 cmdline += configargs;
00902 }
00903
00904
QString builddir =
buildDirectory();
00905
QString dircmd;
00906
00907
00908
if ( !QFile::exists(builddir)) {
00909 dircmd =
"mkdir \"";
00910 dircmd += builddir;
00911 dircmd +=
"\" && ";
00912 }
00913
00914
00915 dircmd +=
"cd \"";
00916 dircmd += builddir;
00917 dircmd +=
"\" && ";
00918
00919
return dircmd + cmdline;
00920 }
00921
00922 void AutoProjectPart::slotConfigure()
00923 {
00924
QString cmdline =
configureCommand();
00925
if (cmdline.isNull())
00926
return;
00927
00928
makeFrontend()->
queueCommand(
buildDirectory(), cmdline);
00929 }
00930
00931 QString AutoProjectPart::makefileCvsCommand()
const
00932
{
00933
QString cmdline = DomUtil::readEntry(*
projectDom(),
"/kdevautoproject/make/makebin");
00934
if (cmdline.isEmpty())
00935 cmdline = MAKE_COMMAND;
00936
00937
if (QFile::exists(
topsourceDirectory() +
"/Makefile.cvs"))
00938 cmdline +=
" -f Makefile.cvs";
00939
else if (QFile::exists(
topsourceDirectory() +
"/Makefile.dist"))
00940 cmdline +=
" -f Makefile.dist";
00941
else if (QFile::exists(
topsourceDirectory() +
"/autogen.sh"))
00942 cmdline =
"./autogen.sh";
00943
else {
00944 KMessageBox::sorry(
m_widget, i18n(
"There is neither a Makefile.cvs file nor an "
00945
"autogen.sh script in the project directory."));
00946
return QString::null;
00947 }
00948
00949 cmdline.prepend(
makeEnvironment());
00950
00951
QString dircmd =
"cd \"";
00952 dircmd +=
topsourceDirectory();
00953 dircmd +=
"\" && ";
00954
00955
return dircmd + cmdline;
00956 }
00957
00958 void AutoProjectPart::slotMakefilecvs()
00959 {
00960
QString cmdline =
makefileCvsCommand();
00961
if ( cmdline.isNull() )
00962
return;
00963
00964
makeFrontend()->
queueCommand(
projectDirectory(), cmdline);
00965 }
00966
00967
00968 void AutoProjectPart::slotInstall()
00969 {
00970
startMakeCommand(
buildDirectory(), QString::fromLatin1(
"install"));
00971 }
00972
00973
00974 void AutoProjectPart::slotInstallWithKdesu()
00975 {
00976
00977
00978
slotBuild();
00979
00980
00981
startMakeCommand(
buildDirectory(), QString::fromLatin1(
"install"),
true);
00982 }
00983
00984
00985 void AutoProjectPart::slotClean()
00986 {
00987
startMakeCommand(
buildDirectory(), QString::fromLatin1(
"clean"));
00988 }
00989
00990
00991 void AutoProjectPart::slotDistClean()
00992 {
00993
startMakeCommand(
buildDirectory(), QString::fromLatin1(
"distclean"));
00994 }
00995
00996
00997 void AutoProjectPart::slotMakeMessages()
00998 {
00999
startMakeCommand(
buildDirectory(), QString::fromLatin1(
"package-messages"));
01000 }
01001
01002
01009 void AutoProjectPart::slotExecute()
01010 {
01011
partController()->
saveAllFiles();
01012
QDomDocument &dom = *
projectDom();
01013
01014
if( DomUtil::readBoolEntry(dom,
"/kdevautoproject/run/autocompile",
true) &&
isDirty() ){
01015
m_executeAfterBuild =
true;
01016
if ( DomUtil::readEntry(dom,
"/kdevautoproject/run/mainprogram").isEmpty() )
01017
01018
slotBuildActiveTarget();
01019
else
01020
01021
slotBuild();
01022
return;
01023 }
01024
01025
if (
appFrontend()->
isRunning()) {
01026
if (KMessageBox::questionYesNo(
m_widget, i18n(
"Your application is currently running. Do you want to restart it?"), i18n(
"Application already running"), i18n(
"&Restart application"), i18n(
"Do &Nothing")) == KMessageBox::No)
01027
return;
01028 connect(
appFrontend(), SIGNAL(processExited()), SLOT(
slotExecute2()));
01029
appFrontend()->
stopApplication();
01030
return;
01031 }
01032
01033
slotExecute2();
01034 }
01035
01036
01041 void AutoProjectPart::slotExecute2()
01042 {
01043 disconnect(
appFrontend(), SIGNAL(processExited()),
this, SLOT(
slotExecute2()));
01044
01045
01046
01047
01048
01049
DomUtil::PairList envvars =
runEnvironmentVars();
01050
QString environstr;
01051 DomUtil::PairList::ConstIterator it;
01052
for (it = envvars.begin(); it != envvars.end(); ++it) {
01053 environstr += (*it).first;
01054 environstr +=
"=";
01055
01056
01057
01058
01059
01060
01061
01062 environstr +=
EnvVarTools::quote((*it).second);
01063 environstr +=
" ";
01064 }
01065
01066
if (
mainProgram(
true).isEmpty())
01067
01068
return;
01069
01070
QString program = environstr;
01071
01072
if (!
mainProgram(
true).startsWith(
"/"))
01073 program +=
"./";
01074 program +=
mainProgram(
true);
01075 program +=
" " +
runArguments();
01076
01077
bool inTerminal = DomUtil::readBoolEntry(*
projectDom(),
"/kdevautoproject/run/terminal");
01078
01079
kdDebug(9020) <<
"runDirectory: <" <<
runDirectory() <<
">" <<
endl;
01080
kdDebug(9020) <<
"environstr : <" << environstr <<
">" <<
endl;
01081
kdDebug(9020) <<
"mainProgram : <" << mainProgram(
true) <<
">" <<
endl;
01082
kdDebug(9020) <<
"runArguments: <" <<
runArguments() <<
">" <<
endl;
01083
01084
appFrontend()->
startAppCommand(
runDirectory(), program, inTerminal);
01085 }
01086
01087
01088 void AutoProjectPart::slotAddTranslation()
01089 {
01090
AddTranslationDialog dlg(
this,
m_widget);
01091 dlg.exec();
01092 }
01093
01094
01095 void AutoProjectPart::slotBuildConfigChanged(
const QString &config)
01096 {
01097 DomUtil::writeEntry(*
projectDom(),
"/kdevautoproject/general/useconfiguration", config);
01098
kdDebug(9020) <<
"Changed used configuration to " << config <<
endl;
01099 }
01100
01101
01102 void AutoProjectPart::slotBuildConfigAboutToShow()
01103 {
01104
QStringList l =
allBuildConfigs();
01105
buildConfigAction->
setItems(l);
01106
buildConfigAction->
setCurrentItem(l.findIndex(
currentBuildConfig()));
01107 }
01108
01109 void AutoProjectPart::restorePartialProjectSession (
const QDomElement* el )
01110 {
01111
m_widget->restoreSession ( el );
01112 }
01113
01114 void AutoProjectPart::savePartialProjectSession (
QDomElement* el )
01115 {
01116
QDomDocument domDoc = el->ownerDocument();
01117
01118 KMessageBox::information ( 0,
"Hallo, Welt!" );
01119
01120
kdDebug ( 9000 ) <<
"*********************************************** 1) AutoProjectPart::savePartialProjectSession()" <<
endl;
01121
01122
if ( domDoc.isNull() )
01123 {
01124
kdDebug ( 9000 ) <<
"*********************************************** 2) AutoProjectPart::savePartialProjectSession()" <<
endl;
01125
return;
01126 }
01127
01128
kdDebug ( 9000 ) <<
"*********************************************** 3) AutoProjectPart::savePartialProjectSession()" <<
endl;
01129
01130
m_widget->saveSession ( el );
01131 }
01132
01133 void AutoProjectPart::slotCommandFinished(
const QString& command )
01134 {
01135
kdDebug(9020) <<
k_funcinfo <<
endl;
01136
01137
if(
m_buildCommand != command )
01138
return;
01139
01140
m_buildCommand = QString::null;
01141
01142
m_timestamp.clear();
01143
QStringList fileList =
allFiles();
01144 QStringList::Iterator it = fileList.begin();
01145
while( it != fileList.end() ){
01146
QString fileName = *it;
01147 ++it;
01148
01149
m_timestamp[ fileName ] =
QFileInfo(
projectDirectory(), fileName ).lastModified();
01150 }
01151
01152 emit
projectCompiled();
01153
01154
01155
m_lastCompilationFailed =
false;
01156
01157
if(
m_executeAfterBuild ){
01158
slotExecute();
01159
m_executeAfterBuild =
false;
01160 }
01161 }
01162
01163 void AutoProjectPart::slotCommandFailed(
const QString& )
01164 {
01165
kdDebug(9020) <<
k_funcinfo <<
endl;
01166
01167
m_lastCompilationFailed =
true;
01168 }
01169
01170 bool AutoProjectPart::isDirty()
01171 {
01172
if (
m_lastCompilationFailed)
return true;
01173
01174
QStringList fileList =
allFiles();
01175 QStringList::Iterator it = fileList.begin();
01176
while( it != fileList.end() ){
01177
QString fileName = *it;
01178 ++it;
01179
01180
QMap<QString, QDateTime>::Iterator it =
m_timestamp.find( fileName );
01181
QDateTime t =
QFileInfo(
projectDirectory(), fileName ).lastModified();
01182
if( it ==
m_timestamp.end() || *it != t ){
01183
return true;
01184 }
01185 }
01186
01187
return false;
01188 }
01189
01190 void AutoProjectPart::needMakefileCvs( )
01191 {
01192
m_needMakefileCvs =
true;
01193 }
01194
01195 bool AutoProjectPart::isKDE()
const
01196
{
01197
return m_isKDE;
01198 }
01199
01200 KDevProject::Options
AutoProjectPart::options()
const
01201
{
01202
return UsesAutotoolsBuildSystem;
01203 }
01204
01205
#include "autoprojectpart.moc"