KDevelop API Documentation

importdlg.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2001-2002 by Bernd Gehrmann                             *
00003  *   bernd@kdevelop.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012 #include "importdlg.h"
00013 #include <stdlib.h>
00014 #include <qcombobox.h>
00015 #include <qdir.h>
00016 #include <qfile.h>
00017 #include <qlabel.h>
00018 #include <qlayout.h>
00019 #include <qlineedit.h>
00020 #include <qpushbutton.h>
00021 #include <qregexp.h>
00022 #include <qtextstream.h>
00023 #include <qtooltip.h>
00024 #include <qcheckbox.h>
00025 #include <kbuttonbox.h>
00026 #include <kdebug.h>
00027 #include <kdialog.h>
00028 #include <kfiledialog.h>
00029 #include <kinstance.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032 #include <kstandarddirs.h>
00033 #include <kcursor.h>
00034 #include <kfile.h>
00035 #include <kurlrequester.h>
00036 #include <ktrader.h>
00037 #include <kparts/componentfactory.h>
00038 #include <kprocess.h>
00039 
00040 #include "kdevcore.h"
00041 #include "kdevversioncontrol.h"
00042 
00043 #include "appwizardfactory.h"
00044 #include "appwizardpart.h"
00045 #include "misc.h"
00046 
00047 
00048 ImportDialog::ImportDialog(AppWizardPart *part, QWidget *parent, const char *name)
00049     : ImportDialogBase(parent, name, true), m_part(part)
00050 {
00051     QString author, email;
00052     AppWizardUtil::guessAuthorAndEmail(&author, &email);
00053     author_edit->setText(author);
00054     email_edit->setText(email);
00055     QToolTip::add( urlinput_edit->button(), i18n("Choose directory to import") );
00056     urlinput_edit->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
00057 
00058     KStandardDirs *dirs = AppWizardFactory::instance()->dirs();
00059     importNames = dirs->findAllResources("appimports", QString::null, false, true);
00060     importNames.sort();
00061 
00062     QStringList::ConstIterator it;
00063     for (it = importNames.begin(); it != importNames.end(); ++it) {
00064         KConfig config(KGlobal::dirs()->findResource("appimports", *it));
00065         config.setGroup("General");
00066         QString type = config.readEntry("Comment");
00067         project_combo->insertItem(type);
00068         
00069         if (config.hasGroup("Infrastructure"))
00070         {
00071             config.setGroup("Infrastructure");
00072             m_infrastructure[type].isOn = true;
00073             m_infrastructure[type].comment = config.readEntry("Comment");
00074             m_infrastructure[type].command = config.readEntry("Command");
00075             m_infrastructure[type].existingPattern = config.readEntry("ExistingProjectPattern");
00076         }
00077         else
00078             m_infrastructure[type].isOn = false;
00079     }
00080 
00081     infrastructureBox->setEnabled(false);
00082     setProjectType("c");
00083     connect( name_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotProjectNameChanged( const QString & ) ) );
00084 //    scanAvailableVCS();
00085     connect( fetchModuleButton, SIGNAL(clicked()),
00086         this, SLOT(slotFetchModulesFromRepository()) );
00087     connect(urlinput_edit, SIGNAL(urlSelected(const QString& )), this, SLOT(dirChanged()));
00088     slotProjectNameChanged( name_edit->text() );
00089 }
00090 
00091 
00092 ImportDialog::~ImportDialog()
00093 {}
00094 
00095 void ImportDialog::slotProjectNameChanged( const QString &_text )
00096 {
00097     ok_button->setEnabled( !_text.isEmpty() );
00098 }
00099 
00100 void ImportDialog::accept()
00101 {
00102     QDir dir(urlinput_edit->url());
00103     if (urlinput_edit->url().isEmpty() || !dir.exists()) {
00104         KMessageBox::sorry(this, i18n("You have to choose a directory."));
00105         return;
00106     }
00107 
00108     QString projectName = name_edit->text();
00109     if (projectName.isEmpty()) {
00110         KMessageBox::sorry(this, i18n("You have to choose a project name."));
00111         return;
00112     }
00113 
00114     for (uint i=0; i < projectName.length(); ++i)
00115         if (!projectName[i].isLetterOrNumber() && projectName[i] != '_') {
00116             KMessageBox::sorry(this, i18n("Your application name should only contain letters and numbers."));
00117             return;
00118         }
00119         
00120     if (infrastructureBox->isVisible() && infrastructureBox->isChecked())
00121         createProjectInfrastructure();
00122 
00123     QString author = author_edit->text();
00124     QString email = email_edit->text();
00125 
00126     QFileInfo finfo(importNames[project_combo->currentItem()]);
00127     QDir importdir(finfo.dir());
00128     importdir.cdUp();
00129     QFile src(importdir.filePath("importfiles/" + finfo.fileName() + ".kdevelop"));
00130     kdDebug(9010) << "Import template " << src.name() << endl;
00131     if (!src.open(IO_ReadOnly)) {
00132         KMessageBox::sorry(this, i18n("Can not open project template."));
00133         return;
00134     }
00135 
00136     QFile dest(dir.filePath(projectName + ".kdevelop"));
00137     if (!dest.open(IO_WriteOnly)) {
00138         KMessageBox::sorry(this, i18n("Can not write the project file."));
00139         return;
00140     }
00141 
00142     QTextStream srcstream(&src);
00143     QTextStream deststream(&dest);
00144 
00145     while (!srcstream.atEnd()) {
00146         QString line = srcstream.readLine();
00147         line.replace(QRegExp("\\$APPNAMELC\\$"), projectName);
00148         line.replace(QRegExp("\\$AUTHOR\\$"), author);
00149         line.replace(QRegExp("\\$EMAIL\\$"), email);
00150         deststream << line << endl;
00151     }
00152 
00153     dest.close();
00154     src.close();
00155 
00156     m_part->core()->openProject(dir.filePath(projectName + ".kdevelop"));
00157 
00158     kdDebug(9010) << "OPENING PROJECT: " << dir.filePath(projectName + ".kdevelop") << endl;
00159 
00160     QDialog::accept();
00161 }
00162 
00163 
00164 // Checks if the directory dir and all of its subdirectories
00165 // (one level recursion) have files that follow patterns
00166 // patterns is comma-separated
00167 static bool dirHasFiles(QDir &dir, const QString &patterns)
00168 {
00169     QStringList::ConstIterator pit, sit;
00170 
00171     QStringList patternList = QStringList::split(",", patterns);
00172     for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
00173         if (!dir.entryList(*pit, QDir::Files).isEmpty()) {
00174             kdDebug() << "Has files " << (*pit) << endl;
00175             return true;
00176         }
00177     }
00178 
00179     QStringList subdirList = dir.entryList("*", QDir::Dirs);
00180     for (sit = subdirList.begin(); sit != subdirList.end(); ++sit) {
00181         QDir subdir(dir);
00182         subdir.cd(*sit);
00183         for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
00184             if (!subdir.entryList(*pit, QDir::Files).isEmpty()) {
00185                 kdDebug() << "Has files " << (*pit) << " in " << (*sit) << endl;
00186                 return true;
00187             }
00188         }
00189     }
00190 
00191     return false;
00192 }
00193 
00194 
00195 void ImportDialog::dirChanged()
00196 {
00197     kdDebug() << "ImportDialog::dirChanged" << endl;
00198     QString dirName = urlinput_edit->url();
00199     QDir dir(dirName);
00200     if (!dir.exists())
00201         return;
00202 
00203     // KDevelop legacy project?
00204     QStringList files = dir.entryList("*.kdevprj");
00205     if (!files.isEmpty()) {
00206         scanLegacyKDevelopProject(dir.absFilePath(files.first()));
00207         return;
00208     }
00209 
00210     // Studio legacy project?
00211     files = dir.entryList("*.studio");
00212     if (!files.isEmpty()) {
00213         scanLegacyStudioProject(dir.absFilePath(files.first()));
00214         return;
00215     }
00216 
00217     // Automake based?
00218     if (dir.exists("config.guess") || dir.exists("configure.in.in")) {
00219         scanAutomakeProject(dirName);
00220         return;
00221     }
00222 
00223     name_edit->setText(dir.dirName());
00224 
00225     // QMake based?
00226     files = dir.entryList("*.pro");
00227     if (!files.isEmpty()) {
00228         setProjectType("qtqmake");
00229         return;
00230     }
00231 
00232     // C++?
00233     if (dirHasFiles(dir, "*.cpp,*.c++,*.cxx,*.C,*.cc")) {
00234         setProjectType("cpp");
00235         return;
00236     }
00237 
00238     // Fortran?
00239     if (dirHasFiles(dir, "*.f77,*.f,*.for,*.ftn")) {
00240         setProjectType("fortran");
00241         return;
00242     }
00243 
00244     // Python?
00245     if (dirHasFiles(dir, "*.py")) {
00246         setProjectType("python");
00247         return;
00248     }
00249 
00250     // Perl?
00251     if (dirHasFiles(dir, "*.pl,*.pm")) {
00252         setProjectType("perl");
00253         return;
00254     }
00255 }
00256 
00257 
00258 void ImportDialog::scanLegacyKDevelopProject(const QString &fileName)
00259 {
00260     kdDebug(9010) << "Scanning legacy KDevelop project file " << fileName << endl;
00261 
00262     KSimpleConfig config(fileName, true);
00263     config.setGroup("General");
00264     author_edit->setText(config.readEntry("author"));
00265     email_edit->setText(config.readEntry("email"));
00266     name_edit->setText(config.readEntry("project_name"));
00267 
00268     QString legacyType = config.readEntry("project_type");
00269     if (QStringList::split(",", "normal_kde,normal_kde2,kde2_normal,mdi_kde2").contains(legacyType))
00270         setProjectType("kde");
00271     else if (legacyType == "normal_gnome")
00272         setProjectType("gnome");
00273     else if (legacyType == "normal_empty")
00274         setProjectType("cpp-auto");
00275     else
00276         setProjectType("cpp");
00277 }
00278 
00279 
00280 void ImportDialog::scanLegacyStudioProject(const QString &fileName)
00281 {
00282     kdDebug(9010) << "Scanning legacy studio project file " << fileName << endl;
00283 
00284     // Not much to do here...
00285     KSimpleConfig config(fileName, true);
00286     config.setGroup("kdestudio");
00287     name_edit->setText(config.readEntry("Name"));
00288 }
00289 
00290 
00291 void ImportDialog::scanAutomakeProject(const QString &dirName)
00292 {
00293     kdDebug(9010) << "Scanning automake project directory " << dirName << endl;
00294 
00295     bool stop = false;
00296     if (QFile::exists(dirName + "/admin/am_edit")) {
00297         setProjectType("kde");
00298         stop = true;
00299     } else if (QFile::exists(dirName + "/macros/gnome.m4")) {
00300         setProjectType("gnome");
00301         stop = true;
00302     } else {
00303         setProjectType("c-auto");
00304     }
00305 
00306     QFile af(dirName + "/AUTHORS");
00307     if (!af.open(IO_ReadOnly))
00308         return;
00309     QTextStream astream(&af);
00310 
00311     QRegExp authorre("(.*)<(.*)>");
00312     while (!astream.atEnd()) {
00313         QString s = astream.readLine();
00314         if (authorre.search(s) != -1) {
00315             author_edit->setText(authorre.cap(1).stripWhiteSpace());
00316             email_edit->setText(authorre.cap(2).stripWhiteSpace());
00317             break;
00318         }
00319     }
00320     af.close();
00321 
00322     QFile cf(dirName + "/configure.in");
00323     if (!cf.open(IO_ReadOnly))
00324         return;
00325     QTextStream cstream(&cf);
00326 
00327     QRegExp namere("\\s*AM_INIT_AUTOMAKE\\((.*),.*\\).*");
00328     QRegExp cppre("\\s*AC_PROG_CXX");
00329     QRegExp f77re("\\s*AC_PROG_F77");
00330     while (!cstream.atEnd()) {
00331         QString s = cstream.readLine();
00332         if (namere.search(s) == 0)
00333             name_edit->setText(namere.cap(1).stripWhiteSpace());
00334         if (!stop)
00335             continue;
00336         else if (cppre.search(s) == 0)
00337             setProjectType("cpp-auto");
00338         else if (f77re.search(s) == 0)
00339             setProjectType("fortran-auto");
00340     }
00341     cf.close();
00342 }
00343 
00344 
00345 void ImportDialog::setProjectType(const QString &type)
00346 {
00347     kdDebug(9010) << "Setting project type " << type << endl;
00348     QString suffix = "/" + type;
00349     int suffixLength = suffix.length();
00350 
00351     int i=0;
00352     QStringList::ConstIterator it;
00353     for (it = importNames.begin(); it != importNames.end(); ++it) {
00354         if ((*it).right(suffixLength) == suffix) {
00355             project_combo->setCurrentItem(i);
00356             break;
00357         }
00358         ++i;
00359     }
00360 }
00361 /*
00362 void ImportDialog::scanAvailableVCS()
00363 {
00364 //    vcsCombo->insertStringList( m_part->registeredVersionControls() );
00365     int i = 0;
00366     KTrader::OfferList offers = KTrader::self()->query("KDevelop/VersionControl");
00367     KTrader::OfferList::const_iterator it = offers.begin();
00368     while( it != offers.end() )
00369     {
00370         vcsCombo->insertItem( (*it)->genericName(), i++ );
00371         ++it;
00372     }   
00373 }
00374 */
00375 /*
00376 void ImportDialog::slotFinishedCheckout( QString destinationDir )
00377 {
00378     urlinput_edit->setURL( destinationDir );
00379 
00380     setCursor( KCursor::arrowCursor() );
00381 //    setEnabled( true );
00382 }
00383 */
00384 /*
00385 void ImportDialog::slotFetchModulesFromRepository()
00386 {
00387     
00388     KDevVersionControl *vcs = m_part->versionControlByName( vcsCombo->currentText() );
00389     if (!vcs)
00390         return;
00391 
00392     setCursor( KCursor::waitCursor() );
00393 //    setEnabled( false );
00394 
00395     connect( vcs, SIGNAL(finishedFetching(QString)),
00396         this, SLOT(slotFinishedCheckout(QString)) );
00397 
00398     //restore cursor if we can't fetch repository
00399     if ( !vcs->fetchFromRepository() )
00400         setCursor( KCursor::arrowCursor() );
00401     
00402 }
00403 */
00404 void ImportDialog::projectTypeChanged( const QString &type )
00405 {
00406     if (m_infrastructure[type].isOn)
00407     {
00408         infrastructureBox->setEnabled(true);
00409         infrastructureBox->setText(m_infrastructure[type].comment);
00410     }
00411     else
00412     {
00413         infrastructureBox->setEnabled(false);
00414         infrastructureBox->setText(i18n("Generate build system infrastrucure"));
00415     }
00416 }
00417 
00418 void ImportDialog::createProjectInfrastructure( )
00419 {
00420     kdDebug() << "ImportDialog::createProjectInfrastructure" << endl;
00421     InfrastructureCmd cmd = m_infrastructure[project_combo->currentText()];
00422     if (!cmd.isOn)
00423         return;
00424     
00425     QDir dir (urlinput_edit->url());
00426     QStringList files = dir.entryList(cmd.existingPattern);
00427     if (!files.isEmpty()) {
00428         if (KMessageBox::questionYesNo(this, i18n("Project infrastrucure already exists in target directory.\nGenerate new project infrastructure and overwrite old?")) == KMessageBox::No)
00429             return;
00430     }
00431     
00432     QString command = "cd " + urlinput_edit->url() + " && " + cmd.command;
00433     kdDebug() << "executing " << command.ascii() << endl;
00434     system(command.ascii());
00435 }
00436 
00437 void ImportDialog::projectTypeChanged( int type )
00438 {
00439     projectTypeChanged(project_combo->text(type));
00440 }
00441 
00442 
00443 #include "importdlg.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:37 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003