/***************************************************************************
* Copyright ( C ) 2001 - 2002 by Bernd Gehrmann *
* bernd @ kdevelop . org *
* Copyright ( C ) 2007 by Andreas Pakulat *
* apaku @ 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 "customprojectpart.h"
# include <tqapplication.h>
# include <kapplication.h>
# include <tqdir.h>
# include <tqfileinfo.h>
# include <tqpopupmenu.h>
# include <tqregexp.h>
# include <tqstringlist.h>
# include <tqtabwidget.h>
# include <tqvaluestack.h>
# include <tqvbox.h>
# include <tqwhatsthis.h>
# include <tqdom.h>
# include <kaction.h>
# include <kconfig.h>
# include <kdebug.h>
# include <kdialogbase.h>
# include <keditlistbox.h>
# include <kdevgenericfactory.h>
# include <kiconloader.h>
# include <klocale.h>
# include <kmainwindow.h>
# include <kmessagebox.h>
# include <kparts/part.h>
# include <kpopupmenu.h>
# include <kdeversion.h>
# include <kprocess.h>
# include "domutil.h"
# include "kdevcore.h"
# include "kdevmainwindow.h"
# include "kdevmakefrontend.h"
# include "kdevappfrontend.h"
# include "kdevpartcontroller.h"
# include "runoptionswidget.h"
# include "makeoptionswidget.h"
# include "custombuildoptionswidget.h"
# include "custommakeconfigwidget.h"
# include "customotherconfigwidget.h"
# include "custommanagerwidget.h"
# include "config.h"
# include "envvartools.h"
# include "urlutil.h"
# include "selectnewfilesdialog.h"
# include <kdevplugininfo.h>
typedef KDevGenericFactory < CustomProjectPart > CustomProjectFactory ;
static const KDevPluginInfo data ( " kdevcustomproject " ) ;
K_EXPORT_COMPONENT_FACTORY ( libkdevcustomproject , CustomProjectFactory ( data ) )
CustomProjectPart : : CustomProjectPart ( TQObject * parent , const char * name , const TQStringList & )
: KDevBuildTool ( & data , parent , name ? name : " CustomProjectPart " )
, m_lastCompilationFailed ( false ) , m_recursive ( false ) , m_first_recursive ( false )
{
setInstance ( CustomProjectFactory : : instance ( ) ) ;
setXMLFile ( " kdevcustomproject.rc " ) ;
m_executeAfterBuild = false ;
KAction * action ;
action = new KAction ( i18n ( " Re-Populate Project " ) , 0 , this , TQT_SLOT ( populateProject ( ) ) , actionCollection ( ) , " repopulate_project " ) ;
action - > setToolTip ( i18n ( " Re-Populate Project " ) ) ;
action - > setWhatsThis ( i18n ( " <b>Re-Populate Project</b><p>Re-Populates the project, searching through the project directory and adding all files that match one of the wildcards set in the custom manager options of the project filelist. " ) ) ;
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>Build Options</b> tab. " ) ) ;
action = new KAction ( i18n ( " &Build Active Directory " ) , " make_kdevelop " , Key_F7 ,
this , TQT_SLOT ( slotBuildActiveDir ( ) ) ,
actionCollection ( ) , " build_buildactivetarget " ) ;
action - > setToolTip ( i18n ( " Build active directory " ) ) ;
action - > setWhatsThis ( i18n ( " <b>Build active directory</b><p>Constructs a series of make commands to build the active directory. "
" Environment variables and make arguments can be specified "
" in the project settings dialog, <b>Make Options</b> tab. " ) ) ;
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>Build Options</b> tab. " ) ) ;
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 = new KAction ( i18n ( " Install Active Directory " ) , 0 ,
this , TQT_SLOT ( slotInstallActiveDir ( ) ) ,
actionCollection ( ) , " build_installactivetarget " ) ;
action - > setToolTip ( i18n ( " Install active directory " ) ) ;
action - > setWhatsThis ( i18n ( " <b>Install active directory</b><p>Runs <b>make install</b> command from the active 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 (as root user) " ) , 0 ,
this , TQT_SLOT ( slotInstallWithKdesu ( ) ) ,
actionCollection ( ) , " build_install_tdesu " ) ;
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 tdesu command.<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 ,
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>Build Options</b> tab. " ) ) ;
action = new KAction ( i18n ( " Execute Program " ) , " exec " , 0 ,
this , TQT_SLOT ( slotExecute ( ) ) ,
actionCollection ( ) , " build_execute " ) ;
action - > setToolTip ( i18n ( " Execute program " ) ) ;
action - > setWhatsThis ( i18n ( " <b>Execute program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab. "
" If it is not specified then the active target is used to determine the application to run. " ) ) ;
KActionMenu * menu = new KActionMenu ( i18n ( " Build &Target " ) ,
actionCollection ( ) , " build_target " ) ;
m_targetMenu = menu - > popupMenu ( ) ;
menu - > setToolTip ( i18n ( " Build target " ) ) ;
menu - > setWhatsThis ( i18n ( " <b>Build target</b><p>Runs <b>make targetname</b> from the project directory (targetname is the name of the target selected).<br> "
" Environment variables and make arguments can be specified "
" in the project settings dialog, <b>Build Options</b> tab. " ) ) ;
m_targetObjectFilesMenu = new TQPopupMenu ( ) ;
m_targetOtherFilesMenu = new TQPopupMenu ( ) ;
m_makeEnvironmentsSelector = new KSelectAction ( i18n ( " Make &Environment " ) , 0 ,
actionCollection ( ) , " build_make_environment " ) ;
m_makeEnvironmentsSelector - > setToolTip ( i18n ( " Make environment " ) ) ;
m_makeEnvironmentsSelector - > setWhatsThis ( i18n ( " <b>Make Environment</b><p> Choose the set of environment variables to be passed on to make.<br> "
" Environment variables can be specified in the project "
" settings dialog, <b>Build Options</b> tab. " ) ) ;
connect ( m_targetMenu , TQT_SIGNAL ( aboutToShow ( ) ) ,
this , TQT_SLOT ( updateTargetMenu ( ) ) ) ;
connect ( m_targetMenu , TQT_SIGNAL ( activated ( int ) ) ,
this , TQT_SLOT ( targetMenuActivated ( int ) ) ) ;
connect ( m_targetObjectFilesMenu , TQT_SIGNAL ( activated ( int ) ) ,
this , TQT_SLOT ( targetObjectFilesMenuActivated ( int ) ) ) ;
connect ( m_targetOtherFilesMenu , TQT_SIGNAL ( activated ( int ) ) ,
this , TQT_SLOT ( targetOtherFilesMenuActivated ( int ) ) ) ;
connect ( m_makeEnvironmentsSelector - > popupMenu ( ) , TQT_SIGNAL ( aboutToShow ( ) ) ,
this , TQT_SLOT ( updateMakeEnvironmentsMenu ( ) ) ) ;
connect ( m_makeEnvironmentsSelector - > popupMenu ( ) , TQT_SIGNAL ( activated ( int ) ) ,
this , TQT_SLOT ( makeEnvironmentsMenuActivated ( int ) ) ) ;
connect ( core ( ) , TQT_SIGNAL ( projectConfigWidget ( KDialogBase * ) ) ,
this , TQT_SLOT ( projectConfigWidget ( KDialogBase * ) ) ) ;
connect ( core ( ) , TQT_SIGNAL ( contextMenu ( TQPopupMenu * , const Context * ) ) ,
this , TQT_SLOT ( contextMenu ( TQPopupMenu * , const Context * ) ) ) ;
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 & ) ) ) ;
}
CustomProjectPart : : ~ CustomProjectPart ( )
{ }
void CustomProjectPart : : projectConfigWidget ( KDialogBase * dlg )
{
TQVBox * vbox ;
vbox = dlg - > addVBoxPage ( i18n ( " Custom Manager " ) , i18n ( " Custom Manager " ) , BarIcon ( " make " , KIcon : : SizeMedium ) ) ;
CustomManagerWidget * w0 = new CustomManagerWidget ( this , vbox ) ;
connect ( dlg , TQT_SIGNAL ( okClicked ( ) ) , w0 , TQT_SLOT ( accept ( ) ) ) ;
vbox = dlg - > addVBoxPage ( i18n ( " Run Options " ) , i18n ( " Run Options " ) , BarIcon ( " make " , KIcon : : SizeMedium ) ) ;
RunOptionsWidget * w1 = new RunOptionsWidget ( * projectDom ( ) , " /kdevcustomproject " , buildDirectory ( ) , vbox ) ;
connect ( dlg , TQT_SIGNAL ( okClicked ( ) ) , w1 , TQT_SLOT ( accept ( ) ) ) ;
vbox = dlg - > addVBoxPage ( i18n ( " Build Options " ) , i18n ( " Build Options " ) , BarIcon ( " make " , KIcon : : SizeMedium ) ) ;
TQTabWidget * buildtab = new TQTabWidget ( vbox ) ;
CustomBuildOptionsWidget * w2 = new CustomBuildOptionsWidget ( * projectDom ( ) , buildtab ) ;
connect ( dlg , TQT_SIGNAL ( okClicked ( ) ) , w2 , TQT_SLOT ( accept ( ) ) ) ;
buildtab - > addTab ( w2 , i18n ( " &Build " ) ) ;
CustomOtherConfigWidget * w4 = new CustomOtherConfigWidget ( this , " /kdevcustomproject " , buildtab ) ;
connect ( dlg , TQT_SIGNAL ( okClicked ( ) ) , w4 , TQT_SLOT ( accept ( ) ) ) ;
buildtab - > addTab ( w4 , i18n ( " &Other " ) ) ;
CustomMakeConfigWidget * w3 = new CustomMakeConfigWidget ( this , " /kdevcustomproject " , buildtab ) ;
buildtab - > addTab ( w3 , i18n ( " Ma&ke " ) ) ;
w2 - > setMakeOptionsWidget ( buildtab , w3 , w4 ) ;
connect ( dlg , TQT_SIGNAL ( okClicked ( ) ) , w3 , TQT_SLOT ( accept ( ) ) ) ;
}
void CustomProjectPart : : contextMenu ( TQPopupMenu * popup , const Context * context )
{
if ( ! context - > hasType ( Context : : FileContext ) )
return ;
const FileContext * fcontext = static_cast < const FileContext * > ( context ) ;
m_contextAddFiles . clear ( ) ;
m_contextRemoveFiles . clear ( ) ;
TQString popupstr = fcontext - > urls ( ) . first ( ) . fileName ( ) ;
if ( popupstr = = TQString ( ) )
popupstr = " . " ;
if ( fcontext - > urls ( ) . size ( ) = = 1 & & URLUtil : : isDirectory ( fcontext - > urls ( ) . first ( ) ) & & ! isInBlacklist ( fcontext - > urls ( ) . first ( ) . path ( ) ) )
{
popup - > insertSeparator ( ) ;
// remember the name of the directory
m_contextDirName = fcontext - > urls ( ) . first ( ) . path ( ) ;
m_contextDirName = m_contextDirName . mid ( project ( ) - > projectDirectory ( ) . length ( ) + 1 ) ;
int id = popup - > insertItem ( i18n ( " Make Active Directory " ) ,
this , TQT_SLOT ( slotChooseActiveDirectory ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Make active directory</b><p> "
" Chooses this directory as the destination for new files created using wizards "
" like the <i>New Class</i> wizard. " ) ) ;
}
kdDebug ( 9025 ) < < " context urls: " < < fcontext - > urls ( ) < < endl ;
if ( fcontext - > urls ( ) . size ( ) = = 1 & & ( isProjectFileType ( fcontext - > urls ( ) . first ( ) . path ( ) ) | | URLUtil : : isDirectory ( fcontext - > urls ( ) . first ( ) ) ) )
{
popup - > insertSeparator ( ) ;
m_contextDirName = fcontext - > urls ( ) . first ( ) . path ( ) ;
m_contextDirName = m_contextDirName . mid ( project ( ) - > projectDirectory ( ) . length ( ) + 1 ) ;
int id ;
if ( isInBlacklist ( m_contextDirName ) )
{
id = popup - > insertItem ( i18n ( " Remove from blacklist " ) ,
this , TQT_SLOT ( slotChangeBlacklist ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Remove from blacklist</b><p> "
" Removes the given file or directory from the "
" blacklist if it is already in it.<br>The blacklist contains files and "
" directories that should be ignored even if they match a project filetype "
" pattern " ) ) ;
}
else
{
id = popup - > insertItem ( i18n ( " Add to blacklist " ) ,
this , TQT_SLOT ( slotChangeBlacklist ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Add to blacklist</b><p> "
" Adds the given file or directory to the blacklist.<br>The blacklist contains files and "
" directories that should be ignored even if they match a project filetype "
" pattern " ) ) ;
}
}
const KURL : : List urls = fcontext - > urls ( ) ;
bool dirAddRecursive = false ;
bool dirDelRecursive = false ;
for ( KURL : : List : : ConstIterator it = urls . begin ( ) ; it ! = urls . end ( ) ; + + it )
{
kdDebug ( 9025 ) < < " Checking URL: " < < * it < < endl ;
TQString canPath ( URLUtil : : canonicalPath ( ( * it ) . path ( ) ) ) ;
TQString relPath = relativeToProject ( canPath ) ;
kdDebug ( 9025 ) < < " relpath: " < < relPath < < " |canpath: " < < canPath < < endl ;
if ( isInBlacklist ( relPath ) )
continue ;
if ( ( ( * it ) . isLocalFile ( ) & & isProjectFileType ( ( * it ) . fileName ( ) ) ) )
{
if ( project ( ) - > isProjectFile ( canPath ) )
m_contextRemoveFiles < < relPath ;
if ( ! project ( ) - > isProjectFile ( canPath ) )
m_contextAddFiles < < relPath ;
}
if ( TQFileInfo ( ( * it ) . path ( ) ) . isDir ( ) )
{
if ( containsProjectFiles ( canPath ) | | project ( ) - > isProjectFile ( canPath ) )
{
if ( containsProjectFiles ( canPath ) )
dirDelRecursive = true ;
m_contextRemoveFiles < < relPath ;
}
if ( containsNonProjectFiles ( canPath ) | | ! project ( ) - > isProjectFile ( canPath ) )
{
if ( containsNonProjectFiles ( canPath ) )
dirAddRecursive = true ;
m_contextAddFiles < < relPath ;
}
}
}
if ( m_contextAddFiles . size ( ) > 0 | | m_contextRemoveFiles . size ( ) > 0 )
popup - > insertSeparator ( ) ;
if ( m_contextAddFiles . size ( ) > 0 )
{
int id = popup - > insertItem ( i18n ( " Add Selected File/Dir(s) to Project " ) ,
this , TQT_SLOT ( slotAddToProject ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Add to project</b><p>Adds selected file/dir(s) to the list of files in the project. "
" Note that the files should be manually added to the corresponding makefile or build.xml. " ) ) ;
if ( dirAddRecursive )
{
int id = popup - > insertItem ( i18n ( " Add Selected Dir(s) to Project (recursive) " ) ,
this , TQT_SLOT ( slotAddToProjectRecursive ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Add to project</b><p>Recursively adds selected dir(s) to the list of files in the project. "
" Note that the files should be manually added to the corresponding makefile or build.xml. " ) ) ;
}
}
if ( m_contextRemoveFiles . size ( ) > 0 )
{
int id = popup - > insertItem ( i18n ( " Remove Selected File/Dir(s) From Project " ) ,
this , TQT_SLOT ( slotRemoveFromProject ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Remove from project</b><p>Removes selected file/dir(s) from the list of files in the project. "
" Note that the files should be manually excluded from the corresponding makefile or build.xml. " ) ) ;
if ( dirDelRecursive )
{
int id = popup - > insertItem ( i18n ( " Remove Selected Dir(s) From Project (recursive) " ) ,
this , TQT_SLOT ( slotRemoveFromProjectRecursive ( ) ) ) ;
popup - > tqsetWhatsThis ( id , i18n ( " <b>Remove from project</b><p>Recursively removes selected dir(s) from the list of files in the project. "
" Note that the files should be manually excluded from the corresponding makefile or build.xml. " ) ) ;
}
}
}
void CustomProjectPart : : slotAddToProject ( )
{
m_recursive = false ;
m_first_recursive = true ;
addFiles ( m_contextAddFiles ) ;
}
void CustomProjectPart : : slotRemoveFromProject ( )
{
m_recursive = false ;
m_first_recursive = true ;
removeFiles ( m_contextRemoveFiles ) ;
}
void CustomProjectPart : : slotAddToProjectRecursive ( )
{
m_recursive = true ;
addFiles ( m_contextAddFiles ) ;
m_recursive = false ;
}
void CustomProjectPart : : slotRemoveFromProjectRecursive ( )
{
m_recursive = true ;
removeFiles ( m_contextRemoveFiles ) ;
m_recursive = false ;
}
void CustomProjectPart : : slotChangeBlacklist ( )
{
switchBlacklistEntry ( m_contextDirName ) ;
}
void CustomProjectPart : : slotChooseActiveDirectory ( )
{
TQString olddir = activeDirectory ( ) ;
TQDomDocument & dom = * projectDom ( ) ;
DomUtil : : writeEntry ( dom , " /kdevcustomproject/general/activedir " , m_contextDirName ) ;
emit activeDirectoryChanged ( olddir , activeDirectory ( ) ) ;
}
void CustomProjectPart : : openProject ( const TQString & dirName , const TQString & projectName )
{
m_projectDirectory = dirName ;
m_projectName = projectName ;
TQDomDocument & dom = * projectDom ( ) ;
// Set the default directory radio to "executable"
if ( DomUtil : : readEntry ( dom , " /kdevcustomproject/run/directoryradio " ) = = " " )
{
DomUtil : : writeEntry ( dom , " /kdevcustomproject/run/directoryradio " , " executable " ) ;
}
if ( filetypes ( ) . isEmpty ( ) )
{
TQStringList types ;
types < < " *.java " < < " *.h " < < " *.H " < < " *.hh " < < " *.hxx " < < " *.hpp " < < " *.c " < < " *.C "
< < " *.cc " < < " *.cpp " < < " *.c++ " < < " *.cxx " < < " Makefile " < < " CMakeLists.txt " ;
DomUtil : : writeListEntry ( dom , " /kdevcustomproject/filetypes " , " filetype " , types ) ;
}
/*this entry is currently only created by the cmake kdevelop3 project generator
in order to support completely - out - of - source builds , where nothing , not
even the kdevelop project files are created in the source directory , Alex < neundorf @ kde . org >
*/
m_filelistDir = DomUtil : : readEntry ( dom , " /kdevcustomproject/filelistdirectory " ) ;
if ( m_filelistDir . isEmpty ( ) )
m_filelistDir = dirName ;
if ( TQFileInfo ( m_filelistDir + " / " + projectName . lower ( ) +
" .kdevelop.filelist " ) . exists ( ) )
{
TQDir ( m_filelistDir ) . rename (
projectName . lower ( ) + " .kdevelop.filelist " ,
projectName + " .kdevelop.filelist " ) ;
}
TQFile f ( m_filelistDir + " / " + projectName + " .kdevelop.filelist " ) ;
if ( f . open ( IO_ReadOnly ) )
{
TQTextStream stream ( & f ) ;
while ( ! stream . atEnd ( ) )
{
TQString s = stream . readLine ( ) ;
// Skip comments.
if ( s . isEmpty ( ) | | s . startsWith ( " # " ) )
continue ;
// Skip non-existent files.
if ( ! TQFileInfo ( projectDirectory ( ) + " / " + s ) . exists ( ) )
continue ;
// Do not bother with files already in project or on blacklist.
if ( isInProject ( s ) | | isInBlacklist ( s ) )
continue ;
addToProject ( s ) ;
}
TQStringList newfiles ;
findNewFiles ( dirName , newfiles ) ;
if ( newfiles . count ( ) > 0 )
{
addNewFilesToProject ( newfiles ) ;
}
}
else
{
int r = KMessageBox : : questionYesNo ( mainWindow ( ) - > main ( ) ,
i18n ( " This project does not contain any files yet. \n "
" Populate it with all C/C++/Java files below "
" the project directory? " ) , TQString ( ) , i18n ( " Populate " ) , i18n ( " Do Not Populate " ) ) ;
if ( r = = KMessageBox : : Yes )
populateProject ( ) ;
}
// check if there is an old envvars entry (from old project file with single make environment)
TQString buildtool = DomUtil : : readEntry ( dom , " /kdevcustomproject/build/buildtool " ) ;
TQDomElement el =
DomUtil : : elementByPath ( dom , " /kdevcustomproject/ " + buildtool + " /envvars " ) ;
if ( ! el . isNull ( ) )
{
TQDomElement envs = DomUtil : : createElementByPath ( dom , " /kdevcustomproject/ " + buildtool + " /environments " ) ;
DomUtil : : makeEmpty ( envs ) ;
el . setTagName ( " default " ) ;
envs . appendChild ( el ) ;
}
KDevProject : : openProject ( dirName , projectName ) ;
}
/**
* @ brief Recursively search given directory searching for files which may be part of this project .
*
* The files found not in a black list ,
* and not being already part of our project are gathered .
*
* @ param dir directory to scan ( and recurse ) for potential project files .
* @ param [ out ] fileList the list of files found .
*/
void CustomProjectPart : : findNewFiles ( const TQString & dir , TQStringList & filelist ) const
{
if ( dir . isEmpty ( ) )
return ;
TQStringList fileentries = TQDir ( dir ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( dir ) . entryList ( TQDir : : Dirs ) ;
TQStringList entries = fileentries + dirs ;
TQString relpath = relativeToProject ( dir ) ;
if ( ! relpath . isEmpty ( ) )
relpath + = " / " ;
for ( TQStringList : : const_iterator it = entries . begin ( ) ; it ! = entries . end ( ) ; + + it )
{
// Only process genuine entries - files and directories.
if ( ( * it = = " . " ) | | ( * it = = " .. " ) )
continue ;
// If the entry (be it a file or a directory) is already part of this project, proceed to next one.
const TQString relativeEntry ( relpath + * it ) ;
if ( isInProject ( relativeEntry ) )
continue ;
// If the entry is blacklisted, proceed to next one.
// Note that by using generic isInBlacklist(),
// we are actually wasting resources,
// because it also tests whether any parent directory of relativeEntry is blacklisted.
// But by the order we are traversing and processing the directories,
// we know it is not the case, ever.
if ( isInBlacklist ( relativeEntry ) )
continue ;
// We have a new, non-blacklisted entry.
// Recurse into it (a directory) or add it to the potential list of new project files.
const TQString absoluteEntry ( dir + " / " + * it ) ;
if ( TQFileInfo ( absoluteEntry ) . isFile ( ) )
{
filelist < < relativeEntry ;
}
else if ( TQFileInfo ( absoluteEntry ) . isDir ( ) )
{
bool searchRecursive = true ;
TQFileInfo fi ( absoluteEntry ) ;
if ( fi . isSymLink ( ) )
{
TQString realDir = fi . readLink ( ) ;
if ( TQFileInfo ( realDir ) . exists ( ) )
{
for ( TQStringList : : const_iterator it = filelist . constBegin ( ) ; it ! = filelist . constEnd ( ) ; + + it )
{
if ( TQFileInfo ( projectDirectory ( ) + " / " + * it ) . absFilePath ( ) . startsWith ( realDir ) )
{
searchRecursive = false ;
}
}
} else {
searchRecursive = false ;
}
}
if ( searchRecursive )
{
findNewFiles ( absoluteEntry , filelist ) ;
}
}
}
}
void CustomProjectPart : : populateProject ( )
{
KDialogBase * dlg = new KDialogBase ( mainWindow ( ) - > main ( ) , " typeselector " , true ,
" Select filetypes of project " , KDialogBase : : Ok | KDialogBase : : Cancel ) ;
TQVBox * box = dlg - > makeVBoxMainWidget ( ) ;
KEditListBox * lb = new KEditListBox ( " Filetypes in the project " , box , " selecttypes " ,
false , KEditListBox : : Add | KEditListBox : : Remove ) ;
lb - > setItems ( filetypes ( ) ) ;
if ( dlg - > exec ( ) = = TQDialog : : Accepted )
{
setFiletypes ( lb - > items ( ) ) ;
}
TQApplication : : setOverrideCursor ( TQt : : waitCursor ) ;
removeFiles ( allFiles ( ) ) ;
updateBlacklist ( TQStringList ( ) ) ;
TQStringList newlist ;
findNewFiles ( projectDirectory ( ) , newlist ) ;
TQApplication : : restoreOverrideCursor ( ) ;
addNewFilesToProject ( newlist ) ;
}
void CustomProjectPart : : closeProject ( )
{
saveProject ( ) ;
}
void CustomProjectPart : : saveProject ( )
{
TQFile f ( m_filelistDir + " / " + m_projectName + " .kdevelop.filelist " ) ;
if ( ! f . open ( IO_WriteOnly ) )
return ;
TQTextStream stream ( & f ) ;
stream < < " # KDevelop Custom Project File List " < < endl ;
ProjectFilesSet : : ConstIterator it ;
for ( it = m_sourceFilesSet . constBegin ( ) ; it ! = m_sourceFilesSet . constEnd ( ) ; + + it )
stream < < it . key ( ) < < endl ;
f . close ( ) ;
}
TQString CustomProjectPart : : projectDirectory ( ) const
{
return m_projectDirectory ;
}
TQString CustomProjectPart : : projectName ( ) const
{
return m_projectName ;
}
/** Retuns a PairList with the run environment variables */
DomUtil : : PairList CustomProjectPart : : runEnvironmentVars ( ) const
{
return DomUtil : : readPairListEntry ( * projectDom ( ) , " /kdevcustomproject/run/envvars " , " envvar " , " name " , " value " ) ;
}
/** 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 CustomProjectPart : : runDirectory ( ) const
{
TQString cwd = defaultRunDirectory ( " kdevcustomproject " ) ;
if ( cwd . isEmpty ( ) )
cwd = buildDirectory ( ) ;
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 CustomProjectPart : : mainProgram ( ) const
{
TQDomDocument * dom = projectDom ( ) ;
if ( ! dom ) return TQString ( ) ;
TQString DomMainProgram = DomUtil : : readEntry ( * dom , " /kdevcustomproject/run/mainprogram " ) ;
if ( DomMainProgram . isEmpty ( ) ) return TQString ( ) ;
if ( DomMainProgram . startsWith ( " / " ) ) // assume absolute path
{
return DomMainProgram ;
}
else // assume project relative path
{
return projectDirectory ( ) + " / " + DomMainProgram ;
}
return TQString ( ) ;
}
/** Retuns a TQString with the debug command line arguments */
TQString CustomProjectPart : : debugArguments ( ) const
{
return DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/run/globaldebugarguments " ) ;
}
/** Retuns a TQString with the run command line arguments */
TQString CustomProjectPart : : runArguments ( ) const
{
return DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/run/programargs " ) ;
}
TQString CustomProjectPart : : activeDirectory ( ) const
{
TQDomDocument & dom = * projectDom ( ) ;
return DomUtil : : readEntry ( dom , " /kdevcustomproject/general/activedir " , " . " ) ;
}
TQStringList CustomProjectPart : : allFiles ( ) const
{
return m_sourceFilesSet . keys ( ) ;
}
void CustomProjectPart : : addFile ( const TQString & fileName )
{
TQStringList fileList ;
fileList . append ( fileName ) ;
this - > addFiles ( fileList ) ;
}
void CustomProjectPart : : addFiles ( const TQStringList & fileList )
{
TQStringList : : ConstIterator it ;
TQStringList addedFiles ;
TQStringList myfileList = fileList ;
kdDebug ( 9025 ) < < " Adding files: " < < myfileList < < endl ;
myfileList . remove ( " . " ) ;
myfileList . remove ( " " ) ;
myfileList . remove ( " .. " ) ;
for ( it = myfileList . begin ( ) ; it ! = myfileList . end ( ) ; + + it )
{
if ( isInBlacklist ( * it ) )
continue ;
TQString relpath ;
kdDebug ( 9025 ) < < " Checking path: " < < * it < < endl ;
if ( TQDir : : isRelativePath ( * it ) )
{
kdDebug ( 9025 ) < < * it < < " is relative " < < endl ;
relpath = * it ;
}
else
{
kdDebug ( 9025 ) < < * it < < " is not relative " < < endl ;
relpath = relativeToProject ( * it ) ;
}
if ( ! TQFileInfo ( projectDirectory ( ) + " / " + relpath ) . exists ( ) )
continue ;
if ( TQFileInfo ( projectDirectory ( ) + " / " + relpath ) . isDir ( ) & & ( m_recursive | | m_first_recursive ) )
{
kdDebug ( 9025 ) < < " is a dir and " < < m_recursive < < " | " < < m_first_recursive < < endl ;
m_first_recursive = false ;
TQStringList fileentries = TQDir ( projectDirectory ( ) + " / " + relpath ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( projectDirectory ( ) + " / " + relpath ) . entryList ( TQDir : : Dirs ) ;
TQStringList subentries = fileentries + dirs ;
for ( TQStringList : : iterator subit = subentries . begin ( ) ; subit ! = subentries . end ( ) ; + + subit )
{
if ( * subit ! = " . " & & * subit ! = " .. " )
* subit = relpath + " / " + ( * subit ) ;
if ( ( * subit ) . startsWith ( " / " ) )
* subit = ( * subit ) . mid ( 1 , ( * subit ) . length ( ) ) ;
}
addFiles ( subentries ) ;
addedFiles < < relpath ;
addToProject ( relpath ) ;
m_first_recursive = true ;
}
else if ( isProjectFileType ( TQFileInfo ( relpath ) . fileName ( ) ) & & ( ! isInProject ( relpath ) ) )
{
TQStringList paths = TQStringList : : split ( " / " , relpath ) ;
paths . pop_back ( ) ;
TQString path ;
for ( TQStringList : : const_iterator it = paths . begin ( ) ; it ! = paths . end ( ) ; + + it )
{
path + = * it ;
if ( ! isInProject ( path ) )
{
addedFiles < < path ;
addToProject ( path ) ;
}
path + = " / " ;
}
addedFiles < < relpath ;
addToProject ( relpath ) ;
}
else
{
kdDebug ( 9025 ) < < " not adding " < < relpath < < endl ;
}
}
m_first_recursive = false ;
saveProject ( ) ;
kdDebug ( 9025 ) < < " Emitting addedFilesToProject " < < addedFiles < < endl ;
emit addedFilesToProject ( addedFiles ) ;
}
void CustomProjectPart : : removeFile ( const TQString & fileName )
{
TQStringList fileList ;
fileList . append ( fileName ) ;
this - > removeFiles ( fileList ) ;
}
void CustomProjectPart : : removeFiles ( const TQStringList & fileList )
{
kdDebug ( 9025 ) < < " Emitting removedFilesFromProject " < < fileList < < endl ;
TQStringList removedFiles ;
TQStringList myfileList = fileList ;
TQStringList : : ConstIterator it ;
myfileList . remove ( " . " ) ;
myfileList . remove ( " .. " ) ;
myfileList . remove ( " " ) ;
for ( it = myfileList . begin ( ) ; it ! = myfileList . end ( ) ; + + it )
{
TQString relpath ;
if ( TQDir : : isRelativePath ( * it ) )
relpath = * it ;
else
relpath = relativeToProject ( * it ) ;
if ( TQFileInfo ( projectDirectory ( ) + " / " + relpath ) . isDir ( ) & & ( m_recursive | | m_first_recursive ) )
{
m_first_recursive = false ;
TQStringList fileentries = TQDir ( projectDirectory ( ) + " / " + relpath ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( projectDirectory ( ) + " / " + relpath ) . entryList ( TQDir : : Dirs ) ;
TQStringList subentries = fileentries + dirs ;
for ( TQStringList : : iterator subit = subentries . begin ( ) ; subit ! = subentries . end ( ) ; + + subit )
if ( * subit ! = " . " & & * subit ! = " .. " )
* subit = relpath + " / " + ( * subit ) ;
removeFiles ( subentries ) ;
if ( ! containsProjectFiles ( relpath ) )
{
removedFiles < < relpath ;
removeFromProject ( relpath ) ;
}
m_first_recursive = true ;
}
else if ( isInProject ( relpath ) )
{
removedFiles < < relpath ;
removeFromProject ( relpath ) ;
TQStringList paths = TQStringList : : split ( " / " , relpath ) ;
TQString lastsubentry = paths [ paths . size ( ) - 1 ] ;
paths . pop_back ( ) ;
while ( paths . size ( ) > 0 )
{
TQString dir = paths . join ( " / " ) ;
TQStringList projectentries = projectFilesInDir ( dir ) ;
if ( projectentries . size ( ) = = 0 )
{
removedFiles < < dir ;
removeFromProject ( dir ) ;
}
else
break ;
lastsubentry = paths [ paths . size ( ) - 1 ] ;
paths . pop_back ( ) ;
}
}
}
saveProject ( ) ;
emit removedFilesFromProject ( removedFiles ) ;
}
TQString CustomProjectPart : : buildDirectory ( ) const
{
TQString dir = DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/build/builddir " ) ;
if ( dir . isEmpty ( ) )
return projectDirectory ( ) ;
if ( TQFileInfo ( dir ) . isRelative ( ) )
return TQDir : : cleanDirPath ( projectDirectory ( ) + " / " + dir ) ;
return dir ;
}
TQString CustomProjectPart : : 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
TQString buildtool = DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/build/buildtool " ) ;
DomUtil : : PairList envvars =
DomUtil : : readPairListEntry ( * projectDom ( ) , " /kdevcustomproject/ " + buildtool + " /environments/ " + currentMakeEnvironment ( ) , " 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 CustomProjectPart : : startMakeCommand ( const TQString & dir , const TQString & target , bool withKdesu )
{
if ( partController ( ) - > saveAllFiles ( ) = = false )
return ; //user cancelled
TQDomDocument & dom = * projectDom ( ) ;
TQString buildtool = DomUtil : : readEntry ( dom , " /kdevcustomproject/build/buildtool " ) ;
TQString cmdline ;
if ( buildtool = = " ant " )
{
cmdline = " ant " ;
}
else if ( buildtool = = " other " )
{
cmdline = DomUtil : : readEntry ( dom , " /kdevcustomproject/other/otherbin " ) ;
if ( cmdline . isEmpty ( ) )
cmdline = " echo " ;
else if ( cmdline . find ( " / " ) = = - 1 )
cmdline = " ./ " + cmdline ;
cmdline + = " " + DomUtil : : readEntry ( dom , " /kdevcustomproject/other/otheroptions " ) ;
}
else
{
cmdline = DomUtil : : readEntry ( dom , " /kdevcustomproject/make/makebin " ) ;
if ( cmdline . isEmpty ( ) )
cmdline = MAKE_COMMAND ;
if ( ! DomUtil : : readBoolEntry ( dom , " /kdevcustomproject/make/abortonerror " ) )
cmdline + = " -k " ;
int jobs = DomUtil : : readIntEntry ( dom , " /kdevcustomproject/make/numberofjobs " ) ;
if ( jobs ! = 0 )
{
cmdline + = " -j " ;
cmdline + = TQString : : number ( jobs ) ;
}
if ( DomUtil : : readBoolEntry ( dom , " /kdevcustomproject/make/dontact " ) )
cmdline + = " -n " ;
cmdline + = " " + DomUtil : : readEntry ( dom , " /kdevcustomproject/make/makeoptions " ) ;
}
cmdline + = " " ;
if ( ! target . isEmpty ( ) )
cmdline + = KProcess : : quote ( target ) ;
TQString dircmd = " cd " ;
dircmd + = KProcess : : quote ( dir ) ;
dircmd + = " && " ;
int prio = DomUtil : : readIntEntry ( dom , " /kdevcustomproject/ " + buildtool + " /prio " ) ;
TQString nice ;
if ( prio ! = 0 )
{
nice = TQString ( " nice -n%1 " ) . tqarg ( prio ) ;
}
cmdline . prepend ( nice ) ;
cmdline . prepend ( makeEnvironment ( ) ) ;
if ( withKdesu )
cmdline = " tdesu -t -c ' " + cmdline + " ' " ;
m_buildCommand = dircmd + cmdline ;
makeFrontend ( ) - > queueCommand ( dir , dircmd + cmdline ) ;
}
void CustomProjectPart : : slotBuild ( )
{
m_lastCompilationFailed = false ;
TQString buildtool = DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/build/buildtool " ) ;
startMakeCommand ( buildDirectory ( ) , DomUtil : : readEntry ( * projectDom ( ) ,
" /kdevcustomproject/ " + buildtool + " /defaulttarget " ) ) ;
}
void CustomProjectPart : : slotBuildActiveDir ( )
{
m_lastCompilationFailed = false ;
TQString buildtool = DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/build/buildtool " ) ;
startMakeCommand ( buildDirectory ( ) + " / " + activeDirectory ( ) , DomUtil : : readEntry ( * projectDom ( ) ,
" /kdevcustomproject/ " + buildtool + " /defaulttarget " ) ) ;
}
void CustomProjectPart : : 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 ( 9025 ) < < " Compiling " < < fileName
< < " in dir " < < sourceDir
< < " with baseName " < < baseName < < endl ;
// What would be nice: In case of non-recursive build system, climb up from
// the source dir until a Makefile is found
TQString buildDir = sourceDir ;
TQString target = baseName + " .o " ;
TQString buildtool = DomUtil : : readEntry ( * projectDom ( ) , " /kdevcustomproject/build/buildtool " ) ;
//if there is no Makefile in the directory of the source file
//try to build it from the main build dir
//this works e.g. for non-recursive cmake Makefiles, Alex
if ( buildtool = = " make " & & ( TQFile : : exists ( sourceDir + " /Makefile " ) = = false )
& & ( TQFile : : exists ( sourceDir + " /makefile " ) = = false ) )
{
buildDir = buildDirectory ( ) ;
}
startMakeCommand ( buildDir , target ) ;
}
void CustomProjectPart : : slotInstallActiveDir ( )
{
startMakeCommand ( buildDirectory ( ) + " / " + activeDirectory ( ) , TQString : : tqfromLatin1 ( " install " ) ) ;
}
void CustomProjectPart : : slotInstall ( )
{
startMakeCommand ( buildDirectory ( ) , TQString : : tqfromLatin1 ( " install " ) ) ;
}
void CustomProjectPart : : 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 : : tqfromLatin1 ( " install " ) , true ) ;
}
void CustomProjectPart : : slotClean ( )
{
startMakeCommand ( buildDirectory ( ) , TQString : : tqfromLatin1 ( " clean " ) ) ;
}
void CustomProjectPart : : slotExecute ( )
{
partController ( ) - > saveAllFiles ( ) ;
bool _auto = false ;
if ( DomUtil : : readBoolEntry ( * projectDom ( ) , " /kdevcustomproject/run/autocompile " , true ) & & ( isDirty ( ) | | ! TQFileInfo ( mainProgram ( ) ) . exists ( ) ) )
{
m_executeAfterBuild = true ;
slotBuild ( ) ;
_auto = true ;
}
if ( DomUtil : : readBoolEntry ( * projectDom ( ) , " /kdevcustomproject/run/autoinstall " , false ) & & ( isDirty ( ) | | ! TQFileInfo ( mainProgram ( ) ) . exists ( ) ) )
{
m_executeAfterBuild = true ;
// Use tdesu??
if ( DomUtil : : readBoolEntry ( * projectDom ( ) , " /kdevcustomproject/run/autotdesu " , false ) )
//slotInstallWithKdesu assumes that it hasn't just been build...
_auto ? slotInstallWithKdesu ( ) : startMakeCommand ( buildDirectory ( ) , TQString : : tqfromLatin1 ( " install " ) , true ) ;
else
slotInstall ( ) ;
_auto = true ;
}
if ( _auto )
return ;
// 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
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 + = " " ;
}
if ( mainProgram ( ) . isEmpty ( ) )
// Do not execute non executable targets
return ;
TQString program = environstr ;
program + = mainProgram ( ) ;
program + = " " + runArguments ( ) ;
bool inTerminal = DomUtil : : readBoolEntry ( * projectDom ( ) , " /kdevcustomproject/run/terminal " ) ;
kdDebug ( 9025 ) < < " runDirectory: < " < < runDirectory ( ) < < " > " < < endl ;
kdDebug ( 9025 ) < < " environstr : < " < < environstr < < " > " < < endl ;
kdDebug ( 9025 ) < < " mainProgram : < " < < mainProgram ( ) < < " > " < < endl ;
kdDebug ( 9025 ) < < " runArguments: < " < < runArguments ( ) < < " > " < < endl ;
appFrontend ( ) - > startAppCommand ( runDirectory ( ) , program , inTerminal ) ;
}
void CustomProjectPart : : updateTargetMenu ( )
{
m_targets . clear ( ) ;
m_targetsObjectFiles . clear ( ) ;
m_targetsOtherFiles . clear ( ) ;
m_targetMenu - > clear ( ) ;
m_targetObjectFilesMenu - > clear ( ) ;
m_targetOtherFilesMenu - > clear ( ) ;
TQDomDocument & dom = * projectDom ( ) ;
bool ant = DomUtil : : readEntry ( dom , " /kdevcustomproject/build/buildtool " ) = = " ant " ;
if ( ant )
{
TQFile f ( buildDirectory ( ) + " /build.xml " ) ;
if ( ! f . open ( IO_ReadOnly ) )
{
kdDebug ( 9025 ) < < " No build file " < < endl ;
return ;
}
TQDomDocument dom ;
if ( ! dom . setContent ( & f ) )
{
kdDebug ( 9025 ) < < " Build script not valid xml " < < endl ;
f . close ( ) ;
return ;
}
f . close ( ) ;
TQDomNode node = dom . documentElement ( ) . firstChild ( ) ;
while ( ! node . isNull ( ) )
{
if ( node . toElement ( ) . tagName ( ) = = " target " )
m_targets . append ( node . toElement ( ) . attribute ( " name " ) ) ;
node = node . nextSibling ( ) ;
}
}
else
{
kdDebug ( 9025 ) < < " Trying to load a makefile... " < < endl ;
m_makefileVars . clear ( ) ;
m_parsedMakefiles . clear ( ) ;
m_makefilesToParse . clear ( ) ;
m_makefilesToParse . push ( " Makefile " ) ;
m_makefilesToParse . push ( " makefile " ) ;
putEnvVarsInVarMap ( ) ;
while ( ! m_makefilesToParse . isEmpty ( ) )
parseMakefile ( m_makefilesToParse . pop ( ) ) ;
//free the memory again
m_makefileVars . clear ( ) ;
m_parsedMakefiles . clear ( ) ;
m_targets . sort ( ) ;
m_targetsObjectFiles . sort ( ) ;
m_targetsOtherFiles . sort ( ) ;
}
m_targetMenu - > insertItem ( i18n ( " Object Files " ) , m_targetObjectFilesMenu ) ;
m_targetMenu - > insertItem ( i18n ( " Other Files " ) , m_targetOtherFilesMenu ) ;
int id = 0 ;
TQStringList : : ConstIterator it ;
for ( it = m_targets . begin ( ) ; it ! = m_targets . end ( ) ; + + it )
m_targetMenu - > insertItem ( * it , id + + ) ;
id = 0 ;
for ( it = m_targetsObjectFiles . begin ( ) ; it ! = m_targetsObjectFiles . end ( ) ; + + it )
m_targetObjectFilesMenu - > insertItem ( * it , id + + ) ;
id = 0 ;
for ( it = m_targetsOtherFiles . begin ( ) ; it ! = m_targetsOtherFiles . end ( ) ; + + it )
m_targetOtherFilesMenu - > insertItem ( * it , id + + ) ;
}
void CustomProjectPart : : putEnvVarsInVarMap ( )
{
DomUtil : : PairList envvars =
DomUtil : : readPairListEntry ( * projectDom ( ) , " /kdevcustomproject/make/environments/ " + currentMakeEnvironment ( ) , " envvar " , " name " , " value " ) ;
for ( DomUtil : : PairList : : ConstIterator it = envvars . begin ( ) ; it ! = envvars . end ( ) ; + + it )
m_makefileVars [ ( * it ) . first ] = ( * it ) . second ; //is qouting here required as in makeEnvironment() ??
}
void CustomProjectPart : : parseMakefile ( const TQString & filename )
{
if ( m_parsedMakefiles . contains ( filename ) )
return ;
m_parsedMakefiles . insert ( filename , 1 ) ;
TQString absFilename = filename ;
if ( ! filename . startsWith ( " / " ) )
absFilename = buildDirectory ( ) + " / " + filename ;
TQFile f ( absFilename ) ;
if ( ! f . open ( IO_ReadOnly ) )
{
kdDebug ( 9025 ) < < " could not open " < < absFilename < < endl ;
return ;
}
TQRegExp targetRe ( " ^ *([^ \\ t$.#] \\ S+) * : . * $ " ) ;
targetRe . setMinimal ( true ) ;
TQRegExp variablesRe ( " \\ $ \\ ( \\ s*([^ \\ ) \ \ s ] + ) \ \ s * \ \ ) " ) ;
TQRegExp assignmentRe ( " ^ \\ s*( \\ S+) \ \ s * [ : \ \ ? ] ? = \ \ s * ( \ \ S + ) \ \ s * ( # . * ) ? $ " ) ;
TQRegExp includedMakefilesRe ( " ^include \\ s+( \\ S+) " ) ;
TQString str = " " ;
while ( ! f . atEnd ( ) )
{
f . readLine ( str , 200 ) ;
// Replace any variables in the current line
int offset = - 1 ;
while ( ( offset = variablesRe . search ( str , offset + 1 ) ) ! = - 1 )
{
TQString variableName = variablesRe . cap ( 1 ) . simplifyWhiteSpace ( ) ;
if ( m_makefileVars . contains ( variableName ) )
{
str . replace ( variablesRe . cap ( 0 ) , m_makefileVars [ variableName ] ) ;
}
}
// Read all continuation lines
// kdDebug(9025) << "Trying: " << str.simplifyWhiteSpace() << endl;
//while (str.right(1) == "\\" && !stream.atEnd()) {
// str.remove(str.length()-1, 1);
// str += stream.readLine();
//}
// Find any variables
if ( assignmentRe . search ( str ) ! = - 1 )
{
m_makefileVars [ assignmentRe . cap ( 1 ) . simplifyWhiteSpace ( ) ] = assignmentRe . cap ( 2 ) . simplifyWhiteSpace ( ) ;
}
else if ( includedMakefilesRe . search ( str ) ! = - 1 )
{
TQString includedMakefile = includedMakefilesRe . cap ( 1 ) . simplifyWhiteSpace ( ) ;
m_makefilesToParse . push ( includedMakefile ) ;
}
else if ( targetRe . search ( str ) ! = - 1 )
{
TQString tmpTarget = targetRe . cap ( 1 ) . simplifyWhiteSpace ( ) ;
if ( tmpTarget . endsWith ( " .o " ) )
{
if ( m_targetsObjectFiles . find ( tmpTarget ) = = m_targetsObjectFiles . end ( ) )
m_targetsObjectFiles + = tmpTarget ;
}
else if ( tmpTarget . contains ( ' . ' ) )
{
if ( m_targetsOtherFiles . find ( tmpTarget ) = = m_targetsOtherFiles . end ( ) )
m_targetsOtherFiles + = tmpTarget ;
}
else
{
if ( m_targets . find ( tmpTarget ) = = m_targets . end ( ) )
m_targets + = tmpTarget ;
}
}
}
f . close ( ) ;
}
void CustomProjectPart : : targetMenuActivated ( int id )
{
TQString target = m_targets [ id ] ;
startMakeCommand ( buildDirectory ( ) , target ) ;
}
void CustomProjectPart : : targetObjectFilesMenuActivated ( int id )
{
TQString target = m_targetsObjectFiles [ id ] ;
startMakeCommand ( buildDirectory ( ) , target ) ;
}
void CustomProjectPart : : targetOtherFilesMenuActivated ( int id )
{
TQString target = m_targetsOtherFiles [ id ] ;
startMakeCommand ( buildDirectory ( ) , target ) ;
}
void CustomProjectPart : : updateMakeEnvironmentsMenu ( )
{
TQDomDocument & dom = * projectDom ( ) ;
bool makeUsed = ( DomUtil : : readEntry ( dom , " /kdevcustomproject/build/buildtool " ) = = " make " ) ;
if ( makeUsed )
{
TQStringList l = allMakeEnvironments ( ) ;
m_makeEnvironmentsSelector - > setItems ( l ) ;
m_makeEnvironmentsSelector - > setCurrentItem ( l . findIndex ( currentMakeEnvironment ( ) ) ) ;
}
else
{
m_makeEnvironmentsSelector - > clear ( ) ;
}
/*
m_makeEnvironmentsMenu - > clear ( ) ;
TQDomDocument & dom = * projectDom ( ) ;
TQStringList environments = allMakeEnvironments ( ) ;
TQStringList : : ConstIterator it ;
int id = 0 ;
for ( it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it )
m_makeEnvironmentsMenu - > insertItem ( * it , id + + ) ;
}
*/
}
void CustomProjectPart : : makeEnvironmentsMenuActivated ( int id )
{
TQDomDocument & dom = * projectDom ( ) ;
TQString environment = allMakeEnvironments ( ) [ id ] ;
DomUtil : : writeEntry ( dom , " /kdevcustomproject/make/selectedenvironment " , environment ) ;
}
void CustomProjectPart : : slotCommandFinished ( const TQString & command )
{
kdDebug ( 9025 ) < < " CustomProjectPart::slotProcessFinished() " < < endl ;
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_executeAfterBuild )
{
slotExecute ( ) ;
m_executeAfterBuild = false ;
}
}
void CustomProjectPart : : slotCommandFailed ( const TQString & /*command*/ )
{
m_lastCompilationFailed = true ;
m_executeAfterBuild = false ;
}
bool CustomProjectPart : : 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 ;
}
TQStringList CustomProjectPart : : allMakeEnvironments ( ) const
{
TQDomDocument & dom = * projectDom ( ) ;
TQStringList allConfigs ;
TQDomNode node =
DomUtil : : elementByPath ( dom , " /kdevcustomproject/make/environments " ) ;
// extract the names of the different make environments
TQDomElement childEl = node . firstChild ( ) . toElement ( ) ;
while ( ! childEl . isNull ( ) )
{
TQString config = childEl . tagName ( ) ;
allConfigs . append ( config ) ;
childEl = childEl . nextSibling ( ) . toElement ( ) ;
}
if ( allConfigs . isEmpty ( ) )
allConfigs . append ( " default " ) ;
return allConfigs ;
}
TQString CustomProjectPart : : currentMakeEnvironment ( ) const
{
TQStringList allEnvs = allMakeEnvironments ( ) ;
TQDomDocument & dom = * projectDom ( ) ;
TQString environment = DomUtil : : readEntry ( dom , " /kdevcustomproject/make/selectedenvironment " ) ;
if ( environment . isEmpty ( ) | | ! allEnvs . contains ( environment ) )
environment = allEnvs [ 0 ] ;
return environment ;
}
/*!
\ fn CustomProjectPart : : distFiles ( ) const
*/
TQStringList CustomProjectPart : : distFiles ( ) const
{
TQStringList sourceList = allFiles ( ) ;
// Scan current source directory for any .pro files.
TQString projectDir = projectDirectory ( ) ;
TQDir dir ( projectDir ) ;
TQStringList files = dir . entryList ( " *README* " ) ;
return sourceList + files ;
}
bool CustomProjectPart : : containsNonProjectFiles ( const TQString & dir )
{
if ( isInBlacklist ( dir ) )
return false ;
TQStringList fileentries = TQDir ( dir ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( dir ) . entryList ( TQDir : : Dirs ) ;
TQStringList subentries = fileentries + dirs ;
subentries . remove ( " . " ) ;
subentries . remove ( " .. " ) ;
for ( TQStringList : : const_iterator it = subentries . begin ( ) ; it ! = subentries . end ( ) ; + + it )
{
if ( isInBlacklist ( * it ) )
continue ;
if ( TQFileInfo ( dir + " / " + * it ) . isDir ( ) & & ! isInBlacklist ( * it ) )
{
if ( containsNonProjectFiles ( dir + " / " + * it ) )
{
return true ;
}
}
else if ( ! project ( ) - > isProjectFile ( URLUtil : : canonicalPath ( dir + " / " + * it ) )
& & ! isInBlacklist ( * it ) )
{
return true ;
}
}
return false ;
}
bool CustomProjectPart : : containsProjectFiles ( const TQString & dir )
{
if ( isInBlacklist ( dir ) )
return false ;
TQStringList fileentries = TQDir ( dir ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( dir ) . entryList ( TQDir : : Dirs ) ;
TQStringList subentries = fileentries + dirs ;
subentries . remove ( " . " ) ;
subentries . remove ( " .. " ) ;
for ( TQStringList : : const_iterator it = subentries . begin ( ) ; it ! = subentries . end ( ) ; + + it )
{
if ( isInBlacklist ( * it ) )
continue ;
if ( TQFileInfo ( dir + " / " + * it ) . isDir ( ) & & ! isInBlacklist ( * it ) )
{
if ( containsProjectFiles ( dir + " / " + * it ) )
{
return true ;
}
}
else if ( project ( ) - > isProjectFile ( URLUtil : : canonicalPath ( dir + " / " + * it ) ) & & ! isInBlacklist ( * it ) )
{
return true ;
}
}
return false ;
}
TQStringList CustomProjectPart : : projectFilesInDir ( const TQString & dir )
{
TQStringList result ;
TQStringList fileentries = TQDir ( projectDirectory ( ) + " / " + dir ) . entryList ( filetypes ( ) . join ( " ; " ) ) ;
TQStringList dirs = TQDir ( projectDirectory ( ) + " / " + dir ) . entryList ( TQDir : : Dirs ) ;
TQStringList subentries = fileentries + dirs ;
subentries . remove ( " . " ) ;
subentries . remove ( " .. " ) ;
for ( TQStringList : : const_iterator it = subentries . begin ( ) ; it ! = subentries . end ( ) ; + + it )
{
if ( isInProject ( dir + " / " + * it ) )
{
result < < ( * it ) ;
}
}
return result ;
}
TQStringList CustomProjectPart : : filetypes ( ) const
{
return DomUtil : : readListEntry ( * projectDom ( ) , " /kdevcustomproject/filetypes " , " filetype " ) ;
}
bool CustomProjectPart : : isProjectFileType ( const TQString & filename ) const
{
TQStringList types = filetypes ( ) ;
TQRegExp re ( " " , true , true ) ;
for ( TQStringList : : const_iterator it = types . begin ( ) ; it ! = types . end ( ) ; + + it )
{
re . setPattern ( * it ) ;
int pos = re . search ( filename ) ;
uint len = re . matchedLength ( ) ;
if ( ( ( * it ) . find ( " * " ) ! = - 1 | | ( * it ) . find ( " ? " ) ! = - 1 ) & & pos + len = = filename . length ( ) )
return true ;
else if ( filename . find ( " / " ) ! = - 1 & & filename . find ( * it ) ! = - 1 )
return true ;
else if ( filename . find ( " / " ) = = - 1 & & filename = = * it )
return true ;
}
return false ;
}
void CustomProjectPart : : switchBlacklistEntry ( const TQString & path )
{
TQStringList blacklist = this - > blacklist ( ) ;
kdDebug ( 9025 ) < < " Switching path " < < path < < endl ;
if ( ! isInBlacklist ( path ) )
{
blacklist < < path ;
m_recursive = true ;
removeFile ( path ) ;
m_recursive = false ;
}
else
{
blacklist . remove ( path ) ;
}
updateBlacklist ( blacklist ) ;
}
TQString CustomProjectPart : : relativeToProject ( const TQString & abspath ) const
{
TQString path = abspath . mid ( projectDirectory ( ) . length ( ) + 1 ) ;
kdDebug ( 9025 ) < < " abspath: " < < " |project dir: " < < projectDirectory ( ) < < " |path: " < < path < < endl ;
if ( path . endsWith ( " / " ) )
path = path . mid ( 0 , path . length ( ) - 1 ) ;
if ( path . startsWith ( " / " ) )
path = path . mid ( 1 , path . length ( ) ) ;
return path ;
}
bool CustomProjectPart : : isInBlacklist ( const TQString & path ) const
{
TQString relpath = path ;
TQStringList blacklist = this - > blacklist ( ) ;
if ( ! TQFileInfo ( relpath ) . isRelative ( ) )
relpath = relativeToProject ( path ) ;
if ( blacklist . find ( relpath ) ! = blacklist . end ( ) )
return true ;
TQStringList paths = TQStringList : : split ( " / " , relpath ) ;
TQString parentpath ;
for ( TQStringList : : const_iterator it = paths . begin ( ) ; it ! = paths . end ( ) ; + + it )
{
parentpath + = * it ;
if ( blacklist . find ( parentpath ) ! = blacklist . end ( ) )
return true ;
parentpath = parentpath + " / " ;
}
return false ;
}
void CustomProjectPart : : updateBlacklist ( const TQStringList & l )
{
DomUtil : : writeListEntry ( * projectDom ( ) , " kdevcustomproject/blacklist " , " path " , l ) ;
}
TQStringList CustomProjectPart : : blacklist ( ) const
{
return DomUtil : : readListEntry ( * projectDom ( ) , " kdevcustomproject/blacklist " , " path " ) ;
}
void CustomProjectPart : : addNewFilesToProject ( const TQStringList & filelist )
{
TQStringList addfiles ;
for ( TQStringList : : const_iterator it = filelist . begin ( ) ; it ! = filelist . end ( ) ; + + it )
{
if ( ( ! isInProject ( * it ) ) & & ( isProjectFileType ( * it ) | | TQFileInfo ( projectDirectory ( ) + " / " + * it ) . isDir ( ) ) & & ! isInBlacklist ( * it ) )
{
addfiles < < * it ;
}
}
if ( addfiles . isEmpty ( ) )
return ;
SelectNewFilesDialog * dlg = new SelectNewFilesDialog ( addfiles , mainWindow ( ) - > main ( ) ) ;
if ( dlg - > exec ( ) = = KDialog : : Accepted )
{
m_first_recursive = false ;
m_recursive = false ;
TQStringList blacklist = this - > blacklist ( ) ;
TQStringList excludelist = dlg - > excludedPaths ( ) ;
TQStringList removeFromExcludes ;
for ( TQStringList : : const_iterator it = excludelist . begin ( ) ; it ! = excludelist . end ( ) ; + + it )
{
if ( TQFileInfo ( projectDirectory ( ) + " / " + * it ) . isDir ( ) )
{
for ( ProjectFilesSet : : ConstIterator it2 = m_sourceFilesSet . constBegin ( ) ; it2 ! = m_sourceFilesSet . constEnd ( ) ; + + it2 )
{
if ( it2 . key ( ) . find ( * it ) ! = - 1 )
{
removeFromExcludes < < * it ;
}
}
}
}
for ( TQStringList : : const_iterator it = removeFromExcludes . begin ( ) ; it ! = removeFromExcludes . end ( ) ; + + it )
{
excludelist . remove ( * it ) ;
}
blacklist + = excludelist ;
updateBlacklist ( blacklist ) ;
addFiles ( dlg - > includedPaths ( ) ) ;
}
}
void CustomProjectPart : : setFiletypes ( const TQStringList & l )
{
DomUtil : : writeListEntry ( * projectDom ( ) , " kdevcustomproject/filetypes " , " filetype " , l ) ;
}
/**
* @ brief Is a given file ( or a directory ) part of this project ?
*
* @ param fileName
*/
bool CustomProjectPart : : isInProject ( const TQString & fileName ) const
{
return m_sourceFilesSet . contains ( fileName ) ;
}
/**
* @ brief Add a file ( or a directory ) to this project .
*
* @ param fileName
*
* @ see removeFromProject ( )
*/
void CustomProjectPart : : addToProject ( const TQString & fileName )
{
m_sourceFilesSet . insert ( fileName , false ) ;
}
/**
* @ brief Remove a file ( or a directory ) from this project .
*
* @ param fileName
*/
void CustomProjectPart : : removeFromProject ( const TQString & fileName )
{
m_sourceFilesSet . remove ( fileName ) ;
}
# include "customprojectpart.moc"