You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1475 lines
54 KiB
1475 lines
54 KiB
/***************************************************************************
|
|
* Copyright (C) 2001-2002 by Bernd Gehrmann *
|
|
* bernd@kdevelop.org *
|
|
* *
|
|
* Copyright (C) 2002 by Victor Roeder *
|
|
* victor_roeder@gmx.de *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <config.h>
|
|
|
|
#include "autoprojectpart.h"
|
|
#include "autolistviewitems.h"
|
|
#include "configureoptionswidget.h"
|
|
#include "addtranslationdlg.h"
|
|
#include "addicondlg.h"
|
|
#include "autoprojectwidget.h"
|
|
|
|
#include <tqdom.h>
|
|
#include <tqdir.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqpopupmenu.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqregexp.h>
|
|
#include <tqgroupbox.h>
|
|
|
|
|
|
#include <kapplication.h>
|
|
#include <kconfig.h>
|
|
#include <kaction.h>
|
|
#include <kdebug.h>
|
|
#include <kdialogbase.h>
|
|
#include <kiconloader.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kparts/part.h>
|
|
#include <kdeversion.h>
|
|
#include <kprocess.h>
|
|
|
|
#include <domutil.h>
|
|
#include <kdevcore.h>
|
|
#include <kdevmakefrontend.h>
|
|
#include <kdevappfrontend.h>
|
|
#include <kdevmainwindow.h>
|
|
#include <kdevpartcontroller.h>
|
|
#include <makeoptionswidget.h>
|
|
#include <runoptionswidget.h>
|
|
#include <envvartools.h>
|
|
|
|
#include <configwidgetproxy.h>
|
|
#include <kdevplugininfo.h>
|
|
#include <urlutil.h>
|
|
|
|
#define CONFIGURE_OPTIONS 1
|
|
#define RUN_OPTIONS 2
|
|
#define MAKE_OPTIONS 3
|
|
|
|
static const KDevPluginInfo data("kdevautoproject");
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( libkdevautoproject, AutoProjectFactory( data ) )
|
|
|
|
AutoProjectPart::AutoProjectPart(TQObject *parent, const char *name, const TQStringList &args)
|
|
: KDevBuildTool(&data, parent, name ? name : "AutoProjectPart")
|
|
, m_lastCompilationFailed(false)
|
|
{
|
|
setInstance(AutoProjectFactory::instance());
|
|
|
|
setXMLFile("kdevautoproject.rc");
|
|
|
|
m_executeAfterBuild = false;
|
|
m_isKDE = (args[0] == "kde");
|
|
m_needMakefileCvs = false;
|
|
|
|
m_widget = new AutoProjectWidget(this, m_isKDE);
|
|
m_widget->setIcon(SmallIcon( info()->icon() ));
|
|
m_widget->setCaption(i18n("Automake Manager"));
|
|
TQWhatsThis::add(m_widget, i18n("<b>Automake manager</b><p>"
|
|
"The project tree consists of two parts. The 'overview' "
|
|
"in the upper half shows the subprojects, each one having a "
|
|
"Makefile.am. The 'details' view in the lower half shows the "
|
|
"targets and files for the subproject selected in the overview."));
|
|
|
|
mainWindow()->embedSelectViewRight(m_widget, i18n("Automake Manager"), i18n("Automake manager"));
|
|
KAction *action;
|
|
|
|
action = new KAction( i18n("Add Translation..."), 0,
|
|
this, TQT_SLOT(slotAddTranslation()),
|
|
actionCollection(), "project_addtranslation" );
|
|
action->setToolTip(i18n("Add translation"));
|
|
action->setWhatsThis(i18n("<b>Add translation</b><p>Creates .po file for the selected language."));
|
|
action->setGroup("autotools");
|
|
|
|
|
|
if (!m_isKDE)
|
|
action->setEnabled(false);
|
|
|
|
action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8,
|
|
this, TQT_SLOT(slotBuild()),
|
|
actionCollection(), "build_build" );
|
|
action->setToolTip(i18n("Build project"));
|
|
action->setWhatsThis(i18n("<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Build &Active Target"), "make_kdevelop", Key_F7,
|
|
this, TQT_SLOT(slotBuildActiveTarget()),
|
|
actionCollection(), "build_buildactivetarget" );
|
|
action->setToolTip(i18n("Build active target"));
|
|
action->setWhatsThis(i18n("<b>Build active target</b><p>Constructs a series of make commands to build an active target. "
|
|
"Also builds dependent targets.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Compile &File"), "make_kdevelop",
|
|
this, TQT_SLOT(slotCompileFile()),
|
|
actionCollection(), "build_compilefile" );
|
|
action->setToolTip(i18n("Compile file"));
|
|
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>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Run Configure"), 0,
|
|
this, TQT_SLOT(slotConfigure()),
|
|
actionCollection(), "build_configure" );
|
|
action->setToolTip(i18n("Run configure"));
|
|
action->setWhatsThis(i18n("<b>Run configure</b><p>Executes <b>configure</b> with flags, arguments "
|
|
"and environment variables specified in the project settings dialog, "
|
|
"<b>Configure Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Run automake && friends"), 0,
|
|
this, TQT_SLOT(slotMakefilecvs()),
|
|
actionCollection(), "build_makefilecvs" );
|
|
action->setToolTip(i18n("Run automake && friends"));
|
|
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."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Install"), 0,
|
|
this, TQT_SLOT(slotInstall()),
|
|
actionCollection(), "build_install" );
|
|
action->setToolTip(i18n("Install"));
|
|
action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Install (as root user)"), 0,
|
|
this, TQT_SLOT(slotInstallWithKdesu()),
|
|
actionCollection(), "build_install_kdesu" );
|
|
action->setToolTip(i18n("Install as root user"));
|
|
action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory with root privileges.<br>"
|
|
"It is executed via kdesu command.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("&Clean Project"), 0,
|
|
this, TQT_SLOT(slotClean()),
|
|
actionCollection(), "build_clean" );
|
|
action->setToolTip(i18n("Clean project"));
|
|
action->setWhatsThis(i18n("<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("&Distclean"), 0,
|
|
this, TQT_SLOT(slotDistClean()),
|
|
actionCollection(), "build_distclean" );
|
|
action->setToolTip(i18n("Distclean"));
|
|
action->setWhatsThis(i18n("<b>Distclean</b><p>Runs <b>make distclean</b> command from the project directory.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
action = new KAction( i18n("Make Messages && Merge"), 0,
|
|
this, TQT_SLOT(slotMakeMessages()),
|
|
actionCollection(), "build_messages" );
|
|
action->setToolTip(i18n("Make messages && merge"));
|
|
action->setWhatsThis(i18n("<b>Make messages && merge</b><p>Runs <b>make package-messages</b> command from the project directory.<br>"
|
|
"Environment variables and make arguments can be specified "
|
|
"in the project settings dialog, <b>Make Options</b> tab."));
|
|
action->setGroup("autotools");
|
|
|
|
if (!m_isKDE)
|
|
action->setEnabled(false);
|
|
|
|
buildConfigAction = new KSelectAction( i18n("Build Configuration"), 0,
|
|
actionCollection(), "project_configuration" );
|
|
buildConfigAction->setToolTip(i18n("Build configuration menu"));
|
|
buildConfigAction->setWhatsThis(i18n("<b>Build configuration menu</b><p>Allows to switch between project build configurations.<br>"
|
|
"Build configuration is a set of build and top source directory settings, "
|
|
"configure flags and arguments, compiler flags, etc.<br>"
|
|
"Modify build configurations in project settings dialog, <b>Configure Options</b> tab."));
|
|
buildConfigAction->setGroup("autotools");
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) {
|
|
//ok we handle the execute in this kpart
|
|
action = new KAction( i18n("Execute Program"), "exec", SHIFT+Key_F9,
|
|
this, TQT_SLOT(slotExecute()),
|
|
actionCollection(), "build_execute" );
|
|
action->setToolTip(i18n("Execute program"));
|
|
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."));
|
|
action->setGroup("autotools");
|
|
}
|
|
|
|
connect( buildConfigAction, TQT_SIGNAL(activated(const TQString&)),
|
|
this, TQT_SLOT(slotBuildConfigChanged(const TQString&)) );
|
|
connect( buildConfigAction->popupMenu(), TQT_SIGNAL(aboutToShow()),
|
|
this, TQT_SLOT(slotBuildConfigAboutToShow()) );
|
|
|
|
// connect( core(), TQT_SIGNAL(projectConfigWidget(KDialogBase*)), this, TQT_SLOT(projectConfigWidget(KDialogBase*)) );
|
|
|
|
_configProxy = new ConfigWidgetProxy( core() );
|
|
_configProxy->createProjectConfigPage( i18n("Configure Options"), CONFIGURE_OPTIONS, info()->icon() );
|
|
_configProxy->createProjectConfigPage( i18n("Run Options"), RUN_OPTIONS, info()->icon() );
|
|
_configProxy->createProjectConfigPage( i18n("Make Options"), MAKE_OPTIONS, info()->icon() );
|
|
connect( _configProxy, TQT_SIGNAL(insertConfigWidget(const KDialogBase*, TQWidget*, unsigned int )),
|
|
this, TQT_SLOT(insertConfigWidget(const KDialogBase*, TQWidget*, unsigned int )) );
|
|
|
|
|
|
connect( makeFrontend(), TQT_SIGNAL(commandFinished(const TQString&)),
|
|
this, TQT_SLOT(slotCommandFinished(const TQString&)) );
|
|
connect( makeFrontend(), TQT_SIGNAL(commandFailed(const TQString&)),
|
|
this, TQT_SLOT(slotCommandFailed(const TQString&)) );
|
|
|
|
setWantautotools();
|
|
|
|
|
|
}
|
|
|
|
|
|
AutoProjectPart::~AutoProjectPart()
|
|
{
|
|
if (m_widget)
|
|
{
|
|
mainWindow()->removeView(m_widget);
|
|
}
|
|
delete m_widget;
|
|
delete _configProxy;
|
|
}
|
|
|
|
|
|
void AutoProjectPart::insertConfigWidget( const KDialogBase* dlg, TQWidget * page, unsigned int pagenumber )
|
|
{
|
|
switch ( pagenumber )
|
|
{
|
|
case CONFIGURE_OPTIONS:
|
|
{
|
|
ConfigureOptionsWidget *w2 = new ConfigureOptionsWidget(this, page );
|
|
connect( dlg, TQT_SIGNAL(okClicked()), w2, TQT_SLOT(accept()) );
|
|
}
|
|
break;
|
|
|
|
case RUN_OPTIONS:
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default"))
|
|
{
|
|
//ok we handle the execute in this kpart
|
|
RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevautoproject", buildDirectory(), page );
|
|
connect( dlg, TQT_SIGNAL(okClicked()), w3, TQT_SLOT(accept()) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MAKE_OPTIONS:
|
|
{
|
|
MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevautoproject", page );
|
|
connect( dlg, TQT_SIGNAL(okClicked()), w4, TQT_SLOT(accept()) );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void AutoProjectPart::openProject(const TQString &dirName, const TQString &projectName)
|
|
{
|
|
m_projectName = projectName;
|
|
m_projectPath =dirName;
|
|
|
|
m_widget->openProject(dirName);
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
TQString activeTarget = DomUtil::readEntry(dom, "/kdevautoproject/general/activetarget");
|
|
kdDebug(9020) << k_funcinfo << "activeTarget " << activeTarget << endl;
|
|
if (!activeTarget.isEmpty())
|
|
m_widget->setActiveTarget(activeTarget);
|
|
else
|
|
{
|
|
KMessageBox::information( m_widget, i18n("No active target specified, running the application will\n"
|
|
"not work until you make a target active in the Automake Manager\n"
|
|
"on the right side or use the Main Program options under\n"
|
|
"Project -> Project Options -> Run Options"), i18n("No active target specified"), "kdevelop_open_project_no_active_target");
|
|
}
|
|
|
|
KDevProject::openProject( dirName, projectName );
|
|
}
|
|
|
|
|
|
void AutoProjectPart::closeProject()
|
|
{
|
|
m_widget->closeProject();
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::projectDirectory() const
|
|
{
|
|
return m_projectPath;
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::projectName() const
|
|
{
|
|
return m_projectName;
|
|
}
|
|
|
|
|
|
/** Retuns a PairList with the run environment variables */
|
|
DomUtil::PairList AutoProjectPart::runEnvironmentVars() const
|
|
{
|
|
return DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/run/envvars", "envvar", "name", "value");
|
|
}
|
|
|
|
|
|
/** Retuns the currently selected run directory
|
|
* If no main Program was selected in the Run Options dialog
|
|
* use the currently active target instead to calculate it.
|
|
* The returned string can be:
|
|
* if /kdevautoproject/run/directoryradio == executable
|
|
* The directory where the executable is
|
|
* if /kdevautoproject/run/directoryradio == build
|
|
* The directory where the executable is relative to build directory
|
|
* if /kdevautoproject/run/directoryradio == custom
|
|
* The custom directory absolute path
|
|
*/
|
|
TQString AutoProjectPart::runDirectory() const
|
|
{
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQString cwd;
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
|
|
{
|
|
cwd = defaultRunDirectory("kdevautoproject");
|
|
}else
|
|
{
|
|
cwd = DomUtil::readEntry( dom, "/kdevautoproject/run/cwd/"+m_widget->activeTarget()->name );
|
|
}
|
|
if( cwd.isEmpty() )
|
|
cwd = buildDirectory() +"/"+ URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) +"/"+m_widget->activeDirectory();
|
|
|
|
return cwd;
|
|
}
|
|
|
|
|
|
/** Retuns the currently selected main program
|
|
* If no main Program was selected in the Run Options dialog
|
|
* use the currently active target instead.
|
|
* The returned string can be:
|
|
* if /kdevautoproject/run/directoryradio == executable
|
|
* The executable name
|
|
* if /kdevautoproject/run/directoryradio == build
|
|
* The path to executable relative to build directory
|
|
* if /kdevautoproject/run/directoryradio == custom or relative == false
|
|
* The absolute path to executable
|
|
*/
|
|
|
|
TQString AutoProjectPart::mainProgram() const
|
|
{
|
|
TQDomDocument * dom = projectDom();
|
|
|
|
if ( !dom ) return TQString();
|
|
|
|
if( DomUtil::readBoolEntry(*dom, "/kdevautoproject/run/useglobalprogram", false) )
|
|
{
|
|
TQString DomMainProgram = DomUtil::readEntry(*dom, "/kdevautoproject/run/mainprogram");
|
|
|
|
if ( DomMainProgram.isEmpty() ) return TQString();
|
|
|
|
if ( DomMainProgram.startsWith("/") ) // assume absolute path
|
|
{
|
|
return DomMainProgram;
|
|
}
|
|
else // assume builddir relative path
|
|
{
|
|
TQString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() );
|
|
if( !relprojectpath.isEmpty() )
|
|
relprojectpath = "/" + relprojectpath;
|
|
return buildDirectory() + relprojectpath + "/" + DomMainProgram;
|
|
}
|
|
|
|
}
|
|
else // If no Main Program was specified, return the active target
|
|
{
|
|
TargetItem* titem = m_widget->activeTarget();
|
|
|
|
if ( !titem ) {
|
|
KMessageBox::error( m_widget, i18n("There is no active target.\n"
|
|
"Unable to determine the main program."), i18n("No active target found") );
|
|
kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
|
|
return TQString::null;
|
|
}
|
|
|
|
if ( titem->primary != "PROGRAMS" ) {
|
|
KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n"
|
|
"Unable to determine the main program. If you want this\n"
|
|
"to be the active target, set a main program under\n"
|
|
"Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") );
|
|
kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
|
|
return TQString::null;
|
|
}
|
|
|
|
TQString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() );
|
|
if( !relprojectpath.isEmpty() )
|
|
relprojectpath = "/" + relprojectpath;
|
|
return buildDirectory() + relprojectpath + "/" + activeDirectory() + "/" + titem->name;
|
|
}
|
|
}
|
|
|
|
|
|
/** Retuns a TQString with the debug command line arguments */
|
|
TQString AutoProjectPart::debugArguments() const
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
|
|
{
|
|
return DomUtil::readEntry(dom, "/kdevautoproject/run/globaldebugarguments");
|
|
}else
|
|
{
|
|
return DomUtil::readEntry(dom, "/kdevautoproject/run/debugarguments/" + m_widget->activeTarget()->name);
|
|
}
|
|
}
|
|
|
|
|
|
/** Retuns a TQString with the run command line arguments */
|
|
TQString AutoProjectPart::runArguments() const
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() )
|
|
{
|
|
return DomUtil::readEntry(dom, "/kdevautoproject/run/programargs");
|
|
}else
|
|
{
|
|
return DomUtil::readEntry(dom, "/kdevautoproject/run/runarguments/" + m_widget->activeTarget()->name);
|
|
}
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::activeDirectory() const
|
|
{
|
|
return m_widget->activeDirectory();
|
|
}
|
|
|
|
|
|
TQStringList AutoProjectPart::allFiles() const
|
|
{
|
|
return m_widget->allFiles();
|
|
}
|
|
|
|
|
|
void AutoProjectPart::setWantautotools()
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
TQDomElement el = DomUtil::elementByPath(dom, "/kdevautoproject/make");
|
|
if ( el.namedItem("envvars").isNull() ) {
|
|
DomUtil::PairList list;
|
|
list << DomUtil::Pair("WANT_AUTOCONF_2_5", "1");
|
|
list << DomUtil::Pair("WANT_AUTOMAKE_1_6", "1");
|
|
DomUtil::writePairListEntry(dom, "/kdevautoproject/make/envvars", "envvar", "name", "value", list);
|
|
}
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::makeEnvironment() const
|
|
{
|
|
// Get the make environment variables pairs into the environstr string
|
|
// in the form of: "ENV_VARIABLE=ENV_VALUE"
|
|
// Note that we quote the variable value due to the possibility of
|
|
// embedded spaces
|
|
DomUtil::PairList envvars =
|
|
DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/make/envvars", "envvar", "name", "value");
|
|
|
|
TQString environstr;
|
|
DomUtil::PairList::ConstIterator it;
|
|
for (it = envvars.begin(); it != envvars.end(); ++it)
|
|
{
|
|
environstr += (*it).first;
|
|
environstr += "=";
|
|
environstr += EnvVarTools::quote((*it).second);
|
|
environstr += " ";
|
|
}
|
|
|
|
KConfigGroup grp( kapp->config(), "MakeOutputView" );
|
|
if( grp.readBoolEntry( "ForceCLocale", true ) )
|
|
environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" ";
|
|
|
|
return environstr;
|
|
}
|
|
|
|
|
|
void AutoProjectPart::addFile(const TQString &fileName)
|
|
{
|
|
TQStringList fileList;
|
|
fileList.append ( fileName );
|
|
|
|
this->addFiles ( fileList );
|
|
}
|
|
|
|
void AutoProjectPart::addFiles ( const TQStringList& fileList )
|
|
{
|
|
TQString directory, name;
|
|
TQStringList::ConstIterator it;
|
|
bool messageBoxShown = false;
|
|
|
|
for ( it = fileList.begin(); it != fileList.end(); ++it )
|
|
{
|
|
int pos = ( *it ).findRev('/');
|
|
if (pos != -1)
|
|
{
|
|
directory = ( *it ).left(pos);
|
|
name = ( *it ).mid(pos+1);
|
|
}
|
|
else
|
|
{
|
|
directory = "";
|
|
name = ( *it );
|
|
}
|
|
|
|
if (directory != m_widget->activeDirectory() ||
|
|
directory.isEmpty())
|
|
{
|
|
if ( !messageBoxShown )
|
|
{
|
|
KMessageBox::information(m_widget, i18n("The directory you selected is not the active directory.\n"
|
|
"You should 'activate' the target you're currently working on in Automake Manager.\n"
|
|
"Just right-click a target and choose 'Make Target Active'."),
|
|
i18n ( "No Active Target Found" ), "No automake manager active target warning" );
|
|
messageBoxShown = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_widget->addFiles(fileList);
|
|
}
|
|
|
|
void AutoProjectPart::removeFile(const TQString &fileName)
|
|
{
|
|
TQStringList fileList;
|
|
fileList.append ( fileName );
|
|
|
|
this->removeFiles ( fileList );
|
|
}
|
|
|
|
void AutoProjectPart::removeFiles ( const TQStringList& fileList )
|
|
{
|
|
/// \FIXME m_widget->removeFiles does nothing!
|
|
m_widget->removeFiles ( fileList );
|
|
|
|
emit removedFilesFromProject ( fileList );
|
|
}
|
|
|
|
TQStringList AutoProjectPart::allBuildConfigs() const
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQStringList allConfigs;
|
|
allConfigs.append("default");
|
|
|
|
TQDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations");
|
|
TQDomElement childEl = node.firstChild().toElement();
|
|
while (!childEl.isNull())
|
|
{
|
|
TQString config = childEl.tagName();
|
|
kdDebug(9020) << k_funcinfo << "Found config " << config << endl;
|
|
if (config != "default")
|
|
allConfigs.append(config);
|
|
childEl = childEl.nextSibling().toElement();
|
|
}
|
|
|
|
return allConfigs;
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::currentBuildConfig() const
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQString config = DomUtil::readEntry(dom, "/kdevautoproject/general/useconfiguration");
|
|
if (config.isEmpty() || !allBuildConfigs().contains(config))
|
|
config = "default";
|
|
|
|
return config;
|
|
}
|
|
|
|
|
|
TQString AutoProjectPart::buildDirectory() const
|
|
{
|
|
TQString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
|
|
|
|
TQString builddir = DomUtil::readEntry(*projectDom(), prefix + "builddir");
|
|
if (builddir.isEmpty())
|
|
return topsourceDirectory();
|
|
else if (builddir.startsWith("/"))
|
|
return builddir;
|
|
else
|
|
return projectDirectory() + "/" + builddir;
|
|
}
|
|
|
|
TQString AutoProjectPart::topsourceDirectory() const
|
|
{
|
|
TQString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
|
|
|
|
TQString topsourcedir = DomUtil::readEntry(*projectDom(), prefix + "topsourcedir");
|
|
if (topsourcedir.isEmpty())
|
|
return projectDirectory();
|
|
else if (topsourcedir.startsWith("/"))
|
|
return topsourcedir;
|
|
else
|
|
return projectDirectory() + "/" + topsourcedir;
|
|
}
|
|
|
|
TQString AutoProjectPart::constructMakeCommandLine(const TQString &dir, const TQString &target) const
|
|
{
|
|
|
|
TQString preCommand;
|
|
TQFileInfo fi1();
|
|
kdDebug(9020) << k_funcinfo << "Looking for Makefile in " << dir << endl;
|
|
if ( !TQFile::exists(dir + "/GNUmakefile") && !TQFile::exists(dir + "/makefile")
|
|
&& ! TQFile::exists(dir + "/Makefile") )
|
|
{
|
|
if (!TQFile::exists(buildDirectory() + "/configure"))
|
|
{
|
|
int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory\n"
|
|
"and no configure script for this project.\n"
|
|
"Run automake & friends and configure first?").arg(buildDirectory()), TQString::null, i18n("Run Them"), i18n("Do Not Run"));
|
|
if (r == KMessageBox::No)
|
|
return TQString::null;
|
|
preCommand = makefileCvsCommand();
|
|
if (preCommand.isNull())
|
|
return TQString::null;
|
|
preCommand += " && ";
|
|
preCommand += configureCommand() + " && ";
|
|
}
|
|
else
|
|
{
|
|
int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory. Run 'configure' first?").arg(dir), TQString::null, i18n("Run configure"), i18n("Do Not Run"));
|
|
if (r == KMessageBox::No)
|
|
return TQString::null;
|
|
preCommand = configureCommand() + " && ";
|
|
}
|
|
}
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQString cmdline = DomUtil::readEntry(dom, "/kdevautoproject/make/makebin");
|
|
int prio = DomUtil::readIntEntry(dom, "/kdevautoproject/make/prio");
|
|
TQString nice;
|
|
kdDebug(9020) << k_funcinfo << "nice = " << prio<< endl;
|
|
if (prio != 0)
|
|
{
|
|
nice = TQString("nice -n%1 ").arg(prio);
|
|
}
|
|
|
|
if (cmdline.isEmpty())
|
|
cmdline = MAKE_COMMAND;
|
|
if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/make/abortonerror"))
|
|
cmdline += " -k";
|
|
bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevautoproject/make/runmultiplejobs");
|
|
int jobs = DomUtil::readIntEntry(dom, "/kdevautoproject/make/numberofjobs");
|
|
if (runmultiple && jobs != 0)
|
|
{
|
|
cmdline += " -j";
|
|
cmdline += TQString::number(jobs);
|
|
}
|
|
if (DomUtil::readBoolEntry(dom, "/kdevautoproject/make/dontact"))
|
|
cmdline += " -n";
|
|
|
|
cmdline += " ";
|
|
cmdline += target;
|
|
cmdline.prepend(nice);
|
|
cmdline.prepend(makeEnvironment());
|
|
|
|
TQString dircmd = "cd ";
|
|
dircmd += KProcess::quote(dir);
|
|
dircmd += " && ";
|
|
|
|
return preCommand + dircmd + cmdline;
|
|
}
|
|
|
|
|
|
void AutoProjectPart::startMakeCommand(const TQString &dir, const TQString &target, bool withKdesu)
|
|
{
|
|
if (partController()->saveAllFiles()==false)
|
|
return; //user cancelled
|
|
kdDebug(9020) << "startMakeCommand:" << dir << ": "<< target << endl;
|
|
m_buildCommand = constructMakeCommandLine(dir, target);
|
|
|
|
if (withKdesu)
|
|
m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'";
|
|
|
|
if (!m_buildCommand.isNull())
|
|
makeFrontend()->queueCommand(dir, m_buildCommand);
|
|
}
|
|
|
|
|
|
/** Adds the make command for the libraries that the target depends on
|
|
* to the make frontend queue (this is a recursive function) */
|
|
bool AutoProjectPart::queueInternalLibDependenciesBuild(TargetItem* titem, TQStringList& alreadyScheduledDeps)
|
|
{
|
|
|
|
TQString addstr = (titem->primary == "PROGRAMS")? titem->ldadd : titem->libadd;
|
|
TQStringList l2 = TQStringList::split(TQRegExp("[ \t]"), addstr); // list of dependencies
|
|
TQString tdir; // temp target directory
|
|
TQString tname; // temp target name
|
|
TQString tcmd; // temp command line
|
|
TQStringList::Iterator l2it;
|
|
for (l2it = l2.begin(); l2it != l2.end(); ++l2it)
|
|
{
|
|
TQString dependency = *l2it;
|
|
if (dependency.startsWith("$(top_builddir)/"))
|
|
{
|
|
// These are the internal libraries
|
|
dependency.remove("$(top_builddir)/");
|
|
|
|
if( !alreadyScheduledDeps.contains(*l2it) )
|
|
{
|
|
alreadyScheduledDeps << *l2it;
|
|
tdir = buildDirectory();
|
|
if (!tdir.endsWith("/") && !tdir.isEmpty())
|
|
tdir += "/";
|
|
int pos = dependency.findRev('/');
|
|
if (pos == -1)
|
|
{
|
|
tname = dependency;
|
|
}
|
|
else
|
|
{
|
|
tdir += dependency.left(pos+1);
|
|
tname = dependency.mid(pos+1);
|
|
}
|
|
kdDebug(9020) << "Scheduling : <" << tdir << "> target <" << tname << ">" << endl;
|
|
// Recursively queue the dependencies for building
|
|
SubprojectItem *spi = m_widget->subprojectItemForPath( dependency.left(pos) );
|
|
if (spi)
|
|
{
|
|
TQPtrList< TargetItem > tl = spi->targets;
|
|
// Cycle through the list of targets to find the one we're looking for
|
|
TargetItem *ti = tl.first();
|
|
do
|
|
{
|
|
if (ti->name == tname)
|
|
{
|
|
// found it: queue it and stop looking
|
|
if( !queueInternalLibDependenciesBuild(ti, alreadyScheduledDeps) )
|
|
return false;
|
|
break;
|
|
}
|
|
ti = tl.next();
|
|
}
|
|
while (ti);
|
|
}
|
|
|
|
kdDebug(9020) << "queueInternalLibDependenciesBuild:" << tdir << ": "<< tname << endl;
|
|
tcmd = constructMakeCommandLine(tdir, tname);
|
|
if (!tcmd.isNull())
|
|
{
|
|
makeFrontend()->queueCommand( tdir, tcmd);
|
|
}
|
|
}else
|
|
{
|
|
//Message box about circular deps.
|
|
tdir = buildDirectory();
|
|
if (!tdir.endsWith("/") && !tdir.isEmpty())
|
|
tdir += "/";
|
|
int pos = dependency.findRev('/');
|
|
if (pos == -1)
|
|
{
|
|
tname = dependency;
|
|
}
|
|
else
|
|
{
|
|
tdir += dependency.left(pos+1);
|
|
tname = dependency.mid(pos+1);
|
|
}
|
|
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") );
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotBuild()
|
|
{
|
|
//m_lastCompilationFailed = false;
|
|
|
|
if( m_needMakefileCvs )
|
|
{
|
|
slotMakefilecvs();
|
|
slotConfigure();
|
|
m_needMakefileCvs = false;
|
|
}
|
|
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1(""));
|
|
}
|
|
|
|
|
|
void AutoProjectPart::buildTarget(TQString relpath, TargetItem* titem)
|
|
{
|
|
|
|
if ( !titem )
|
|
return;
|
|
|
|
//m_lastCompilationFailed = false;
|
|
|
|
// Calculate the complete name of the target and store it in name
|
|
TQString name = titem->name;
|
|
if ( titem->primary == "KDEDOCS" )
|
|
name = "index.cache.bz2";
|
|
|
|
// Calculate the full path of the target and store it in path
|
|
TQString path = buildDirectory();
|
|
if (!path.endsWith("/") && !path.isEmpty())
|
|
path += "/";
|
|
if (relpath.at(0) == '/')
|
|
path += relpath.mid(1);
|
|
else
|
|
path += relpath;
|
|
|
|
// Save all files once
|
|
partController()->saveAllFiles();
|
|
|
|
// Add the make command for the libraries that the target depends on to the make frontend queue
|
|
// if this recursive behavour is un-wanted comment the next line
|
|
TQStringList deps;
|
|
if( !queueInternalLibDependenciesBuild(titem, deps) )
|
|
return;
|
|
|
|
// Calculate the "make" command line for the target
|
|
//TQString relpath = dir.path().mid( projectDirectory().length() );
|
|
m_runProg=buildDirectory() + "/" + relpath+"/"+name;
|
|
kdDebug(9020) << "buildTarget:" << buildDirectory()<< endl;
|
|
kdDebug(9020) << "buildTarget:" << relpath << " " << path << ": "<< name << " : " << m_runProg << endl;
|
|
TQString tcmd = constructMakeCommandLine( path, name );
|
|
|
|
// Call make
|
|
if (!tcmd.isNull())
|
|
{
|
|
m_buildCommand = tcmd;
|
|
makeFrontend()->queueCommand( path, tcmd);
|
|
}
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotBuildActiveTarget()
|
|
{
|
|
// Get a pointer to the active target
|
|
TargetItem* titem = m_widget->activeTarget();
|
|
|
|
if ( !titem )
|
|
return;
|
|
|
|
// build it
|
|
buildTarget( URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + activeDirectory(), titem);
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotCompileFile()
|
|
{
|
|
KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
|
|
if (!part || !part->url().isLocalFile())
|
|
return;
|
|
|
|
TQString fileName = part->url().path();
|
|
TQFileInfo fi(fileName);
|
|
TQString sourceDir = fi.dirPath();
|
|
TQString baseName = fi.baseName(true);
|
|
kdDebug(9020) << "Compiling " << fileName
|
|
<< " in dir " << sourceDir
|
|
<< " with baseName " << baseName << endl;
|
|
|
|
TQString projectDir = projectDirectory();
|
|
if (!sourceDir.startsWith(projectDir)) {
|
|
KMessageBox::sorry(m_widget, i18n("Can only compile files in directories which belong to the project."));
|
|
return;
|
|
}
|
|
|
|
TQString buildDir = buildDirectory() + sourceDir.mid(projectDir.length());
|
|
TQString target = baseName + ".lo";
|
|
kdDebug(9020) << "builddir " << buildDir << ", target " << target << endl;
|
|
|
|
startMakeCommand(buildDir, target);
|
|
}
|
|
|
|
TQString AutoProjectPart::configureCommand() const
|
|
{
|
|
TQDomDocument &dom = *projectDom();
|
|
TQString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/";
|
|
|
|
TQString cmdline = "\"" + topsourceDirectory();
|
|
cmdline += "/configure\"";
|
|
TQString cc = DomUtil::readEntry(dom, prefix + "ccompilerbinary");
|
|
if (!cc.isEmpty())
|
|
cmdline.prepend(TQString("CC=%1 ").arg(cc));
|
|
TQString cflags = DomUtil::readEntry(dom, prefix + "cflags");
|
|
if (!cflags.isEmpty())
|
|
cmdline.prepend(TQString("CFLAGS=\"%1\" ").arg(cflags));
|
|
TQString cxx = DomUtil::readEntry(dom, prefix + "cxxcompilerbinary");
|
|
if (!cxx.isEmpty())
|
|
cmdline.prepend(TQString("CXX=%1 ").arg(cxx));
|
|
TQString cxxflags = DomUtil::readEntry(dom, prefix + "cxxflags");
|
|
if (!cxxflags.isEmpty())
|
|
cmdline.prepend(TQString("CXXFLAGS=\"%1\" ").arg(cxxflags));
|
|
TQString f77 = DomUtil::readEntry(dom, prefix + "f77compilerbinary");
|
|
if (!f77.isEmpty())
|
|
cmdline.prepend(TQString("F77=%1 ").arg(f77));
|
|
TQString fflags = DomUtil::readEntry(dom, prefix + "f77flags");
|
|
if (!fflags.isEmpty())
|
|
cmdline.prepend(TQString("FFLAGS=\"%1\" ").arg(fflags));
|
|
TQString cppflags = DomUtil::readEntry(dom, prefix + "cppflags");
|
|
if (!cppflags.isEmpty())
|
|
cmdline.prepend(TQString("CPPFLAGS=\"%1\" ").arg(cppflags));
|
|
TQString ldflags = DomUtil::readEntry(dom, prefix + "ldflags");
|
|
if (!ldflags.isEmpty())
|
|
cmdline.prepend(TQString("LDFLAGS=\"%1\" ").arg(ldflags));
|
|
|
|
TQString configargs = DomUtil::readEntry(dom, prefix + "configargs");
|
|
if (!configargs.isEmpty()) {
|
|
cmdline += " ";
|
|
cmdline += configargs;
|
|
}
|
|
|
|
DomUtil::PairList envvars =
|
|
DomUtil::readPairListEntry(*projectDom(), prefix + "envvars", "envvar", "name", "value");
|
|
|
|
TQString environstr;
|
|
DomUtil::PairList::ConstIterator it;
|
|
for (it = envvars.begin(); it != envvars.end(); ++it) {
|
|
environstr += (*it).first;
|
|
environstr += "=";
|
|
environstr += EnvVarTools::quote((*it).second);
|
|
environstr += " ";
|
|
}
|
|
cmdline.prepend(environstr);
|
|
|
|
TQString builddir = buildDirectory();
|
|
TQString dircmd;
|
|
|
|
// if the build directory doesn't exist, add it's creation to the configureCommand
|
|
if ( !TQFile::exists(builddir)) {
|
|
dircmd = "mkdir ";
|
|
dircmd += KProcess::quote(builddir);
|
|
dircmd += " && ";
|
|
}
|
|
|
|
// add "cd into the build directory" to the configureCommand
|
|
dircmd += "cd ";
|
|
dircmd += KProcess::quote(builddir);
|
|
dircmd += " && ";
|
|
|
|
return dircmd + cmdline;
|
|
}
|
|
|
|
void AutoProjectPart::slotConfigure()
|
|
{
|
|
TQString cmdline = configureCommand();
|
|
if (cmdline.isNull())
|
|
return;
|
|
|
|
makeFrontend()->queueCommand(buildDirectory(), cmdline);
|
|
}
|
|
|
|
TQString AutoProjectPart::makefileCvsCommand() const
|
|
{
|
|
kdDebug(9020) << "makefileCvsCommand: runDirectory :" << runDirectory() << ":" <<endl;
|
|
kdDebug(9020) << "makefileCvsCommand: topsourceDirectory :" << topsourceDirectory() << ":" <<endl;
|
|
kdDebug(9020) << "makefileCvsCommand: makeEnvironment :" << makeEnvironment() << ":" <<endl;
|
|
kdDebug(9020) << "makefileCvsCommand: currentBuildConfig :" << currentBuildConfig() << ":" <<endl;
|
|
|
|
|
|
TQString cmdline = DomUtil::readEntry(*projectDom(), "/kdevautoproject/make/makebin");
|
|
if (cmdline.isEmpty())
|
|
cmdline = MAKE_COMMAND;
|
|
|
|
int prio = DomUtil::readIntEntry(*projectDom(), "/kdevautoproject/make/prio");
|
|
TQString nice;
|
|
kdDebug(9020) << "makefileCvsCommand() nice = " << prio<< endl;
|
|
if (prio != 0) {
|
|
nice = TQString("nice -n%1 ").arg(prio);
|
|
}
|
|
|
|
if (TQFile::exists(topsourceDirectory() + "/Makefile.cvs"))
|
|
cmdline += " -f Makefile.cvs";
|
|
else if (TQFile::exists(topsourceDirectory() + "/Makefile.dist"))
|
|
cmdline += " -f Makefile.dist";
|
|
else if (TQFile::exists(topsourceDirectory() + "/autogen.sh"))
|
|
cmdline = "./autogen.sh";
|
|
else {
|
|
KMessageBox::sorry(m_widget, i18n("There is neither a Makefile.cvs file nor an "
|
|
"autogen.sh script in the project directory."));
|
|
return TQString::null;
|
|
}
|
|
|
|
cmdline.prepend(nice);
|
|
cmdline.prepend(makeEnvironment());
|
|
|
|
TQString dircmd = "cd ";
|
|
dircmd += KProcess::quote(topsourceDirectory());
|
|
dircmd += " && ";
|
|
|
|
return dircmd + cmdline;
|
|
}
|
|
|
|
void AutoProjectPart::slotMakefilecvs()
|
|
{
|
|
TQString cmdline = makefileCvsCommand();
|
|
if ( cmdline.isNull() )
|
|
return;
|
|
|
|
makeFrontend()->queueCommand(projectDirectory(), cmdline);
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotInstall()
|
|
{
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1("install"));
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotInstallWithKdesu()
|
|
{
|
|
// First issue "make" to build the entire project with the current user
|
|
// This way we make sure all files are up to date before we do the "make install"
|
|
slotBuild();
|
|
|
|
// After that issue "make install" with the root user
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1("install"), true);
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotClean()
|
|
{
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1("clean"));
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotDistClean()
|
|
{
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1("distclean"));
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotMakeMessages()
|
|
{
|
|
startMakeCommand(buildDirectory(), TQString::fromLatin1("package-messages"));
|
|
}
|
|
|
|
|
|
/** Checks if the currently selected main program or,
|
|
* if no main Program was selected in the Run Options dialog,
|
|
* the currently active target is up-to-date and builds it if necessary.
|
|
* In the end checks if the program is already running and if not calls the
|
|
* slotExecute2() function to execute it or asks the user what to do.
|
|
*/
|
|
void AutoProjectPart::slotExecute()
|
|
{
|
|
partController()->saveAllFiles();
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
m_runProg=m_runProg.isEmpty()?mainProgram():m_runProg;
|
|
|
|
bool _auto = false;
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autocompile", true) && isDirty() ){
|
|
m_executeAfterBuild = true;
|
|
if ( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) ){
|
|
// A Main Program was specified, build all targets because we don't know which is it
|
|
kdDebug(9020) << "slotExecute: before slotBuild" << endl;
|
|
slotBuild();
|
|
|
|
}
|
|
else{
|
|
// If no Main Program was specified, build the active target
|
|
kdDebug(9020) << "slotExecute: before slotBuildActiveTarget" << endl;
|
|
slotBuildActiveTarget();
|
|
}
|
|
_auto = true;
|
|
}
|
|
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autoinstall", false) && isDirty() ){
|
|
m_executeAfterBuild = true;
|
|
// Use kdesu??
|
|
if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autokdesu", false) ){
|
|
//slotInstallWithKdesu assumes that it hasn't just been build...
|
|
kdDebug(9020) << "slotExecute: before startMakeCommand" << endl;
|
|
_auto ? slotInstallWithKdesu() : startMakeCommand(buildDirectory(), TQString::fromLatin1("install"), true);
|
|
}
|
|
else{
|
|
kdDebug(9020) << "slotExecute: before slotInstall" << endl;
|
|
slotInstall();
|
|
}
|
|
_auto = true;
|
|
}
|
|
|
|
if ( _auto ){
|
|
m_runProg.truncate(0);
|
|
return;
|
|
}
|
|
|
|
if (appFrontend()->isRunning()) {
|
|
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)
|
|
return;
|
|
connect(appFrontend(), TQT_SIGNAL(processExited()), TQT_SLOT(slotExecute2()));
|
|
appFrontend()->stopApplication();
|
|
return;
|
|
}
|
|
kdDebug(9020) << "slotExecute: before slotExecute2" << endl;
|
|
slotExecute2();
|
|
}
|
|
|
|
void AutoProjectPart::executeTarget(const TQDir& dir, const TargetItem* titem)
|
|
{
|
|
m_executeAfterBuild=true;
|
|
partController()->saveAllFiles();
|
|
|
|
bool is_dirty = false;
|
|
TQDateTime t = TQFileInfo(dir , titem->name ).lastModified();
|
|
TQPtrListIterator<FileItem> it( titem->sources );
|
|
for( ; it.current() ; ++it )
|
|
{
|
|
if( t < TQFileInfo(dir , (*it)->name).lastModified())
|
|
is_dirty = true;
|
|
}
|
|
|
|
if( DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/autocompile", true) && is_dirty )
|
|
{
|
|
connect( makeFrontend(), TQT_SIGNAL(commandFinished(const TQString&)), this, TQT_SLOT(slotExecuteTargetAfterBuild(const TQString&)) );
|
|
connect( makeFrontend(), TQT_SIGNAL(commandFailed(const TQString&)), this, TQT_SLOT(slotNotExecuteTargetAfterBuildFailed(const TQString&)) );
|
|
|
|
m_runProg=titem->name;
|
|
m_executeTargetAfterBuild.first = dir;
|
|
m_executeTargetAfterBuild.second = const_cast<TargetItem*>(titem);
|
|
|
|
TQString relpath = "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->subdir;
|
|
kdDebug(9020) << "executeTarget: before buildTarget " << relpath << endl;
|
|
buildTarget(relpath, const_cast<TargetItem*>(titem));
|
|
return;
|
|
}
|
|
|
|
|
|
bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal");
|
|
|
|
TQString program = environString();
|
|
|
|
if ( !titem ) {
|
|
KMessageBox::error( m_widget, i18n("There is no active target.\n"
|
|
"Unable to determine the main program"), i18n("No active target found") );
|
|
kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
|
|
program += titem->name;
|
|
}else if ( titem->primary != "PROGRAMS" ) {
|
|
KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n"
|
|
"Unable to determine the main program. If you want this\n"
|
|
"to be the active target, set a main program under\n"
|
|
"Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") );
|
|
kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl;
|
|
program += titem->name;
|
|
}else
|
|
program += buildDirectory() + "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath()+ "/" + titem->name;
|
|
|
|
TQString args = DomUtil::readEntry(*projectDom(), "/kdevautoproject/run/runarguments/" + titem->name);
|
|
|
|
program += " " + args;
|
|
kdDebug(9020) << "executeTarget:cmd=" << dir.path() << " " << program << endl;
|
|
appFrontend()->startAppCommand(dir.path(), program ,inTerminal);
|
|
m_executeAfterBuild=false;
|
|
|
|
}
|
|
|
|
void AutoProjectPart::slotExecuteTargetAfterBuild(const TQString& command)
|
|
{
|
|
kdDebug(9020) << "slotExecuteTargetAfterBuild " << command << endl;
|
|
if ( m_executeAfterBuild && constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command )
|
|
{
|
|
disconnect( makeFrontend(), TQT_SIGNAL(commandFinished(const TQString&)), this, TQT_SLOT(slotExecuteAfterTargetBuild()) );
|
|
disconnect( makeFrontend(), TQT_SIGNAL(commandFailed(const TQString&)), this, TQT_SLOT(slotExecuteAfterTargetBuildFailed()) );
|
|
kdDebug(9020) << "slotExecuteTargetAfterBuild " << endl;
|
|
executeTarget(m_executeTargetAfterBuild.first, m_executeTargetAfterBuild.second);
|
|
}
|
|
|
|
}
|
|
|
|
void AutoProjectPart::slotNotExecuteTargetAfterBuildFailed(const TQString& command)
|
|
{
|
|
kdDebug(9020) << "executeTargetAfterBuildFailed" << endl;
|
|
if ( constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command )
|
|
{
|
|
m_executeAfterBuild=false;
|
|
disconnect( makeFrontend(), TQT_SIGNAL(commandFinished(const TQString&)), this, TQT_SLOT(slotExecuteTargetAfterBuild()) );
|
|
disconnect( makeFrontend(), TQT_SIGNAL(commandFailed(const TQString&)), this, TQT_SLOT(slotNotExecuteTargetAfterBuildFailed()) );
|
|
}
|
|
}
|
|
|
|
|
|
/* Get the run environment variables pairs into the environstr string
|
|
* in the form of: "ENV_VARIABLE=ENV_VALUE"
|
|
* Note that we quote the variable value due to the possibility of
|
|
* embedded spaces. */
|
|
TQString AutoProjectPart::environString() const
|
|
{
|
|
DomUtil::PairList envvars = runEnvironmentVars();
|
|
TQString environstr;
|
|
DomUtil::PairList::ConstIterator it;
|
|
for (it = envvars.begin(); it != envvars.end(); ++it) {
|
|
environstr += (*it).first;
|
|
environstr += "=";
|
|
environstr += EnvVarTools::quote((*it).second);
|
|
environstr += " ";
|
|
}
|
|
return environstr;
|
|
}
|
|
|
|
/** Executes the currently selected main program.
|
|
* If no main Program was selected in the Run Options dialog
|
|
* the currently active target is executed instead.
|
|
*/
|
|
void AutoProjectPart::slotExecute2()
|
|
{
|
|
disconnect(appFrontend(), TQT_SIGNAL(processExited()), this, TQT_SLOT(slotExecute2()));
|
|
|
|
if (m_runProg.isEmpty()){
|
|
// Do not execute non executable targets
|
|
return;
|
|
}
|
|
|
|
TQString program = environString();
|
|
// Adds the ./ that is necessary to execute the program in bash shells
|
|
if (!m_runProg.startsWith("/")){
|
|
program += "./";
|
|
}
|
|
program += m_runProg;
|
|
program += " " + runArguments();
|
|
|
|
bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal");
|
|
|
|
kdDebug(9020) << "slotExecute2: runDirectory: <" << runDirectory() << ">" <<endl;
|
|
kdDebug(9020) << "slotExecute2: environstr : <" << environString() << ">" <<endl;
|
|
kdDebug(9020) << "slotExecute2: mainProgram : <" << mainProgram() << ">" <<endl;
|
|
kdDebug(9020) << "slotExecute2: runArguments: <" << runArguments() << ">" <<endl;
|
|
kdDebug(9020) << "slotExecute2: program : <" << program << ">" <<endl;
|
|
|
|
appFrontend()->startAppCommand(runDirectory(), program, inTerminal);
|
|
m_executeAfterBuild=false;
|
|
m_runProg.truncate(0);
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotAddTranslation()
|
|
{
|
|
AddTranslationDialog dlg(this, m_widget);
|
|
dlg.exec();
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotBuildConfigChanged(const TQString &config)
|
|
{
|
|
DomUtil::writeEntry(*projectDom(), "/kdevautoproject/general/useconfiguration", config);
|
|
kdDebug(9020) << "Changed used configuration to " << config << endl;
|
|
}
|
|
|
|
|
|
void AutoProjectPart::slotBuildConfigAboutToShow()
|
|
{
|
|
TQStringList l = allBuildConfigs();
|
|
buildConfigAction->setItems(l);
|
|
buildConfigAction->setCurrentItem(l.findIndex(currentBuildConfig()));
|
|
}
|
|
|
|
void AutoProjectPart::restorePartialProjectSession ( const TQDomElement* el )
|
|
{
|
|
m_widget->restoreSession ( el );
|
|
}
|
|
|
|
void AutoProjectPart::savePartialProjectSession ( TQDomElement* el )
|
|
{
|
|
TQDomDocument domDoc = el->ownerDocument();
|
|
|
|
KMessageBox::information ( 0, "Hallo, Welt!" );
|
|
|
|
kdDebug ( 9020 ) << k_funcinfo << "1" << endl;
|
|
|
|
if ( domDoc.isNull() )
|
|
{
|
|
kdDebug ( 9020 ) << k_funcinfo << "2" << endl;
|
|
return;
|
|
}
|
|
|
|
kdDebug ( 9020 ) << k_funcinfo << "3" << endl;
|
|
|
|
m_widget->saveSession ( el );
|
|
}
|
|
|
|
void AutoProjectPart::slotCommandFinished( const TQString& command )
|
|
{
|
|
kdDebug(9020) << k_funcinfo << endl;
|
|
|
|
if( m_buildCommand != command )
|
|
return;
|
|
|
|
m_buildCommand = TQString::null;
|
|
|
|
m_timestamp.clear();
|
|
TQStringList fileList = allFiles();
|
|
TQStringList::Iterator it = fileList.begin();
|
|
while( it != fileList.end() ){
|
|
TQString fileName = *it;
|
|
++it;
|
|
|
|
m_timestamp[ fileName ] = TQFileInfo( projectDirectory(), fileName ).lastModified();
|
|
}
|
|
|
|
emit projectCompiled();
|
|
|
|
// reset the "last compilation has failed" flag
|
|
m_lastCompilationFailed = false;
|
|
|
|
if( m_executeAfterBuild ){
|
|
slotExecute();
|
|
}
|
|
}
|
|
|
|
void AutoProjectPart::slotCommandFailed( const TQString& /*command*/ )
|
|
{
|
|
kdDebug(9020) << "slotCommandFinished " << k_funcinfo << endl;
|
|
|
|
m_lastCompilationFailed = true;
|
|
m_executeAfterBuild=false;
|
|
}
|
|
|
|
bool AutoProjectPart::isDirty()
|
|
{
|
|
if (m_lastCompilationFailed) return true;
|
|
|
|
TQStringList fileList = allFiles();
|
|
TQStringList::Iterator it = fileList.begin();
|
|
while( it != fileList.end() ){
|
|
TQString fileName = *it;
|
|
++it;
|
|
|
|
TQMap<TQString, TQDateTime>::Iterator it = m_timestamp.find( fileName );
|
|
TQDateTime t = TQFileInfo( projectDirectory(), fileName ).lastModified();
|
|
if( it == m_timestamp.end() || *it != t ){
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void AutoProjectPart::needMakefileCvs( )
|
|
{
|
|
m_needMakefileCvs = true;
|
|
}
|
|
|
|
bool AutoProjectPart::isKDE() const
|
|
{
|
|
return m_isKDE;
|
|
}
|
|
|
|
KDevProject::Options AutoProjectPart::options() const
|
|
{
|
|
return UsesAutotoolsBuildSystem;
|
|
}
|
|
|
|
TQStringList recursiveATFind( const TQString &currDir, const TQString &baseDir )
|
|
{
|
|
kdDebug(9020) << "Dir " << currDir << endl;
|
|
TQStringList fileList;
|
|
|
|
if( !currDir.contains( "/..") && !currDir.contains("/.") )
|
|
{
|
|
TQDir dir(currDir);
|
|
TQStringList dirList = dir.entryList(TQDir::Dirs );
|
|
TQStringList::Iterator idx = dirList.begin();
|
|
for( ; idx != dirList.end(); ++idx )
|
|
{
|
|
fileList += recursiveATFind( currDir + "/" + (*idx),baseDir );
|
|
}
|
|
TQStringList newFiles = dir.entryList("*.am *.in");
|
|
idx = newFiles.begin();
|
|
for( ; idx != newFiles.end(); ++idx )
|
|
{
|
|
TQString file = currDir + "/" + (*idx);
|
|
fileList.append( file.remove( baseDir ) );
|
|
}
|
|
}
|
|
|
|
|
|
return fileList;
|
|
}
|
|
|
|
/*!
|
|
\fn AutoProjectPart::distFiles() const
|
|
*/
|
|
TQStringList AutoProjectPart::distFiles() const
|
|
{
|
|
TQStringList sourceList = allFiles();
|
|
// Scan current source directory for any .pro files.
|
|
TQString projectDir = projectDirectory();
|
|
TQDir dir(projectDir);
|
|
TQDir admin(projectDir +"/admin");
|
|
TQStringList 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");
|
|
TQStringList adminFiles = admin.entryList(TQDir::Files);
|
|
TQStringList::Iterator idx = adminFiles.begin();
|
|
for( ; idx != adminFiles.end(); ++idx)
|
|
{
|
|
files.append( "admin/" + (*idx) );
|
|
}
|
|
TQStringList srcDirs = dir.entryList(TQDir::Dirs);
|
|
idx = srcDirs.begin();
|
|
for(; idx != srcDirs.end(); ++idx)
|
|
{
|
|
sourceList += recursiveATFind( projectDirectory() + "/" + (*idx), projectDirectory());
|
|
}
|
|
return sourceList + files;
|
|
}
|
|
|
|
void AutoProjectPart::startSimpleMakeCommand( const TQString & dir, const TQString & command, bool withKdesu )
|
|
{
|
|
if (partController()->saveAllFiles()==false)
|
|
return; //user cancelled
|
|
|
|
// m_buildCommand = constructMakeCommandLine(dir, target);
|
|
|
|
TQString cmdline = command;
|
|
cmdline.prepend(makeEnvironment());
|
|
|
|
TQString dircmd = "cd ";
|
|
dircmd += KProcess::quote(dir);
|
|
dircmd += " && ";
|
|
|
|
m_buildCommand = dircmd + cmdline;
|
|
|
|
if (withKdesu)
|
|
m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'";
|
|
|
|
if (!m_buildCommand.isNull())
|
|
makeFrontend()->queueCommand(dir, m_buildCommand);
|
|
}
|
|
|
|
TQString AutoProjectPart::getAutoConfFile(const TQString& dir){
|
|
|
|
TQFile inFile(dir + "/configure.in");
|
|
TQFile acFile(dir + "/configure.ac");
|
|
if ( inFile.exists()){
|
|
return inFile.name();
|
|
}else if (acFile.exists()){
|
|
return acFile.name();
|
|
}
|
|
return acFile.name();;
|
|
}
|
|
|
|
#include "autoprojectpart.moc"
|
|
|
|
// kate: space-indent on; indent-width 4;
|