KDevelop API Documentation

appwizarddlg.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2001-2002 by Bernd Gehrmann                             *
00003  *   bernd@kdevelop.org                                                    *
00004  *   Copyright (C) 2001 by Sandy Meier                                     *
00005  *   smeier@kdevelop.org                                                   *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 #include "appwizarddlg.h"
00015 
00016 #include <qvbox.h>
00017 #include <qbuttongroup.h>
00018 #include <qcombobox.h>
00019 #include <qtabwidget.h>
00020 #include <qwidgetstack.h>
00021 #include <qdir.h>
00022 #include <qfileinfo.h>
00023 #include <qgrid.h>
00024 #include <qheader.h>
00025 #include <qmap.h>
00026 #include <qmultilineedit.h>
00027 #include <qpushbutton.h>
00028 #include <qradiobutton.h>
00029 #include <qregexp.h>
00030 #include <qtextstream.h>
00031 #include <qtextview.h>
00032 #include <qtoolbutton.h>
00033 #include <qtooltip.h>
00034 #include <qvalidator.h>
00035 #include <klistview.h>
00036 #include <kiconview.h>
00037 #include <kconfig.h>
00038 #include <kdebug.h>
00039 #include <kglobal.h>
00040 #include <kglobalsettings.h>
00041 #include <klocale.h>
00042 #include <kmessagebox.h>
00043 #include <kprocess.h>
00044 #include <kstandarddirs.h>
00045 #include <ktempfile.h>
00046 #include <kiconloader.h>
00047 #include <kfiledialog.h>
00048 #include <kfile.h>
00049 #include <kapplication.h>
00050 #include <kpopupmenu.h>
00051 
00052 #include <ktrader.h>
00053 #include <kparts/componentfactory.h>
00054 #include <kio/netaccess.h>
00055 #include <qfile.h>
00056 #include <qdir.h>
00057 #include <qtextstream.h>
00058 #include <kmacroexpander.h>
00059 #include <karchive.h>
00060 #include <ktar.h>
00061 #include <ktempdir.h>
00062 #include <kfileitem.h>
00063 #include <kio/chmodjob.h>
00064 
00065 #include <qlayout.h>
00066 
00067 #include "domutil.h"
00068 #include "kdevversioncontrol.h"
00069 #include "kdevmakefrontend.h"
00070 #include "kdevpartcontroller.h"
00071 #include "kdevlicense.h"
00072 #include "kdevcore.h"
00073 #include "appwizardfactory.h"
00074 #include "appwizardpart.h"
00075 #include "filepropspage.h"
00076 #include "misc.h"
00077 #include "dataform.h"
00078 
00079 AppWizardDialog::AppWizardDialog(AppWizardPart *part, QWidget *parent, const char *name)
00080     : AppWizardDialogBase(parent, name,true), m_pCurrentAppInfo(0)
00081 {
00082     kdDebug( 9000 ) << "  ** AppWizardDialog::AppWizardDialog()" << endl;
00083 
00084     m_customOptions = 0L;
00085     connect( this, SIGNAL( selected( const QString & ) ), this, SLOT( pageChanged() ) );
00086     
00087     helpButton()->hide();
00088     templates_listview->header()->hide();
00089     templates_listview->setColumnWidthMode(0, QListView::Maximum);  //to provide horiz scrollbar.
00090     
00091     m_templatesMenu = new KPopupMenu(templates_listview);
00092     m_templatesMenu->insertItem(i18n("&Add to Favorites"), this, SLOT(addTemplateToFavourites()));
00093     
00094     m_favouritesMenu = new KPopupMenu(favourites_iconview);
00095     m_favouritesMenu->insertItem(i18n("&Remove Favorite"), this, SLOT(removeFavourite()));
00096     
00097     m_pathIsValid=false;
00098     m_part = part;
00099     m_projectLocationWasChanged=false;
00100     m_appsInfo.setAutoDelete(true);
00101     m_tempFiles.setAutoDelete(true);
00102 
00103     KConfig *config = kapp->config();
00104     
00105     //config->setGroup("AppWizard");
00106     //templates_tabwidget->setCurrentPage(config->readNumEntry("CurrentTab", 0));
00107 
00108     config->setGroup("General Options");
00109     QString defaultProjectsDir = config->readPathEntry("DefaultProjectsDir", QDir::homeDirPath()+"/");
00110 
00111     KStandardDirs *dirs = AppWizardFactory::instance()->dirs();
00112     QStringList m_templateNames = dirs->findAllResources("apptemplates", QString::null, false, true);
00113 
00114     kdDebug(9010) << "Templates: " << endl;
00115     QStringList categories;
00116 
00117     QStringList::Iterator it;
00118     for (it = m_templateNames.begin(); it != m_templateNames.end(); ++it) {
00119         kdDebug(9010) << (*it) << endl;
00120         
00121 
00122         ApplicationInfo *info = new ApplicationInfo;
00123         info->templateFile = KGlobal::dirs()->findResource("apptemplates", *it);
00124         info->templateName = (*it);
00125         
00126         KConfig templateConfig(info->templateFile);
00127         templateConfig.setGroup("General");
00128         
00129         info->name = templateConfig.readEntry("Name");
00130         info->icon = templateConfig.readEntry("Icon");
00131         info->comment = templateConfig.readEntry("Comment");
00132         info->fileTemplates = templateConfig.readEntry("FileTemplates");
00133         info->openFilesAfterGeneration = templateConfig.readListEntry("ShowFilesAfterGeneration");
00134         QString destDir = templateConfig.readPathEntry("DefaultDestinatonDir", defaultProjectsDir);
00135         destDir.replace(QRegExp("HOMEDIR"), QDir::homeDirPath());
00136         info->defaultDestDir = destDir;
00137         QString category = templateConfig.readEntry("Category");
00138         // format category to a unique status
00139         if (category.right(1) == "/")
00140             category.remove(category.length()-1, 1); // remove /
00141         if (category.left(1) != "/")
00142             category.prepend("/"); // prepend /
00143         categories.append(category);
00144         info->category = category;
00145         info->sourceArchive = templateConfig.readEntry("Archive");
00146         
00147         // Grab includes list
00148         QStringList groups = templateConfig.groupList();
00149         groups.remove("General");
00150         QStringList::Iterator group = groups.begin();
00151         for(  ; group != groups.end(); ++group)
00152         {
00153             templateConfig.setGroup( (*group) );
00154             QString type = templateConfig.readEntry("Type").lower();
00155             if( type == "include" )  // Add value
00156             {
00157                 info->includes.append( templateConfig.readEntry( "File" ) );
00158                 kdDebug() << "Adding: " << templateConfig.readEntry( "File" ) << endl;
00159             }
00160         }
00161         
00162         // Build builtins map to bootstrap.
00163         QString source = kdevRoot( info->templateName );
00164         info->subMap.insert("kdevelop", source );
00165         
00166         // Add includes to the main template...
00167         QStringList::Iterator include = info->includes.begin();
00168         for( ; include != info->includes.end(); ++include)
00169         {
00170             if( !(*include).isEmpty() )
00171             {
00172                 QString file = KMacroExpander::expandMacros( ( *include ), info->subMap);
00173                 KConfig tmpCfg( file );
00174                 tmpCfg.copyTo( "", &templateConfig);
00175                 kdDebug() << "Merging: " << tmpCfg.name() << endl;
00176             }
00177         }
00178         
00179         groups = templateConfig.groupList();  // Must get this again since its changed!
00180         group = groups.begin();
00181         for(  ; group != groups.end(); ++group)
00182         {
00183             templateConfig.setGroup( (*group) );
00184             QString type = templateConfig.readEntry("Type", "value").lower();
00185             kdDebug(9010) << "Reading " <<  (*group) << " of type " << type << endl;
00186             if( type == "value" )  // Add value
00187             {
00188                 QString name = templateConfig.readEntry( "Value" );
00189                 QString label = templateConfig.readEntry( "Comment" );
00190                 QString type = templateConfig.readEntry( "ValueType", "String" );
00191                 autoKey key( name, label);
00192                 QVariant value = templateConfig.readPropertyEntry( "Default", QVariant::nameToType( type.latin1() ) );
00193                 value.cast( QVariant::nameToType( type.latin1() ) );  // fix this in kdelibs...
00194                 info->subValues.insert( key, value );
00195             } 
00196             else if( type == "install" ) // copy dir
00197             {
00198                 installFile file;
00199                 file.source = templateConfig.readPathEntry("Source");
00200                 file.dest = templateConfig.readPathEntry("Dest");
00201                 file.process = templateConfig.readBoolEntry("Process",true);
00202                 file.isXML = templateConfig.readBoolEntry("EscapeXML",false);
00203                 file.option = templateConfig.readEntry("Option");
00204                 info->fileList.append(file);
00205             }
00206             else if( type == "install archive" )
00207             {
00208                 installArchive arch;
00209                 arch.source = templateConfig.readPathEntry("Source");
00210                 arch.dest = templateConfig.readPathEntry("Dest");
00211                 arch.process = templateConfig.readBoolEntry("Process",true);
00212                 arch.option = templateConfig.readEntry("Option", "" );
00213                 info->archList.append(arch);
00214             }
00215             else if( type == "mkdir" )
00216             {
00217                 installDir dir;
00218                 dir.dir = templateConfig.readPathEntry("Dir");
00219                 dir.option = templateConfig.readEntry("Option", "" );
00220                 dir.perms = templateConfig.readNumEntry("Perms", 0777 );
00221                 info->dirList.append(dir);
00222             }
00223             else if( type == "ui")
00224             {
00225                 QString name = templateConfig.readPathEntry("File");
00226                 info->customUI = name;
00227             }
00228             else if( type == "message" )
00229             {
00230                 info->message = templateConfig.readEntry( "Comment" );
00231             }
00232         }
00233     
00234         
00235         m_appsInfo.append(info);
00236     }
00237 
00238     // Insert categories into list view
00239     categories.sort();
00240     for (it = categories.begin(); it != categories.end(); ++it)
00241         insertCategoryIntoTreeView(*it);
00242 
00243     // Insert items into list view
00244     QPtrListIterator<ApplicationInfo> ait(m_appsInfo);
00245     for (; ait.current(); ++ait) {
00246         QListViewItem *item = m_categoryMap.find(ait.current()->category);
00247         if (item)
00248         {
00249             item = new KListViewItem(item, ait.current()->name);
00250             item->setPixmap(0, SmallIcon("kdevelop"));
00251         }
00252         else
00253             kdDebug(9010) << "Error can't find category in categoryMap: "
00254                           << ait.current()->category << endl;
00255         ait.current()->item = item;
00256     }
00257     
00258     //Load favourites from config
00259     populateFavourites();
00260     
00261     QString author, email;
00262     AppWizardUtil::guessAuthorAndEmail(&author, &email);
00263     author_edit->setText(author);
00264     email_edit->setText(email);
00265     QToolTip::add( dest_edit->button(), i18n("Choose projects directory") );
00266     dest_edit->setURL(defaultProjectsDir);
00267     dest_edit->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
00268 
00269 //    loadVcs();
00270 
00271     //    addPage(m_sdi_fileprops_page,"Class/File Properties");
00272 
00273     //    licenseChanged();
00274 
00275     setNextEnabled(generalPage, false);
00276 
00277 //    QRegExp appname_regexp ("[a-zA-Z][a-zA-Z0-9_]*"); //Non-Unicode version
00278     /* appname will start with a letter, and will contain letters,
00279        digits or underscores. */
00280     QRegExp appname_regexp ("[a-zA-Z][a-zA-Z0-9_]*");
00281     // How about names like "__" or "123" for project name? Are they legal?
00282     QRegExpValidator *appname_edit_validator;
00283     appname_edit_validator = new QRegExpValidator (appname_regexp,
00284                                                    appname_edit,
00285                                                    "AppNameValidator");
00286     appname_edit->setValidator(appname_edit_validator);
00287     
00288     // insert the licenses into the license_combo
00289     QDict< KDevLicense > lics( m_part->core()->licenses() );
00290     QDictIterator< KDevLicense > dit(lics);
00291     int idx=1;
00292     for( ; dit.current(); ++dit )
00293     {
00294         license_combo->insertItem( dit.currentKey(), idx++ );
00295         if( dit.currentKey() == "GPL" )
00296             license_combo->setCurrentItem( idx - 1 );
00297     }
00298     
00299     m_custom_options_layout = new QHBoxLayout( custom_options );
00300     m_custom_options_layout->setAutoAdd(true);
00301 }
00302 
00303 AppWizardDialog::~AppWizardDialog()
00304 {}
00305 /*
00306 void AppWizardDialog::loadVcs()
00307 {
00308     m_vcsForm = new VcsForm();
00309 
00310     int i=0;
00311     m_vcsForm->combo->insertItem( i18n("no version control system", "None"), i );
00312     m_vcsForm->stack->addWidget( 0, i++ );
00313 
00314     // We query for all vcs plugins for KDevelop
00315     QStringList availableVcs = m_part->registeredVersionControls();
00316 
00317     for(QStringList::const_iterator it( availableVcs.begin() ); it != availableVcs.end(); ++it)
00318     {
00319         KDevVersionControl *vcs = m_part->versionControlByName( (*it) );
00320         QString vcsName = vcs->uid();
00321 
00322         QWidget *newProjectWidget = vcs->newProjectWidget( m_vcsForm->stack );
00323         if (newProjectWidget) {
00324             m_vcsForm->combo->insertItem( vcsName, i );
00325             m_vcsForm->stack->addWidget( newProjectWidget, i++ );
00326         }
00327         else
00328         {
00329             kdDebug( 9000 ) << "  ** Warning: VCS has not widget. Skipping. " << endl;
00330         }
00331     }
00332 
00333     addPage( m_vcsForm, i18n("Version Control System") );
00334 }
00335 */
00336 
00337 void AppWizardDialog::updateNextButtons()
00338 {
00339     bool validGeneralPage = m_pCurrentAppInfo
00340                             && !appname_edit->text().isEmpty()
00341                             && m_pathIsValid;
00342     bool validPropsPage = !version_edit->text().isEmpty()
00343                             && !author_edit->text().isEmpty();
00344 
00345     setFinishEnabled(m_lastPage, validGeneralPage && validPropsPage);
00346     nextButton()->setEnabled(
00347         currentPage() == generalPage ? validGeneralPage : validPropsPage );
00348 }
00349 
00350 void AppWizardDialog::textChanged()
00351 {
00352     licenseChanged();
00353 
00354     updateNextButtons();
00355 }
00356 
00357 void AppWizardDialog::licenseChanged()
00358 {
00359     QValueList<AppWizardFileTemplate>::Iterator it;
00360     if( license_combo->currentItem() == 0 )
00361     {
00362         for (it = m_fileTemplates.begin(); it != m_fileTemplates.end(); ++it)
00363         {
00364             QMultiLineEdit *edit = (*it).edit;
00365             edit->setText( QString::null );
00366         }
00367     } else {
00368         KDevLicense* lic = m_part->core()->licenses()[ license_combo->currentText() ];
00369         for (it = m_fileTemplates.begin(); it != m_fileTemplates.end(); ++it) {
00370             QString style = (*it).style;
00371             QMultiLineEdit *edit = (*it).edit;
00372             
00373             KDevFile::CommentingStyle commentStyle = KDevFile::CPPStyle;
00374             if (style == "PStyle") {
00375                 commentStyle = KDevFile::PascalStyle;
00376             } else if (style == "AdaStyle") {
00377                 commentStyle = KDevFile::AdaStyle;
00378             } else if (style == "ShellStyle") {
00379                 commentStyle = KDevFile::BashStyle;
00380             }
00381             
00382             QString text;
00383             text = lic->assemble( commentStyle, author_edit->text(), email_edit->text() , 0 );
00384             edit->setText(text);
00385         }
00386     }
00387 }
00388 
00389 QString AppWizardDialog::kdevRoot(const QString &templateName ) const
00390 {
00391     QString source;
00392     QFileInfo finfo(templateName);
00393     QDir dir(finfo.dir());
00394     dir.cdUp();
00395     return dir.absPath();
00396 }
00397 
00398 void AppWizardDialog::accept()
00399 {
00400     QFileInfo fi(finalLoc_label->text());
00401     // check /again/ whether the dir already exists; maybe users create it in the meantime
00402     if (fi.exists()) {
00403         KMessageBox::sorry(this, i18n("The directory you have chosen as the location for "
00404                                       "the project already exists."));
00405         showPage(generalPage);
00406         appname_edit->setFocus();
00407         projectLocationChanged();
00408         return;
00409     }
00410     
00411     QString source = kdevRoot( m_pCurrentAppInfo->templateName );
00412 
00413     // Unpack template archive to temp dir, and get the name
00414     
00415     KTempDir archDir;
00416     archDir.setAutoDelete(true);
00417     KTar templateArchive( source + "/" + m_pCurrentAppInfo->sourceArchive, "application/x-gzip" );
00418     if( templateArchive.open( IO_ReadOnly ) )
00419     {
00420         //templateArchive.directory()->copyTo(archDir.name(), true);
00421         unpackArchive(templateArchive.directory(), archDir.name(), false);
00422     }
00423     else
00424     {
00425         KMessageBox::sorry(this, QString( i18n("The template %1 cannot be opened.")).arg( source + "/" + m_pCurrentAppInfo->sourceArchive ) );
00426         templateArchive.close();
00427         return;
00428     }
00429     templateArchive.close();
00430             
00431     // Build KMacroExpander map
00432     m_customOptions->dataForm()->fillPropertyMap(&m_pCurrentAppInfo->subMap); 
00433     
00434     m_pCurrentAppInfo->subMap.insert("src", archDir.name() );
00435     m_pCurrentAppInfo->subMap.insert("dest", finalLoc_label->text() );
00436     m_pCurrentAppInfo->subMap.insert("APPNAME", appname_edit->text() );
00437     m_pCurrentAppInfo->subMap.insert("APPNAMELC", appname_edit->text().lower() );
00438     m_pCurrentAppInfo->subMap.insert("APPNAMEUC", appname_edit->text().upper() );
00439     m_pCurrentAppInfo->subMap.insert("AUTHOR", author_edit->text() );
00440     m_pCurrentAppInfo->subMap.insert("EMAIL", email_edit->text() );
00441     m_pCurrentAppInfo->subMap.insert("VERSION", version_edit->text());
00442     m_pCurrentAppInfo->subMap.insert("LICENSE", license_combo->currentText() );
00443     m_pCurrentAppInfo->subMap.insert( "I18N", "i18n" );
00444 
00445     QStringList cleanUpSubstMap;
00446     cleanUpSubstMap << "src" << "I18N" << "kdevelop";
00447     
00448     // Add template files to the fileList
00449     installDir templateDir;
00450     templateDir.dir = "%{dest}/templates";
00451     m_pCurrentAppInfo->dirList.prepend(templateDir);
00452     
00453     installDir baseDir;
00454     baseDir.dir = "%{dest}";
00455     m_pCurrentAppInfo->dirList.prepend( baseDir );
00456     
00457     QValueList<AppWizardFileTemplate>::Iterator it;
00458     for (it = m_fileTemplates.begin(); it != m_fileTemplates.end(); ++it) {
00459         KTempFile *tempFile = new KTempFile();
00460         m_tempFiles.append(tempFile);
00461 
00462         QString templateText( (*it).edit->text() );
00463         QFile f;
00464         f.open(IO_WriteOnly, tempFile->handle());
00465         QTextStream temps(&f);
00466         temps << templateText;
00467         f.flush();
00468         QString templateName( QString( "%1_TEMPLATE" ).arg( (*it).suffix ).upper() );
00469         cleanUpSubstMap << templateName;
00470         m_pCurrentAppInfo->subMap.insert( templateName, KMacroExpander::expandMacros(templateText , m_pCurrentAppInfo->subMap)  );
00471 
00472         installFile file;
00473         file.source = tempFile->name();
00474         file.dest = QString( "%{dest}/templates/%1" ).arg( (*it).suffix );
00475         file.process = true;
00476         file.isXML = false;
00477         m_pCurrentAppInfo->fileList.append( file );
00478     }
00479     
00480     // Add license file to the file list
00481     QString licenseFile, licenseName = i18n("Custom");
00482     
00483     if( license_combo->currentItem() != 0 )
00484     {
00485         licenseName = license_combo->currentText();
00486         KDevLicense* lic = m_part->core()->licenses()[ licenseName ];
00487         if( lic )
00488         {
00489             QStringList files( lic->copyFiles() );
00490             QStringList::Iterator it = files.begin();
00491             for( ; it != files.end(); ++it )
00492             {
00493                 installFile file;
00494                 file.source = QString( "%{kdevelop}/template-common/%1" ).arg( *it );
00495                 file.dest = QString("%{dest}/%1").arg( *it );
00496                 file.process = true;
00497                 file.isXML = false;
00498                 m_pCurrentAppInfo->fileList.append( file );
00499             }
00500             
00501             m_pCurrentAppInfo->subMap.insert("LICENSEFILE", files.first()  ); 
00502         }
00503     }
00504     
00505     // Run macro expander on both the dir map and file maps
00506     QValueList<installFile>::Iterator fileIt = m_pCurrentAppInfo->fileList.begin();
00507     for( ; fileIt != m_pCurrentAppInfo->fileList.end(); ++fileIt)
00508     {
00509         (*fileIt).source = KMacroExpander::expandMacros((*fileIt).source , m_pCurrentAppInfo->subMap);
00510         (*fileIt).dest = KMacroExpander::expandMacros((*fileIt).dest , m_pCurrentAppInfo->subMap);
00511     }
00512     
00513     QValueList<installArchive>::Iterator archIt = m_pCurrentAppInfo->archList.begin();
00514     for( ; archIt != m_pCurrentAppInfo->archList.end(); ++archIt)
00515     {
00516         (*archIt).source = KMacroExpander::expandMacros((*archIt).source , m_pCurrentAppInfo->subMap);
00517         (*archIt).dest = KMacroExpander::expandMacros((*archIt).dest , m_pCurrentAppInfo->subMap);
00518     }
00519     
00520     QValueList<installDir>::Iterator dirIt = m_pCurrentAppInfo->dirList.begin();
00521     for( ; dirIt != m_pCurrentAppInfo->dirList.end(); ++dirIt)
00522     {
00523         (*dirIt).dir = KMacroExpander::expandMacros((*dirIt).dir , m_pCurrentAppInfo->subMap);
00524     }
00525     
00526     QMap<QString,QString>::Iterator mapIt( m_pCurrentAppInfo->subMap.begin() );
00527     for( ; mapIt != m_pCurrentAppInfo->subMap.end(); ++mapIt )
00528     {
00529         QString escaped( mapIt.data() );
00530         escaped.replace( "&", "&amp;" );
00531         escaped.replace( "<", "&lt;" );
00532         escaped.replace( ">", "&gt;" );
00533         m_pCurrentAppInfo->subMapXML.insert( mapIt.key(), escaped );
00534     }
00535     
00536     // Create dirs
00537     dirIt = m_pCurrentAppInfo->dirList.begin();
00538     for( ; dirIt != m_pCurrentAppInfo->dirList.end(); ++dirIt)
00539     {
00540         kdDebug( 9000 ) << "Process dir " << (*dirIt).dir  << endl;
00541         if( m_pCurrentAppInfo->subMap[(*dirIt).option] != "false" )
00542         {
00543             if( ! KIO::NetAccess::mkdir( (*dirIt).dir, this ) )
00544             {
00545                 KMessageBox::sorry(this, QString( i18n("The directory %1 cannot be created.")).arg( (*dirIt).dir ) );
00546                 return;
00547             }
00548         }
00549     }
00550     // Unpack archives
00551     archIt = m_pCurrentAppInfo->archList.begin();
00552     for( ; archIt != m_pCurrentAppInfo->archList.end(); ++archIt)
00553     {
00554         if( m_pCurrentAppInfo->subMap[(*archIt).option] != "false" )
00555         {
00556             kdDebug( 9010 ) << "unpacking archive " << (*archIt).source << endl;
00557             KTar archive( (*archIt).source, "application/x-gzip" );
00558             if( archive.open( IO_ReadOnly ) )
00559             {
00560                 unpackArchive( archive.directory(), (*archIt).dest, (*archIt).process );
00561             }
00562             else
00563             {
00564                 KMessageBox::sorry(this, QString( i18n("The archive %1 cannot be opened.")).arg( (*archIt).source ) );
00565                 archive.close();
00566                 return;
00567             }
00568             archive.close();
00569         }
00570     
00571     }
00572     
00573     // Copy files & Process
00574     fileIt = m_pCurrentAppInfo->fileList.begin();
00575     for( ; fileIt != m_pCurrentAppInfo->fileList.end(); ++fileIt)
00576     {
00577         kdDebug( 9000 ) << "Process file " << (*fileIt).source << endl;
00578         if( m_pCurrentAppInfo->subMap[(*fileIt).option] != "false" )
00579         {
00580             if( !copyFile( *fileIt ) )
00581             {
00582                 KMessageBox::sorry(this, QString( i18n("The file %1 cannot be created.")).arg( (*fileIt).dest) );
00583                 return;
00584             }
00585             setPermissions(*fileIt);
00586         }
00587     }
00588     // if dir still does not exist
00589     if (!fi.dir().exists()) {
00590       KMessageBox::sorry(this, i18n("The directory above the chosen location does not exist and cannot be created."));
00591       showPage(generalPage);
00592       dest_edit->setFocus();
00593       return;
00594     }
00595 /* 
00596     if (m_vcsForm->stack->id(m_vcsForm->stack->visibleWidget())) {
00597         KDevVersionControl* pVC = m_part->versionControlByName( m_vcsForm->combo->currentText() );
00598         if (pVC) {
00599             kdDebug( 9000 ) << "Creating new project with selected VCS ..." << endl;
00600             pVC->createNewProject(finalLoc_label->text());
00601         }
00602         else
00603         {
00604             kdDebug( 9000 ) << "Could not grab the selected VCS: " << m_vcsForm->combo->currentText() << endl;
00605         }
00606     }
00607 */    
00608     KMessageBox::information(this, KMacroExpander::expandMacros(m_pCurrentAppInfo->message, m_pCurrentAppInfo->subMap));
00609     
00610     QStringList::Iterator cleanIt = cleanUpSubstMap.begin();
00611     for(;cleanIt != cleanUpSubstMap.end(); ++cleanIt )
00612     {
00613         m_pCurrentAppInfo->subMap.remove( *cleanIt );
00614     }
00615 
00616     openAfterGeneration();
00617     
00618     QWizard::accept();
00619 }
00620 
00621 bool AppWizardDialog::copyFile( const installFile& file )
00622 {
00623     return
00624         copyFile( file.source, file.dest, file.isXML, file.process );
00625 }
00626 
00627 bool AppWizardDialog::copyFile( const QString &source, const QString &dest, bool isXML, bool process )
00628 {
00629     kdDebug( 9010 ) << "Copy: " << source << " to " << dest << endl;
00630     if( process )
00631     {
00632         // Process the file and save it at the destFile location
00633         QFile inputFile( source);
00634         QFile outputFile( dest );
00635         const QMap<QString,QString> &subMap = isXML ?
00636             m_pCurrentAppInfo->subMapXML : m_pCurrentAppInfo->subMap;
00637         if( inputFile.open( IO_ReadOnly ) && outputFile.open(IO_WriteOnly) )
00638         {
00639             QTextStream input( &inputFile );
00640             QTextStream output( &outputFile );
00641             while( !input.atEnd() )
00642                 output << KMacroExpander::expandMacros(input.readLine(), subMap) << "\n";
00643         }
00644         else
00645         {
00646             inputFile.close();
00647             outputFile.close();
00648             return false;
00649         }
00650     }
00651     else
00652     {
00653         // Copy the source file to the destFile.
00654         return KIO::NetAccess::copy( source, dest, this );
00655     }
00656     return true;
00657 }
00658 
00659 void AppWizardDialog::unpackArchive( const KArchiveDirectory *dir, const QString &dest, bool process )
00660 {
00661     KIO::NetAccess::mkdir( dest , this );
00662     kdDebug() << "Dir : " << dir->name() << " at " << dest << endl;
00663     QStringList entries = dir->entries();
00664     kdDebug() << "Entries : " << entries.join(",") << endl;
00665     
00666     KTempDir tdir;
00667     
00668     QStringList::Iterator entry = entries.begin();
00669     for( ; entry != entries.end(); ++entry )
00670     {
00671         
00672         if( dir->entry( (*entry) )->isDirectory()  )
00673         {
00674             const KArchiveDirectory *file = (KArchiveDirectory *)dir->entry( (*entry) );
00675             unpackArchive( file , dest + "/" + file->name(), process);
00676         }
00677         else if( dir->entry( (*entry) )->isFile()  )
00678         {
00679             const KArchiveFile *file = (KArchiveFile *) dir->entry( (*entry) );
00680             if( !process )
00681             {
00682                 file->copyTo( dest );
00683                 setPermissions(file, dest + "/" + file->name());
00684             }
00685             else
00686             {
00687                 file->copyTo(tdir.name());
00688                 // assume that an archive does not contain XML files
00689                 // ( where should we currently get that info from? )
00690                 if ( !copyFile( QDir::cleanDirPath(tdir.name()+"/"+file->name()), dest + "/" + file->name(), false, process ) )
00691                 {
00692                     KMessageBox::sorry(this, QString( i18n("The file %1 cannot be created.")).arg( dest) );
00693                     return;
00694                 }
00695                 setPermissions(file, dest + "/" + file->name());
00696             }
00697         }
00698     }
00699     tdir.unlink();
00700 }
00701 
00702 void AppWizardDialog::templatesTreeViewClicked(QListViewItem *item)
00703 {
00704     if( m_customOptions )
00705         delete m_customOptions;
00706         
00707     // Delete old file template pages
00708     while (!m_fileTemplates.isEmpty()) {
00709         QMultiLineEdit *edit = m_fileTemplates.first().edit;
00710         removePage(edit);
00711         delete edit;
00712         m_fileTemplates.remove(m_fileTemplates.begin());
00713     }
00714     m_lastPage = 0;
00715 
00716     ApplicationInfo *info = templateForItem(item);
00717     if (info) {
00718         m_pCurrentAppInfo = info;
00719         if (!info->icon.isEmpty()) {
00720             QFileInfo fi(info->templateName);
00721             QDir dir(fi.dir());
00722             dir.cdUp();
00723             QPixmap pm;
00724             pm.load(dir.filePath(info->icon));
00725             icon_label->setPixmap(pm);
00726         } else {
00727             icon_label->clear();
00728         }
00729         desc_textview->setText(info->comment);
00730 //        dest_edit->setURL(info->defaultDestDir);
00731         m_projectLocationWasChanged = false;
00732         //projectNameChanged(); // set the dest new
00733 
00734         // Populate new custom options form
00735         m_customOptions = new AutoForm( &m_pCurrentAppInfo->subValues, custom_options );
00736         
00737         custom_options->adjustSize();
00738         
00739         // Create new file template pages
00740         QStringList l = QStringList::split(",", info->fileTemplates);
00741         QStringList::ConstIterator it = l.begin();
00742         while (it != l.end()) {
00743             AppWizardFileTemplate fileTemplate;
00744             fileTemplate.suffix = *it;
00745             ++it;
00746             if (it != l.end()) {
00747                 fileTemplate.style = *it;
00748                 ++it;
00749             } else
00750                 fileTemplate.style = "";
00751 
00752             QMultiLineEdit *edit = new QMultiLineEdit(this);
00753             edit->setWordWrap(QTextEdit::NoWrap);
00754             edit->setFont(KGlobalSettings::fixedFont());
00755             if (it == l.end())
00756                 m_lastPage = edit;
00757             fileTemplate.edit = edit;
00758             addPage(edit, i18n("Template for .%1 Files").arg(fileTemplate.suffix));
00759             m_fileTemplates.append(fileTemplate);
00760         }
00761         textChanged(); // calls licenseChanged() && update Next button state
00762     } else {
00763     m_customOptions=0;
00764         m_pCurrentAppInfo=0;
00765         icon_label->clear();
00766         desc_textview->clear();
00767         nextButton()->setEnabled(false);
00768     }
00769 }
00770 
00771 
00772 void AppWizardDialog::destButtonClicked(const QString& dir)
00773 {
00774     if(!dir.isEmpty()) {
00775 
00776         // set new location as default project dir?
00777         KConfig *config = kapp->config();
00778         config->setGroup("General Options");
00779         QDir defPrjDir( config->readPathEntry("DefaultProjectsDir", QDir::homeDirPath()) );
00780         QDir newDir (dir);
00781         kdDebug(9010) << "DevPrjDir == newdir?: " << defPrjDir.absPath() << " == " << newDir.absPath() << endl;
00782         if (defPrjDir != newDir) {
00783             if (KMessageBox::questionYesNo(this, i18n("Set default project location to: ") + newDir.absPath() + "?",
00784                                            i18n("New Project")) == KMessageBox::Yes)
00785             {
00786                 config->writePathEntry("DefaultProjectsDir", newDir.absPath() + "/");
00787                 config->sync();
00788             }
00789         }
00790     }
00791 }
00792 
00793 
00794 void AppWizardDialog::projectNameChanged()
00795 {
00796     // Location was already edited by hand => don't change
00797 }
00798 
00799 
00800 void AppWizardDialog::projectLocationChanged()
00801 {
00802   // Jakob Simon-Gaarde: Got tired of the anoying bug with the appname/location confussion.
00803   // This version insures WYSIWYG and checks pathvalidity
00804   finalLoc_label->setText(dest_edit->url() + (dest_edit->url().right(1)=="/" ? "":"/") + appname_edit->text().lower());
00805   QDir qd(dest_edit->url());
00806   QFileInfo fi(dest_edit->url() + "/" + appname_edit->text().lower());
00807   if (!qd.exists() || appname_edit->displayText().isEmpty()||fi.exists())
00808   {
00809     if (!fi.exists() || appname_edit->displayText().isEmpty()) {
00810       finalLoc_label->setText(finalLoc_label->text() + i18n("invalid location", " (invalid)"));
00811     } else {
00812       finalLoc_label->setText(finalLoc_label->text() + i18n(" (dir/file already exist)"));
00813     }
00814     m_pathIsValid=false;
00815   } else {
00816     m_pathIsValid=true;
00817   }
00818     updateNextButtons();
00819 }
00820 
00821 
00822 void AppWizardDialog::insertCategoryIntoTreeView(const QString &completeCategoryPath)
00823 {
00824     kdDebug(9010) << "TemplateCategory: " << completeCategoryPath << endl;
00825     QStringList categories = QStringList::split("/", completeCategoryPath);
00826     QString category ="";
00827     QListViewItem* pParentItem=0;
00828 
00829     QStringList::ConstIterator it;
00830     for (it = categories.begin(); it != categories.end(); ++it) {
00831         category = category + "/" + *it;
00832         QListViewItem *item = m_categoryMap.find(category);
00833         if (!item) { // not found, create it
00834             if (!pParentItem)
00835                 pParentItem = new KListViewItem(templates_listview,*it);
00836             else
00837                 pParentItem = new KListViewItem(pParentItem,*it);
00838 
00839             pParentItem->setPixmap(0, SmallIcon("folder"));
00840             //pParentItem->setOpen(true);
00841             kdDebug(9010) << "Category: " << category << endl;
00842             m_categoryMap.insert(category,pParentItem);
00843         } else {
00844             pParentItem = item;
00845         }
00846     }
00847 }
00848 
00849 
00850 ApplicationInfo *AppWizardDialog::templateForItem(QListViewItem *item)
00851 {
00852     QPtrListIterator<ApplicationInfo> it(m_appsInfo);
00853     for (; it.current(); ++it)
00854         if (it.current()->item == item)
00855             return it.current();
00856 
00857     return 0;
00858 }
00859 
00860 void AppWizardDialog::openAfterGeneration()
00861 {
00862     QString projectFile( finalLoc_label->text() + "/" + appname_edit->text().lower() + ".kdevelop" );
00863     
00864     // Read the DOM of the newly created project
00865     QFile file( projectFile );
00866     if( !file.open( IO_ReadOnly ) )
00867         return;
00868     QDomDocument projectDOM;
00869     projectDOM.setContent( &file );
00870     file.close();
00871 
00872     // DOM Modifications go here
00873     DomUtil::writeMapEntry( projectDOM, "substmap", m_pCurrentAppInfo->subMap );
00874 
00876 
00877     QStringList loadList = QStringList::split( ',', "KDevBookmarks,KDevCTags2,KDevClassView,KDevFileView,KDevQuickOpen" );
00878     QString lang = DomUtil::readEntry(projectDOM, "/general/primarylanguage");
00879     if ((lang == "C") || (lang == "C++"))
00880         loadList << "KDevDebugger" << "KDevDoxygen";
00881     QString bs = DomUtil::readEntry(projectDOM, "/general/projectmanagement");
00882     if ((bs == "KDevAutoProject") || (bs == "KDevKDEAutoProject"))
00883         loadList << "KDevdistpart";
00884     QStringList ignoreList;
00885 
00886     KTrader::OfferList offers = KTrader::self()->query("KDevelop/Plugin", "[X-KDevelop-Scope] == 'Project'");
00887     KTrader::OfferList::ConstIterator itt = offers.begin();
00888     while( itt != offers.end() )
00889     {
00890         if ( !loadList.contains( (*itt)->name() ) )
00891         {
00892             ignoreList << (*itt)->name();
00893         }
00894         ++itt;
00895     }
00896 
00897     DomUtil::writeListEntry( projectDOM, "/general/ignoreparts", "part", ignoreList );
00898 
00900 
00901     // write the dom back
00902     if( !file.open( IO_WriteOnly ) )
00903         return;
00904     QTextStream ts( &file );
00905     ts << projectDOM.toString(2);
00906     file.close();
00907     
00908     // open the new project
00909     m_part->core()->openProject( projectFile );
00910     
00911     // open files to open
00912     QStringList::Iterator it = m_pCurrentAppInfo->openFilesAfterGeneration.begin();
00913     for( ; it != m_pCurrentAppInfo->openFilesAfterGeneration.end(); ++it )
00914     {
00915         QString fileName( *it );
00916         if ( !fileName.isNull() )
00917         {
00918             fileName = KMacroExpander::expandMacros(fileName, m_pCurrentAppInfo->subMap);
00919             m_part->partController()->editDocument( fileName );
00920         }
00921     }
00922 }
00923 
00924 void AppWizardDialog::pageChanged()
00925 {
00926     kdDebug(9010) << "AppWizardDialog::pageChanged()" << endl;
00927     projectLocationChanged();
00928 }
00929 
00930 void AppWizardDialog::addTemplateToFavourites()
00931 {
00932     addFavourite(templates_listview->currentItem());
00933 }
00934 
00935 void AppWizardDialog::addFavourite(QListViewItem* item, QString favouriteName)
00936 {
00937     if(item->childCount())  
00938         return;
00939         
00940     ApplicationInfo* info = templateForItem(item);
00941     
00942     if(!info->favourite)
00943     {
00944         info->favourite = new KIconViewItem(favourites_iconview, 
00945                                             ((favouriteName=="")?info->name:favouriteName), 
00946                                             DesktopIcon("kdevelop"));
00947                                             
00948         info->favourite->setRenameEnabled(true);
00949     }
00950 }
00951 
00952 ApplicationInfo* AppWizardDialog::findFavouriteInfo(QIconViewItem* item)
00953 {
00954     QPtrListIterator<ApplicationInfo> info(m_appsInfo);
00955     for (; info.current(); ++info)
00956         if (info.current()->favourite == item)
00957             return info.current();
00958 
00959     return 0;
00960 }
00961 
00962 void AppWizardDialog::favouritesIconViewClicked( QIconViewItem* item)
00963 {
00964     ApplicationInfo* info = findFavouriteInfo(item);
00965     templatesTreeViewClicked(info->item);
00966 }
00967 
00968 void AppWizardDialog::removeFavourite()
00969 {
00970     QIconViewItem* curFavourite = favourites_iconview->currentItem();
00971     
00972     //remove reference to favourite from associated appinfo
00973     QPtrListIterator<ApplicationInfo> info(m_appsInfo);
00974     for (; info.current(); ++info)
00975     {
00976         if(info.current()->favourite && info.current()->favourite == curFavourite)
00977         {
00978             info.current()->favourite = 0;
00979         }
00980     }
00981     
00982     //remove favourite from iconview
00983     delete curFavourite;
00984     curFavourite=0;
00985     favourites_iconview->sort();    //re-arrange all items.
00986 }
00987 
00988 void AppWizardDialog::populateFavourites()
00989 {
00990     KConfig* config = kapp->config();
00991     config->setGroup("AppWizard");
00992     
00993     //favourites are stored in config as a list of templates and a seperate
00994     //list of icon names.  
00995     QStringList templatesList = config->readPathListEntry("FavTemplates");
00996     QStringList iconNamesList = config->readListEntry("FavNames");
00997     
00998     QStringList::Iterator curTemplate = templatesList.begin();
00999     QStringList::Iterator curIconName = iconNamesList.begin();
01000     while(curTemplate != templatesList.end())
01001     {
01002         QPtrListIterator<ApplicationInfo> info(m_appsInfo);
01003         for (; info.current(); ++info) 
01004         {
01005             if(info.current()->templateName == *curTemplate)
01006             {
01007                 addFavourite(info.current()->item, *curIconName);
01008                 break;
01009             }
01010         }
01011         curTemplate++;
01012         curIconName++;
01013     }
01014 }
01015 
01016 void AppWizardDialog::done(int r)
01017 {
01018     //need to save the template for each favourite and
01019     //it's icon name.  We have a one list for the templates
01020     //and one for the names.
01021     
01022     QStringList templatesList;
01023     QStringList iconNamesList;
01024     
01025     //Built the stringlists for each template that has a favourite.
01026     QPtrListIterator<ApplicationInfo> it(m_appsInfo);
01027     for (; it.current(); ++it)
01028     {
01029         if(it.current()->favourite)
01030         {
01031             templatesList.append(it.current()->templateName);
01032             iconNamesList.append(it.current()->favourite->text());
01033         }
01034     }
01035     
01036     KConfig* config = kapp->config();
01037     config->setGroup("AppWizard");
01038     config->writePathEntry("FavTemplates", templatesList);
01039     config->writeEntry("FavNames", iconNamesList);
01040     //config->writeEntry("CurrentTab", templates_tabwidget->currentPageIndex());
01041     config->sync();
01042 
01043     QDialog::done(r);
01044 }
01045 
01046 void AppWizardDialog::templatesContextMenu(QListViewItem* item, const QPoint& point, int)
01047 {
01048     if(item && !item->childCount())
01049         m_templatesMenu->popup(point);
01050 }
01051 
01052 void AppWizardDialog::favouritesContextMenu(QIconViewItem* item, const QPoint& point)
01053 {
01054     if(item)
01055         m_favouritesMenu->popup(point);
01056 }
01057 
01058 void AppWizardDialog::setPermissions(const KArchiveFile *source, QString dest)
01059 {
01060     kdDebug() << "AppWizardDialog::setPermissions(const KArchiveFile *source, QString dest)" << endl;
01061     kdDebug() << "  dest: " << dest << endl;
01062     
01063     if (source->permissions() & 00100)
01064     {
01065         kdDebug() << "source is executable" << endl;
01066         KIO::UDSEntry entry;
01067         KURL kurl = KURL::fromPathOrURL(dest);
01068         if (KIO::NetAccess::stat(kurl, entry, 0))
01069         {
01070             KFileItem it(entry, kurl);
01071             int mode = it.permissions();
01072             kdDebug() << "stat shows permissions: " << mode << endl;
01073             KIO::chmod(KURL::fromPathOrURL(dest), mode | 00100 );
01074         }
01075     }
01076 }
01077 
01078 void AppWizardDialog::setPermissions(const installFile &file)
01079 {
01080     kdDebug() << "AppWizardDialog::setPermissions(const installFile &file)" << endl;
01081     kdDebug() << "  dest: " << file.dest << endl;
01082     
01083     KIO::UDSEntry sourceentry;
01084     KURL sourceurl = KURL::fromPathOrURL(file.source);
01085     if (KIO::NetAccess::stat(sourceurl, sourceentry, 0))
01086     {
01087         KFileItem sourceit(sourceentry, sourceurl);
01088         int sourcemode = sourceit.permissions();
01089         if (sourcemode & 00100)
01090         {
01091             kdDebug() << "source is executable" << endl;
01092             KIO::UDSEntry entry;
01093             KURL kurl = KURL::fromPathOrURL(file.dest);
01094             if (KIO::NetAccess::stat(kurl, entry, 0))
01095             {
01096                 KFileItem it(entry, kurl);
01097                 int mode = it.permissions();
01098                 kdDebug() << "stat shows permissions: " << mode << endl;
01099                 KIO::chmod(KURL::fromPathOrURL(file.dest), mode | 00100 );
01100             }
01101         }
01102     }
01103 }
01104 
01105 #include "appwizarddlg.moc"
01106 
01107 // kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;
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