00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include "trollprojectpart.h"
00017
00018
#include <qdir.h>
00019
#include <qfileinfo.h>
00020
#include <qwhatsthis.h>
00021
#include <kdeversion.h>
00022
#include <kdebug.h>
00023
#include <kdialogbase.h>
00024
#include <kiconloader.h>
00025
#include <klocale.h>
00026
#include <kmessagebox.h>
00027
#include <qmessagebox.h>
00028
#include <kdevgenericfactory.h>
00029
#include <kaction.h>
00030
#include <kparts/part.h>
00031
#include <kprocess.h>
00032
#include <makeoptionswidget.h>
00033
00034
00035
#include "domutil.h"
00036
#include "kdevcore.h"
00037
#include "kdevmainwindow.h"
00038
#include "kdevmakefrontend.h"
00039
#include "kdevappfrontend.h"
00040
#include "kdevpartcontroller.h"
00041
#include "trollprojectwidget.h"
00042
#include "runoptionswidget.h"
00043
#include "config.h"
00044
#include "envvartools.h"
00045
00046
00047 typedef KDevGenericFactory<TrollProjectPart> TrollProjectFactory;
00048
static const KAboutData data(
"kdevtrollproject",
I18N_NOOP(
"QMake Manager"),
"1.0");
00049 K_EXPORT_COMPONENT_FACTORY( libkdevtrollproject,
TrollProjectFactory( &data ) )
00050
00051
TrollProjectPart::
TrollProjectPart(
QObject *parent, const
char *name, const
QStringList& args )
00052 :
KDevProject("TrollProject", "trollproject", parent, name ? name : "
TrollProjectPart")
00053 {
00054 setInstance(TrollProjectFactory::instance());
00055
00056
if ( args.count() == 1 && args[0] ==
"TMake" )
00057 m_tmakeProject =
true;
00058
else
00059 m_tmakeProject =
false;
00060
00061 setXMLFile(
"kdevtrollproject.rc");
00062
00063 m_executeAfterBuild =
false;
00064
00065 m_widget =
new TrollProjectWidget(
this);
00066 m_widget->setIcon(SmallIcon(
"make"));
00067 m_widget->setCaption(i18n(
"QMake Manager"));
00068 QWhatsThis::add(m_widget, i18n(
"<b>QMake manager</b><p>"
00069
"The QMake manager project tree consists of two parts. The 'overview' "
00070
"in the upper half shows the subprojects, each one having a "
00071
".pro file. The 'details' view in the lower half shows the "
00072
"list of files for the active subproject selected in the overview."));
00073
00074 mainWindow()->embedSelectViewRight(m_widget, i18n(
"QMake Manager"), i18n(
"QMake manager"));
00075
00076
KAction *action;
00077
00078
const QIconSet icon(SmallIcon(
"compfile"));
00079 action =
new KAction( i18n(
"Compile &File"),
"compfile", 0,
00080 m_widget, SLOT(slotBuildFile()),
00081 actionCollection(),
"build_compilefile" );
00082 action->setToolTip(i18n(
"Compile file"));
00083 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>"
00084
"Environment variables and make arguments can be specified "
00085
"in the project settings dialog, <b>Make Options</b> tab."));
00086
00087
00088 action =
new KAction( i18n(
"&Build Project"),
"make_kdevelop", Key_F8,
00089 m_widget, SLOT(slotBuildProject()),
00090 actionCollection(),
"build_build_project" );
00091 action->setToolTip(i18n(
"Build project"));
00092 action->setWhatsThis(i18n(
"<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>"
00093
"Environment variables and make arguments can be specified "
00094
"in the project settings dialog, <b>Make Options</b> tab."));
00095
00096 action =
new KAction( i18n(
"&Rebuild Project"),
"rebuild" , 0,
00097 m_widget, SLOT(slotRebuildProject()),
00098 actionCollection(),
"build_rebuild_project" );
00099 action->setToolTip(i18n(
"Rebuild project"));
00100 action->setWhatsThis(i18n(
"<b>Rebuild project</b><p>Runs <b>make clean</b> and then <b>make</b> from the project directory.<br>"
00101
"Environment variables and make arguments can be specified "
00102
"in the project settings dialog, <b>Make Options</b> tab."));
00103
00104 action =
new KAction( i18n(
"&Clean Project"), 0,
00105 m_widget, SLOT(slotCleanProject()),
00106 actionCollection(),
"build_clean_project" );
00107 action->setToolTip(i18n(
"Clean project"));
00108 action->setWhatsThis(i18n(
"<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>"
00109
"Environment variables and make arguments can be specified "
00110
"in the project settings dialog, <b>Make Options</b> tab."));
00111
00112 action =
new KAction( i18n(
"Execute Main Program"),
"exec", SHIFT+Key_F9,
00113 m_widget, SLOT(slotExecuteProject()),
00114 actionCollection(),
"build_execute_project" );
00115 action->setToolTip(i18n(
"Execute main program"));
00116 action->setWhatsThis(i18n(
"<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab."));
00117
00118
00119
00120
00121
00122 action =
new KAction( i18n(
"&Build Subproject"),
"make_kdevelop", Key_F7,
00123 m_widget, SLOT(slotBuildTarget()),
00124 actionCollection(),
"build_build_target" );
00125 action->setToolTip(i18n(
"Build subproject"));
00126 action->setWhatsThis(i18n(
"<b>Build subproject</b><p>Runs <b>make</b> from the current subproject directory. "
00127
"Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>"
00128
"Environment variables and make arguments can be specified "
00129
"in the project settings dialog, <b>Make Options</b> tab."));
00130
00131 action =
new KAction( i18n(
"&Rebuild Subproject"),
"rebuild", 0,
00132 m_widget, SLOT(slotRebuildTarget()),
00133 actionCollection(),
"build_rebuild_target" );
00134 action->setToolTip(i18n(
"Rebuild subproject"));
00135 action->setWhatsThis(i18n(
"<b>Rebuild subproject</b><p>Runs <b>make clean</b> and then <b>make</b> from the current subproject directory. "
00136
"Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>"
00137
"Environment variables and make arguments can be specified "
00138
"in the project settings dialog, <b>Make Options</b> tab."));
00139
00140 action =
new KAction( i18n(
"&Clean Subproject"), 0,
00141 m_widget, SLOT(slotCleanTarget()),
00142 actionCollection(),
"build_clean_target" );
00143 action->setToolTip(i18n(
"Clean subproject"));
00144 action->setWhatsThis(i18n(
"<b>Clean subproject</b><p>Runs <b>make clean</b> from the current subproject directory. "
00145
"Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>"
00146
"Environment variables and make arguments can be specified "
00147
"in the project settings dialog, <b>Make Options</b> tab."));
00148
00149 action =
new KAction( i18n(
"Execute Subproject"),
"exec", 0,
00150 m_widget, SLOT(slotExecuteTarget()),
00151 actionCollection(),
"build_execute_target" );
00152 action->setToolTip(i18n(
"Execute subproject"));
00153 action->setWhatsThis(i18n(
"<b>Execute subproject</b><p>Executes the target program for the currently selected subproject. "
00154
"This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be "
00155
"defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu)."));
00156
00157 connect( core(), SIGNAL(projectConfigWidget(
KDialogBase*)),
00158
this, SLOT(projectConfigWidget(
KDialogBase*)) );
00159
00160 connect( makeFrontend(), SIGNAL(commandFinished(
const QString&)),
00161
this, SLOT(slotCommandFinished(
const QString&)) );
00162
00163 m_qmakeHeader = i18n(
"# File generated by kdevelop's qmake manager. \n"
00164
"# ------------------------------------------- \n"
00165
"# Subdir relative project main directory: %s\n"
00166
"# Target is %s %s\n");
00167
00168 m_availableQtDirList = availableQtDirList();
00169 m_defaultQtDir = ::getenv(
"QTDIR" );
00170
if( m_defaultQtDir.isEmpty() && !m_availableQtDirList.isEmpty() )
00171 m_defaultQtDir = m_availableQtDirList.front();
00172 }
00173
00174
00175 TrollProjectPart::~TrollProjectPart()
00176 {
00177
if (
m_widget)
00178
mainWindow()->
removeView(
m_widget);
00179
delete m_widget;
00180 }
00181
00182 QString TrollProjectPart::makeEnvironment()
00183 {
00184
00185
00186
00187
00188
DomUtil::PairList envvars =
00189 DomUtil::readPairListEntry(*
projectDom(),
"/kdevtrollproject/make/envvars",
"envvar",
"name",
"value");
00190
00191
QString environstr;
00192 DomUtil::PairList::ConstIterator it;
00193
bool hasQtDir =
false;
00194
for (it = envvars.begin(); it != envvars.end(); ++it) {
00195
if( (*it).first ==
"QTDIR" )
00196 hasQtDir =
true;
00197
00198 environstr += (*it).first;
00199 environstr +=
"=";
00200
00201
00202
00203
00204
00205
00206
00207 environstr +=
EnvVarTools::quote((*it).second);
00208 environstr +=
" ";
00209 }
00210
00211
if( !hasQtDir && !
m_defaultQtDir.isEmpty() )
00212 {
00213 environstr +=
QString(
"QTDIR=" ) +
EnvVarTools::quote(
m_defaultQtDir ) + QString(
" " );
00214 }
00215
00216
return environstr;
00217 }
00218
00219 void TrollProjectPart::projectConfigWidget(
KDialogBase *dlg)
00220 {
00221
QVBox *vbox;
00222 vbox = dlg->
addVBoxPage(i18n(
"Run Options"));
00223
RunOptionsWidget *optdlg =
new RunOptionsWidget(*
projectDom(),
"/kdevtrollproject",
buildDirectory(), vbox);
00224
00225 vbox = dlg->
addVBoxPage(i18n(
"Make Options"));
00226
MakeOptionsWidget *w4 =
new MakeOptionsWidget(*
projectDom(),
"/kdevtrollproject", vbox);
00227 connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) );
00228
00229 connect( dlg, SIGNAL(okClicked()), optdlg, SLOT(accept()) );
00230 }
00231
00232
00233 void TrollProjectPart::openProject(
const QString &dirName,
const QString &projectName)
00234 {
00235
m_widget->openProject(dirName);
00236
m_projectName = projectName;
00237
00238
QDomDocument &dom = *
projectDom();
00239
00240
if (DomUtil::readEntry(dom,
"/kdevtrollproject/run/directoryradio") ==
"" ) {
00241 DomUtil::writeEntry(dom,
"/kdevtrollproject/run/directoryradio",
"executable");
00242 }
00243
00244 KDevProject::openProject( dirName, projectName );
00245 }
00246
00247
00248 void TrollProjectPart::closeProject()
00249 {
00250
m_widget->closeProject();
00251 }
00252
00253
00254 QString TrollProjectPart::projectDirectory()
const
00255
{
00256
return m_widget->projectDirectory();
00257 }
00258
00259
00260 QString TrollProjectPart::buildDirectory()
const
00261
{
00262
return m_widget->projectDirectory();
00263 }
00264
00265 QString TrollProjectPart::projectName()
const
00266
{
00267
return m_projectName;
00268 }
00269
00270
00272 DomUtil::PairList TrollProjectPart::runEnvironmentVars()
const
00273
{
00274
return DomUtil::readPairListEntry(*
projectDom(),
"/kdevtrollproject/run/envvars",
"envvar",
"name",
"value");
00275 }
00276
00277
00287 QString TrollProjectPart::runDirectory()
const
00288
{
00289
QDomDocument &dom = *
projectDom();
00290
00291
QString directoryRadioString = DomUtil::readEntry(dom,
"/kdevtrollproject/run/directoryradio");
00292
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevtrollproject/run/mainprogram");
00293
00294
if ( directoryRadioString ==
"build" )
00295
return buildDirectory();
00296
00297
if ( directoryRadioString ==
"custom" )
00298
return DomUtil::readEntry(dom,
"/kdevtrollproject/run/customdirectory");
00299
00300
int pos = DomMainProgram.findRev(
'/');
00301
if (pos != -1)
00302
return buildDirectory() +
"/" + DomMainProgram.left(pos);
00303
00304
if ( DomMainProgram.isEmpty() )
00305 {
00306
return m_widget->subprojectDirectory();
00307 }
00308
return buildDirectory() +
"/" + DomMainProgram;
00309
00310 }
00311
00312
00322 QString TrollProjectPart::mainProgram(
bool relative)
const
00323
{
00324
QDomDocument &dom = *
projectDom();
00325
00326
QString directoryRadioString = DomUtil::readEntry(dom,
"/kdevtrollproject/run/directoryradio");
00327
QString DomMainProgram = DomUtil::readEntry(dom,
"/kdevtrollproject/run/mainprogram");
00328
00329
if ( directoryRadioString ==
"custom" )
00330
return DomMainProgram;
00331
00332
if ( relative ==
false && !DomMainProgram.isEmpty() )
00333
return buildDirectory() +
"/" + DomMainProgram;
00334
00335
if ( directoryRadioString ==
"executable" ) {
00336
int pos = DomMainProgram.findRev(
'/');
00337
if (pos != -1)
00338
return DomMainProgram.mid(pos+1);
00339
00340
if ( DomMainProgram.isEmpty() )
00341 {
00342
return runDirectory() +
"/" +
m_widget->getCurrentOutputFilename();
00343 }
00344
return DomMainProgram;
00345 }
00346
else
00347
return DomMainProgram;
00348 }
00349
00350
00352 QString TrollProjectPart::runArguments()
const
00353
{
00354
return DomUtil::readEntry(*
projectDom(),
"/kdevtrollproject/run/programargs");
00355 }
00356
00357
00358 QString TrollProjectPart::activeDirectory()
const
00359
{
00360
QDomDocument &dom = *
projectDom();
00361
00362
return DomUtil::readEntry(dom,
"/kdevtrollproject/general/activedir");
00363 }
00364
00365
00366 QStringList TrollProjectPart::allFiles()
const
00367
{
00368
return m_widget->allFiles();
00369 }
00370
00371
00372 void TrollProjectPart::addFile(
const QString &fileName)
00373 {
00374
QStringList fileList;
00375 fileList.append ( fileName );
00376
00377 this->
addFiles ( fileList );
00378 }
00379
00380 void TrollProjectPart::addFiles (
const QStringList &fileList )
00381 {
00382
QStringList files = fileList;
00383
for (QStringList::iterator it = files.begin(); it != files.end(); ++it)
00384
if (!isProjectFile(
projectDirectory() +
"/" + (*it)))
00385
00386 *it =
projectDirectory() +
"/" + (*it);
00387
00388
m_widget->addFiles(files);
00389
00390
00391 }
00392
00393 void TrollProjectPart::removeFile(
const QString & )
00394 {
00396
00397
00398
00399
00400 }
00401
00402 void TrollProjectPart::removeFiles (
const QStringList& fileList )
00403 {
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 emit removedFilesFromProject ( fileList );
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 void TrollProjectPart::startQMakeCommand(
const QString &dir)
00469 {
00470
QFileInfo fi(dir);
00471
00472
QString cmdline = QString::fromLatin1(
isTMakeProject() ?
"tmake " :
"qmake " );
00473
00474
QDir d(dir);
00475
QStringList l = d.entryList(
"*.pro");
00476
00477 cmdline += l.count()?l[0]:(fi.baseName() +
".pro");
00478
00479
00480
00481
QString dircmd =
"cd ";
00482 dircmd += dir;
00483 dircmd +=
" && ";
00484
00485 cmdline.prepend(
makeEnvironment());
00486
makeFrontend()->
queueCommand(dir, dircmd + cmdline);
00487 }
00488
00489 void TrollProjectPart::queueCmd(
const QString &dir,
const QString &cmd)
00490 {
00491
makeFrontend()->
queueCommand(dir, cmd);
00492 }
00493
00494 void TrollProjectPart::slotCommandFinished(
const QString& command )
00495 {
00496 Q_UNUSED( command );
00497
00498
if(
m_buildCommand != command )
00499
return;
00500
00501
m_buildCommand = QString::null;
00502
00503
m_timestamp.clear();
00504
QStringList fileList =
allFiles();
00505 QStringList::Iterator it = fileList.begin();
00506
while( it != fileList.end() ){
00507
QString fileName = *it;
00508 ++it;
00509
00510
m_timestamp[ fileName ] =
QFileInfo(
projectDirectory(), fileName ).lastModified();
00511 }
00512
00513 emit
projectCompiled();
00514
00515
if(
m_executeAfterBuild ){
00516
m_widget->slotExecuteProject();
00517
m_executeAfterBuild =
false;
00518 }
00519 }
00520
00521 bool TrollProjectPart::isDirty()
00522 {
00523
QStringList fileList =
allFiles();
00524 QStringList::Iterator it = fileList.begin();
00525
while( it != fileList.end() ){
00526
QString fileName = *it;
00527 ++it;
00528
00529
QMap<QString, QDateTime>::Iterator it =
m_timestamp.find( fileName );
00530
QDateTime t =
QFileInfo(
projectDirectory(), fileName ).lastModified();
00531
if( it ==
m_timestamp.end() || *it != t ){
00532
return true;
00533 }
00534 }
00535
00536
return false;
00537 }
00538
00539 KDevProject::Options
TrollProjectPart::options( )
00540 {
00541
return UsesQMakeBuildSystem;
00542 }
00543
00544 bool TrollProjectPart::isValidQtDir(
const QString& path )
const
00545
{
00546
return QFile::exists( path +
"/include/qt.h" );
00547 }
00548
00549 QStringList TrollProjectPart::availableQtDirList()
const
00550
{
00551
QStringList qtdirs, lst;
00552 qtdirs.push_back( ::getenv(
"QTDIR") );
00553 qtdirs.push_back(
"/usr/lib/qt3" );
00554 qtdirs.push_back(
"/usr/lib/qt" );
00555 qtdirs.push_back(
"/usr/share/qt3" );
00556
00557
for( QStringList::Iterator it=qtdirs.begin(); it!=qtdirs.end(); ++it )
00558 {
00559
QString qtdir = *it;
00560
if( !qtdir.isEmpty() &&
isValidQtDir(qtdir) )
00561 lst.push_back( qtdir );
00562 }
00563
return lst;
00564 }
00565
00566
#include "trollprojectpart.moc"