summaryrefslogtreecommitdiffstats
path: root/parts/appwizard/importdlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/appwizard/importdlg.cpp')
-rw-r--r--parts/appwizard/importdlg.cpp582
1 files changed, 582 insertions, 0 deletions
diff --git a/parts/appwizard/importdlg.cpp b/parts/appwizard/importdlg.cpp
new file mode 100644
index 00000000..b900181d
--- /dev/null
+++ b/parts/appwizard/importdlg.cpp
@@ -0,0 +1,582 @@
+/***************************************************************************
+ * 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 "importdlg.h"
+#include <stdlib.h>
+#include <qcombobox.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qtooltip.h>
+#include <qcheckbox.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, QWidget *parent, const char *name)
+ : ImportDialogBase(parent, name, true), m_part(part)
+{
+ QString author, email;
+ AppWizardUtil::guessAuthorAndEmail(&author, &email);
+ author_edit->setText(author);
+ email_edit->setText(email);
+ QToolTip::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", QString::null, false, true);
+ importNames.sort();
+
+ QStringList::ConstIterator it;
+ for (it = importNames.begin(); it != importNames.end(); ++it) {
+ KConfig config(KGlobal::dirs()->findResource("appimports", *it));
+ config.setGroup("General");
+ QString 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, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotProjectNameChanged( const QString & ) ) );
+// scanAvailableVCS();
+ connect( fetchModuleButton, SIGNAL(clicked()),
+ this, SLOT(slotFetchModulesFromRepository()) );
+ connect(urlinput_edit, SIGNAL(urlSelected(const QString& )), this, SLOT(dirChanged()));
+ connect(urlinput_edit, SIGNAL(returnPressed(const QString& )), this, SLOT(dirChanged()));
+ slotProjectNameChanged( name_edit->text() );
+}
+
+
+ImportDialog::~ImportDialog()
+{}
+
+void ImportDialog::slotProjectNameChanged( const QString &_text )
+{
+ ok_button->setEnabled( !_text.isEmpty() && !urlinput_edit->url().contains( QRegExp("\\s") ) );
+}
+
+void ImportDialog::accept()
+{
+ QDir dir(urlinput_edit->url());
+ if (urlinput_edit->url().isEmpty() || !dir.exists()) {
+ KMessageBox::sorry(this, i18n("You have to choose a directory."));
+ return;
+ }
+
+ QString 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();
+
+// QString author = author_edit->text();
+// QString email = email_edit->text();
+
+ QFileInfo finfo(importNames[project_combo->currentItem()]);
+ QDir importdir(finfo.dir());
+ importdir.cdUp();
+ QFile src(importdir.filePath("importfiles/" + finfo.fileName() + ".kdevelop"));
+ 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
+ QDomDocument projectDOM;
+
+ int errorLine, errorCol;
+ QString 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
+ QString profileName = DomUtil::readEntry( projectDOM, "general/profile" );
+ if ( profileName.isEmpty() )
+ {
+ QString language = DomUtil::readEntry( projectDOM, "general/primarylanguage" );
+ QStringList keywords = DomUtil::readListEntry( projectDOM, "general/keywords", "keyword" );
+
+ profileName = Settings::profileByAttributes( language, keywords );
+ }
+
+ ProfileEngine & engine = m_part->pluginController()->engine();
+ Profile * profile = engine.findProfile( profileName );
+
+ QStringList 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
+ QFile dest(dir.filePath(projectName + ".kdevelop"));
+ if (!dest.open(IO_WriteOnly)) {
+ KMessageBox::sorry(this, i18n("Cannot write the project file."));
+ return;
+ }
+ QTextStream ts( &dest );
+ ts.setEncoding(QTextStream::UnicodeUTF8);
+ ts << projectDOM.toString(2);
+ dest.close();
+
+
+// QTextStream srcstream(&src);
+// QTextStream deststream(&dest);
+//
+// while (!srcstream.atEnd()) {
+// QString line = srcstream.readLine();
+// line.replace(QRegExp("\\$APPNAMELC\\$"), projectName);
+// line.replace(QRegExp("\\$AUTHOR\\$"), author);
+// line.replace(QRegExp("\\$EMAIL\\$"), email);
+// deststream << line << endl;
+// }
+//
+// dest.close();
+// src.close();
+
+ m_part->core()->openProject(dir.filePath(projectName + ".kdevelop"));
+
+ kdDebug(9010) << "OPENING PROJECT: " << dir.filePath(projectName + ".kdevelop") << endl;
+
+ QDialog::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(QDir &dir, const QString &patterns)
+{
+ QStringList::ConstIterator pit, sit;
+
+ QStringList patternList = QStringList::split(",", patterns);
+ for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
+ if (!dir.entryList(*pit, QDir::Files).isEmpty()) {
+ kdDebug(9010) << "Has files " << (*pit) << endl;
+ return true;
+ }
+ }
+
+ QStringList subdirList = dir.entryList("*", QDir::Dirs);
+ for (sit = subdirList.begin(); sit != subdirList.end(); ++sit) {
+ QDir subdir(dir);
+ subdir.cd(*sit);
+ for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
+ if (!subdir.entryList(*pit, QDir::Files).isEmpty()) {
+ kdDebug(9010) << "Has files " << (*pit) << " in " << (*sit) << endl;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void ImportDialog::dirChanged()
+{
+ kdDebug(9010) << "ImportDialog::dirChanged" << endl;
+ QString dirName = urlinput_edit->url();
+ QDir dir(dirName);
+ if (!dir.exists())
+ return;
+
+ if ( dirName.contains( QRegExp("\\s") ) )
+ {
+ ok_button->setEnabled( false );
+ return;
+ }else
+ {
+ ok_button->setEnabled( true );
+ }
+
+ // KDevelop legacy project?
+ QStringList 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
+ QString projectName(dir.dirName().replace(QRegExp("[^a-zA-Z0-9_]"), "_"));
+
+ // Set the project name
+ name_edit->setText(projectName);
+
+ // QMake 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 QString &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"));
+
+ QString legacyType = config.readEntry("project_type");
+ if (QStringList::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 QString &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 QString &dirName)
+{
+ kdDebug(9010) << "Scanning automake project directory " << dirName << endl;
+
+ bool stop = false;
+ if (QFile::exists(dirName + "/admin/am_edit")) {
+ setProjectType("kde");
+ stop = true;
+ } else if (QFile::exists(dirName + "/macros/gnome.m4")) {
+ setProjectType("gnome");
+ stop = true;
+ } else {
+ setProjectType("c-auto");
+ }
+
+ // if we get an authors file, use it.
+ QFile af(dirName + "/AUTHORS");
+ if (af.open(IO_ReadOnly)){
+ QTextStream astream(&af);
+
+ QRegExp authorre("(.*)<(.*)>");
+ while (!astream.atEnd()) {
+ QString 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])
+ QRegExp ac_init("^AC_INIT\\s*\\(\\s*([^,]+),([^,\\)]+)(.*)");
+
+ // AM_INIT_AUTOMAKE([OPTIONS])
+ // example: AM_INIT_AUTOMAKE([gnits 1.5 no-define dist-bzip2])
+ QRegExp am_autoSpace("^AM_INIT_AUTOMAKE\\s{0,}\\(\\s{0,}([\\[\\s]{0,}[^\\s]+)\\s+([^\\s\\)\\]]+)(.*)");
+
+ // AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+ QRegExp am_autoComma("^AM_INIT_AUTOMAKE\\s*\\(\\s*([^,]+),([^,\\)]+)(.*)");
+
+ // look for version in a define.
+ // AC_DEFINE(VERSION, "5.6")
+ QRegExp ac_define("^AC_DEFINE\\s*\\(\\s*[^,]+,([^\\)]+)");
+ QRegExp version("(\\bversion\\b)");
+ version.setCaseSensitive(FALSE);
+
+ QTextStream cstream;
+ // try for configure.in.in, configure.in, then configure.ac
+ QFile configInIn(dirName + "/configure.in.in");
+ QFile configIn(dirName+"/configure.in");
+ QFile configAc(dirName+"/configure.ac");
+ if (configInIn.open(IO_ReadOnly)){
+ cstream.setDevice(&configInIn);
+ while (!cstream.atEnd()) {
+ QString 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(&configIn);
+ }
+ else{
+ if (configAc.open(IO_ReadOnly)){
+ cstream.setDevice(&configAc);
+ }
+ else{
+ return;
+ }
+ }
+
+ QRegExp namere("\\s*AM_INIT_AUTOMAKE\\((.*),.*\\).*");
+ QRegExp cppre("\\s*AC_PROG_CXX");
+ QRegExp f77re("\\s*AC_PROG_F77");
+ while (!cstream.atEnd()) {
+ QString 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 QString &type)
+{
+ kdDebug(9010) << "Setting project type " << type << endl;
+ QString suffix = "/" + type;
+ int suffixLength = suffix.length();
+
+ int i=0;
+ QStringList::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( QString 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, SIGNAL(finishedFetching(QString)),
+ this, SLOT(slotFinishedCheckout(QString)) );
+
+ //restore cursor if we can't fetch repository
+ if ( !vcs->fetchFromRepository() )
+ setCursor( KCursor::arrowCursor() );
+
+}
+*/
+void ImportDialog::projectTypeChanged( const QString &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;
+
+ QDir dir (urlinput_edit->url());
+ QStringList files = dir.entryList(cmd.existingPattern);
+ if (!files.isEmpty()) {
+ if (KMessageBox::questionYesNo(this, i18n("Project infrastrucure already exists in target directory.\nGenerate new project infrastructure and overwrite old?"), QString::null, i18n("Generate"), i18n("Do Not Generate")) == KMessageBox::No)
+ return;
+ }
+
+ QString 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"