|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2001-2002 by Bernd Gehrmann *
|
|
|
|
* bernd@kdevelop.org *
|
|
|
|
* *
|
|
|
|
* 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 "scriptprojectpart.h"
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqvaluestack.h>
|
|
|
|
#include <tqvbox.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kdialogbase.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kdevgenericfactory.h>
|
|
|
|
#include <kdevcreatefile.h>
|
|
|
|
#include <kdirwatch.h>
|
|
|
|
|
|
|
|
#include "domutil.h"
|
|
|
|
#include "kdevcore.h"
|
|
|
|
#include "kdevmainwindow.h"
|
|
|
|
#include "kdevpartcontroller.h"
|
|
|
|
#include "kdevlanguagesupport.h"
|
|
|
|
#include "scriptoptionswidget.h"
|
|
|
|
#include "scriptnewfiledlg.h"
|
|
|
|
#include "kdevplugininfo.h"
|
|
|
|
|
|
|
|
typedef KDevGenericFactory<ScriptProjectPart> ScriptProjectFactory;
|
|
|
|
static const KDevPluginInfo data("kdevscriptproject");
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( libkdevscriptproject, ScriptProjectFactory( data ) )
|
|
|
|
|
|
|
|
ScriptProjectPart::ScriptProjectPart(TQObject *parent, const char *name, const TQStringList &)
|
|
|
|
: KDevBuildTool(&data, parent, name ? name : "ScriptProjectPart")
|
|
|
|
{
|
|
|
|
setInstance(ScriptProjectFactory::instance());
|
|
|
|
|
|
|
|
setXMLFile("kdevscriptproject.rc");
|
|
|
|
|
|
|
|
// only create new file action if file creation part not available
|
|
|
|
if (!extension<KDevCreateFile>("KDevelop/CreateFile")) {
|
|
|
|
KAction *action;
|
|
|
|
action = new KAction( i18n("New File..."), 0,
|
|
|
|
this, TQT_SLOT(slotNewFile()),
|
|
|
|
actionCollection(), "file_newfile" );
|
|
|
|
action->setWhatsThis( i18n("<b>New file</b><p>Creates a new file.") );
|
|
|
|
action->setToolTip( i18n("Create a new file") );
|
|
|
|
}
|
|
|
|
new KAction( i18n("Rescan Project"), 0, CTRL+ALT+Key_R,
|
|
|
|
this, TQT_SLOT(rescan()),
|
|
|
|
actionCollection(), "rescan" );
|
|
|
|
|
|
|
|
connect( core(), TQT_SIGNAL(projectConfigWidget(KDialogBase*)),
|
|
|
|
this, TQT_SLOT(projectConfigWidget(KDialogBase*)) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ScriptProjectPart::~ScriptProjectPart()
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
void ScriptProjectPart::projectConfigWidget(KDialogBase *dlg)
|
|
|
|
{
|
|
|
|
TQVBox *vbox;
|
|
|
|
vbox = dlg->addVBoxPage(i18n("Script Project Options"), i18n("Script Project Options"), BarIcon("kdevelop", KIcon::SizeMedium));
|
|
|
|
ScriptOptionsWidget *w = new ScriptOptionsWidget(this, vbox);
|
|
|
|
connect( dlg, TQT_SIGNAL(okClicked()), w, TQT_SLOT(accept()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @todo This should really be merged with FileTreeWidget::matchesHidePattern()
|
|
|
|
* and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp
|
|
|
|
*/
|
|
|
|
static bool matchesPattern(const TQString &fileName, const TQStringList &patternList)
|
|
|
|
{
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
for (it = patternList.begin(); it != patternList.end(); ++it) {
|
|
|
|
TQRegExp re(*it, true, true);
|
|
|
|
if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length())
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScriptProjectPart::openProject(const TQString &dirName, const TQString &projectName)
|
|
|
|
{
|
|
|
|
if (!languageSupport())
|
|
|
|
kdDebug(9015) << "ScriptProjectPart::openProject: no language support found!" << endl;
|
|
|
|
|
|
|
|
m_projectDirectory = dirName;
|
|
|
|
m_projectName = projectName;
|
|
|
|
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
|
|
|
|
// Set the default directory radio to "executable"
|
|
|
|
if (DomUtil::readEntry(dom, "/kdevscriptproject/run/directoryradio") == "" ) {
|
|
|
|
DomUtil::writeEntry(dom, "/kdevscriptproject/run/directoryradio", "executable");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put all files from all subdirectories into file list
|
|
|
|
TQValueStack<TQString> s;
|
|
|
|
int prefixlen = m_projectDirectory.length()+1;
|
|
|
|
s.push(m_projectDirectory);
|
|
|
|
|
|
|
|
TQDir dir;
|
|
|
|
do {
|
|
|
|
dir.setPath(s.pop());
|
|
|
|
kdDebug(9015) << "Examining: " << dir.path() << endl;
|
|
|
|
const TQFileInfoList *dirEntries = dir.entryInfoList();
|
|
|
|
if ( dirEntries )
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TQFileInfo> it(*dirEntries);
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
TQString fileName = it.current()->fileName();
|
|
|
|
if (fileName == "." || fileName == "..")
|
|
|
|
continue;
|
|
|
|
TQString path = it.current()->absFilePath();
|
|
|
|
if (it.current()->isDir()) {
|
|
|
|
//do not follow symlinks which point to the themselves
|
|
|
|
if (it.current()->isSymLink())
|
|
|
|
{
|
|
|
|
TQString symLink = it.current()->readLink();
|
|
|
|
if ((symLink == path) || (symLink == "./"))
|
|
|
|
continue;
|
|
|
|
} else if (canAddDirectoryToProject(path)) {
|
|
|
|
kdDebug(9015) << "Pushing: " << path << endl;
|
|
|
|
s.push(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (canAddToProject(path))
|
|
|
|
m_sourceFiles.append(path.mid(prefixlen));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!s.isEmpty());
|
|
|
|
|
|
|
|
KDevProject::openProject( dirName, projectName );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScriptProjectPart::closeProject()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString ScriptProjectPart::projectDirectory() const
|
|
|
|
{
|
|
|
|
return m_projectDirectory;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString ScriptProjectPart::buildDirectory() const
|
|
|
|
{
|
|
|
|
return m_projectDirectory;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ScriptProjectPart::projectName() const
|
|
|
|
{
|
|
|
|
return m_projectName;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Retuns a PairList with the run environment variables */
|
|
|
|
DomUtil::PairList ScriptProjectPart::runEnvironmentVars() const
|
|
|
|
{
|
|
|
|
return DomUtil::readPairListEntry(*projectDom(), "/kdevscriptproject/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 ScriptProjectPart::runDirectory() const
|
|
|
|
{
|
|
|
|
TQString cwd = defaultRunDirectory("kdevscriptproject");
|
|
|
|
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 ScriptProjectPart::mainProgram() const
|
|
|
|
{
|
|
|
|
TQDomDocument * dom = projectDom();
|
|
|
|
|
|
|
|
if ( !dom ) return TQString();
|
|
|
|
|
|
|
|
TQString DomMainProgram = DomUtil::readEntry( *dom, "/kdevscriptproject/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 ScriptProjectPart::debugArguments() const
|
|
|
|
{
|
|
|
|
return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/globaldebugarguments");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Retuns a TQString with the run command line arguments */
|
|
|
|
TQString ScriptProjectPart::runArguments() const
|
|
|
|
{
|
|
|
|
return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/programargs");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString ScriptProjectPart::activeDirectory() const
|
|
|
|
{
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
|
|
|
|
return DomUtil::readEntry(dom, "/kdevscriptproject/general/activedir");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQStringList ScriptProjectPart::allFiles() const
|
|
|
|
{
|
|
|
|
/* TQStringList res;
|
|
|
|
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it)
|
|
|
|
res += (m_projectDirectory + "/" + (*it));
|
|
|
|
|
|
|
|
return res;*/
|
|
|
|
|
|
|
|
// return all files relative to the project directory!
|
|
|
|
return m_sourceFiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::addFile(const TQString &fileName)
|
|
|
|
{
|
|
|
|
kdDebug(9015) << "AddFile2" << fileName << endl;
|
|
|
|
|
|
|
|
TQStringList fileList;
|
|
|
|
fileList.append ( fileName );
|
|
|
|
|
|
|
|
this->addFiles ( fileList );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::addFiles ( const TQStringList& fileList )
|
|
|
|
{
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
|
|
|
|
for ( it = fileList.begin(); it != fileList.end(); ++it )
|
|
|
|
{
|
|
|
|
m_sourceFiles.append ( ( *it ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
emit addedFilesToProject ( fileList );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::removeFile(const TQString &fileName)
|
|
|
|
{
|
|
|
|
TQStringList fileList;
|
|
|
|
fileList.append ( fileName );
|
|
|
|
|
|
|
|
this->addFiles ( fileList );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::removeFiles ( const TQStringList& fileList )
|
|
|
|
{
|
|
|
|
emit removedFilesFromProject ( fileList );
|
|
|
|
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
|
|
|
|
for ( it = fileList.begin(); it != fileList.end(); ++it )
|
|
|
|
{
|
|
|
|
m_sourceFiles.remove ( ( *it ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::slotNewFile()
|
|
|
|
{
|
|
|
|
ScriptNewFileDialog dlg(this);
|
|
|
|
dlg.exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn ScriptProjectPart::distFiles() const
|
|
|
|
*/
|
|
|
|
TQStringList ScriptProjectPart::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptProjectPart::rescan()
|
|
|
|
{
|
|
|
|
// kdDebug() << "Directory " << path << " changed, scanning for new files in the project" << endl;
|
|
|
|
|
|
|
|
// Put all files from all subdirectories into file list
|
|
|
|
TQValueStack<TQString> s;
|
|
|
|
int prefixlen = m_projectDirectory.length()+1;
|
|
|
|
s.push(m_projectDirectory);
|
|
|
|
|
|
|
|
TQDir dir;
|
|
|
|
do {
|
|
|
|
dir.setPath(s.pop());
|
|
|
|
kdDebug(9015) << "Examining: " << dir.path() << endl;
|
|
|
|
const TQFileInfoList *dirEntries = dir.entryInfoList();
|
|
|
|
if ( dirEntries )
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TQFileInfo> it(*dirEntries);
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
TQString fileName = it.current()->fileName();
|
|
|
|
if (fileName == "." || fileName == "..")
|
|
|
|
continue;
|
|
|
|
TQString path = it.current()->absFilePath();
|
|
|
|
if (it.current()->isDir()) {
|
|
|
|
//do not follow symlinks which point to the themselves
|
|
|
|
if (it.current()->isSymLink())
|
|
|
|
{
|
|
|
|
TQString symLink = it.current()->readLink();
|
|
|
|
if ((symLink == path) || (symLink == "./"))
|
|
|
|
continue;
|
|
|
|
} else if (canAddDirectoryToProject(path)) {
|
|
|
|
kdDebug(9015) << "Pushing: " << path << endl;
|
|
|
|
s.push(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!isProjectFile(path) && canAddToProject(path))
|
|
|
|
addFile(path.mid(prefixlen));
|
|
|
|
// m_sourceFiles.append(path.mid(prefixlen));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!s.isEmpty());
|
|
|
|
|
|
|
|
/* const TQFileInfoList *dirEntries = TQDir(path).entryInfoList();
|
|
|
|
if ( dirEntries )
|
|
|
|
{
|
|
|
|
kdDebug() << "1" << endl;
|
|
|
|
TQPtrListIterator<TQFileInfo> it(*dirEntries);
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
kdDebug() << "2" << endl;
|
|
|
|
TQString fileName = it.current()->fileName();
|
|
|
|
if (fileName == "." || fileName == "..")
|
|
|
|
continue;
|
|
|
|
kdDebug() << "3" << endl;
|
|
|
|
TQString filePath = it.current()->absFilePath();
|
|
|
|
if (!it.current()->isDir() && canAddToProject(filePath) && !isProjectFile(filePath)) {
|
|
|
|
kdDebug() << "=== adding " << filePath << endl;
|
|
|
|
addFile(filePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptProjectPart::canAddToProject(const TQString & path)
|
|
|
|
{
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQString includepatterns
|
|
|
|
= DomUtil::readEntry(dom, "/kdevscriptproject/general/includepatterns");
|
|
|
|
TQStringList includepatternList;
|
|
|
|
if ( includepatterns.isNull() ) {
|
|
|
|
if ( languageSupport() ){
|
|
|
|
KMimeType::List list = languageSupport()->mimeTypes();
|
|
|
|
KMimeType::List::Iterator it = list.begin();
|
|
|
|
while( it != list.end() ){
|
|
|
|
includepatternList += (*it)->patterns();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
includepatternList = TQStringList::split(",", includepatterns);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString excludepatterns
|
|
|
|
= DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns");
|
|
|
|
if (excludepatterns.isNull())
|
|
|
|
excludepatterns = "*~";
|
|
|
|
TQStringList excludepatternList = TQStringList::split(",", excludepatterns);
|
|
|
|
|
|
|
|
if (matchesPattern(path, includepatternList)
|
|
|
|
&& !matchesPattern(path, excludepatternList)) {
|
|
|
|
kdDebug(9015) << "Adding: " << path << endl;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
kdDebug(9015) << "Ignoring: " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptProjectPart::canAddDirectoryToProject(const TQString & path)
|
|
|
|
{
|
|
|
|
TQDomDocument &dom = *projectDom();
|
|
|
|
TQString excludepatterns
|
|
|
|
= DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns");
|
|
|
|
if (excludepatterns.isNull()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
TQStringList excludepatternList = TQStringList::split(",", excludepatterns);
|
|
|
|
|
|
|
|
if (!matchesPattern(path, excludepatternList)) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
kdDebug(9015) << "Ignoring Directory: " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "scriptprojectpart.moc"
|