/***************************************************************************
* Copyright ( C ) 2001 - 2002 by Bernd Gehrmann *
* bernd @ tdevelop . 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 "importdlg.h"
# include <stdlib.h>
# include <tqcombobox.h>
# include <tqdir.h>
# include <tqfile.h>
# include <tqlabel.h>
# include <tqlayout.h>
# include <klineedit.h>
# include <tqpushbutton.h>
# include <tqregexp.h>
# include <tqtextstream.h>
# include <tqtooltip.h>
# include <tqcheckbox.h>
# include <kbuttonbox.h>
# include <kdebug.h>
# include <kdialog.h>
# include <kfiledialog.h>
# include <kinstance.h>
# include <klocale.h>
# include <kmessagebox.h>
# include <kstandarddirs.h>
# include <kcursor.h>
# include <kfile.h>
# include <kurlrequester.h>
# include <ktrader.h>
# include <kparts/componentfactory.h>
# include <kprocess.h>
# include "kdevcore.h"
# include "kdevversioncontrol.h"
# include "kdevplugincontroller.h"
# include "domutil.h"
# include "settings.h"
# include "profile.h"
# include "profileengine.h"
# include "appwizardfactory.h"
# include "appwizardpart.h"
# include "misc.h"
ImportDialog : : ImportDialog ( AppWizardPart * part , TQWidget * parent , const char * name )
: ImportDialogBase ( parent , name , true ) , m_part ( part )
{
TQString author , email ;
AppWizardUtil : : guessAuthorAndEmail ( & author , & email ) ;
author_edit - > setText ( author ) ;
email_edit - > setText ( email ) ;
TQToolTip : : add ( urlinput_edit - > button ( ) , i18n ( " Choose directory to import " ) ) ;
urlinput_edit - > setMode ( KFile : : Directory | KFile : : ExistingOnly | KFile : : LocalOnly ) ;
KStandardDirs * dirs = AppWizardFactory : : instance ( ) - > dirs ( ) ;
importNames = dirs - > findAllResources ( " appimports " , TQString ( ) , false , true ) ;
importNames . sort ( ) ;
TQStringList : : ConstIterator it ;
for ( it = importNames . begin ( ) ; it ! = importNames . end ( ) ; + + it ) {
KConfig config ( KGlobal : : dirs ( ) - > findResource ( " appimports " , * it ) ) ;
config . setGroup ( " General " ) ;
TQString type = config . readEntry ( " Comment " ) ;
project_combo - > insertItem ( type ) ;
if ( config . hasGroup ( " Infrastructure " ) )
{
config . setGroup ( " Infrastructure " ) ;
m_infrastructure [ type ] . isOn = true ;
m_infrastructure [ type ] . comment = config . readEntry ( " Comment " ) ;
m_infrastructure [ type ] . command = config . readEntry ( " Command " ) ;
m_infrastructure [ type ] . existingPattern = config . readEntry ( " ExistingProjectPattern " ) ;
}
else
m_infrastructure [ type ] . isOn = false ;
}
infrastructureBox - > setEnabled ( false ) ;
setProjectType ( " c " ) ;
connect ( name_edit , TQT_SIGNAL ( textChanged ( const TQString & ) ) , this , TQT_SLOT ( slotProjectNameChanged ( const TQString & ) ) ) ;
// scanAvailableVCS();
connect ( fetchModuleButton , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( slotFetchModulesFromRepository ( ) ) ) ;
connect ( urlinput_edit , TQT_SIGNAL ( urlSelected ( const TQString & ) ) , this , TQT_SLOT ( dirChanged ( ) ) ) ;
connect ( urlinput_edit , TQT_SIGNAL ( returnPressed ( const TQString & ) ) , this , TQT_SLOT ( dirChanged ( ) ) ) ;
slotProjectNameChanged ( name_edit - > text ( ) ) ;
}
ImportDialog : : ~ ImportDialog ( )
{ }
void ImportDialog : : slotProjectNameChanged ( const TQString & _text )
{
ok_button - > setEnabled ( ! _text . isEmpty ( ) & & ! urlinput_edit - > url ( ) . contains ( TQRegExp ( " \\ s " ) ) ) ;
}
void ImportDialog : : accept ( )
{
TQDir dir ( urlinput_edit - > url ( ) ) ;
if ( urlinput_edit - > url ( ) . isEmpty ( ) | | ! dir . exists ( ) ) {
KMessageBox : : sorry ( this , i18n ( " You have to choose a directory. " ) ) ;
return ;
}
TQString projectName = name_edit - > text ( ) ;
if ( projectName . isEmpty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " You have to choose a project name. " ) ) ;
return ;
}
for ( uint i = 0 ; i < projectName . length ( ) ; + + i )
if ( ! projectName [ i ] . isLetterOrNumber ( ) & & projectName [ i ] ! = ' _ ' ) {
KMessageBox : : sorry ( this , i18n ( " Your application name should only contain letters and numbers. " ) ) ;
return ;
}
if ( infrastructureBox - > isVisible ( ) & & infrastructureBox - > isChecked ( ) )
createProjectInfrastructure ( ) ;
// TQString author = author_edit->text();
// TQString email = email_edit->text();
TQFileInfo finfo ( importNames [ project_combo - > currentItem ( ) ] ) ;
TQDir importdir ( finfo . dir ( ) ) ;
importdir . cdUp ( ) ;
TQFile src ( importdir . filePath ( " importfiles/ " + finfo . fileName ( ) + " .tdevelop " ) ) ;
kdDebug ( 9010 ) < < " Import template " < < src . name ( ) < < endl ;
if ( ! src . open ( IO_ReadOnly ) ) {
KMessageBox : : sorry ( this , i18n ( " Cannot open project template. " ) ) ;
return ;
}
// Read the DOM of the newly created project
TQDomDocument projectDOM ;
int errorLine , errorCol ;
TQString errorMsg ;
bool success = projectDOM . setContent ( & src , & errorMsg , & errorLine , & errorCol ) ;
src . close ( ) ;
if ( ! success )
{
KMessageBox : : sorry ( 0 , i18n ( " This is not a valid project file. \n "
" XML error in line %1, column %2: \n %3 " )
. arg ( errorLine ) . arg ( errorCol ) . arg ( errorMsg ) ) ;
return ;
}
DomUtil : : writeEntry ( projectDOM , " /general/author " , author_edit - > text ( ) ) ;
DomUtil : : writeEntry ( projectDOM , " /general/email " , email_edit - > text ( ) ) ;
DomUtil : : writeEntry ( projectDOM , " /general/projectname " , name_edit - > text ( ) ) ;
if ( ! projectVersion . isNull ( ) ) {
DomUtil : : writeEntry ( projectDOM , " /general/version " , projectVersion ) ;
} else {
DomUtil : : writeEntry ( projectDOM , " /general/version " , " 1 " ) ;
}
// figure out what plugins we should disable by default
TQString profileName = DomUtil : : readEntry ( projectDOM , " general/profile " ) ;
if ( profileName . isEmpty ( ) )
{
TQString language = DomUtil : : readEntry ( projectDOM , " general/primarylanguage " ) ;
TQStringList keywords = DomUtil : : readListEntry ( projectDOM , " general/keywords " , " keyword " ) ;
profileName = Settings : : profileByAttributes ( language , keywords ) ;
}
ProfileEngine & engine = m_part - > pluginController ( ) - > engine ( ) ;
Profile * profile = engine . findProfile ( profileName ) ;
TQStringList disableList ;
Profile : : EntryList disableEntryList = profile - > list ( Profile : : ExplicitDisable ) ;
for ( Profile : : EntryList : : const_iterator it = disableEntryList . constBegin ( ) ; it ! = disableEntryList . constEnd ( ) ; + + it )
{
disableList < < ( * it ) . name ;
}
DomUtil : : writeListEntry ( projectDOM , " /general/ignoreparts " , " part " , disableList ) ;
// write the dom back
TQFile dest ( dir . filePath ( projectName + " .tdevelop " ) ) ;
if ( ! dest . open ( IO_WriteOnly ) ) {
KMessageBox : : sorry ( this , i18n ( " Cannot write the project file. " ) ) ;
return ;
}
TQTextStream ts ( & dest ) ;
ts . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
ts < < projectDOM . toString ( 2 ) ;
dest . close ( ) ;
// TQTextStream srcstream(&src);
// TQTextStream deststream(&dest);
//
// while (!srcstream.atEnd()) {
// TQString line = srcstream.readLine();
// line.replace(TQRegExp("\\$APPNAMELC\\$"), projectName);
// line.replace(TQRegExp("\\$AUTHOR\\$"), author);
// line.replace(TQRegExp("\\$EMAIL\\$"), email);
// deststream << line << endl;
// }
//
// dest.close();
// src.close();
m_part - > core ( ) - > openProject ( dir . filePath ( projectName + " .tdevelop " ) ) ;
kdDebug ( 9010 ) < < " OPENING PROJECT: " < < dir . filePath ( projectName + " .tdevelop " ) < < endl ;
TQDialog : : accept ( ) ;
}
// Checks if the directory dir and all of its subdirectories
// (one level recursion) have files that follow patterns
// patterns is comma-separated
static bool dirHasFiles ( TQDir & dir , const TQString & patterns )
{
TQStringList : : ConstIterator pit , sit ;
TQStringList patternList = TQStringList : : split ( " , " , patterns ) ;
for ( pit = patternList . begin ( ) ; pit ! = patternList . end ( ) ; + + pit ) {
if ( ! dir . entryList ( * pit , TQDir : : Files ) . isEmpty ( ) ) {
kdDebug ( 9010 ) < < " Has files " < < ( * pit ) < < endl ;
return true ;
}
}
TQStringList subdirList = dir . entryList ( " * " , TQDir : : Dirs ) ;
for ( sit = subdirList . begin ( ) ; sit ! = subdirList . end ( ) ; + + sit ) {
TQDir subdir ( dir ) ;
subdir . cd ( * sit ) ;
for ( pit = patternList . begin ( ) ; pit ! = patternList . end ( ) ; + + pit ) {
if ( ! subdir . entryList ( * pit , TQDir : : Files ) . isEmpty ( ) ) {
kdDebug ( 9010 ) < < " Has files " < < ( * pit ) < < " in " < < ( * sit ) < < endl ;
return true ;
}
}
}
return false ;
}
void ImportDialog : : dirChanged ( )
{
kdDebug ( 9010 ) < < " ImportDialog::dirChanged " < < endl ;
TQString dirName = urlinput_edit - > url ( ) ;
TQDir dir ( dirName ) ;
if ( ! dir . exists ( ) )
return ;
if ( dirName . contains ( TQRegExp ( " \\ s " ) ) )
{
ok_button - > setEnabled ( false ) ;
return ;
} else
{
ok_button - > setEnabled ( true ) ;
}
// KDevelop legacy project?
TQStringList files = dir . entryList ( " *.kdevprj " ) ;
if ( ! files . isEmpty ( ) ) {
scanLegacyKDevelopProject ( dir . absFilePath ( files . first ( ) ) ) ;
return ;
}
// Studio legacy project?
files = dir . entryList ( " *.studio " ) ;
if ( ! files . isEmpty ( ) ) {
scanLegacyStudioProject ( dir . absFilePath ( files . first ( ) ) ) ;
return ;
}
// Automake based?
if ( dir . exists ( " configure.in.in " ) | | dir . exists ( " configure.ac " ) | | dir . exists ( " configure.in " ) ) {
scanAutomakeProject ( dirName ) ;
return ;
}
// Remove any characters from the dirName that would be invalid in a project name
TQString projectName ( dir . dirName ( ) . replace ( TQRegExp ( " [^a-zA-Z0-9_] " ) , " _ " ) ) ;
// Set the project name
name_edit - > setText ( projectName ) ;
// TQMake based?
files = dir . entryList ( " *.pro " ) ;
if ( ! files . isEmpty ( ) ) {
setProjectType ( " qtqmake " ) ;
return ;
}
// C++?
if ( dirHasFiles ( dir , " *.cpp,*.c++,*.cxx,*.C,*.cc,*.ocl " ) ) {
setProjectType ( " cpp " ) ;
return ;
}
// Fortran?
if ( dirHasFiles ( dir , " *.f77,*.f,*.for,*.ftn " ) ) {
setProjectType ( " fortran " ) ;
return ;
}
// Python?
if ( dirHasFiles ( dir , " *.py " ) ) {
setProjectType ( " python " ) ;
return ;
}
// Perl?
if ( dirHasFiles ( dir , " *.pl,*.pm " ) ) {
setProjectType ( " perl " ) ;
return ;
}
}
void ImportDialog : : scanLegacyKDevelopProject ( const TQString & fileName )
{
kdDebug ( 9010 ) < < " Scanning legacy KDevelop project file " < < fileName < < endl ;
KSimpleConfig config ( fileName , true ) ;
config . setGroup ( " General " ) ;
author_edit - > setText ( config . readEntry ( " author " ) ) ;
email_edit - > setText ( config . readEntry ( " email " ) ) ;
name_edit - > setText ( config . readEntry ( " project_name " ) ) ;
TQString legacyType = config . readEntry ( " project_type " ) ;
if ( TQStringList : : split ( " , " , " normal_kde,normal_kde2,kde2_normal,mdi_kde2 " ) . contains ( legacyType ) )
setProjectType ( " kde " ) ;
else if ( legacyType = = " normal_gnome " )
setProjectType ( " gnome " ) ;
else if ( legacyType = = " normal_empty " )
setProjectType ( " cpp-auto " ) ;
else
setProjectType ( " cpp " ) ;
}
void ImportDialog : : scanLegacyStudioProject ( const TQString & fileName )
{
kdDebug ( 9010 ) < < " Scanning legacy studio project file " < < fileName < < endl ;
// Not much to do here...
KSimpleConfig config ( fileName , true ) ;
config . setGroup ( " kdestudio " ) ;
name_edit - > setText ( config . readEntry ( " Name " ) ) ;
}
void ImportDialog : : scanAutomakeProject ( const TQString & dirName )
{
kdDebug ( 9010 ) < < " Scanning automake project directory " < < dirName < < endl ;
bool stop = false ;
if ( TQFile : : exists ( dirName + " /admin/am_edit " ) ) {
setProjectType ( " kde " ) ;
stop = true ;
} else if ( TQFile : : exists ( dirName + " /macros/gnome.m4 " ) ) {
setProjectType ( " gnome " ) ;
stop = true ;
} else {
setProjectType ( " c-auto " ) ;
}
// if we get an authors file, use it.
TQFile af ( dirName + " /AUTHORS " ) ;
if ( af . open ( IO_ReadOnly ) ) {
TQTextStream astream ( & af ) ;
TQRegExp authorre ( " (.*) < ( . * ) > " ) ;
while ( ! astream . atEnd ( ) ) {
TQString s = astream . readLine ( ) ;
if ( authorre . search ( s ) ! = - 1 ) {
author_edit - > setText ( authorre . cap ( 1 ) . stripWhiteSpace ( ) ) ;
email_edit - > setText ( authorre . cap ( 2 ) . stripWhiteSpace ( ) ) ;
break ;
}
}
af . close ( ) ;
}
// we ignore old AC_INIT that had no version..
// only match the if there is a comma and at least two args..
// AC_INIT (package, version, [bug-report], [tarname])
TQRegExp ac_init ( " ^AC_INIT \\ s* \\ ( \\ s*([^,]+) , ( [ ^ , \ \ ) ] + ) ( . * ) " ) ;
// AM_INIT_AUTOMAKE([OPTIONS])
// example: AM_INIT_AUTOMAKE([gnits 1.5 no-define dist-bzip2])
TQRegExp am_autoSpace ( " ^AM_INIT_AUTOMAKE \\ s{0,} \\ ( \\ s{0,}([ \\ [ \\ s]{0,}[^ \\ s]+) \ \ s + ( [ ^ \ \ s \ \ ) \ \ ] ] + ) ( . * ) " ) ;
// AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
TQRegExp am_autoComma ( " ^AM_INIT_AUTOMAKE \\ s* \\ ( \\ s*([^,]+) , ( [ ^ , \ \ ) ] + ) ( . * ) " ) ;
// look for version in a define.
// AC_DEFINE(VERSION, "5.6")
TQRegExp ac_define ( " ^AC_DEFINE \\ s* \\ ( \\ s*[^,]+,([^ \\ ) ] + ) " ) ;
TQRegExp version ( " ( \\ bversion \\ b) " ) ;
version . setCaseSensitive ( FALSE ) ;
TQTextStream cstream ;
// try for configure.in.in, configure.in, then configure.ac
TQFile configInIn ( dirName + " /configure.in.in " ) ;
TQFile configIn ( dirName + " /configure.in " ) ;
TQFile configAc ( dirName + " /configure.ac " ) ;
if ( configInIn . open ( IO_ReadOnly ) ) {
cstream . setDevice ( TQT_TQIODEVICE ( & configInIn ) ) ;
while ( ! cstream . atEnd ( ) ) {
TQString line = cstream . readLine ( ) ;
if ( ac_init . search ( line ) > = 0 ) {
projectVersion = ac_init . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( am_autoComma . search ( line ) > = 0 ) {
projectVersion = am_autoComma . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( am_autoSpace . search ( line ) > = 0 ) {
projectVersion = am_autoSpace . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( ac_define . search ( line ) > = 0 & & version . search ( line ) > = 0 ) {
projectVersion = ac_define . cap ( 2 ) . stripWhiteSpace ( ) ;
}
}
configInIn . close ( ) ;
}
if ( configIn . open ( IO_ReadOnly ) ) {
cstream . setDevice ( TQT_TQIODEVICE ( & configIn ) ) ;
}
else {
if ( configAc . open ( IO_ReadOnly ) ) {
cstream . setDevice ( TQT_TQIODEVICE ( & configAc ) ) ;
}
else {
return ;
}
}
TQRegExp namere ( " \\ s*AM_INIT_AUTOMAKE \\ ((.*) , . * \ \ ) . * " ) ;
TQRegExp cppre ( " \\ s*AC_PROG_CXX " ) ;
TQRegExp f77re ( " \\ s*AC_PROG_F77 " ) ;
while ( ! cstream . atEnd ( ) ) {
TQString line = cstream . readLine ( ) ;
if ( ac_init . search ( line ) > = 0 ) {
projectVersion = ac_init . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( am_autoComma . search ( line ) > = 0 ) {
projectVersion = am_autoComma . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( am_autoSpace . search ( line ) > = 0 ) {
projectVersion = am_autoSpace . cap ( 2 ) . stripWhiteSpace ( ) ;
}
else if ( ac_define . search ( line ) > = 0 & & version . search ( line ) > = 0 ) {
projectVersion = ac_define . cap ( 2 ) . stripWhiteSpace ( ) ;
}
if ( namere . search ( line ) = = 0 )
name_edit - > setText ( namere . cap ( 1 ) . stripWhiteSpace ( ) ) ;
if ( ! stop )
continue ;
else if ( cppre . search ( line ) = = 0 )
setProjectType ( " cpp-auto " ) ;
else if ( f77re . search ( line ) = = 0 )
setProjectType ( " fortran-auto " ) ;
}
if ( configIn . isOpen ( ) ) configIn . close ( ) ;
if ( configAc . isOpen ( ) ) configAc . close ( ) ;
}
void ImportDialog : : setProjectType ( const TQString & type )
{
kdDebug ( 9010 ) < < " Setting project type " < < type < < endl ;
TQString suffix = " / " + type ;
int suffixLength = suffix . length ( ) ;
int i = 0 ;
TQStringList : : ConstIterator it ;
for ( it = importNames . begin ( ) ; it ! = importNames . end ( ) ; + + it ) {
if ( ( * it ) . right ( suffixLength ) = = suffix ) {
project_combo - > setCurrentItem ( i ) ;
break ;
}
+ + i ;
}
}
/*
void ImportDialog : : scanAvailableVCS ( )
{
// vcsCombo->insertStringList( m_part->registeredVersionControls() );
int i = 0 ;
KTrader : : OfferList offers = KTrader : : self ( ) - > query ( " KDevelop/VersionControl " ) ;
KTrader : : OfferList : : const_iterator it = offers . begin ( ) ;
while ( it ! = offers . end ( ) )
{
vcsCombo - > insertItem ( ( * it ) - > genericName ( ) , i + + ) ;
+ + it ;
}
}
*/
/*
void ImportDialog : : slotFinishedCheckout ( TQString destinationDir )
{
urlinput_edit - > setURL ( destinationDir ) ;
setCursor ( KCursor : : arrowCursor ( ) ) ;
// setEnabled( true );
}
*/
/*
void ImportDialog : : slotFetchModulesFromRepository ( )
{
KDevVersionControl * vcs = m_part - > versionControlByName ( vcsCombo - > currentText ( ) ) ;
if ( ! vcs )
return ;
setCursor ( KCursor : : waitCursor ( ) ) ;
// setEnabled( false );
connect ( vcs , TQT_SIGNAL ( finishedFetching ( TQString ) ) ,
this , TQT_SLOT ( slotFinishedCheckout ( TQString ) ) ) ;
//restore cursor if we can't fetch repository
if ( ! vcs - > fetchFromRepository ( ) )
setCursor ( KCursor : : arrowCursor ( ) ) ;
}
*/
void ImportDialog : : projectTypeChanged ( const TQString & type )
{
if ( m_infrastructure [ type ] . isOn )
{
infrastructureBox - > setEnabled ( true ) ;
infrastructureBox - > setText ( m_infrastructure [ type ] . comment ) ;
}
else
{
infrastructureBox - > setEnabled ( false ) ;
infrastructureBox - > setText ( i18n ( " Generate build system infrastrucure " ) ) ;
}
}
void ImportDialog : : createProjectInfrastructure ( )
{
kdDebug ( 9010 ) < < " ImportDialog::createProjectInfrastructure " < < endl ;
InfrastructureCmd cmd = m_infrastructure [ project_combo - > currentText ( ) ] ;
if ( ! cmd . isOn )
return ;
TQDir dir ( urlinput_edit - > url ( ) ) ;
TQStringList files = dir . entryList ( cmd . existingPattern ) ;
if ( ! files . isEmpty ( ) ) {
if ( KMessageBox : : questionYesNo ( this , i18n ( " Project infrastrucure already exists in target directory. \n Generate new project infrastructure and overwrite old? " ) , TQString ( ) , i18n ( " Generate " ) , i18n ( " Do Not Generate " ) ) = = KMessageBox : : No )
return ;
}
TQString command = " cd " + urlinput_edit - > url ( ) + " && " + cmd . command ;
kdDebug ( 9010 ) < < " executing " < < command . ascii ( ) < < endl ;
system ( command . ascii ( ) ) ;
}
void ImportDialog : : projectTypeChanged ( int type )
{
projectTypeChanged ( project_combo - > text ( type ) ) ;
}
# include "importdlg.moc"