~ubuntu-branches/debian/sid/kdevelop/sid

« back to all changes in this revision

Viewing changes to buildtools/autotools/autoprojectpart.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Lainé
  • Date: 2010-05-05 07:21:55 UTC
  • mfrom: (1.2.3 upstream) (5.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100505072155-h78lx19pu04sbhtn
Tags: 4:4.0.0-2
* Upload to unstable (Closes: #579947, #481832).
* Acknowledge obsolete NMU fixes (Closes: #562410, #546961).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *   Copyright (C) 2001-2002 by Bernd Gehrmann                             *
3
 
 *   bernd@kdevelop.org                                                    *
4
 
 *                                                                         *
5
 
 *   Copyright (C) 2002 by Victor Roeder                                   *
6
 
 *   victor_roeder@gmx.de                                                  *
7
 
 *                                                                         *
8
 
 *   This program is free software; you can redistribute it and/or modify  *
9
 
 *   it under the terms of the GNU General Public License as published by  *
10
 
 *   the Free Software Foundation; either version 2 of the License, or     *
11
 
 *   (at your option) any later version.                                   *
12
 
 *                                                                         *
13
 
 ***************************************************************************/
14
 
 
15
 
#include <config.h>
16
 
 
17
 
#include "autoprojectpart.h"
18
 
#include "autolistviewitems.h"
19
 
#include "configureoptionswidget.h"
20
 
#include "addtranslationdlg.h"
21
 
#include "addicondlg.h"
22
 
#include "autoprojectwidget.h"
23
 
 
24
 
#include <qdom.h>
25
 
#include <qdir.h>
26
 
#include <qfileinfo.h>
27
 
#include <qpopupmenu.h>
28
 
#include <qstringlist.h>
29
 
#include <qwhatsthis.h>
30
 
#include <qregexp.h>
31
 
#include <qgroupbox.h>
32
 
 
33
 
 
34
 
#include <kapplication.h>
35
 
#include <kconfig.h>
36
 
#include <kaction.h>
37
 
#include <kdebug.h>
38
 
#include <kdialogbase.h>
39
 
#include <kiconloader.h>
40
 
#include <klocale.h>
41
 
#include <kmessagebox.h>
42
 
#include <kparts/part.h>
43
 
#include <kdeversion.h>
44
 
#include <kprocess.h>
45
 
 
46
 
#include <domutil.h>
47
 
#include <kdevcore.h>
48
 
#include <kdevmakefrontend.h>
49
 
#include <kdevappfrontend.h>
50
 
#include <kdevmainwindow.h>
51
 
#include <kdevpartcontroller.h>
52
 
#include <makeoptionswidget.h>
53
 
#include <runoptionswidget.h>
54
 
#include <envvartools.h>
55
 
 
56
 
#include <configwidgetproxy.h>
57
 
#include <kdevplugininfo.h>
58
 
#include <urlutil.h>
59
 
 
60
 
#define CONFIGURE_OPTIONS 1
61
 
#define RUN_OPTIONS 2
62
 
#define MAKE_OPTIONS 3
63
 
 
64
 
static const KDevPluginInfo data("kdevautoproject");
65
 
 
66
 
K_EXPORT_COMPONENT_FACTORY( libkdevautoproject, AutoProjectFactory( data ) )
67
 
 
68
 
AutoProjectPart::AutoProjectPart(QObject *parent, const char *name, const QStringList &args)
69
 
    : KDevBuildTool(&data, parent, name ? name : "AutoProjectPart")
70
 
    , m_lastCompilationFailed(false)
71
 
{
72
 
    setInstance(AutoProjectFactory::instance());
73
 
 
74
 
    setXMLFile("kdevautoproject.rc");
75
 
 
76
 
    m_executeAfterBuild = false;
77
 
    m_isKDE = (args[0] == "kde");
78
 
    m_needMakefileCvs = false;
79
 
 
80
 
    m_widget = new AutoProjectWidget(this, m_isKDE);
81
 
    m_widget->setIcon(SmallIcon( info()->icon() ));
82
 
    m_widget->setCaption(i18n("Automake Manager"));
83
 
    QWhatsThis::add(m_widget, i18n("<b>Automake manager</b><p>"
84
 
                                   "The project tree consists of two parts. The 'overview' "
85
 
                                   "in the upper half shows the subprojects, each one having a "
86
 
                                   "Makefile.am. The 'details' view in the lower half shows the "
87
 
                                   "targets and files for the subproject selected in the overview."));
88
 
 
89
 
    mainWindow()->embedSelectViewRight(m_widget, i18n("Automake Manager"), i18n("Automake manager"));
90
 
    KAction *action;
91
 
 
92
 
    action = new KAction( i18n("Add Translation..."), 0,
93
 
                          this, SLOT(slotAddTranslation()),
94
 
                          actionCollection(), "project_addtranslation" );
95
 
    action->setToolTip(i18n("Add translation"));
96
 
    action->setWhatsThis(i18n("<b>Add translation</b><p>Creates .po file for the selected language."));
97
 
    action->setGroup("autotools");
98
 
 
99
 
 
100
 
    if (!m_isKDE)
101
 
        action->setEnabled(false);
102
 
 
103
 
    action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8,
104
 
                          this, SLOT(slotBuild()),
105
 
                          actionCollection(), "build_build" );
106
 
    action->setToolTip(i18n("Build project"));
107
 
    action->setWhatsThis(i18n("<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>"
108
 
                              "Environment variables and make arguments can be specified "
109
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
110
 
    action->setGroup("autotools");
111
 
 
112
 
    action = new KAction( i18n("Build &Active Target"), "make_kdevelop", Key_F7,
113
 
                          this, SLOT(slotBuildActiveTarget()),
114
 
                          actionCollection(), "build_buildactivetarget" );
115
 
    action->setToolTip(i18n("Build active target"));
116
 
    action->setWhatsThis(i18n("<b>Build active target</b><p>Constructs a series of make commands to build an active target. "
117
 
                              "Also builds dependent targets.<br>"
118
 
                              "Environment variables and make arguments can be specified "
119
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
120
 
    action->setGroup("autotools");
121
 
 
122
 
    action = new KAction( i18n("Compile &File"), "make_kdevelop",
123
 
                          this, SLOT(slotCompileFile()),
124
 
                          actionCollection(), "build_compilefile" );
125
 
    action->setToolTip(i18n("Compile file"));
126
 
    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>"
127
 
                              "Environment variables and make arguments can be specified "
128
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
129
 
    action->setGroup("autotools");
130
 
 
131
 
    action = new KAction( i18n("Run Configure"), 0,
132
 
                          this, SLOT(slotConfigure()),
133
 
                          actionCollection(), "build_configure" );
134
 
    action->setToolTip(i18n("Run configure"));
135
 
    action->setWhatsThis(i18n("<b>Run configure</b><p>Executes <b>configure</b> with flags, arguments "
136
 
                              "and environment variables specified in the project settings dialog, "
137
 
                              "<b>Configure Options</b> tab."));
138
 
    action->setGroup("autotools");
139
 
 
140
 
    action = new KAction( i18n("Run automake && friends"), 0,
141
 
                          this, SLOT(slotMakefilecvs()),
142
 
                          actionCollection(), "build_makefilecvs" );
143
 
    action->setToolTip(i18n("Run automake && friends"));
144
 
    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."));
145
 
    action->setGroup("autotools");
146
 
 
147
 
    action = new KAction( i18n("Install"), 0,
148
 
                          this, SLOT(slotInstall()),
149
 
                          actionCollection(), "build_install" );
150
 
    action->setToolTip(i18n("Install"));
151
 
    action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory.<br>"
152
 
                              "Environment variables and make arguments can be specified "
153
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
154
 
    action->setGroup("autotools");
155
 
 
156
 
    action = new KAction( i18n("Install (as root user)"), 0,
157
 
                          this, SLOT(slotInstallWithKdesu()),
158
 
                          actionCollection(), "build_install_kdesu" );
159
 
    action->setToolTip(i18n("Install as root user"));
160
 
    action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory with root privileges.<br>"
161
 
                              "It is executed via kdesu command.<br>"
162
 
                              "Environment variables and make arguments can be specified "
163
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
164
 
    action->setGroup("autotools");
165
 
 
166
 
    action = new KAction( i18n("&Clean Project"), 0,
167
 
                          this, SLOT(slotClean()),
168
 
                          actionCollection(), "build_clean" );
169
 
    action->setToolTip(i18n("Clean project"));
170
 
    action->setWhatsThis(i18n("<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>"
171
 
                              "Environment variables and make arguments can be specified "
172
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
173
 
    action->setGroup("autotools");
174
 
 
175
 
    action = new KAction( i18n("&Distclean"), 0,
176
 
                          this, SLOT(slotDistClean()),
177
 
                          actionCollection(), "build_distclean" );
178
 
    action->setToolTip(i18n("Distclean"));
179
 
    action->setWhatsThis(i18n("<b>Distclean</b><p>Runs <b>make distclean</b> command from the project directory.<br>"
180
 
                              "Environment variables and make arguments can be specified "
181
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
182
 
    action->setGroup("autotools");
183
 
 
184
 
    action = new KAction( i18n("Make Messages && Merge"), 0,
185
 
                          this, SLOT(slotMakeMessages()),
186
 
                          actionCollection(), "build_messages" );
187
 
    action->setToolTip(i18n("Make messages && merge"));
188
 
    action->setWhatsThis(i18n("<b>Make messages && merge</b><p>Runs <b>make package-messages</b> command from the project directory.<br>"
189
 
                              "Environment variables and make arguments can be specified "
190
 
                              "in the project settings dialog, <b>Make Options</b> tab."));
191
 
    action->setGroup("autotools");
192
 
 
193
 
    if (!m_isKDE)
194
 
        action->setEnabled(false);
195
 
 
196
 
    buildConfigAction = new KSelectAction( i18n("Build Configuration"), 0,
197
 
                                           actionCollection(), "project_configuration" );
198
 
    buildConfigAction->setToolTip(i18n("Build configuration menu"));
199
 
    buildConfigAction->setWhatsThis(i18n("<b>Build configuration menu</b><p>Allows to switch between project build configurations.<br>"
200
 
                                         "Build configuration is a set of build and top source directory settings, "
201
 
                                         "configure flags and arguments, compiler flags, etc.<br>"
202
 
                                         "Modify build configurations in project settings dialog, <b>Configure Options</b> tab."));
203
 
    buildConfigAction->setGroup("autotools");
204
 
 
205
 
    QDomDocument &dom = *projectDom();
206
 
    if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) {
207
 
        //ok we handle the execute in this kpart
208
 
        action = new KAction( i18n("Execute Program"), "exec", SHIFT+Key_F9,
209
 
                              this, SLOT(slotExecute()),
210
 
                              actionCollection(), "build_execute" );
211
 
        action->setToolTip(i18n("Execute program"));
212
 
        action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the currently active target or the main program specified in project settings, <b>Run Options</b> tab."));
213
 
        action->setGroup("autotools");
214
 
    }
215
 
 
216
 
    connect( buildConfigAction, SIGNAL(activated(const QString&)),
217
 
             this, SLOT(slotBuildConfigChanged(const QString&)) );
218
 
    connect( buildConfigAction->popupMenu(), SIGNAL(aboutToShow()),
219
 
             this, SLOT(slotBuildConfigAboutToShow()) );
220
 
 
221
 
//    connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*)) );
222
 
 
223
 
    _configProxy = new ConfigWidgetProxy( core() );
224
 
    _configProxy->createProjectConfigPage( i18n("Configure Options"), CONFIGURE_OPTIONS, info()->icon() );
225
 
    _configProxy->createProjectConfigPage( i18n("Run Options"), RUN_OPTIONS, info()->icon() );
226
 
    _configProxy->createProjectConfigPage( i18n("Make Options"), MAKE_OPTIONS, info()->icon() );
227
 
    connect( _configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )),
228
 
             this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )) );
229
 
 
230
 
 
231
 
    connect( makeFrontend(), SIGNAL(commandFinished(const QString&)),
232
 
             this, SLOT(slotCommandFinished(const QString&)) );
233
 
    connect( makeFrontend(), SIGNAL(commandFailed(const QString&)),
234
 
             this, SLOT(slotCommandFailed(const QString&)) );
235
 
 
236
 
    setWantautotools();
237
 
 
238
 
 
239
 
}
240
 
 
241
 
 
242
 
AutoProjectPart::~AutoProjectPart()
243
 
{
244
 
    if (m_widget)
245
 
    {
246
 
        mainWindow()->removeView(m_widget);
247
 
    }
248
 
    delete m_widget;
249
 
    delete _configProxy;
250
 
}
251
 
 
252
 
 
253
 
void AutoProjectPart::insertConfigWidget( const KDialogBase* dlg, QWidget * page, unsigned int pagenumber )
254
 
{
255
 
    switch ( pagenumber )
256
 
    {
257
 
    case CONFIGURE_OPTIONS:
258
 
        {
259
 
            ConfigureOptionsWidget *w2 = new ConfigureOptionsWidget(this, page );
260
 
            connect( dlg, SIGNAL(okClicked()), w2, SLOT(accept()) );
261
 
        }
262
 
        break;
263
 
 
264
 
    case RUN_OPTIONS:
265
 
        {
266
 
            QDomDocument &dom = *projectDom();
267
 
            if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default"))
268
 
            {
269
 
                //ok we handle the execute in this kpart
270
 
                RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevautoproject", buildDirectory(), page );
271
 
                connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) );
272
 
            }
273
 
        }
274
 
        break;
275
 
 
276
 
    case MAKE_OPTIONS:
277
 
        {
278
 
            MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevautoproject", page );
279
 
            connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) );
280
 
        }
281
 
        break;
282
 
    }
283
 
}
284
 
 
285
 
void AutoProjectPart::openProject(const QString &dirName, const QString &projectName)
286
 
{
287
 
    m_projectName = projectName;
288
 
    m_projectPath =dirName;
289
 
 
290
 
        m_widget->openProject(dirName);
291
 
 
292
 
    QDomDocument &dom = *projectDom();
293
 
    QString activeTarget = DomUtil::readEntry(dom, "/kdevautoproject/general/activetarget");
294
 
    kdDebug(9020) << k_funcinfo << "activeTarget " << activeTarget << endl;
295
 
    if (!activeTarget.isEmpty())
296
 
        m_widget->setActiveTarget(activeTarget);
297
 
    else
298
 
    {
299
 
        KMessageBox::information( m_widget, i18n("No active target specified, running the application will\n"
300
 
                                   "not work until you make a target active in the Automake Manager\n"
301
 
                                   "on the right side or use the Main Program options under\n"
302
 
                                   "Project -> Project Options -> Run Options"), i18n("No active target specified"),  "kdevelop_open_project_no_active_target");
303
 
    }
304
 
 
305
 
    KDevProject::openProject( dirName, projectName );
306
 
}
307
 
 
308
 
 
309
 
void AutoProjectPart::closeProject()
310
 
{
311
 
    m_widget->closeProject();
312
 
}
313
 
 
314
 
 
315
 
QString AutoProjectPart::projectDirectory() const
316
 
{
317
 
    return m_projectPath;
318
 
}
319
 
 
320
 
 
321
 
QString AutoProjectPart::projectName() const
322
 
{
323
 
    return m_projectName;
324
 
}
325
 
 
326
 
 
327
 
/** Retuns a PairList with the run environment variables */
328
 
DomUtil::PairList AutoProjectPart::runEnvironmentVars() const
329
 
{
330
 
    return DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/run/envvars", "envvar", "name", "value");
331
 
}
332
 
 
333
 
 
334
 
/** Retuns the currently selected run directory
335
 
  * If no main Program was selected in the Run Options dialog
336
 
  * use the currently active target instead to calculate it.
337
 
  * The returned string can be:
338
 
  *   if /kdevautoproject/run/directoryradio == executable
339
 
  *        The directory where the executable is
340
 
  *   if /kdevautoproject/run/directoryradio == build
341
 
  *        The directory where the executable is relative to build directory
342
 
  *   if /kdevautoproject/run/directoryradio == custom
343
 
  *        The custom directory absolute path
344
 
  */
345
 
QString AutoProjectPart::runDirectory() const
346
 
{
347
 
 
348
 
    QDomDocument &dom = *projectDom();
349
 
 
350
 
    QString cwd;
351
 
    if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
352
 
    {
353
 
        cwd = defaultRunDirectory("kdevautoproject");
354
 
    }else
355
 
    {
356
 
        cwd = DomUtil::readEntry( dom, "/kdevautoproject/run/cwd/"+m_widget->activeTarget()->name );
357
 
    }
358
 
    if( cwd.isEmpty() )
359
 
        cwd = buildDirectory() +"/"+ URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) +"/"+m_widget->activeDirectory();
360
 
 
361
 
    return cwd;
362
 
}
363
 
 
364
 
 
365
 
/** Retuns the currently selected main program
366
 
  * If no main Program was selected in the Run Options dialog
367
 
  * use the currently active target instead.
368
 
  * The returned string can be:
369
 
  *   if /kdevautoproject/run/directoryradio == executable
370
 
  *        The executable name
371
 
  *   if /kdevautoproject/run/directoryradio == build
372
 
  *        The path to executable relative to build directory
373
 
  *   if /kdevautoproject/run/directoryradio == custom or relative == false
374
 
  *        The absolute path to executable
375
 
  */
376
 
 
377
 
QString AutoProjectPart::mainProgram() const
378
 
{
379
 
    QDomDocument * dom = projectDom();
380
 
 
381
 
    if ( !dom ) return QString();
382
 
 
383
 
    if( DomUtil::readBoolEntry(*dom, "/kdevautoproject/run/useglobalprogram", false) )
384
 
    {
385
 
        QString DomMainProgram = DomUtil::readEntry(*dom, "/kdevautoproject/run/mainprogram");
386
 
 
387
 
        if ( DomMainProgram.isEmpty() ) return QString();
388
 
 
389
 
        if ( DomMainProgram.startsWith("/") )   // assume absolute path
390
 
        {
391
 
            return DomMainProgram;
392
 
        }
393
 
        else // assume builddir relative path
394
 
        {
395
 
            QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() );
396
 
            if( !relprojectpath.isEmpty() )
397
 
                relprojectpath = "/" + relprojectpath;
398
 
            return buildDirectory() + relprojectpath + "/" + DomMainProgram;
399
 
        }
400
 
 
401
 
    }
402
 
    else // If no Main Program was specified, return the active target
403
 
    {
404
 
        TargetItem* titem = m_widget->activeTarget();
405
 
 
406
 
        if ( !titem ) {
407
 
            KMessageBox::error( m_widget, i18n("There is no active target.\n"
408
 
                                "Unable to determine the main program."), i18n("No active target found") );
409
 
            kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
410
 
            return QString::null;
411
 
        }
412
 
 
413
 
        if ( titem->primary != "PROGRAMS" ) {
414
 
            KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n"
415
 
                                "Unable to determine the main program.  If you want this\n"
416
 
                                "to be the active target, set a main program under\n"
417
 
                                "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") );
418
 
            kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
419
 
            return QString::null;
420
 
        }
421
 
 
422
 
        QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() );
423
 
        if( !relprojectpath.isEmpty() )
424
 
            relprojectpath = "/" + relprojectpath;
425
 
        return buildDirectory() + relprojectpath + "/" + activeDirectory() + "/" + titem->name;
426
 
    }
427
 
}
428
 
 
429
 
 
430
 
/** Retuns a QString with the debug command line arguments */
431
 
QString AutoProjectPart::debugArguments() const
432
 
{
433
 
    QDomDocument &dom = *projectDom();
434
 
 
435
 
    if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
436
 
    {
437
 
        return DomUtil::readEntry(dom, "/kdevautoproject/run/globaldebugarguments");
438
 
    }else
439
 
    {
440
 
        return DomUtil::readEntry(dom, "/kdevautoproject/run/debugarguments/" + m_widget->activeTarget()->name);
441
 
    }
442
 
}
443
 
 
444
 
 
445
 
/** Retuns a QString with the run command line arguments */
446
 
QString AutoProjectPart::runArguments() const
447
 
{
448
 
    QDomDocument &dom = *projectDom();
449
 
 
450
 
    if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
451
 
    {
452
 
        return DomUtil::readEntry(dom, "/kdevautoproject/run/programargs");
453
 
    }else
454
 
    {
455
 
        return DomUtil::readEntry(dom, "/kdevautoproject/run/runarguments/" + m_widget->activeTarget()->name);
456
 
    }
457
 
}
458
 
 
459
 
 
460
 
QString AutoProjectPart::activeDirectory() const
461
 
{
462
 
    return m_widget->activeDirectory();
463
 
}
464
 
 
465
 
 
466
 
QStringList AutoProjectPart::allFiles() const
467
 
{
468
 
    return m_widget->allFiles();
469
 
}
470
 
 
471
 
 
472
 
void AutoProjectPart::setWantautotools()
473
 
{
474
 
    QDomDocument &dom = *projectDom();
475
 
    QDomElement el  = DomUtil::elementByPath(dom, "/kdevautoproject/make");
476
 
    if ( el.namedItem("envvars").isNull() ) {
477
 
        DomUtil::PairList list;
478
 
        list << DomUtil::Pair("WANT_AUTOCONF_2_5", "1");
479
 
        list << DomUtil::Pair("WANT_AUTOMAKE_1_6", "1");
480
 
        DomUtil::writePairListEntry(dom, "/kdevautoproject/make/envvars", "envvar", "name", "value", list);
481
 
    }
482
 
}
483
 
 
484
 
 
485
 
QString AutoProjectPart::makeEnvironment() const
486
 
{
487
 
    // Get the make environment variables pairs into the environstr string
488
 
    // in the form of: "ENV_VARIABLE=ENV_VALUE"
489
 
    // Note that we quote the variable value due to the possibility of
490
 
    // embedded spaces
491
 
    DomUtil::PairList envvars =
492
 
        DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/make/envvars", "envvar", "name", "value");
493
 
 
494
 
    QString environstr;
495
 
    DomUtil::PairList::ConstIterator it;
496
 
    for (it = envvars.begin(); it != envvars.end(); ++it)
497
 
    {
498
 
        environstr += (*it).first;
499
 
        environstr += "=";
500
 
        environstr += EnvVarTools::quote((*it).second);
501
 
        environstr += " ";
502
 
    }
503
 
 
504
 
    KConfigGroup grp( kapp->config(), "MakeOutputView" );
505
 
    if( grp.readBoolEntry( "ForceCLocale", true ) )
506
 
        environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" ";
507
 
 
508
 
    return environstr;
509
 
}
510
 
 
511
 
 
512
 
void AutoProjectPart::addFile(const QString &fileName)
513
 
{
514
 
    QStringList fileList;
515
 
    fileList.append ( fileName );
516
 
 
517
 
    this->addFiles ( fileList );
518
 
}
519
 
 
520
 
void AutoProjectPart::addFiles ( const QStringList& fileList )
521
 
{
522
 
    QString directory, name;
523
 
    QStringList::ConstIterator it;
524
 
    bool messageBoxShown = false;
525
 
 
526
 
    for ( it = fileList.begin(); it != fileList.end(); ++it )
527
 
    {
528
 
        int pos = ( *it ).findRev('/');
529
 
        if (pos != -1)
530
 
        {
531
 
            directory = ( *it ).left(pos);
532
 
            name = ( *it ).mid(pos+1);
533
 
        }
534
 
        else
535
 
        {
536
 
            directory = "";
537
 
            name = ( *it );
538
 
        }
539
 
 
540
 
        if (directory != m_widget->activeDirectory() ||
541
 
                directory.isEmpty())
542
 
        {
543
 
            if ( !messageBoxShown )
544
 
            {
545
 
                KMessageBox::information(m_widget, i18n("The directory you selected is not the active directory.\n"
546
 
                                                        "You should 'activate' the target you're currently working on in Automake Manager.\n"
547
 
                                                        "Just right-click a target and choose 'Make Target Active'."),
548
 
                                         i18n ( "No Active Target Found" ), "No automake manager active target warning" );
549
 
                messageBoxShown = true;
550
 
            }
551
 
        }
552
 
    }
553
 
 
554
 
    m_widget->addFiles(fileList);
555
 
}
556
 
 
557
 
void AutoProjectPart::removeFile(const QString &fileName)
558
 
{
559
 
        QStringList fileList;
560
 
        fileList.append ( fileName );
561
 
 
562
 
        this->removeFiles ( fileList );
563
 
}
564
 
 
565
 
void AutoProjectPart::removeFiles ( const QStringList& fileList )
566
 
{
567
 
        /// \FIXME m_widget->removeFiles does nothing!
568
 
        m_widget->removeFiles ( fileList );
569
 
 
570
 
        emit removedFilesFromProject ( fileList );
571
 
}
572
 
 
573
 
QStringList AutoProjectPart::allBuildConfigs() const
574
 
{
575
 
    QDomDocument &dom = *projectDom();
576
 
 
577
 
    QStringList allConfigs;
578
 
    allConfigs.append("default");
579
 
 
580
 
    QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations");
581
 
    QDomElement childEl = node.firstChild().toElement();
582
 
    while (!childEl.isNull())
583
 
    {
584
 
        QString config = childEl.tagName();
585
 
        kdDebug(9020) << k_funcinfo << "Found config " << config << endl;
586
 
        if (config != "default")
587
 
            allConfigs.append(config);
588
 
        childEl = childEl.nextSibling().toElement();
589
 
    }
590
 
 
591
 
    return allConfigs;
592
 
}
593
 
 
594
 
 
595
 
QString AutoProjectPart::currentBuildConfig() const
596
 
{
597
 
    QDomDocument &dom = *projectDom();
598
 
 
599
 
    QString config = DomUtil::readEntry(dom, "/kdevautoproject/general/useconfiguration");
600
 
    if (config.isEmpty() || !allBuildConfigs().contains(config))
601
 
        config = "default";
602
 
 
603
 
    return config;
604
 
}
605
 
 
606
 
 
607
 
QString AutoProjectPart::buildDirectory() const
608
 
{
609
 
    QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
610
 
 
611
 
    QString builddir = DomUtil::readEntry(*projectDom(), prefix + "builddir");
612
 
    if (builddir.isEmpty())
613
 
        return topsourceDirectory();
614
 
    else if (builddir.startsWith("/"))
615
 
        return builddir;
616
 
    else
617
 
        return projectDirectory() + "/" + builddir;
618
 
}
619
 
 
620
 
QString AutoProjectPart::topsourceDirectory() const
621
 
{
622
 
    QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
623
 
 
624
 
    QString topsourcedir = DomUtil::readEntry(*projectDom(), prefix + "topsourcedir");
625
 
    if (topsourcedir.isEmpty())
626
 
        return projectDirectory();
627
 
    else if (topsourcedir.startsWith("/"))
628
 
        return topsourcedir;
629
 
    else
630
 
        return projectDirectory() + "/" + topsourcedir;
631
 
}
632
 
 
633
 
QString AutoProjectPart::constructMakeCommandLine(const QString &dir, const QString &target) const
634
 
{
635
 
 
636
 
    QString preCommand;
637
 
    QFileInfo fi1();
638
 
    kdDebug(9020) << k_funcinfo << "Looking for Makefile in " << dir << endl;
639
 
    if ( !QFile::exists(dir + "/GNUmakefile") && !QFile::exists(dir + "/makefile")
640
 
            && ! QFile::exists(dir + "/Makefile") )
641
 
    {
642
 
        if (!QFile::exists(buildDirectory() + "/configure"))
643
 
        {
644
 
            int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory\n"
645
 
                                               "and no configure script for this project.\n"
646
 
                                               "Run automake & friends and configure first?").arg(buildDirectory()), QString::null, i18n("Run Them"), i18n("Do Not Run"));
647
 
            if (r == KMessageBox::No)
648
 
                return QString::null;
649
 
            preCommand = makefileCvsCommand();
650
 
            if (preCommand.isNull())
651
 
                return QString::null;
652
 
            preCommand += " && ";
653
 
            preCommand += configureCommand() + " && ";
654
 
        }
655
 
        else
656
 
        {
657
 
            int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory. Run 'configure' first?").arg(dir), QString::null, i18n("Run configure"), i18n("Do Not Run"));
658
 
            if (r == KMessageBox::No)
659
 
                return QString::null;
660
 
            preCommand = configureCommand() + " && ";
661
 
        }
662
 
    }
663
 
    QDomDocument &dom = *projectDom();
664
 
 
665
 
    QString cmdline = DomUtil::readEntry(dom, "/kdevautoproject/make/makebin");
666
 
    int prio = DomUtil::readIntEntry(dom, "/kdevautoproject/make/prio");
667
 
    QString nice;
668
 
    kdDebug(9020) << k_funcinfo << "nice = " << prio<< endl;
669
 
    if (prio != 0)
670
 
    {
671
 
        nice = QString("nice -n%1 ").arg(prio);
672
 
    }
673
 
 
674
 
    if (cmdline.isEmpty())
675
 
        cmdline = MAKE_COMMAND;
676
 
    if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/make/abortonerror"))
677
 
        cmdline += " -k";
678
 
    bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevautoproject/make/runmultiplejobs");
679
 
    int jobs = DomUtil::readIntEntry(dom, "/kdevautoproject/make/numberofjobs");
680
 
    if (runmultiple && jobs != 0)
681
 
    {
682
 
        cmdline += " -j";
683
 
        cmdline += QString::number(jobs);
684
 
    }
685
 
    if (DomUtil::readBoolEntry(dom, "/kdevautoproject/make/dontact"))
686
 
        cmdline += " -n";
687
 
 
688
 
    cmdline += " ";
689
 
    cmdline += target;
690
 
    cmdline.prepend(nice);
691
 
    cmdline.prepend(makeEnvironment());
692
 
 
693
 
    QString dircmd = "cd ";
694
 
    dircmd += KProcess::quote(dir);
695
 
    dircmd += " && ";
696
 
 
697
 
    return preCommand + dircmd + cmdline;
698
 
}
699
 
 
700
 
 
701
 
void AutoProjectPart::startMakeCommand(const QString &dir, const QString &target, bool withKdesu)
702
 
{
703
 
    if (partController()->saveAllFiles()==false)
704
 
       return; //user cancelled
705
 
    kdDebug(9020) << "startMakeCommand:" << dir << ": "<< target << endl;
706
 
    m_buildCommand = constructMakeCommandLine(dir, target);
707
 
 
708
 
    if (withKdesu)
709
 
        m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'";
710
 
 
711
 
    if (!m_buildCommand.isNull())
712
 
         makeFrontend()->queueCommand(dir, m_buildCommand);
713
 
}
714
 
 
715
 
 
716
 
/** Adds the make command for the libraries that the target depends on
717
 
  * to the make frontend queue (this is a recursive function) */
718
 
bool AutoProjectPart::queueInternalLibDependenciesBuild(TargetItem* titem, QStringList& alreadyScheduledDeps)
719
 
{
720
 
 
721
 
    QString addstr = (titem->primary == "PROGRAMS")? titem->ldadd : titem->libadd;
722
 
    QStringList l2 = QStringList::split(QRegExp("[ \t]"), addstr); // list of dependencies
723
 
    QString tdir;          // temp target directory
724
 
    QString tname;         // temp target name
725
 
    QString tcmd;          // temp command line
726
 
    QStringList::Iterator l2it;
727
 
    for (l2it = l2.begin(); l2it != l2.end(); ++l2it)
728
 
    {
729
 
        QString dependency = *l2it;
730
 
        if (dependency.startsWith("$(top_builddir)/"))
731
 
        {
732
 
            // These are the internal libraries
733
 
            dependency.remove("$(top_builddir)/");
734
 
 
735
 
            if( !alreadyScheduledDeps.contains(*l2it) )
736
 
            {
737
 
                alreadyScheduledDeps << *l2it;
738
 
                tdir = buildDirectory();
739
 
                if (!tdir.endsWith("/") && !tdir.isEmpty())
740
 
                    tdir += "/";
741
 
                int pos = dependency.findRev('/');
742
 
                if (pos == -1)
743
 
                {
744
 
                    tname = dependency;
745
 
                }
746
 
                else
747
 
                {
748
 
                    tdir += dependency.left(pos+1);
749
 
                    tname = dependency.mid(pos+1);
750
 
                }
751
 
                kdDebug(9020) << "Scheduling : <" << tdir << ">  target <" << tname << ">" << endl;
752
 
                // Recursively queue the dependencies for building
753
 
                SubprojectItem *spi = m_widget->subprojectItemForPath( dependency.left(pos) );
754
 
                if (spi)
755
 
                {
756
 
                    QPtrList< TargetItem > tl = spi->targets;
757
 
                    // Cycle through the list of targets to find the one we're looking for
758
 
                    TargetItem *ti = tl.first();
759
 
                    do
760
 
                    {
761
 
                        if (ti->name == tname)
762
 
                        {
763
 
                            // found it: queue it and stop looking
764
 
                            if( !queueInternalLibDependenciesBuild(ti, alreadyScheduledDeps) )
765
 
                                return false;
766
 
                            break;
767
 
                        }
768
 
                        ti = tl.next();
769
 
                    }
770
 
                    while (ti);
771
 
                }
772
 
 
773
 
                kdDebug(9020) << "queueInternalLibDependenciesBuild:" << tdir << ": "<< tname << endl;
774
 
                tcmd = constructMakeCommandLine(tdir, tname);
775
 
                if (!tcmd.isNull())
776
 
                {
777
 
                    makeFrontend()->queueCommand( tdir, tcmd);
778
 
                }
779
 
            }else
780
 
            {
781
 
                //Message box about circular deps.
782
 
                tdir = buildDirectory();
783
 
                if (!tdir.endsWith("/") && !tdir.isEmpty())
784
 
                    tdir += "/";
785
 
                int pos = dependency.findRev('/');
786
 
                if (pos == -1)
787
 
                {
788
 
                    tname = dependency;
789
 
                }
790
 
                else
791
 
                {
792
 
                    tdir += dependency.left(pos+1);
793
 
                    tname = dependency.mid(pos+1);
794
 
                }
795
 
                KMessageBox::error( 0, i18n("Found a circular dependency in the project, between this target and %1.\nCannot build this project until this is resolved.").arg(tname), i18n("Circular Dependency found") );
796
 
                return false;
797
 
            }
798
 
        }
799
 
    }
800
 
    return true;
801
 
}
802
 
 
803
 
 
804
 
void AutoProjectPart::slotBuild()
805
 
{
806
 
    //m_lastCompilationFailed = false;
807
 
 
808
 
    if( m_needMakefileCvs )
809
 
    {
810
 
        slotMakefilecvs();
811
 
        slotConfigure();
812
 
        m_needMakefileCvs = false;
813
 
    }
814
 
 
815
 
    startMakeCommand(buildDirectory(), QString::fromLatin1(""));
816
 
}
817
 
 
818
 
 
819
 
void AutoProjectPart::buildTarget(QString relpath, TargetItem* titem)
820
 
{
821
 
 
822
 
    if ( !titem )
823
 
        return;
824
 
 
825
 
    //m_lastCompilationFailed = false;
826
 
 
827
 
    // Calculate the complete name of the target and store it in name
828
 
    QString name = titem->name;
829
 
    if ( titem->primary == "KDEDOCS" )
830
 
        name = "index.cache.bz2";
831
 
 
832
 
    // Calculate the full path of the target and store it in path
833
 
    QString path = buildDirectory();
834
 
    if (!path.endsWith("/") && !path.isEmpty())
835
 
        path += "/";
836
 
    if (relpath.at(0) == '/')
837
 
        path += relpath.mid(1);
838
 
    else
839
 
        path += relpath;
840
 
 
841
 
    // Save all files once
842
 
    partController()->saveAllFiles();
843
 
 
844
 
    // Add the make command for the libraries that the target depends on to the make frontend queue
845
 
    // if this recursive behavour is un-wanted comment the next line
846
 
    QStringList deps;
847
 
    if( !queueInternalLibDependenciesBuild(titem, deps) )
848
 
        return;
849
 
 
850
 
    // Calculate the "make" command line for the target
851
 
    //QString relpath = dir.path().mid( projectDirectory().length() );
852
 
    m_runProg=buildDirectory() + "/" + relpath+"/"+name;
853
 
    kdDebug(9020) << "buildTarget:" << buildDirectory()<< endl;
854
 
    kdDebug(9020) << "buildTarget:" << relpath << "  " << path << ": "<< name << " : " << m_runProg << endl;
855
 
    QString tcmd = constructMakeCommandLine( path, name );
856
 
 
857
 
    // Call make
858
 
    if (!tcmd.isNull())
859
 
    {
860
 
        m_buildCommand = tcmd;
861
 
        makeFrontend()->queueCommand( path, tcmd);
862
 
    }
863
 
}
864
 
 
865
 
 
866
 
void AutoProjectPart::slotBuildActiveTarget()
867
 
{
868
 
  // Get a pointer to the active target
869
 
  TargetItem* titem = m_widget->activeTarget();
870
 
 
871
 
  if ( !titem )
872
 
    return;
873
 
 
874
 
  // build it
875
 
  buildTarget( URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + activeDirectory(), titem);
876
 
}
877
 
 
878
 
 
879
 
void AutoProjectPart::slotCompileFile()
880
 
{
881
 
    KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
882
 
    if (!part || !part->url().isLocalFile())
883
 
        return;
884
 
 
885
 
    QString fileName = part->url().path();
886
 
    QFileInfo fi(fileName);
887
 
    QString sourceDir = fi.dirPath();
888
 
    QString baseName = fi.baseName(true);
889
 
    kdDebug(9020) << "Compiling " << fileName
890
 
                  << " in dir " << sourceDir
891
 
                  << " with baseName " << baseName << endl;
892
 
 
893
 
    QString projectDir = projectDirectory();
894
 
    if (!sourceDir.startsWith(projectDir)) {
895
 
        KMessageBox::sorry(m_widget, i18n("Can only compile files in directories which belong to the project."));
896
 
        return;
897
 
    }
898
 
 
899
 
    QString buildDir = buildDirectory() + sourceDir.mid(projectDir.length());
900
 
    QString target = baseName + ".lo";
901
 
    kdDebug(9020) << "builddir " << buildDir << ", target " << target << endl;
902
 
 
903
 
    startMakeCommand(buildDir, target);
904
 
}
905
 
 
906
 
QString AutoProjectPart::configureCommand() const
907
 
{
908
 
    QDomDocument &dom = *projectDom();
909
 
    QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
910
 
 
911
 
    QString cmdline = "\"" + topsourceDirectory();
912
 
    cmdline += "/configure\"";
913
 
    QString cc = DomUtil::readEntry(dom, prefix + "ccompilerbinary");
914
 
    if (!cc.isEmpty())
915
 
        cmdline.prepend(QString("CC=%1 ").arg(cc));
916
 
    QString cflags = DomUtil::readEntry(dom, prefix + "cflags");
917
 
    if (!cflags.isEmpty())
918
 
        cmdline.prepend(QString("CFLAGS=\"%1\" ").arg(cflags));
919
 
    QString cxx = DomUtil::readEntry(dom, prefix + "cxxcompilerbinary");
920
 
    if (!cxx.isEmpty())
921
 
        cmdline.prepend(QString("CXX=%1 ").arg(cxx));
922
 
    QString cxxflags = DomUtil::readEntry(dom, prefix + "cxxflags");
923
 
    if (!cxxflags.isEmpty())
924
 
        cmdline.prepend(QString("CXXFLAGS=\"%1\" ").arg(cxxflags));
925
 
    QString f77 = DomUtil::readEntry(dom, prefix + "f77compilerbinary");
926
 
    if (!f77.isEmpty())
927
 
        cmdline.prepend(QString("F77=%1 ").arg(f77));
928
 
    QString fflags = DomUtil::readEntry(dom, prefix + "f77flags");
929
 
    if (!fflags.isEmpty())
930
 
        cmdline.prepend(QString("FFLAGS=\"%1\" ").arg(fflags));
931
 
    QString cppflags = DomUtil::readEntry(dom, prefix + "cppflags");
932
 
    if (!cppflags.isEmpty())
933
 
        cmdline.prepend(QString("CPPFLAGS=\"%1\" ").arg(cppflags));
934
 
    QString ldflags = DomUtil::readEntry(dom, prefix + "ldflags");
935
 
    if (!ldflags.isEmpty())
936
 
        cmdline.prepend(QString("LDFLAGS=\"%1\" ").arg(ldflags));
937
 
 
938
 
    QString configargs = DomUtil::readEntry(dom, prefix + "configargs");
939
 
    if (!configargs.isEmpty()) {
940
 
        cmdline += " ";
941
 
        cmdline += configargs;
942
 
    }
943
 
 
944
 
   DomUtil::PairList envvars =
945
 
        DomUtil::readPairListEntry(*projectDom(), prefix + "envvars", "envvar", "name", "value");
946
 
 
947
 
    QString environstr;
948
 
    DomUtil::PairList::ConstIterator it;
949
 
    for (it = envvars.begin(); it != envvars.end(); ++it) {
950
 
        environstr += (*it).first;
951
 
        environstr += "=";
952
 
        environstr += EnvVarTools::quote((*it).second);
953
 
        environstr += " ";
954
 
    }
955
 
    cmdline.prepend(environstr);
956
 
 
957
 
    QString builddir = buildDirectory();
958
 
    QString dircmd;
959
 
 
960
 
    // if the build directory doesn't exist, add it's creation to the configureCommand
961
 
    if ( !QFile::exists(builddir)) {
962
 
        dircmd = "mkdir ";
963
 
        dircmd += KProcess::quote(builddir);
964
 
        dircmd += " && ";
965
 
    }
966
 
 
967
 
    // add "cd into the build directory" to the configureCommand
968
 
    dircmd += "cd ";
969
 
    dircmd += KProcess::quote(builddir);
970
 
    dircmd += " && ";
971
 
 
972
 
    return dircmd + cmdline;
973
 
}
974
 
 
975
 
void AutoProjectPart::slotConfigure()
976
 
{
977
 
    QString cmdline = configureCommand();
978
 
    if (cmdline.isNull())
979
 
        return;
980
 
 
981
 
    makeFrontend()->queueCommand(buildDirectory(), cmdline);
982
 
}
983
 
 
984
 
QString AutoProjectPart::makefileCvsCommand() const
985
 
{
986
 
    kdDebug(9020) << "makefileCvsCommand: runDirectory       :" << runDirectory() << ":" <<endl;
987
 
    kdDebug(9020) << "makefileCvsCommand: topsourceDirectory :" << topsourceDirectory() << ":" <<endl;
988
 
    kdDebug(9020) << "makefileCvsCommand: makeEnvironment    :" << makeEnvironment() << ":" <<endl;
989
 
    kdDebug(9020) << "makefileCvsCommand: currentBuildConfig :" << currentBuildConfig() << ":" <<endl;
990
 
 
991
 
 
992
 
    QString cmdline = DomUtil::readEntry(*projectDom(), "/kdevautoproject/make/makebin");
993
 
    if (cmdline.isEmpty())
994
 
        cmdline = MAKE_COMMAND;
995
 
 
996
 
    int prio = DomUtil::readIntEntry(*projectDom(), "/kdevautoproject/make/prio");
997
 
    QString nice;
998
 
    kdDebug(9020) << "makefileCvsCommand() nice = " << prio<< endl;
999
 
    if (prio != 0) {
1000
 
        nice = QString("nice -n%1 ").arg(prio);
1001
 
    }
1002
 
 
1003
 
    if (QFile::exists(topsourceDirectory() + "/Makefile.cvs"))
1004
 
        cmdline += " -f Makefile.cvs";
1005
 
    else if (QFile::exists(topsourceDirectory() + "/Makefile.dist"))
1006
 
        cmdline += " -f Makefile.dist";
1007
 
    else if (QFile::exists(topsourceDirectory() + "/autogen.sh"))
1008
 
        cmdline = "./autogen.sh";
1009
 
    else {
1010
 
        KMessageBox::sorry(m_widget, i18n("There is neither a Makefile.cvs file nor an "
1011
 
                                          "autogen.sh script in the project directory."));
1012
 
        return QString::null;
1013
 
    }
1014
 
 
1015
 
    cmdline.prepend(nice);
1016
 
    cmdline.prepend(makeEnvironment());
1017
 
 
1018
 
    QString dircmd = "cd ";
1019
 
    dircmd += KProcess::quote(topsourceDirectory());
1020
 
    dircmd += " && ";
1021
 
 
1022
 
    return dircmd + cmdline;
1023
 
}
1024
 
 
1025
 
void AutoProjectPart::slotMakefilecvs()
1026
 
{
1027
 
    QString cmdline = makefileCvsCommand();
1028
 
    if ( cmdline.isNull() )
1029
 
        return;
1030
 
 
1031
 
    makeFrontend()->queueCommand(projectDirectory(), cmdline);
1032
 
}
1033
 
 
1034
 
 
1035
 
void AutoProjectPart::slotInstall()
1036
 
{
1037
 
    startMakeCommand(buildDirectory(), QString::fromLatin1("install"));
1038
 
}
1039
 
 
1040
 
 
1041
 
void AutoProjectPart::slotInstallWithKdesu()
1042
 
{
1043
 
    // First issue "make" to build the entire project with the current user
1044
 
    // This way we make sure all files are up to date before we do the "make install"
1045
 
    slotBuild();
1046
 
 
1047
 
    // After that issue "make install" with the root user
1048
 
    startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true);
1049
 
}
1050
 
 
1051
 
 
1052
 
void AutoProjectPart::slotClean()
1053
 
{
1054
 
    startMakeCommand(buildDirectory(), QString::fromLatin1("clean"));
1055
 
}
1056
 
 
1057
 
 
1058
 
void AutoProjectPart::slotDistClean()
1059
 
{
1060
 
    startMakeCommand(buildDirectory(), QString::fromLatin1("distclean"));
1061
 
}
1062
 
 
1063
 
 
1064
 
void AutoProjectPart::slotMakeMessages()
1065
 
{
1066
 
    startMakeCommand(buildDirectory(), QString::fromLatin1("package-messages"));
1067
 
}
1068
 
 
1069
 
 
1070
 
/** Checks if the currently selected main program or,
1071
 
  * if no main Program was selected in the Run Options dialog,
1072
 
  * the currently active target is up-to-date and builds it if necessary.
1073
 
  * In the end checks if the program is already running and if not calls the
1074
 
  * slotExecute2() function to execute it or asks the user what to do.
1075
 
  */
1076
 
void AutoProjectPart::slotExecute()
1077
 
{
1078
 
    partController()->saveAllFiles();
1079
 
    QDomDocument &dom = *projectDom();
1080
 
 
1081
 
    m_runProg=m_runProg.isEmpty()?mainProgram():m_runProg;
1082
 
 
1083
 
    bool _auto = false;
1084
 
    if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autocompile", true) && isDirty() ){
1085
 
        m_executeAfterBuild = true;
1086
 
        if ( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) ){
1087
 
          // A Main Program was specified, build all targets because we don't know which is it
1088
 
            kdDebug(9020) << "slotExecute: before slotBuild" << endl;
1089
 
            slotBuild();
1090
 
 
1091
 
        }
1092
 
        else{
1093
 
          // If no Main Program was specified, build the active target
1094
 
            kdDebug(9020) << "slotExecute: before slotBuildActiveTarget" << endl;
1095
 
            slotBuildActiveTarget();
1096
 
        }
1097
 
        _auto = true;
1098
 
    }
1099
 
 
1100
 
    if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autoinstall", false) && isDirty() ){
1101
 
        m_executeAfterBuild = true;
1102
 
        // Use kdesu??
1103
 
        if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autokdesu", false) ){
1104
 
            //slotInstallWithKdesu assumes that it hasn't just been build...
1105
 
            kdDebug(9020) << "slotExecute: before startMakeCommand" << endl;
1106
 
            _auto ? slotInstallWithKdesu() : startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true);
1107
 
        }
1108
 
        else{
1109
 
            kdDebug(9020) << "slotExecute: before slotInstall" << endl;
1110
 
            slotInstall();
1111
 
        }
1112
 
        _auto = true;
1113
 
    }
1114
 
 
1115
 
    if ( _auto ){
1116
 
        m_runProg.truncate(0);
1117
 
        return;
1118
 
    }
1119
 
 
1120
 
    if (appFrontend()->isRunning()) {
1121
 
        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)
1122
 
            return;
1123
 
        connect(appFrontend(), SIGNAL(processExited()), SLOT(slotExecute2()));
1124
 
        appFrontend()->stopApplication();
1125
 
        return;
1126
 
    }
1127
 
    kdDebug(9020) << "slotExecute: before slotExecute2" << endl;
1128
 
    slotExecute2();
1129
 
}
1130
 
 
1131
 
void AutoProjectPart::executeTarget(const QDir& dir, const TargetItem* titem)
1132
 
{
1133
 
    m_executeAfterBuild=true;
1134
 
    partController()->saveAllFiles();
1135
 
 
1136
 
    bool is_dirty = false;
1137
 
    QDateTime t = QFileInfo(dir , titem->name ).lastModified();
1138
 
    QPtrListIterator<FileItem> it( titem->sources );
1139
 
    for( ; it.current() ; ++it )
1140
 
    {
1141
 
        if( t < QFileInfo(dir , (*it)->name).lastModified())
1142
 
            is_dirty = true;
1143
 
    }
1144
 
 
1145
 
    if( DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/autocompile", true) && is_dirty )
1146
 
    {
1147
 
        connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild(const QString&)) );
1148
 
        connect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed(const QString&)) );
1149
 
 
1150
 
        m_runProg=titem->name;
1151
 
        m_executeTargetAfterBuild.first = dir;
1152
 
        m_executeTargetAfterBuild.second = const_cast<TargetItem*>(titem);
1153
 
 
1154
 
        QString relpath = "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->subdir;
1155
 
        kdDebug(9020) << "executeTarget: before buildTarget " << relpath << endl;
1156
 
        buildTarget(relpath, const_cast<TargetItem*>(titem));
1157
 
        return;
1158
 
    }
1159
 
 
1160
 
 
1161
 
    bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal");
1162
 
 
1163
 
    QString program = environString();
1164
 
 
1165
 
    if ( !titem ) {
1166
 
        KMessageBox::error( m_widget, i18n("There is no active target.\n"
1167
 
                                "Unable to determine the main program"), i18n("No active target found") );
1168
 
        kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
1169
 
        program += titem->name;
1170
 
    }else if ( titem->primary != "PROGRAMS" ) {
1171
 
        KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n"
1172
 
                                "Unable to determine the main program. If you want this\n"
1173
 
                                "to be the active target, set a main program under\n"
1174
 
                                "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") );
1175
 
        kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
1176
 
        program += titem->name;
1177
 
    }else
1178
 
        program += buildDirectory() + "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath()+ "/" + titem->name;
1179
 
 
1180
 
    QString args = DomUtil::readEntry(*projectDom(), "/kdevautoproject/run/runarguments/" + titem->name);
1181
 
 
1182
 
    program += " " + args;
1183
 
    kdDebug(9020) << "executeTarget:cmd=" << dir.path() << " " << program << endl;
1184
 
    appFrontend()->startAppCommand(dir.path(), program ,inTerminal);
1185
 
    m_executeAfterBuild=false;
1186
 
 
1187
 
}
1188
 
 
1189
 
void AutoProjectPart::slotExecuteTargetAfterBuild(const QString& command)
1190
 
{
1191
 
    kdDebug(9020) << "slotExecuteTargetAfterBuild " << command << endl;
1192
 
    if ( m_executeAfterBuild && constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command )
1193
 
    {
1194
 
        disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteAfterTargetBuild()) );
1195
 
        disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotExecuteAfterTargetBuildFailed()) );
1196
 
        kdDebug(9020) << "slotExecuteTargetAfterBuild " << endl;
1197
 
        executeTarget(m_executeTargetAfterBuild.first, m_executeTargetAfterBuild.second);
1198
 
    }
1199
 
 
1200
 
}
1201
 
 
1202
 
void AutoProjectPart::slotNotExecuteTargetAfterBuildFailed(const QString& command)
1203
 
{
1204
 
    kdDebug(9020) << "executeTargetAfterBuildFailed" << endl;
1205
 
    if ( constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command )
1206
 
    {
1207
 
        m_executeAfterBuild=false;
1208
 
        disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild()) );
1209
 
        disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed()) );
1210
 
    }
1211
 
}
1212
 
 
1213
 
 
1214
 
/* Get the run environment variables pairs into the environstr string
1215
 
 * in the form of: "ENV_VARIABLE=ENV_VALUE"
1216
 
 * Note that we quote the variable value due to the possibility of
1217
 
 * embedded spaces. */
1218
 
QString AutoProjectPart::environString() const
1219
 
{
1220
 
    DomUtil::PairList envvars = runEnvironmentVars();
1221
 
    QString environstr;
1222
 
    DomUtil::PairList::ConstIterator it;
1223
 
    for (it = envvars.begin(); it != envvars.end(); ++it) {
1224
 
        environstr += (*it).first;
1225
 
        environstr += "=";
1226
 
        environstr += EnvVarTools::quote((*it).second);
1227
 
        environstr += " ";
1228
 
    }
1229
 
 return environstr;
1230
 
}
1231
 
 
1232
 
/** Executes the currently selected main program.
1233
 
  * If no main Program was selected in the Run Options dialog
1234
 
  * the currently active target is executed instead.
1235
 
  */
1236
 
void AutoProjectPart::slotExecute2()
1237
 
{
1238
 
    disconnect(appFrontend(), SIGNAL(processExited()), this, SLOT(slotExecute2()));
1239
 
 
1240
 
    if (m_runProg.isEmpty()){
1241
 
        // Do not execute non executable targets
1242
 
        return;
1243
 
    }
1244
 
 
1245
 
    QString program = environString();
1246
 
    // Adds the ./ that is necessary to execute the program in bash shells
1247
 
    if (!m_runProg.startsWith("/")){
1248
 
        program += "./";
1249
 
    }
1250
 
    program += m_runProg;
1251
 
    program += " " + runArguments();
1252
 
 
1253
 
    bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal");
1254
 
 
1255
 
    kdDebug(9020) << "slotExecute2: runDirectory: <" << runDirectory() << ">" <<endl;
1256
 
    kdDebug(9020) << "slotExecute2: environstr  : <" << environString() << ">" <<endl;
1257
 
    kdDebug(9020) << "slotExecute2: mainProgram : <" << mainProgram() << ">" <<endl;
1258
 
    kdDebug(9020) << "slotExecute2: runArguments: <" << runArguments() << ">" <<endl;
1259
 
    kdDebug(9020) << "slotExecute2: program     : <" << program << ">" <<endl;
1260
 
 
1261
 
    appFrontend()->startAppCommand(runDirectory(), program, inTerminal);
1262
 
    m_executeAfterBuild=false;
1263
 
    m_runProg.truncate(0);
1264
 
}
1265
 
 
1266
 
 
1267
 
void AutoProjectPart::slotAddTranslation()
1268
 
{
1269
 
    AddTranslationDialog dlg(this, m_widget);
1270
 
    dlg.exec();
1271
 
}
1272
 
 
1273
 
 
1274
 
void AutoProjectPart::slotBuildConfigChanged(const QString &config)
1275
 
{
1276
 
    DomUtil::writeEntry(*projectDom(), "/kdevautoproject/general/useconfiguration", config);
1277
 
    kdDebug(9020) << "Changed used configuration to " << config << endl;
1278
 
}
1279
 
 
1280
 
 
1281
 
void AutoProjectPart::slotBuildConfigAboutToShow()
1282
 
{
1283
 
    QStringList l = allBuildConfigs();
1284
 
    buildConfigAction->setItems(l);
1285
 
    buildConfigAction->setCurrentItem(l.findIndex(currentBuildConfig()));
1286
 
}
1287
 
 
1288
 
void AutoProjectPart::restorePartialProjectSession ( const QDomElement* el )
1289
 
{
1290
 
    m_widget->restoreSession ( el );
1291
 
}
1292
 
 
1293
 
void AutoProjectPart::savePartialProjectSession ( QDomElement* el )
1294
 
{
1295
 
    QDomDocument domDoc = el->ownerDocument();
1296
 
 
1297
 
    KMessageBox::information ( 0, "Hallo, Welt!" );
1298
 
 
1299
 
    kdDebug ( 9020 ) << k_funcinfo << "1" << endl;
1300
 
 
1301
 
    if ( domDoc.isNull() )
1302
 
    {
1303
 
        kdDebug ( 9020 ) << k_funcinfo << "2" << endl;
1304
 
        return;
1305
 
    }
1306
 
 
1307
 
    kdDebug ( 9020 ) << k_funcinfo << "3" << endl;
1308
 
 
1309
 
    m_widget->saveSession ( el );
1310
 
}
1311
 
 
1312
 
void AutoProjectPart::slotCommandFinished( const QString& command )
1313
 
{
1314
 
    kdDebug(9020) << k_funcinfo << endl;
1315
 
 
1316
 
    if( m_buildCommand != command )
1317
 
        return;
1318
 
 
1319
 
    m_buildCommand = QString::null;
1320
 
 
1321
 
    m_timestamp.clear();
1322
 
    QStringList fileList = allFiles();
1323
 
    QStringList::Iterator it = fileList.begin();
1324
 
    while( it != fileList.end() ){
1325
 
        QString fileName = *it;
1326
 
        ++it;
1327
 
 
1328
 
        m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified();
1329
 
    }
1330
 
 
1331
 
    emit projectCompiled();
1332
 
 
1333
 
    // reset the "last compilation has failed" flag
1334
 
    m_lastCompilationFailed = false;
1335
 
 
1336
 
    if( m_executeAfterBuild ){
1337
 
        slotExecute();
1338
 
    }
1339
 
}
1340
 
 
1341
 
void AutoProjectPart::slotCommandFailed( const QString& /*command*/ )
1342
 
{
1343
 
    kdDebug(9020) << "slotCommandFinished " << k_funcinfo << endl;
1344
 
 
1345
 
    m_lastCompilationFailed = true;
1346
 
    m_executeAfterBuild=false;
1347
 
}
1348
 
 
1349
 
bool AutoProjectPart::isDirty()
1350
 
{
1351
 
    if (m_lastCompilationFailed) return true;
1352
 
 
1353
 
    QStringList fileList = allFiles();
1354
 
    QStringList::Iterator it = fileList.begin();
1355
 
    while( it != fileList.end() ){
1356
 
        QString fileName = *it;
1357
 
        ++it;
1358
 
 
1359
 
        QMap<QString, QDateTime>::Iterator it = m_timestamp.find( fileName );
1360
 
        QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified();
1361
 
        if( it == m_timestamp.end() || *it != t ){
1362
 
            return true;
1363
 
        }
1364
 
    }
1365
 
 
1366
 
    return false;
1367
 
}
1368
 
 
1369
 
void AutoProjectPart::needMakefileCvs( )
1370
 
{
1371
 
    m_needMakefileCvs = true;
1372
 
}
1373
 
 
1374
 
bool AutoProjectPart::isKDE() const
1375
 
{
1376
 
    return m_isKDE;
1377
 
}
1378
 
 
1379
 
KDevProject::Options AutoProjectPart::options() const
1380
 
{
1381
 
    return UsesAutotoolsBuildSystem;
1382
 
}
1383
 
 
1384
 
QStringList recursiveATFind( const QString &currDir, const QString &baseDir )
1385
 
{
1386
 
    kdDebug(9020) << "Dir " << currDir << endl;
1387
 
    QStringList fileList;
1388
 
 
1389
 
    if( !currDir.contains( "/..") && !currDir.contains("/.") )
1390
 
    {
1391
 
        QDir dir(currDir);
1392
 
        QStringList dirList = dir.entryList(QDir::Dirs );
1393
 
        QStringList::Iterator idx = dirList.begin();
1394
 
        for( ; idx != dirList.end(); ++idx )
1395
 
        {
1396
 
            fileList += recursiveATFind( currDir + "/" + (*idx),baseDir );
1397
 
        }
1398
 
        QStringList newFiles = dir.entryList("*.am *.in");
1399
 
        idx = newFiles.begin();
1400
 
        for( ; idx != newFiles.end(); ++idx )
1401
 
        {
1402
 
            QString file = currDir + "/" + (*idx);
1403
 
            fileList.append( file.remove( baseDir ) );
1404
 
        }
1405
 
    }
1406
 
 
1407
 
 
1408
 
    return fileList;
1409
 
}
1410
 
 
1411
 
/*!
1412
 
    \fn AutoProjectPart::distFiles() const
1413
 
 */
1414
 
QStringList AutoProjectPart::distFiles() const
1415
 
{
1416
 
    QStringList sourceList = allFiles();
1417
 
    // Scan current source directory for any .pro files.
1418
 
    QString projectDir = projectDirectory();
1419
 
    QDir dir(projectDir);
1420
 
    QDir admin(projectDir +"/admin");
1421
 
    QStringList files = dir.entryList( "Makefile.cvs Makefile.am configure* INSTALL README NEWS TODO ChangeLog COPYING AUTHORS stamp-h.in acinclude.m4 config.h.in Makefile.in install-sh config.sub config.guess mkinstalldirs missing ltmain.sh depcomp");
1422
 
    QStringList adminFiles = admin.entryList(QDir::Files);
1423
 
    QStringList::Iterator idx = adminFiles.begin();
1424
 
    for( ; idx != adminFiles.end(); ++idx)
1425
 
    {
1426
 
        files.append( "admin/" + (*idx) );
1427
 
    }
1428
 
    QStringList srcDirs = dir.entryList(QDir::Dirs);
1429
 
    idx = srcDirs.begin();
1430
 
    for(; idx != srcDirs.end(); ++idx)
1431
 
    {
1432
 
        sourceList += recursiveATFind( projectDirectory() + "/" + (*idx), projectDirectory());
1433
 
    }
1434
 
    return sourceList + files;
1435
 
}
1436
 
 
1437
 
void AutoProjectPart::startSimpleMakeCommand( const QString & dir, const QString & command, bool withKdesu )
1438
 
{
1439
 
    if (partController()->saveAllFiles()==false)
1440
 
        return; //user cancelled
1441
 
 
1442
 
    //  m_buildCommand = constructMakeCommandLine(dir, target);
1443
 
 
1444
 
    QString cmdline = command;
1445
 
    cmdline.prepend(makeEnvironment());
1446
 
 
1447
 
    QString dircmd = "cd ";
1448
 
    dircmd += KProcess::quote(dir);
1449
 
    dircmd += " && ";
1450
 
 
1451
 
    m_buildCommand = dircmd + cmdline;
1452
 
 
1453
 
    if (withKdesu)
1454
 
        m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'";
1455
 
 
1456
 
    if (!m_buildCommand.isNull())
1457
 
        makeFrontend()->queueCommand(dir, m_buildCommand);
1458
 
}
1459
 
 
1460
 
QString AutoProjectPart::getAutoConfFile(const QString& dir){
1461
 
 
1462
 
    QFile inFile(dir + "/configure.in");
1463
 
    QFile acFile(dir + "/configure.ac");
1464
 
    if ( inFile.exists()){
1465
 
        return inFile.name();
1466
 
    }else if (acFile.exists()){
1467
 
        return acFile.name();
1468
 
    }
1469
 
    return acFile.name();;
1470
 
}
1471
 
 
1472
 
#include "autoprojectpart.moc"
1473
 
 
1474
 
// kate: space-indent on; indent-width 4;