/*************************************************************************** * Copyright (C) 2003 by Thomas Hasart * * thasart@gmx.de * * Copyright (C) 2001-2002 by Bernd Gehrmann * * bernd@kdevelop.org * * Copyright (C) 2002 by Jakob Simon-Gaarde * * jakob@jsg.dk * * * * 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 "trollprojectpart.h" #include <tqdir.h> #include <tqfileinfo.h> #include <tqwhatsthis.h> #include <kdeversion.h> #include <kdebug.h> #include <kdialogbase.h> #include <kiconloader.h> #include <klocale.h> #include <kmessagebox.h> #include <kdirwatch.h> #include <kstatusbar.h> #include <tqmessagebox.h> #include <kdevgenericfactory.h> #include <kaction.h> #include <kparts/part.h> #include <kprocess.h> #include <kconfig.h> #include <kapplication.h> #include <kurlrequesterdlg.h> #include <kurlrequester.h> #include <kurlcompletion.h> #include <kfile.h> #include <makeoptionswidget.h> #include "domutil.h" #include "kdevcore.h" #include "kdevmainwindow.h" #include "kdevmakefrontend.h" #include "kdevappfrontend.h" #include "kdevpartcontroller.h" #include "trollprojectwidget.h" #include "runoptionswidget.h" #include "config.h" #include "envvartools.h" #include "qmakeoptionswidget.h" #include "scope.h" #include <kdevplugininfo.h> #include <urlutil.h> typedef KDevGenericFactory<TrollProjectPart> TrollProjectFactory; static const KDevPluginInfo data("kdevtrollproject"); K_EXPORT_COMPONENT_FACTORY( libkdevtrollproject, TrollProjectFactory( data ) ) TrollProjectPart::TrollProjectPart(TQObject *parent, const char *name, const TQStringList& args ) : KDevBuildTool(&data, parent, name ? name : "TrollProjectPart") { setInstance(TrollProjectFactory::instance()); if ( args.count() == 1 && args[0] == "TMake" ) m_tmakeProject = true; else m_tmakeProject = false; setXMLFile("kdevtrollproject.rc"); m_executeProjectAfterBuild = false; m_executeTargetAfterBuild = false; m_dirWatch = new KDirWatch(this); m_widget = new TrollProjectWidget(this); m_widget->setIcon(SmallIcon("qmakerun")); m_widget->setCaption(i18n("TQMake Manager")); TQWhatsThis::add(m_widget, i18n("<b>TQMake manager</b><p>" "The TQMake manager project tree consists of two parts. The 'overview' " "in the upper half shows the subprojects, each one having a " ".pro file. The 'details' view in the lower half shows the " "list of files for the active subproject selected in the overview.")); mainWindow()->embedSelectViewRight(m_widget, i18n("TQMake Manager"), i18n("TQMake manager")); KAction *action; const TQIconSet icon(SmallIcon("compfile")); action = new KAction( i18n("Compile &File"), "compfile", 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotBuildOpenFile()), 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 = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, TQT_TQOBJECT(m_widget), TQT_SLOT(slotBuildProject()), actionCollection(), "build_build_project" ); 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 = new KAction( i18n("&Rebuild Project"),"rebuild" , 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotRebuildProject()), actionCollection(),"build_rebuild_project" ); action->setToolTip(i18n("Rebuild project")); action->setWhatsThis(i18n("<b>Rebuild project</b><p>Runs <b>make clean</b> and then <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 = new KAction( i18n("&Install Project"),"install" , 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotInstallProject()), actionCollection(),"build_install_project" ); action->setToolTip(i18n("Install project")); action->setWhatsThis(i18n("<b>Install project</b><p>Runs <b>make install</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 = new KAction( i18n("&Clean Project"), 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotCleanProject()), actionCollection(), "build_clean_project" ); 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 = new KAction( i18n("&Dist-Clean Project"), 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotDistCleanProject()), actionCollection(), "build_distclean_project" ); action->setToolTip(i18n("Dist-Clean project")); action->setWhatsThis(i18n("<b>Dist-Clean project</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 = new KAction( i18n("Execute Main Program"), "exec", SHIFT+Key_F9, this, TQT_SLOT(slotBuildAndExecuteProject()), actionCollection(), "build_execute_project" ); action->setToolTip(i18n("Execute main program")); action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the currently selected subproject if it is an application or the program specified in project settings, <b>Run Options</b> tab.")); action = new KAction( i18n("&Build Subproject"), "make_kdevelop", Key_F7, TQT_TQOBJECT(m_widget), TQT_SLOT(slotBuildTarget()), actionCollection(), "build_build_target" ); action->setToolTip(i18n("Build subproject")); action->setWhatsThis(i18n("<b>Build subproject</b><p>Runs <b>make</b> from the current subproject directory. " "Current subproject is a subproject selected in <b>TQMake manager</b> 'overview' window.<br>" "Environment variables and make arguments can be specified " "in the project settings dialog, <b>Make Options</b> tab.")); action = new KAction( i18n("&Rebuild Subproject"), "rebuild", 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotRebuildTarget()), actionCollection(),"build_rebuild_target" ); action->setToolTip(i18n("Rebuild subproject")); action->setWhatsThis(i18n("<b>Rebuild subproject</b><p>Runs <b>make clean</b> and then <b>make</b> from the current subproject directory. " "Current subproject is a subproject selected in <b>TQMake manager</b> 'overview' window.<br>" "Environment variables and make arguments can be specified " "in the project settings dialog, <b>Make Options</b> tab.")); action = new KAction( i18n("&Install Subproject"), "install", 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotInstallTarget()), actionCollection(),"build_install_target" ); action->setToolTip(i18n("Install subproject")); action->setWhatsThis(i18n("<b>Install subproject</b><p>Runs <b>make install</b> from the current subproject directory. " "The current subproject is the subproject selected in the <b>TQMake manager</b> 'overview' window.<br>" "Environment variables and make arguments can be specified " "in the project settings dialog, <b>Make Options</b> tab.")); action = new KAction( i18n("&Clean Subproject"), 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotCleanTarget()), actionCollection(), "build_clean_target" ); action->setToolTip(i18n("Clean subproject")); action->setWhatsThis(i18n("<b>Clean subproject</b><p>Runs <b>make clean</b> from the current subproject directory. " "The current subproject is the subproject selected in the <b>TQMake manager</b> 'overview' window.<br>" "Environment variables and make arguments can be specified " "in the project settings dialog, <b>Make Options</b> tab.")); action = new KAction( i18n("&Dist-Clean Subproject"), 0, TQT_TQOBJECT(m_widget), TQT_SLOT(slotDistCleanTarget()), actionCollection(), "build_distclean_target" ); action->setToolTip(i18n("Dist-Clean subproject")); action->setWhatsThis(i18n("<b>Dist-Clean subproject</b><p>Runs <b>make distclean</b> from the current" " subproject directory. The current subproject is the subproject selected in the <b>TQMake manager</b> 'overview' window.<br>" "Environment variables and make arguments can be specified " "in the project settings dialog, <b>Make Options</b> tab.")); action = new KAction( i18n("Execute Subproject"), "exec", 0, this, TQT_SLOT(slotBuildAndExecuteTarget()), actionCollection(), "build_execute_target" ); action->setToolTip(i18n("Execute subproject")); action->setWhatsThis(i18n("<b>Execute subproject</b><p>Executes the target program for the currently selected subproject. " "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu).")); connect( core(), TQT_SIGNAL(projectConfigWidget(KDialogBase*)), this, TQT_SLOT(projectConfigWidget(KDialogBase*)) ); connect( makeFrontend(), TQT_SIGNAL(commandFinished(const TQString&)), this, TQT_SLOT(slotCommandFinished(const TQString&)) ); TQString m_defaultTQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); TQString m_qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); TQString qtversion = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/version", "3"); if( m_defaultTQtDir.isEmpty() || !isValidTQtDir( m_defaultTQtDir ) ) { m_defaultTQtDir = findTQtDir(); kdDebug(9024) << "Setting default dir to: " << m_defaultTQtDir << endl; DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/root", m_defaultTQtDir ); } if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) { m_qmakePath = findExecutable( "qmake-qt"+qtversion ); if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) m_qmakePath = findExecutable( "qmake" ); kdDebug(9024) << "Setting qmake binary to: " << m_qmakePath << endl; DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/qmake", m_qmakePath ); } } TrollProjectPart::~TrollProjectPart() { if (m_widget) mainWindow()->removeView(m_widget); delete m_widget; } TQString TrollProjectPart::makeEnvironment() { // 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(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); TQString environstr; DomUtil::PairList::ConstIterator it; bool hasTQtDir = false; for (it = envvars.begin(); it != envvars.end(); ++it) { if( (*it).first == "QTDIR" ) hasTQtDir = true; environstr += (*it).first; environstr += "="; environstr += EnvVarTools::quote((*it).second); environstr += " "; } if( !hasTQtDir && !isTQt4Project() && !DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) { environstr += TQString( "QTDIR=" ) + EnvVarTools::quote( DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "") ) + TQString( " PATH=$TQTDIR/bin:$PATH " ); } KConfigGroup grp( kapp->config(), "MakeOutputView" ); if( grp.readBoolEntry( "ForceCLocale", true ) ) environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; return environstr; } void TrollProjectPart::projectConfigWidget(KDialogBase *dlg) { TQVBox *vbox; vbox = dlg->addVBoxPage(i18n("Run Options"), i18n("Run Options"), BarIcon( "make", KIcon::SizeMedium )); RunOptionsWidget *optdlg = new RunOptionsWidget(*projectDom(), "/kdevtrollproject", buildDirectory(), vbox); vbox = dlg->addVBoxPage(i18n("Make Options"), i18n("Make Options"), BarIcon( "make", KIcon::SizeMedium )); MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevtrollproject", vbox); vbox = dlg->addVBoxPage(i18n("TQMake Manager"), i18n("TQMake Manager"), BarIcon( "make", KIcon::SizeMedium )); QMakeOptionsWidget *qm = new QMakeOptionsWidget( projectDirectory(), *projectDom(), "/kdevtrollproject", vbox); connect( dlg, TQT_SIGNAL(okClicked()), w4, TQT_SLOT(accept()) ); connect( dlg, TQT_SIGNAL(okClicked()), qm, TQT_SLOT(accept()) ); connect( dlg, TQT_SIGNAL(okClicked()), optdlg, TQT_SLOT(accept()) ); } void TrollProjectPart::openProject(const TQString &dirName, const TQString &projectName) { mainWindow()->statusBar()->message( i18n("Loading Project...") ); TQString defaultTQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); if( !isTQt4Project() && ( defaultTQtDir.isEmpty() || !isValidTQtDir( defaultTQtDir ) ) ) { bool doask = true; while( doask ) { KURLRequesterDlg dlg( i18n("Choose TQt3 directory"), i18n("Choose the TQt3 directory to use. This directory needs to have an include directory containing tqt.h.") , m_widget, 0); dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); dlg.urlRequester() ->setURL( TQString() ); dlg.urlRequester() ->completionObject() ->setDir( "/" ); if ( dlg.exec() == TQDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) { TQString qtdir = dlg.urlRequester()->url(); if( !isValidTQtDir( qtdir ) ) { if( KMessageBox::warningYesNo( m_widget, i18n("The directory you gave is not a proper TQt directory, the " "project might not work properly without one.\nPlease make " "sure you give a directory that contains a bin with the " "qmake binary in it and for TQt3 project also contains an " "include directory with tqt.h in it.\nDo you want to try " "setting a TQt directory again?"), i18n("Wrong TQt directory given")) == KMessageBox::Yes ) doask = true; else doask = false; }else { defaultTQtDir = qtdir; doask = false; } }else { if( KMessageBox::warningYesNo( m_widget, i18n("You did not specify a TQt directory, and the project might not " "work properly without one.\nDo you want to try setting a TQt" " directory again?"), i18n("No TQt directory given")) == KMessageBox::Yes ) doask = true; else doask = false; } } } TQString qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); if( qmakePath.isEmpty() || !isExecutable( qmakePath ) ) { bool doask = true; while( doask ) { KURLRequesterDlg dlg( i18n("Choose TQMake executable"), i18n("Choose the TQMake binary to use. TQMake is used to generate Makefiles from the project files."), m_widget, 0); dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); dlg.urlRequester() ->setURL( TQString() ); dlg.urlRequester() ->completionObject() ->setDir( "/" ); if ( dlg.exec() == TQDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) { TQString qmake = dlg.urlRequester()->url(); if( !isExecutable( qmake ) ) { if( KMessageBox::warningYesNo( m_widget, i18n("The binary you gave is not executable, the " "project might not work properly.\nPlease make " "sure you give a qmake binary that is executable.\nDo you want to try " "setting the TQMake binary again?"), i18n("Wrong TQMake binary given")) == KMessageBox::Yes ) doask = true; else doask = false; }else { qmakePath = qmake; doask = false; } }else { if( KMessageBox::warningYesNo( m_widget, i18n("You did not specify a TQMake binary, and the project might not " "work properly without one.\nDo you want to try setting a TQMake" " binary again?"), i18n("No TQMake binary given")) == KMessageBox::Yes ) doask = true; else doask = false; } } } DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/root", defaultTQtDir ); DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/qmake", qmakePath ); m_projectName = projectName; m_widget->openProject(dirName); TQDomDocument &dom = *projectDom(); // Set the default directory radio to "executable" if (DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio") == "" ) { DomUtil::writeEntry(dom, "/kdevtrollproject/run/directoryradio", "executable"); } KDevProject::openProject( dirName, projectName ); } void TrollProjectPart::closeProject() { m_widget->closeProject(); } TQString TrollProjectPart::projectDirectory() const { return m_widget->projectDirectory(); } TQString TrollProjectPart::buildDirectory() const { return m_widget->projectDirectory(); } TQString TrollProjectPart::projectName() const { return m_projectName; } /** Retuns a PairList with the run environment variables */ DomUtil::PairList TrollProjectPart::runEnvironmentVars() const { return DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/run/envvars", "envvar", "name", "value"); } void TrollProjectPart::slotBuildAndExecuteProject() { partController()->saveAllFiles(); if (isDirty()) { m_executeProjectAfterBuild = true; m_widget->slotBuildProject(); } else m_widget->slotExecuteProject(); } void TrollProjectPart::slotBuildAndExecuteTarget() { partController()->saveAllFiles(); if (isDirty()) { m_executeTargetAfterBuild = true; m_widget->slotBuildTarget(); } else m_widget->slotExecuteTarget(); } /** Retuns the currently selected run directory * The returned string can be: * if run/directoryradio == executable * The directory where the executable is * if run/directoryradio == build * The directory where the executable is relative to build directory * if run/directoryradio == custom * The custom directory absolute path */ TQString TrollProjectPart::runDirectory() const { TQDomDocument &dom = *projectDom(); TQString cwd; if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", true) ) { cwd = defaultRunDirectory("kdevtrollproject"); }else { TQString name = m_widget->getCurrentOutputFilename(); if( name.findRev("/") != -1 ) name = name.right( name.length()-name.findRev("/")-1 ); cwd = DomUtil::readEntry( dom, "/kdevtrollproject/run/cwd/" + name ); } if( cwd.isEmpty() ) { TQString destpath = m_widget->getCurrentTarget(); if( TQDir::isRelativePath( destpath ) ) { destpath = m_widget->subprojectDirectory() + TQString( TQChar( TQDir::separator() ) ) + destpath; } destpath = destpath.left( destpath.findRev("/") ); cwd = destpath; } return cwd; } /** Retuns the currently selected main program * The returned string can be: * if run/directoryradio == executable * The executable name * if run/directoryradio == build * The path to executable relative to build directory * if run/directoryradio == custom or relative == false * The absolute path to executable */ TQString TrollProjectPart::mainProgram() const { TQDomDocument &dom = *projectDom(); if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", false) ) { TQString DomMainProgram = DomUtil::readEntry(dom, "/kdevtrollproject/run/mainprogram"); if ( DomMainProgram.isEmpty() ) return TQString(); if ( DomMainProgram.startsWith("/") ) // assume absolute path { return DomMainProgram; } else // assume project relative path { return projectDirectory() + "/" + DomMainProgram; } }else { if( !m_widget->currentSubproject()) { KMessageBox::error( m_widget, "There's no selected subproject!\n" "Unable to determine the main program", "No selected subproject found" ); kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; return TQString(); } if ( m_widget->currentSubproject()->scope->variableValues("TEMPLATE").findIndex("app") == -1 ) { KMessageBox::error( m_widget, "Selected Subproject \""+m_widget->currentSubproject()->scope->projectName()+"\"isn't binary ( " + m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") + " ) !\n" "Unable to determine the main program. If you want this\n" "to be the selected subproject, set a main program under\n" "Project -> Project Options -> Run Options", "Selected subproject is not a library" ); kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") << ") ! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; return TQString(); } TQString destpath = m_widget->getCurrentTarget(); if( TQDir::isRelativePath( destpath ) ) { destpath = m_widget->subprojectDirectory() + TQString( TQChar( TQDir::separator() ) ) + destpath; } return destpath; } } TQString TrollProjectPart::debugArguments() const { if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true ) ) { return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/globaldebugarguments"); }else { return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/debugarguments/"+m_widget->getCurrentOutputFilename() ); } } /** Retuns a TQString with the run command line arguments */ TQString TrollProjectPart::runArguments() const { if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true) ) { return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/programargs"); }else { return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/runarguments/"+m_widget->getCurrentOutputFilename() ); } } TQString TrollProjectPart::activeDirectory() const { TQDomDocument &dom = *projectDom(); return DomUtil::readEntry(dom, "/kdevtrollproject/general/activedir"); } TQStringList TrollProjectPart::allFiles() const { return m_widget->allFiles(); } void TrollProjectPart::addFile(const TQString &fileName) { TQStringList fileList; fileList.append ( fileName ); this->addFiles ( TQStringList( fileName ) ); } void TrollProjectPart::addFiles ( const TQStringList &fileList ) { TQStringList files = fileList; for (TQStringList::iterator it = files.begin(); it != files.end(); ++it) { if( !TQFileInfo( *it ).isRelative() ) { *it = URLUtil::relativePathToFile( projectDirectory(), *it ); } } m_widget->addFiles(files); } void TrollProjectPart::removeFile(const TQString & /* fileName */) { /// \FIXME /* TQStringList fileList; fileList.append ( fileName ); this->removeFiles ( fileList );*/ } void TrollProjectPart::removeFiles ( const TQStringList& fileList ) { /// \FIXME missing remove files functionality // TQStringList::ConstIterator it; // // it = fileList.begin(); // // for ( ; it != fileList.end(); ++it ) // { // FIXME // } emit removedFilesFromProject ( fileList ); } /* void TrollProjectPart::startMakeCommand(const TQString &dir, const TQString &target) { partController()->saveAllFiles(); TQFileInfo fi(dir + "/Makefile"); if (!fi.exists()) { int r = KMessageBox::questionYesNo(m_widget, i18n("There is no Makefile in this directory. Run qmake first?"), TQString(), i18n("Run qmake"), i18n("Do Not Run")); if (r == KMessageBox::No) return; startTQMakeCommand(dir); } TQDomDocument &dom = *projectDom(); if (target=="clean") { TQString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); if (cmdline.isEmpty()) cmdline = MAKE_COMMAND; cmdline += " clean"; TQString dircmd = "cd "; dircmd += dir; dircmd += " && "; cmdline.prepend(makeEnvironment()); makeFrontend()->queueCommand(dir, dircmd + cmdline); } TQString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); if (cmdline.isEmpty()) cmdline = MAKE_COMMAND; if (!DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/abortonerror")) cmdline += " -k"; int jobs = DomUtil::readIntEntry(dom, "/kdevtrollproject/make/numberofjobs"); if (jobs != 0) { cmdline += " -j"; cmdline += TQString::number(jobs); } if (DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/dontact")) cmdline += " -n"; cmdline += " "; cmdline += target; TQString dircmd = "cd "; dircmd += dir; dircmd += " && "; cmdline.prepend(makeEnvironment()); makeFrontend()->queueCommand(dir, dircmd + cmdline); } */ void TrollProjectPart::startTQMakeCommand(const TQString &dir, bool recursive) { TQFileInfo fi(dir); TQString cmdline; if ( isTMakeProject() ) { cmdline = "tmake "; }else { cmdline = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", "")+" "; } if(isTQt4Project() && recursive) { cmdline += " -recursive "; } //TQString cmdline = TQString::fromLatin1( isTMakeProject() ? "tmake " : "qmake " ); // cmdline += fi.baseName() + ".pro"; TQDir d(dir); TQStringList l = d.entryList("*.pro"); if( l.isEmpty() || ( l.count() && l.findIndex( projectName() + ".pro" ) != -1 ) ) cmdline += projectName()+".pro"; else if( l.isEmpty() || (l.count() && l.findIndex( fi.baseName() + ".pro" ) != -1 ) ) cmdline += fi.baseName() + ".pro"; else cmdline += l[0]; // cmdline += TQString::fromLatin1( " -o Makefile" ); TQString dircmd = "cd "; dircmd += KProcess::quote(dir); dircmd += " && "; cmdline.prepend(makeEnvironment()); makeFrontend()->queueCommand(dir, dircmd + cmdline); } void TrollProjectPart::queueCmd(const TQString &dir, const TQString &cmd) { makeFrontend()->queueCommand(dir, cmd); } void TrollProjectPart::slotCommandFinished( const TQString& command ) { Q_UNUSED( command ); // if( m_buildCommand != command ) // return; // // m_buildCommand = TQString(); 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(); if( m_executeProjectAfterBuild ) { m_widget->slotExecuteProject(); m_executeProjectAfterBuild = false; }else if( m_executeTargetAfterBuild ) { m_widget->slotExecuteTarget(); m_executeTargetAfterBuild = false; } } bool TrollProjectPart::isDirty() { 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; } KDevProject::Options TrollProjectPart::options( ) const { return UsesTQMakeBuildSystem; } bool TrollProjectPart::isValidTQtDir( const TQString& path ) const { TQFileInfo inc( path + TQString( TQChar( TQDir::separator() ) )+ "include"+TQString( TQChar( TQDir::separator() ) )+ "tqt.h" ); return ( isTQt4Project() || ( !isTQt4Project() && inc.exists() ) ); } void TrollProjectPart::buildBinDirs( TQStringList & dirs ) const { if( !isTQt4Project() ) { TQString m_defaultTQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); if( !m_defaultTQtDir.isEmpty() ) dirs << (m_defaultTQtDir + TQString( TQChar( TQDir::separator() ) ) + "bin" ); dirs << ( ::getenv("QTDIR") + TQString( TQChar( TQDir::separator() ) ) + "bin" ); } TQStringList paths = TQStringList::split(":",::getenv("PATH")); dirs += paths; TQString binpath = TQDir::rootDirPath() + "bin"; if( dirs.findIndex( binpath ) != -1 ) dirs << binpath; binpath = TQDir::rootDirPath() + "usr" + TQString( TQChar( TQDir::separator() ) ) + "bin"; if( dirs.findIndex( binpath ) != -1 ) dirs << binpath; binpath = TQDir::rootDirPath() + "usr" + TQString( TQChar( TQDir::separator() ) ) + "local" + TQString( TQChar( TQDir::separator() ) ) + "bin"; if( dirs.findIndex( binpath ) != -1 ) dirs << binpath; } TQString TrollProjectPart::findExecutable( const TQString& execname ) const { TQStringList dirs; buildBinDirs( dirs ); for( TQStringList::Iterator it=dirs.begin(); it!=dirs.end(); ++it ) { TQString designer = *it + TQString( TQChar( TQDir::separator() ) ) + execname; if( !designer.isEmpty() && isExecutable( designer ) ) { return designer; } } return ""; } bool TrollProjectPart::isExecutable( const TQString& path ) const { TQFileInfo fi(path); return( fi.exists() && fi.isExecutable() ); } TQString TrollProjectPart::findTQtDir() { TQStringList qtdirs; if( !isTQt4Project() ) qtdirs.push_back( ::getenv("QTDIR") ); qtdirs.push_back( TQDir::rootDirPath()+"usr"+TQString( TQChar( TQDir::separator() ) )+"lib"+TQString( TQChar( TQDir::separator() ) )+"qt"+TQString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); qtdirs.push_back( TQDir::rootDirPath()+"usr"+TQString( TQChar( TQDir::separator() ) )+"lib"+TQString( TQChar( TQDir::separator() ) )+"qt"+TQString( TQChar( TQDir::separator() ) )+TQString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); qtdirs.push_back( TQDir::rootDirPath()+"usr"+TQString( TQChar( TQDir::separator() ) )+"share"+TQString( TQChar( TQDir::separator() ) )+"qt"+TQString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); qtdirs.push_back( TQDir::rootDirPath()+"usr" ); qtdirs.push_back( TQDir::rootDirPath()+"usr"+TQString( TQChar( TQDir::separator() ) )+"lib"+TQString( TQChar( TQDir::separator() ) )+"qt" ); for( TQStringList::Iterator it=qtdirs.begin(); it!=qtdirs.end(); ++it ) { TQString qtdir = *it; if( !qtdir.isEmpty() && isValidTQtDir(qtdir) ) { return qtdir; } } return ""; } TQStringList recursiveProFind( const TQString &currDir, const TQString &baseDir ) { TQStringList fileList; if( !currDir.contains( TQString( TQChar ( TQDir::separator() ) ) +".." ) && !currDir.contains( TQString( TQChar( TQDir::separator() ) )+".") ) { TQDir dir(currDir); TQStringList dirList = dir.entryList(TQDir::Dirs ); TQStringList::Iterator idx = dirList.begin(); for( ; idx != dirList.end(); ++idx ) { fileList += recursiveProFind( currDir + TQString( TQChar( TQDir::separator() ) ) + (*idx),baseDir ); } TQStringList newFiles = dir.entryList("*.pro *.PRO"); idx = newFiles.begin(); for( ; idx != newFiles.end(); ++idx ) { TQString file = currDir + TQString( TQChar( TQDir::separator() ) ) + (*idx); fileList.append( file.remove( baseDir ) ); } } return fileList; } /*! \fn TrollProjectPart::distFiles() const */ TQStringList TrollProjectPart::distFiles() const { TQStringList sourceList = allFiles(); // Scan current source directory for any .pro files. TQString projectDir = projectDirectory(); TQStringList files = recursiveProFind( projectDir, projectDir + TQString( TQChar( TQDir::separator() ) ) ); return sourceList + files; } bool TrollProjectPart::isTQt4Project() const { return ( DomUtil::readIntEntry( *projectDom(), "kdevcppsupport/qt/version", 3 ) == 4 ); } KDirWatch* TrollProjectPart::dirWatch() { return m_dirWatch; } void TrollProjectPart::slotBuild() { m_widget->slotBuildProject(); } #include "trollprojectpart.moc" //kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on