00001
00002
00003
00004
00005
00006
00007
00008
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
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
00165
00166
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
00204 QStringList files = dir.entryList("*.kdevprj");
00205 if (!files.isEmpty()) {
00206 scanLegacyKDevelopProject(dir.absFilePath(files.first()));
00207 return;
00208 }
00209
00210
00211 files = dir.entryList("*.studio");
00212 if (!files.isEmpty()) {
00213 scanLegacyStudioProject(dir.absFilePath(files.first()));
00214 return;
00215 }
00216
00217
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
00226 files = dir.entryList("*.pro");
00227 if (!files.isEmpty()) {
00228 setProjectType("qtqmake");
00229 return;
00230 }
00231
00232
00233 if (dirHasFiles(dir, "*.cpp,*.c++,*.cxx,*.C,*.cc")) {
00234 setProjectType("cpp");
00235 return;
00236 }
00237
00238
00239 if (dirHasFiles(dir, "*.f77,*.f,*.for,*.ftn")) {
00240 setProjectType("fortran");
00241 return;
00242 }
00243
00244
00245 if (dirHasFiles(dir, "*.py")) {
00246 setProjectType("python");
00247 return;
00248 }
00249
00250
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
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
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
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"