~ubuntu-branches/debian/sid/kdevelop/sid

« back to all changes in this revision

Viewing changes to parts/appwizard/importdlg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Lainé
  • Date: 2006-05-23 18:39:42 UTC
  • Revision ID: james.westby@ubuntu.com-20060523183942-hucifbvh68k2bwz7
Tags: upstream-3.3.2
Import upstream version 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2001-2002 by Bernd Gehrmann                             *
 
3
 *   bernd@kdevelop.org                                                    *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 2 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 ***************************************************************************/
 
11
 
 
12
#include "importdlg.h"
 
13
#include <stdlib.h>
 
14
#include <qcombobox.h>
 
15
#include <qdir.h>
 
16
#include <qfile.h>
 
17
#include <qlabel.h>
 
18
#include <qlayout.h>
 
19
#include <qlineedit.h>
 
20
#include <qpushbutton.h>
 
21
#include <qregexp.h>
 
22
#include <qtextstream.h>
 
23
#include <qtooltip.h>
 
24
#include <qcheckbox.h>
 
25
#include <kbuttonbox.h>
 
26
#include <kdebug.h>
 
27
#include <kdialog.h>
 
28
#include <kfiledialog.h>
 
29
#include <kinstance.h>
 
30
#include <klocale.h>
 
31
#include <kmessagebox.h>
 
32
#include <kstandarddirs.h>
 
33
#include <kcursor.h>
 
34
#include <kfile.h>
 
35
#include <kurlrequester.h>
 
36
#include <ktrader.h>
 
37
#include <kparts/componentfactory.h>
 
38
#include <kprocess.h>
 
39
 
 
40
#include "kdevcore.h"
 
41
#include "kdevversioncontrol.h"
 
42
 
 
43
#include "appwizardfactory.h"
 
44
#include "appwizardpart.h"
 
45
#include "misc.h"
 
46
 
 
47
 
 
48
ImportDialog::ImportDialog(AppWizardPart *part, QWidget *parent, const char *name)
 
49
    : ImportDialogBase(parent, name, true), m_part(part)
 
50
{
 
51
    QString author, email;
 
52
    AppWizardUtil::guessAuthorAndEmail(&author, &email);
 
53
    author_edit->setText(author);
 
54
    email_edit->setText(email);
 
55
    QToolTip::add( urlinput_edit->button(), i18n("Choose directory to import") );
 
56
    urlinput_edit->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
 
57
 
 
58
    KStandardDirs *dirs = AppWizardFactory::instance()->dirs();
 
59
    importNames = dirs->findAllResources("appimports", QString::null, false, true);
 
60
    importNames.sort();
 
61
 
 
62
    QStringList::ConstIterator it;
 
63
    for (it = importNames.begin(); it != importNames.end(); ++it) {
 
64
        KConfig config(KGlobal::dirs()->findResource("appimports", *it));
 
65
        config.setGroup("General");
 
66
        QString type = config.readEntry("Comment");
 
67
        project_combo->insertItem(type);
 
68
        
 
69
        if (config.hasGroup("Infrastructure"))
 
70
        {
 
71
            config.setGroup("Infrastructure");
 
72
            m_infrastructure[type].isOn = true;
 
73
            m_infrastructure[type].comment = config.readEntry("Comment");
 
74
            m_infrastructure[type].command = config.readEntry("Command");
 
75
            m_infrastructure[type].existingPattern = config.readEntry("ExistingProjectPattern");
 
76
        }
 
77
        else
 
78
            m_infrastructure[type].isOn = false;
 
79
    }
 
80
 
 
81
    infrastructureBox->setEnabled(false);
 
82
    setProjectType("c");
 
83
    connect( name_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotProjectNameChanged( const QString & ) ) );
 
84
//    scanAvailableVCS();
 
85
    connect( fetchModuleButton, SIGNAL(clicked()),
 
86
        this, SLOT(slotFetchModulesFromRepository()) );
 
87
    connect(urlinput_edit, SIGNAL(urlSelected(const QString& )), this, SLOT(dirChanged()));
 
88
    slotProjectNameChanged( name_edit->text() );
 
89
}
 
90
 
 
91
 
 
92
ImportDialog::~ImportDialog()
 
93
{}
 
94
 
 
95
void ImportDialog::slotProjectNameChanged( const QString &_text )
 
96
{
 
97
    ok_button->setEnabled( !_text.isEmpty() );
 
98
}
 
99
 
 
100
void ImportDialog::accept()
 
101
{
 
102
    QDir dir(urlinput_edit->url());
 
103
    if (urlinput_edit->url().isEmpty() || !dir.exists()) {
 
104
        KMessageBox::sorry(this, i18n("You have to choose a directory."));
 
105
        return;
 
106
    }
 
107
 
 
108
    QString projectName = name_edit->text();
 
109
    if (projectName.isEmpty()) {
 
110
        KMessageBox::sorry(this, i18n("You have to choose a project name."));
 
111
        return;
 
112
    }
 
113
 
 
114
    for (uint i=0; i < projectName.length(); ++i)
 
115
        if (!projectName[i].isLetterOrNumber() && projectName[i] != '_') {
 
116
            KMessageBox::sorry(this, i18n("Your application name should only contain letters and numbers."));
 
117
            return;
 
118
        }
 
119
        
 
120
    if (infrastructureBox->isVisible() && infrastructureBox->isChecked())
 
121
        createProjectInfrastructure();
 
122
 
 
123
    QString author = author_edit->text();
 
124
    QString email = email_edit->text();
 
125
 
 
126
    QFileInfo finfo(importNames[project_combo->currentItem()]);
 
127
    QDir importdir(finfo.dir());
 
128
    importdir.cdUp();
 
129
    QFile src(importdir.filePath("importfiles/" + finfo.fileName() + ".kdevelop"));
 
130
    kdDebug(9010) << "Import template " << src.name() << endl;
 
131
    if (!src.open(IO_ReadOnly)) {
 
132
        KMessageBox::sorry(this, i18n("Cannot open project template."));
 
133
        return;
 
134
    }
 
135
 
 
136
    QFile dest(dir.filePath(projectName + ".kdevelop"));
 
137
    if (!dest.open(IO_WriteOnly)) {
 
138
        KMessageBox::sorry(this, i18n("Cannot write the project file."));
 
139
        return;
 
140
    }
 
141
 
 
142
    QTextStream srcstream(&src);
 
143
    QTextStream deststream(&dest);
 
144
 
 
145
    while (!srcstream.atEnd()) {
 
146
        QString line = srcstream.readLine();
 
147
        line.replace(QRegExp("\\$APPNAMELC\\$"), projectName);
 
148
        line.replace(QRegExp("\\$AUTHOR\\$"), author);
 
149
        line.replace(QRegExp("\\$EMAIL\\$"), email);
 
150
        deststream << line << endl;
 
151
    }
 
152
 
 
153
    dest.close();
 
154
    src.close();
 
155
 
 
156
    m_part->core()->openProject(dir.filePath(projectName + ".kdevelop"));
 
157
 
 
158
    kdDebug(9010) << "OPENING PROJECT: " << dir.filePath(projectName + ".kdevelop") << endl;
 
159
 
 
160
    QDialog::accept();
 
161
}
 
162
 
 
163
 
 
164
// Checks if the directory dir and all of its subdirectories
 
165
// (one level recursion) have files that follow patterns
 
166
// patterns is comma-separated
 
167
static bool dirHasFiles(QDir &dir, const QString &patterns)
 
168
{
 
169
    QStringList::ConstIterator pit, sit;
 
170
 
 
171
    QStringList patternList = QStringList::split(",", patterns);
 
172
    for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
 
173
        if (!dir.entryList(*pit, QDir::Files).isEmpty()) {
 
174
            kdDebug(9010) << "Has files " << (*pit) << endl;
 
175
            return true;
 
176
        }
 
177
    }
 
178
 
 
179
    QStringList subdirList = dir.entryList("*", QDir::Dirs);
 
180
    for (sit = subdirList.begin(); sit != subdirList.end(); ++sit) {
 
181
        QDir subdir(dir);
 
182
        subdir.cd(*sit);
 
183
        for (pit = patternList.begin(); pit != patternList.end(); ++pit) {
 
184
            if (!subdir.entryList(*pit, QDir::Files).isEmpty()) {
 
185
                kdDebug(9010) << "Has files " << (*pit) << " in " << (*sit) << endl;
 
186
                return true;
 
187
            }
 
188
        }
 
189
    }
 
190
 
 
191
    return false;
 
192
}
 
193
 
 
194
 
 
195
void ImportDialog::dirChanged()
 
196
{
 
197
    kdDebug(9010) << "ImportDialog::dirChanged" << endl;
 
198
    QString dirName = urlinput_edit->url();
 
199
    QDir dir(dirName);
 
200
    if (!dir.exists())
 
201
        return;
 
202
 
 
203
    // KDevelop legacy project?
 
204
    QStringList files = dir.entryList("*.kdevprj");
 
205
    if (!files.isEmpty()) {
 
206
        scanLegacyKDevelopProject(dir.absFilePath(files.first()));
 
207
        return;
 
208
    }
 
209
 
 
210
    // Studio legacy project?
 
211
    files = dir.entryList("*.studio");
 
212
    if (!files.isEmpty()) {
 
213
        scanLegacyStudioProject(dir.absFilePath(files.first()));
 
214
        return;
 
215
    }
 
216
 
 
217
    // Automake based?
 
218
    if (dir.exists("config.guess") || dir.exists("configure.in.in")) {
 
219
        scanAutomakeProject(dirName);
 
220
        return;
 
221
    }
 
222
 
 
223
    name_edit->setText(dir.dirName());
 
224
 
 
225
    // QMake based?
 
226
    files = dir.entryList("*.pro");
 
227
    if (!files.isEmpty()) {
 
228
        setProjectType("qtqmake");
 
229
        return;
 
230
    }
 
231
 
 
232
    // C++?
 
233
    if (dirHasFiles(dir, "*.cpp,*.c++,*.cxx,*.C,*.cc,*.ocl")) {
 
234
        setProjectType("cpp");
 
235
        return;
 
236
    }
 
237
 
 
238
    // Fortran?
 
239
    if (dirHasFiles(dir, "*.f77,*.f,*.for,*.ftn")) {
 
240
        setProjectType("fortran");
 
241
        return;
 
242
    }
 
243
 
 
244
    // Python?
 
245
    if (dirHasFiles(dir, "*.py")) {
 
246
        setProjectType("python");
 
247
        return;
 
248
    }
 
249
 
 
250
    // Perl?
 
251
    if (dirHasFiles(dir, "*.pl,*.pm")) {
 
252
        setProjectType("perl");
 
253
        return;
 
254
    }
 
255
}
 
256
 
 
257
 
 
258
void ImportDialog::scanLegacyKDevelopProject(const QString &fileName)
 
259
{
 
260
    kdDebug(9010) << "Scanning legacy KDevelop project file " << fileName << endl;
 
261
 
 
262
    KSimpleConfig config(fileName, true);
 
263
    config.setGroup("General");
 
264
    author_edit->setText(config.readEntry("author"));
 
265
    email_edit->setText(config.readEntry("email"));
 
266
    name_edit->setText(config.readEntry("project_name"));
 
267
 
 
268
    QString legacyType = config.readEntry("project_type");
 
269
    if (QStringList::split(",", "normal_kde,normal_kde2,kde2_normal,mdi_kde2").contains(legacyType))
 
270
        setProjectType("kde");
 
271
    else if (legacyType == "normal_gnome")
 
272
        setProjectType("gnome");
 
273
    else if (legacyType == "normal_empty")
 
274
        setProjectType("cpp-auto");
 
275
    else
 
276
        setProjectType("cpp");
 
277
}
 
278
 
 
279
 
 
280
void ImportDialog::scanLegacyStudioProject(const QString &fileName)
 
281
{
 
282
    kdDebug(9010) << "Scanning legacy studio project file " << fileName << endl;
 
283
 
 
284
    // Not much to do here...
 
285
    KSimpleConfig config(fileName, true);
 
286
    config.setGroup("kdestudio");
 
287
    name_edit->setText(config.readEntry("Name"));
 
288
}
 
289
 
 
290
 
 
291
void ImportDialog::scanAutomakeProject(const QString &dirName)
 
292
{
 
293
    kdDebug(9010) << "Scanning automake project directory " << dirName << endl;
 
294
 
 
295
    bool stop = false;
 
296
    if (QFile::exists(dirName + "/admin/am_edit")) {
 
297
        setProjectType("kde");
 
298
        stop = true;
 
299
    } else if (QFile::exists(dirName + "/macros/gnome.m4")) {
 
300
        setProjectType("gnome");
 
301
        stop = true;
 
302
    } else {
 
303
        setProjectType("c-auto");
 
304
    }
 
305
 
 
306
    QFile af(dirName + "/AUTHORS");
 
307
    if (!af.open(IO_ReadOnly))
 
308
        return;
 
309
    QTextStream astream(&af);
 
310
 
 
311
    QRegExp authorre("(.*)<(.*)>");
 
312
    while (!astream.atEnd()) {
 
313
        QString s = astream.readLine();
 
314
        if (authorre.search(s) != -1) {
 
315
            author_edit->setText(authorre.cap(1).stripWhiteSpace());
 
316
            email_edit->setText(authorre.cap(2).stripWhiteSpace());
 
317
            break;
 
318
        }
 
319
    }
 
320
    af.close();
 
321
 
 
322
    QFile cf(dirName + "/configure.in");
 
323
    if (!cf.open(IO_ReadOnly))
 
324
        return;
 
325
    QTextStream cstream(&cf);
 
326
 
 
327
    QRegExp namere("\\s*AM_INIT_AUTOMAKE\\((.*),.*\\).*");
 
328
    QRegExp cppre("\\s*AC_PROG_CXX");
 
329
    QRegExp f77re("\\s*AC_PROG_F77");
 
330
    while (!cstream.atEnd()) {
 
331
        QString s = cstream.readLine();
 
332
        if (namere.search(s) == 0)
 
333
            name_edit->setText(namere.cap(1).stripWhiteSpace());
 
334
        if (!stop)
 
335
            continue;
 
336
        else if (cppre.search(s) == 0)
 
337
            setProjectType("cpp-auto");
 
338
        else if (f77re.search(s) == 0)
 
339
            setProjectType("fortran-auto");
 
340
    }
 
341
    cf.close();
 
342
}
 
343
 
 
344
 
 
345
void ImportDialog::setProjectType(const QString &type)
 
346
{
 
347
    kdDebug(9010) << "Setting project type " << type << endl;
 
348
    QString suffix = "/" + type;
 
349
    int suffixLength = suffix.length();
 
350
 
 
351
    int i=0;
 
352
    QStringList::ConstIterator it;
 
353
    for (it = importNames.begin(); it != importNames.end(); ++it) {
 
354
        if ((*it).right(suffixLength) == suffix) {
 
355
            project_combo->setCurrentItem(i);
 
356
            break;
 
357
        }
 
358
        ++i;
 
359
    }
 
360
}
 
361
/*
 
362
void ImportDialog::scanAvailableVCS()
 
363
{
 
364
//    vcsCombo->insertStringList( m_part->registeredVersionControls() );
 
365
        int i = 0;
 
366
        KTrader::OfferList offers = KTrader::self()->query("KDevelop/VersionControl");
 
367
        KTrader::OfferList::const_iterator it = offers.begin();
 
368
        while( it != offers.end() )
 
369
        {
 
370
                vcsCombo->insertItem( (*it)->genericName(), i++ );
 
371
                ++it;
 
372
        }       
 
373
}
 
374
*/
 
375
/*
 
376
void ImportDialog::slotFinishedCheckout( QString destinationDir )
 
377
{
 
378
    urlinput_edit->setURL( destinationDir );
 
379
 
 
380
    setCursor( KCursor::arrowCursor() );
 
381
//    setEnabled( true );
 
382
}
 
383
*/
 
384
/*
 
385
void ImportDialog::slotFetchModulesFromRepository()
 
386
{
 
387
        
 
388
    KDevVersionControl *vcs = m_part->versionControlByName( vcsCombo->currentText() );
 
389
    if (!vcs)
 
390
        return;
 
391
 
 
392
    setCursor( KCursor::waitCursor() );
 
393
//    setEnabled( false );
 
394
 
 
395
    connect( vcs, SIGNAL(finishedFetching(QString)),
 
396
        this, SLOT(slotFinishedCheckout(QString)) );
 
397
 
 
398
    //restore cursor if we can't fetch repository
 
399
    if ( !vcs->fetchFromRepository() )
 
400
        setCursor( KCursor::arrowCursor() );
 
401
        
 
402
}
 
403
*/
 
404
void ImportDialog::projectTypeChanged( const QString &type )
 
405
{
 
406
    if (m_infrastructure[type].isOn)
 
407
    {
 
408
        infrastructureBox->setEnabled(true);
 
409
        infrastructureBox->setText(m_infrastructure[type].comment);
 
410
    }
 
411
    else
 
412
    {
 
413
        infrastructureBox->setEnabled(false);
 
414
        infrastructureBox->setText(i18n("Generate build system infrastrucure"));
 
415
    }
 
416
}
 
417
 
 
418
void ImportDialog::createProjectInfrastructure( )
 
419
{
 
420
    kdDebug(9010) << "ImportDialog::createProjectInfrastructure" << endl;
 
421
    InfrastructureCmd cmd = m_infrastructure[project_combo->currentText()];
 
422
    if (!cmd.isOn)
 
423
        return;
 
424
    
 
425
    QDir dir (urlinput_edit->url());
 
426
    QStringList files = dir.entryList(cmd.existingPattern);
 
427
    if (!files.isEmpty()) {
 
428
        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)
 
429
            return;
 
430
    }
 
431
    
 
432
    QString command = "cd " + urlinput_edit->url() + " && " + cmd.command;
 
433
    kdDebug(9010) << "executing " << command.ascii() << endl;
 
434
    system(command.ascii());
 
435
}
 
436
 
 
437
void ImportDialog::projectTypeChanged( int type )
 
438
{
 
439
    projectTypeChanged(project_combo->text(type));
 
440
}
 
441
 
 
442
 
 
443
#include "importdlg.moc"