KDevelop API Documentation

autosubprojectview.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                              -------------------
00003     begin                : 19.01.2003
00004     copyright            : (C) 2002 by Victor Rder
00005     email                : victor_roeder@gmx.de
00006  ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU General Public License as published by  *
00012  *   the Free Software Foundation; either version 2 of the License, or     *
00013  *   (at your option) any later version.                                   *
00014  *                                                                         *
00015  ***************************************************************************/
00016 
00018 #include <qregexp.h>
00019 #include <qcheckbox.h>
00020 #include <qstringlist.h>
00021 
00023 #include <kaction.h>
00024 #include <kdebug.h>
00025 #include <klocale.h>
00026 #include <kpopupmenu.h>
00027 #include <kmessagebox.h>
00028 #include <kapplication.h>
00029 #include <kprocess.h>
00030 #include <ksqueezedtextlabel.h>
00031 
00033 #include <kdevmainwindow.h>
00034 #include <kdevmakefrontend.h>
00035 
00037 #include "subprojectoptionsdlg.h"
00038 #include "addsubprojectdlg.h"
00039 #include "addtargetdlg.h"
00040 #include "addservicedlg.h"
00041 #include "addapplicationdlg.h"
00042 #include "addexistingdirectoriesdlg.h"
00043 #include "autolistviewitems.h"
00044 #include "autoprojectwidget.h"
00045 #include "autoprojectpart.h"
00046 #include "autosubprojectview.h"
00047 #include "removesubprojectdialog.h"
00048 
00049 namespace AutoProjectPrivate
00050 {
00051 
00052 bool isHeader( const QString& fileName )
00053 {
00054     return QStringList::split( ";", "h;H;hh;hxx;hpp;tcc;h++" ).contains( QFileInfo(fileName).extension(false) );
00055 }
00056 
00057 static QString cleanWhitespace( const QString &str )
00058 {
00059     QString res;
00060 
00061     QStringList l = QStringList::split( QRegExp( "[ \t]" ), str );
00062     QStringList::ConstIterator it;
00063     for ( it = l.begin(); it != l.end(); ++it )
00064     {
00065         res += *it;
00066         res += " ";
00067     }
00068 
00069     return res.left( res.length() - 1 );
00070 }
00071 
00072 static void removeDir( const QString& dirName )
00073 {
00074     QDir d( dirName );
00075     const QFileInfoList* fileList = d.entryInfoList();
00076     if( !fileList )
00077     return;
00078 
00079     QFileInfoListIterator it( *fileList );
00080     while( it.current() ){
00081     const QFileInfo* fileInfo = it.current();
00082     ++it;
00083 
00084     if( fileInfo->fileName() == "." || fileInfo->fileName() == ".." )
00085         continue;
00086 
00087     if( fileInfo->isDir() && !fileInfo->isSymLink() )
00088         removeDir( fileInfo->absFilePath() );
00089 
00090     kdDebug(9020) << "remove " << fileInfo->absFilePath() << endl;
00091     d.remove( fileInfo->fileName(), false );
00092     }
00093 
00094     kdDebug(9020) << "remove dir " << dirName << endl;
00095     d.rmdir( d.absPath(), true );
00096 }
00097 
00098 }
00099 
00100 
00101 AutoSubprojectView::AutoSubprojectView(AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name)
00102   : KListView(parent, name)
00103 {
00104     m_widget = widget;
00105     m_part = part;
00106 
00107     initActions();
00108 }
00109 
00110 
00111 AutoSubprojectView::~AutoSubprojectView()
00112 {
00113 }
00114 
00115 void AutoSubprojectView::loadMakefileams ( const QString& dir )
00116 {
00117     SubprojectItem * item = new SubprojectItem( this, m_part->projectDirectory() + "/" + m_part->projectName() + ".kdevelop" );
00118     item->setPixmap ( 0, SmallIcon ( "kdevelop" ) );
00119     item->subdir = "/";
00120     item->path = dir;
00121     parse( item );
00122     item->setOpen( true );
00123 
00124     setSelected( item, true );
00125 }
00126 
00127 
00128 void AutoSubprojectView::initActions()
00129 {
00130     KActionCollection * actions = new KActionCollection( this );
00131 
00132     subProjectOptionsAction = new KAction( i18n( "Options..." ), "configure", 0,
00133                                            this, SLOT( slotSubprojectOptions() ), actions, "subproject options" );
00134     subProjectOptionsAction->setWhatsThis(i18n("<b>Options</b><p>Shows subproject options dialog that provides settings for compiler, include paths, prefixes and build order."));
00135     addSubprojectAction = new KAction( i18n( "Add Subproject..." ), "folder_new", 0,
00136                                        this, SLOT( slotAddSubproject() ), actions, "add subproject" );
00137     addSubprojectAction->setWhatsThis(i18n("<b>Add subproject</b><p>Creates a new subproject in currently selected subproject."));
00138     removeSubprojectAction = new KAction( i18n( "Remove Subproject..." ), "remove_subdir", 0,
00139                                        this, SLOT( slotRemoveSubproject() ), actions, "remove subproject" );
00140     removeSubprojectAction->setWhatsThis(i18n("<b>Remove subproject</b><p>Removes the subproject. Asks if the subproject should be also removed from disk. Only subprojects which do not hold other subprojects can be removed."));
00141     addExistingSubprojectAction = new KAction( i18n( "Add Existing Subprojects..." ), "fileimport", 0,
00142                                                this, SLOT( slotAddExistingSubproject() ), actions, "add existing subproject" );
00143     addExistingSubprojectAction->setWhatsThis(i18n("<b>Add existing subprojects</b><p>Imports existing subprojects containing Makefile.am."));
00144     addTargetAction = new KAction( i18n( "Add Target..." ), "targetnew_kdevelop", 0,
00145                                    this, SLOT( slotAddTarget() ), actions, "add target" );
00146     addTargetAction->setWhatsThis(i18n("<b>Add target</b><p>Adds a new target to the currently selected subproject. Target can be a binary program, library, script, also a collection of data or header files."));
00147     addServiceAction = new KAction( i18n( "Add Service..." ), "servicenew_kdevelop", 0,
00148                                     this, SLOT( slotAddService() ), actions, "add service" );
00149     addServiceAction->setWhatsThis(i18n("<b>Add service</b><p>Creates a .desktop file describing the service."));
00150     addApplicationAction = new KAction( i18n( "Add Application..." ), "window_new", 0,
00151                                         this, SLOT( slotAddApplication() ), actions, "add application" );
00152     addApplicationAction->setWhatsThis(i18n("<b>Add application</b><p>Creates an application .desktop file."));
00153     buildSubprojectAction = new KAction( i18n( "Build" ), "launch", 0,
00154                                          this, SLOT( slotBuildSubproject() ), actions, "add build subproject" );
00155     buildSubprojectAction->setWhatsThis(i18n("<b>Build</b><p>Runs <b>make</b> from the directory of the selected subproject.<br>"
00156                                              "Environment variables and make arguments can be specified "
00157                                              "in the project settings dialog, <b>Make Options</b> tab."));
00158     forceReeditSubprojectAction = new KAction( i18n( "Force Reedit" ), 0, 0,
00159                                          this, SLOT( slotForceReeditSubproject() ), actions, "force-reedit subproject" );
00160     forceReeditSubprojectAction->setWhatsThis(i18n("<b>Force Reedit</b><p>Runs <b>make force-reedit</b> from the directory of the selected subproject.<br>"
00161                                                    "This recreates makefile (tip: and solves most of .moc related problems)<br>"
00162                                                    "Environment variables and make arguments can be specified "
00163                                                    "in the project settings dialog, <b>Make Options</b> tab."));
00164     cleanSubprojectAction = new KAction( i18n( "Clean" ), 0, 0,
00165                                          this, SLOT( slotCleanSubproject() ), actions, "clean subproject" );
00166     cleanSubprojectAction->setWhatsThis(i18n("<b>Clean</b><p>Runs <b>make clean</b> from the directory of the selected subproject.<br>"
00167                                              "Environment variables and make arguments can be specified "
00168                                              "in the project settings dialog, <b>Make Options</b> tab."));
00169     if (!m_part->isKDE())
00170         forceReeditSubprojectAction->setEnabled(false);
00171     installSubprojectAction = new KAction( i18n( "Install" ), 0, 0,
00172                                          this, SLOT( slotInstallSubproject() ), actions, "install subproject" );
00173     installSubprojectAction->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> from the directory of the selected subproject.<br>"
00174                                              "Environment variables and make arguments can be specified "
00175                                              "in the project settings dialog, <b>Make Options</b> tab."));
00176     installSuSubprojectAction = new KAction( i18n( "Install (as root user)" ), 0, 0,
00177                                          this, SLOT( slotInstallSuSubproject() ), actions, "install subproject as root" );
00178     installSuSubprojectAction->setWhatsThis(i18n("<b>Install as root user</b><p>Runs <b>make install</b> command from the directory of the selected subproject with root privileges.<br>"
00179                               "It is executed via kdesu command.<br>"
00180                               "Environment variables and make arguments can be specified "
00181                               "in the project settings dialog, <b>Make Options</b> tab."));
00182 
00183     connect( this, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ),
00184              this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint& ) ) );
00185 /*  connect ( this, SIGNAL ( executed ( QListViewItem* ),
00186             this, SLOT ( slotSubprojectExecuted ( QListViewItem* ) ) );
00187     connect ( this, SIGNAL ( returnPressed ( QListViewItem* ),
00188             this, SLOT ( slotSubprojectExecuted ( QListViewItem* ) ) );*/
00189 }
00190 
00191 void AutoSubprojectView::slotContextMenu( KListView *, QListViewItem *item, const QPoint &p )
00192 {
00193     if ( !item )
00194         return ;
00195 
00196     KPopupMenu popup( i18n( "Subproject: %1" ).arg( item->text( 0 ) ), this );
00197 
00198     subProjectOptionsAction->plug( &popup );
00199     popup.insertSeparator();
00200     addSubprojectAction->plug( &popup );
00201     addTargetAction->plug( &popup );
00202     addServiceAction->plug( &popup );
00203     addApplicationAction->plug( &popup );
00204     popup.insertSeparator();
00205     addExistingSubprojectAction->plug( &popup );
00206     popup.insertSeparator();
00207     removeSubprojectAction->plug( &popup );
00208     popup.insertSeparator();
00209     buildSubprojectAction->plug( &popup );
00210     popup.insertSeparator();
00211     forceReeditSubprojectAction->plug( &popup );
00212     cleanSubprojectAction->plug( &popup );
00213     popup.insertSeparator();
00214     installSubprojectAction->plug( &popup );
00215     installSuSubprojectAction->plug( &popup );
00216 
00217     popup.exec( p );
00218 }
00219 /*
00220 void AutoSubprojectView::slotSubprojectExecuted ( QListViewItem* item )
00221 {
00222     emit selectionChanged ( item );
00223 }*/
00224 
00225 void AutoSubprojectView::slotSubprojectOptions()
00226 {
00227     kdDebug( 9020 ) << "AutoSubprojectView::slotSubprojectOptions()" << endl;
00228 
00229     SubprojectItem* spitem = static_cast <SubprojectItem*> ( selectedItem() );
00230     if ( !spitem )  return;
00231 
00232     SubprojectOptionsDialog dlg( m_part, m_widget, spitem, this, "subproject options dialog" );
00233     dlg.exec();
00234 }
00235 
00236 
00237 void AutoSubprojectView::slotAddSubproject()
00238 {
00239     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00240     if ( !spitem )  return;
00241 
00242     AddSubprojectDialog dlg( m_part, this, spitem, this, "add subproject dialog" );
00243 
00244     dlg.setCaption ( i18n ( "Add New Subproject to '%1'" ).arg ( spitem->subdir ) );
00245     dlg.exec();
00246 }
00247 
00248 
00249 void AutoSubprojectView::slotAddExistingSubproject()
00250 {
00251     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00252     if ( !spitem )  return;
00253 
00254     AddExistingDirectoriesDialog dlg ( m_part, m_widget, spitem, this, "add existing subprojects" );
00255 
00256     dlg.setCaption ( i18n ( "Add Existing Subproject to '%1'" ).arg ( spitem->subdir ) );
00257     dlg.targetLabel->setText("");
00258     dlg.directoryLabel->setText(spitem->path);
00259 
00260     if ( dlg.exec() )
00261         emit selectionChanged ( spitem );
00262 }
00263 
00264 void AutoSubprojectView::slotAddTarget()
00265 {
00266     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00267     if ( !spitem )  return;
00268 
00269     AddTargetDialog dlg( m_widget, spitem, this, "add target dialog" );
00270 
00271     dlg.setCaption ( i18n ( "Add New Target to '%1'" ).arg ( spitem->subdir ) );
00272 
00273     // Update the details view if a target was added
00274     if ( dlg.exec() )
00275         emit selectionChanged( spitem );
00276 }
00277 
00278 
00279 void AutoSubprojectView::slotAddService()
00280 {
00281     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00282     if ( !spitem )  return;
00283 
00284     AddServiceDialog dlg( m_widget, spitem, this, "add service dialog" );
00285 
00286     dlg.setCaption ( i18n ( "Add New Service to '%1'" ).arg ( spitem->subdir ) );
00287 
00288     // Update the details view if a service was added
00289     if ( dlg.exec() )
00290         emit selectionChanged( spitem );
00291 }
00292 
00293 
00294 void AutoSubprojectView::slotAddApplication()
00295 {
00296     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00297     if ( !spitem )  return;
00298 
00299     AddApplicationDialog dlg( m_widget, spitem, this, "add application dialog" );
00300 
00301     dlg.setCaption ( i18n ( "Add New Application to '%1'" ).arg ( spitem->subdir ) );
00302 
00303     // Update the details view if an application was added
00304     if ( dlg.exec() )
00305         emit selectionChanged( spitem );
00306 }
00307 
00308 
00309 void AutoSubprojectView::slotBuildSubproject()
00310 {
00311     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00312     if ( !spitem )  return;
00313 
00314     QString relpath = spitem->path.mid( m_part->projectDirectory().length() );
00315 
00316     m_part->startMakeCommand( m_part->buildDirectory() + relpath, QString::fromLatin1( "" ) );
00317 }
00318 
00319 void AutoSubprojectView::slotRemoveSubproject()
00320 {
00321     kdDebug(9020) << "AutoSubprojectView::slotRemoveSubproject()" << endl;
00322 
00323     SubprojectItem* spitem = static_cast<SubprojectItem*>( selectedItem() );
00324     if( !spitem )
00325     return;
00326 
00327     SubprojectItem* parent = static_cast<SubprojectItem*>( spitem->parent() );
00328     if( !parent || !parent->listView() || spitem->childCount() != 0 ){
00329     KMessageBox::error( 0, i18n("This item cannot be removed"), i18n("Automake Manager") );
00330     return;
00331     }
00332 
00333     // check for config.status
00334     if( !QFileInfo(m_part->buildDirectory(), "config.status").exists() ){
00335     KMessageBox::sorry(this, i18n("There is no config.status in the project root build directory. Run 'Configure' first"));
00336     return;
00337     }
00338 
00339     QStringList list = QStringList::split( QRegExp("[ \t]"), parent->variables["SUBDIRS"] );
00340     QStringList::Iterator it = list.find( spitem->subdir );
00341     QString subdirToRemove = spitem->subdir;
00342     bool topsubdirs = true;
00343     if ((parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") == -1)
00344         && (parent->variables["SUBDIRS"].find("$(AUTODIRS)") == -1))
00345     {
00346         topsubdirs = false;
00347         if( it == list.end() ){
00348             KMessageBox::sorry(this, i18n("There is no subproject %1 in SUBDIRS").arg(spitem->subdir));
00349             return;
00350         }
00351     }
00352 
00353     RemoveSubprojectDialog dlg;
00354     dlg.setCaption(i18n("Remove Subproject %1").arg(spitem->text(0)));
00355     dlg.removeLabel->setText(i18n("Do you really want to remove subproject %1 with all targets and files?").arg(spitem->text(0)));
00356     if( dlg.exec() ){
00357 
00358     bool removeSources = dlg.removeCheckBox->isChecked();
00359 
00360     if (!topsubdirs)
00361     {
00362     list.remove( it );
00363     parent->variables[ "SUBDIRS" ] = list.join( " " );
00364     }
00365 
00366     parent->listView()->setSelected( parent, true );
00367     kapp->processEvents( 500 );
00368 
00369 
00370     if( removeSources ){
00371         kdDebug(9020) << "remove dir " << spitem->path << endl;
00372         AutoProjectPrivate::removeDir( spitem->path );
00373     }
00374 
00375     if( m_widget->activeSubproject() == spitem ){
00376         m_widget->setActiveSubproject( 0 );
00377     }
00378 
00379     // Adjust AC_OUTPUT in configure.in
00380     if ( !m_part->isKDE() ) {
00381 
00382         QString projroot = m_part->projectDirectory() + "/";
00383         QString subdirectory = spitem->path;
00384         QString relpath = subdirectory.replace(0, projroot.length(),"");
00385 
00386         QString configurein = projroot + "configure.in";
00387 
00388         QStringList list = AutoProjectTool::configureinLoadMakefiles(configurein);
00389 
00390         QStringList::iterator it;
00391 
00392         for ( it = list.begin(); it != list.end(); it++ ) {
00393             QString current = (QString) (*it);
00394             QRegExp path_regex(relpath);
00395             if ( path_regex.search(current) >= 0) {
00396                 list.remove(it);
00397                 break;
00398             }
00399         }
00400         AutoProjectTool::configureinSaveMakefiles(configurein, list);
00401 
00402     }
00403 
00404     // remove all targets
00405     spitem->targets.setAutoDelete( true );
00406     spitem->targets.clear();
00407     delete( spitem );
00408     spitem = 0;
00409 
00410     // Adjust SUBDIRS variable in containing Makefile.am
00411     QMap<QString,QString> replaceMap;
00412     if (parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1)
00413     {
00414         QFile subdirsfile( parent->path + "/subdirs" );
00415         QStringList topdirs;
00416         if ( subdirsfile.open( IO_ReadOnly ) )
00417         {
00418             QTextStream subdirsstream( &subdirsfile );
00419             while (!subdirsstream.atEnd())
00420                 topdirs.append(subdirsstream.readLine());
00421             subdirsfile.close();
00422         }
00423         topdirs.remove(subdirToRemove);
00424         if ( subdirsfile.open( IO_WriteOnly | IO_Truncate ) )
00425         {
00426             QTextStream subdirsstream( &subdirsfile );
00427             for (QStringList::const_iterator it = topdirs.begin(); it != topdirs.end(); ++it)
00428                 subdirsstream << *it << endl;
00429             subdirsfile.close();
00430         }
00431     }
00432     replaceMap.insert( "SUBDIRS", parent->variables["SUBDIRS"] );
00433     AutoProjectTool::modifyMakefileam( parent->path + "/Makefile.am", replaceMap );
00434 
00435     QString relmakefile = ( parent->path + "/Makefile" ).mid( m_part->projectDirectory().length()+1 );
00436     kdDebug(9020) << "Relative makefile path: " << relmakefile << endl;
00437 
00438     QString cmdline = "cd ";
00439     cmdline += KProcess::quote(m_part->projectDirectory());
00440     cmdline += " && automake ";
00441     cmdline += KProcess::quote(relmakefile);
00442     cmdline += " && cd ";
00443     cmdline += KProcess::quote(m_part->buildDirectory());
00444     cmdline += " && CONFIG_HEADERS=config.h CONFIG_FILES=";
00445     cmdline += KProcess::quote(relmakefile);
00446     cmdline += " ./config.status";
00447     m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), cmdline );
00448     }
00449 }
00450 
00451 
00452 void AutoSubprojectView::parsePrimary( SubprojectItem *item,
00453                                       const QString &lhs, const QString &rhs )
00454 {
00455     // Parse line foo_bar = bla bla
00456 
00457     int pos = lhs.findRev( '_' );
00458     QString prefix = lhs.left( pos );
00459     QString primary = lhs.right( lhs.length() - pos - 1 );
00460     //    kdDebug(9020) << "Prefix:" << prefix << ",Primary:" << primary << endl;
00461 
00462 
00463 #if 0
00464 
00465     QStrList prefixes;
00466     prefixes.append( "bin" );
00467     prefixes.append( "pkglib" );
00468     prefixes.append( "pkgdata" );
00469     prefixes.append( "noinst" );
00470     prefixes.append( "check" );
00471     prefixes.append( "sbin" );
00472     QStrList primaries;
00473     primaries.append( "PROGRAMS" );
00474     primaries.append( "LIBRARIES" );
00475     primaries.append( "LTLIBRARIES" );
00476     primaries.append( "SCRIPTS" );
00477     primaries.append( "HEADERS" );
00478     primaries.append( "DATA" );
00479 #endif
00480 
00481     // Not all combinations prefix/primary are possible, so this
00482     // could also be checked... not trivial because the list of
00483     // possible prefixes can be extended dynamically (see below)
00484     if ( primary == "PROGRAMS" || primary == "LIBRARIES" || primary == "LTLIBRARIES" )
00485     {
00486         QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs );
00487         QStringList::Iterator it1;
00488         for ( it1 = l.begin(); it1 != l.end(); ++it1 )
00489         {
00490             TargetItem *titem = m_widget->createTargetItem( *it1, prefix, primary );
00491             item->targets.append( titem );
00492 
00493             QString canonname = AutoProjectTool::canonicalize( *it1 );
00494             titem->ldflags = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDFLAGS" ] );
00495             titem->ldadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDADD" ] );
00496             titem->libadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LIBADD" ] );
00497             titem->dependencies = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_DEPENDENCIES" ] );
00498 
00499             QString sources = item->variables[ canonname + "_SOURCES" ];
00500             QStringList sourceList = QStringList::split( QRegExp( "[ \t\n]" ), sources );
00501             QMap<QString, bool> dict;
00502             QStringList::Iterator it = sourceList.begin();
00503             while( it != sourceList.end() ){
00504                 dict.insert( *it, true );
00505                 ++it;
00506             }
00507 
00508             QMap<QString, bool>::Iterator dictIt = dict.begin();
00509             while( dictIt != dict.end() ){
00510                 QString fname = dictIt.key();
00511                 ++dictIt;
00512 
00513                 FileItem *fitem = m_widget->createFileItem( fname, item );
00514                 titem->sources.append( fitem );
00515 
00516                 if( AutoProjectPrivate::isHeader(fname) )
00517                     headers += fname;
00518             }
00519             }
00520     }
00521     else if ( primary == "SCRIPTS" || primary == "HEADERS" || primary == "DATA" )
00522     {
00523         // See if we have already such a group
00524         for ( uint i = 0; i < item->targets.count(); ++i )
00525         {
00526             TargetItem *titem = item->targets.at( i );
00527             if ( primary == titem->primary && prefix == titem->prefix )
00528             {
00529                 item->targets.remove( i );
00530                 break;
00531             }
00532         }
00533         // Create a new one
00534         TargetItem *titem = m_widget->createTargetItem( "", prefix, primary );
00535         item->targets.append( titem );
00536 
00537         QStringList l = QStringList::split( QRegExp( "[ \t]" ), rhs );
00538         QStringList::Iterator it3;
00539         for ( it3 = l.begin(); it3 != l.end(); ++it3 )
00540         {
00541             QString fname = *it3;
00542             FileItem *fitem = m_widget->createFileItem( fname, item );
00543             titem->sources.append( fitem );
00544 
00545             if( AutoProjectPrivate::isHeader(fname) )
00546                 headers += fname;
00547 
00548         }
00549     }
00550     else if ( primary == "JAVA" )
00551     {
00552         QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs );
00553         QStringList::Iterator it1;
00554         TargetItem *titem = m_widget->createTargetItem( "", prefix, primary );
00555         item->targets.append( titem );
00556 
00557         for ( it1 = l.begin(); it1 != l.end(); ++it1 )
00558         {
00559             FileItem *fitem = m_widget->createFileItem( *it1, item );
00560             titem->sources.append( fitem );
00561         }
00562     }
00563 }
00564 
00565 
00566 void AutoSubprojectView::parseKDEDOCS( SubprojectItem *item,
00567                                       const QString & /*lhs*/, const QString & /*rhs*/ )
00568 {
00569     // Handle the line KDE_ICON =
00570     // (actually, no parsing is involved here)
00571 
00572     QString prefix = "kde_docs";
00573     QString primary = "KDEDOCS";
00574 
00575     TargetItem *titem = m_widget->createTargetItem( "", prefix, primary );
00576     item->targets.append( titem );
00577 
00578     QDir d( item->path );
00579     QStringList l = d.entryList( QDir::Files );
00580 
00581     QRegExp re( "Makefile.*|\\..*|.*~|index.cache.bz2" );
00582 
00583     QStringList::ConstIterator it;
00584     for ( it = l.begin(); it != l.end(); ++it )
00585     {
00586         if ( !re.exactMatch( *it ) )
00587         {
00588             QString fname = *it;
00589             FileItem * fitem = m_widget->createFileItem( fname, item );
00590             titem->sources.append( fitem );
00591         }
00592     }
00593 }
00594 
00595 
00596 void AutoSubprojectView::parseKDEICON( SubprojectItem *item,
00597                                       const QString &lhs, const QString &rhs )
00598 {
00599     // Parse a line foo_ICON = bla bla
00600 
00601     int pos = lhs.find( "_ICON" );
00602     QString prefix = lhs.left( pos );
00603     if ( prefix == "KDE" )
00604         prefix = "kde_icon";
00605 
00606     QString primary = "KDEICON";
00607 
00608     TargetItem *titem = m_widget->createTargetItem( "", prefix, primary );
00609     item->targets.append( titem );
00610 
00611     QDir d( item->path );
00612     QStringList l = d.entryList( QDir::Files );
00613 
00614     QString regexp;
00615 
00616     if ( rhs == "AUTO" )
00617     {
00618         regexp = ".*\\.(png|mng|xpm)";
00619     }
00620     else
00621     {
00622         QStringList appNames = QStringList::split( QRegExp( "[ \t\n]" ), rhs );
00623         regexp = ".*(-" + appNames.join( "|-" ) + ")\\.(png|mng|xpm)";
00624     }
00625 
00626     QRegExp re( regexp );
00627 
00628     QStringList::ConstIterator it;
00629     for ( it = l.begin(); it != l.end(); ++it )
00630     {
00631         if ( re.exactMatch( *it ) )
00632         {
00633             FileItem * fitem = m_widget->createFileItem( *it, item );
00634             titem->sources.append( fitem );
00635         }
00636     }
00637 }
00638 
00639 
00640 void AutoSubprojectView::parsePrefix( SubprojectItem *item,
00641                                      const QString &lhs, const QString &rhs )
00642 {
00643     // Parse a line foodir = bla bla
00644     QString name = lhs.left( lhs.length() - 3 );
00645     QString dir = rhs;
00646     item->prefixes.insert( name, dir );
00647 }
00648 
00649 
00650 void AutoSubprojectView::parseSUBDIRS( SubprojectItem *item,
00651                                       const QString & /*lhs*/, const QString &rhs )
00652 {
00653     // Parse a line SUBDIRS = bla bla
00654     QString subdirs = rhs;
00655     kdDebug( 9020 ) << "subdirs are " << subdirs << endl;
00656 
00657     // Take care of KDE hacks:
00658     // TOPSUBDIRS is an alias for all directories
00659     // listed in the subdirs file
00660     if ( subdirs.find( "$(TOPSUBDIRS)" ) != -1 )
00661     {
00662         QStringList dirs;
00663         QFile subdirsfile( item->path + "/subdirs" );
00664         if ( subdirsfile.open( IO_ReadOnly ) )
00665         {
00666             QTextStream subdirsstream( &subdirsfile );
00667             while ( !subdirsstream.atEnd() )
00668                 dirs.append( subdirsstream.readLine() );
00669             subdirsfile.close();
00670         }
00671         subdirs.replace( QRegExp( "\\$\\(TOPSUBDIRS\\)" ), dirs.join( " " ) );
00672     }
00673 
00674     // AUTODIRS is an alias for all subdirectories
00675     if ( subdirs.find( "$(AUTODIRS)" ) != -1 )
00676     {
00677         QDir d( item->path );
00678         QStringList dirs = d.entryList( QDir::Dirs );
00679         dirs.remove( "." );
00680         dirs.remove( ".." );
00681         dirs.remove( "CVS" );
00682         subdirs.replace( QRegExp( "\\$\\(AUTODIRS\\)" ), dirs.join( " " ) );
00683     }
00684 
00685     // If there are any variables in the subdirs line then search
00686     // the Makefile(.am?) for its definition. Unfortunately, it may be
00687     // defined outside this file in which case those dirs won't be added.
00688     QRegExp varre( "\\$\\(\\s*(.*)\\s*\\)" );
00689     varre.setMinimal( true );
00690     while ( varre.search( subdirs ) != -1 )
00691     {
00692         QString varname = varre.cap( 1 );
00693         QString varvalue;
00694 
00695         // Search the whole Makefile(.am?)
00696         // Note that if the variable isn't found it just disappears
00697         // (Perhaps we should add it back in this case?)
00698         QMap<QString, QString>::ConstIterator varit = item->variables.find( varname );
00699         if ( varit != item->variables.end() )
00700         {
00701             kdDebug( 9020 ) << "Found Makefile var " << varname << ", adding dirs <" << varit.data() << ">" << endl;
00702             varvalue = varit.data();
00703         }
00704         else
00705         {
00706             kdDebug( 9020 ) << "Not found Makefile var " << varname << endl;
00707         }
00708         subdirs.replace( QRegExp( "\\$\\(\\s*" + varname + "\\s*\\)" ), varvalue );
00709     }
00710 
00711     QStringList l = QStringList::split( QRegExp( "[ \t]" ), subdirs );
00712     l.sort();
00713     QStringList::Iterator it;
00714     for ( it = l.begin(); it != l.end(); ++it )
00715     {
00716         if ( *it == "." )
00717             continue;
00718         SubprojectItem *newitem = new SubprojectItem( item, ( *it ) );
00719         newitem->subdir = ( *it );
00720         newitem->path = item->path + "/" + ( *it );
00721         parse( newitem );
00722         // Experience tells me this :-)
00723         bool open = true;
00724         if ( newitem->subdir == "doc" )
00725             open = false;
00726         if ( newitem->subdir == "po" )
00727             open = false;
00728         if ( newitem->subdir == "pics" )
00729             open = false;
00730         if ( newitem && static_cast<SubprojectItem*>( newitem->parent() )
00731                 ->subdir == "doc" )
00732             open = false;
00733         if ( newitem && static_cast<SubprojectItem*>
00734                 ( newitem->parent() ) ->subdir == "po" )
00735             open = false;
00736         if ( newitem && static_cast<SubprojectItem*>
00737                 ( newitem->parent() ) ->subdir == "pics" )
00738             open = false;
00739         newitem->setOpen( open );
00740 
00741         // Move to the bottom of the list
00742         QListViewItem *lastItem = item->firstChild();
00743         while ( lastItem->nextSibling()
00744               )
00745             lastItem = lastItem->nextSibling();
00746         if ( lastItem != newitem )
00747             newitem->moveItem( lastItem );
00748     }
00749 }
00750 
00751 void AutoSubprojectView::parse( SubprojectItem *item )
00752 {
00753     headers.clear();
00754     AutoProjectTool::parseMakefileam( item->path + "/Makefile.am", &item->variables );
00755 
00756     QMap<QString, QString>::ConstIterator it;
00757     for ( it = item->variables.begin(); it != item->variables.end(); ++it )
00758     {
00759         QString lhs = it.key();
00760         QString rhs = it.data();
00761         if ( lhs == "KDE_DOCS" )
00762             parseKDEDOCS( item, lhs, rhs );
00763         else if ( lhs.right( 5 ) == "_ICON" )
00764             parseKDEICON( item, lhs, rhs );
00765         else if ( lhs.find( '_' ) > 0 )
00766             parsePrimary( item, lhs, rhs );
00767         else if ( lhs.right( 3 ) == "dir" )
00768             parsePrefix( item, lhs, rhs );
00769         else if ( lhs == "SUBDIRS" )
00770             parseSUBDIRS( item, lhs, rhs );
00771     }
00772 
00774     TargetItem* noinst_HEADERS_item = findNoinstHeaders(item);
00775 
00776     QDir dir( item->path );
00777     QStringList headersList = QStringList::split( QRegExp("[ \t]"), item->variables[ "noinst_HEADERS" ] );
00778 
00779     headersList += dir.entryList( "*.h;*.H;*.hh;*.hxx;*.hpp;*.tcc", QDir::Files );
00780     headersList.sort();
00781     headersList = QStringList::split(QRegExp("[ \t]"), headersList.join( " " ));
00782 
00783     QStringList::Iterator fileIt = headersList.begin();
00784     while( fileIt != headersList.end() ){
00785         QString fname = *fileIt;
00786         ++fileIt;
00787 
00788         if( AutoProjectPrivate::isHeader(fname) && !headers.contains(fname) ){
00789             FileItem *fitem = m_widget->createFileItem( fname, item );
00790             noinst_HEADERS_item->sources.append( fitem );
00791         }
00792     }
00793 }
00794 
00795 void AutoSubprojectView::slotForceReeditSubproject( )
00796 {
00797     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00798     if ( !spitem )  return;
00799 
00800     QString relpath = spitem->path.mid( m_part->projectDirectory().length() );
00801 
00802     m_part->startMakeCommand( m_part->buildDirectory() + relpath, "force-reedit" );
00803 }
00804 
00805 void AutoSubprojectView::slotInstallSubproject( )
00806 {
00807     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00808     if ( !spitem )  return;
00809 
00810     QString relpath = spitem->path.mid( m_part->projectDirectory().length() );
00811 
00812     m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install" );
00813 }
00814 
00815 void AutoSubprojectView::slotInstallSuSubproject( )
00816 {
00817     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00818     if ( !spitem )  return;
00819 
00820     QString relpath = spitem->path.mid( m_part->projectDirectory().length() );
00821 
00822     m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install", true );
00823 }
00824 
00825 TargetItem * AutoSubprojectView::findNoinstHeaders( SubprojectItem *item )
00826 {
00827     TargetItem* noinst_HEADERS_item = 0;
00828     QPtrListIterator<TargetItem> itemIt( item->targets );
00829     while( itemIt.current() ){
00830         TargetItem* titem = itemIt.current();
00831         ++itemIt;
00832 
00833         if( titem->prefix == "noinst" && titem->primary == "HEADERS" ){
00834             noinst_HEADERS_item = titem;
00835         break;
00836         }
00837     }
00838 
00839     if( !noinst_HEADERS_item ){
00840         noinst_HEADERS_item = m_widget->createTargetItem( "", "noinst", "HEADERS" );
00841         item->targets.append( noinst_HEADERS_item );
00842     }
00843 
00844     return noinst_HEADERS_item;
00845 }
00846 
00847 void AutoSubprojectView::slotCleanSubproject( )
00848 {
00849     SubprojectItem* spitem = static_cast <SubprojectItem*>  ( selectedItem() );
00850     if ( !spitem )  return;
00851 
00852     QString relpath = spitem->path.mid( m_part->projectDirectory().length() );
00853 
00854     m_part->startMakeCommand( m_part->buildDirectory() + relpath, "clean" );
00855 }
00856 
00857 void AutoSubprojectView::focusOutEvent( QFocusEvent */* e*/ )
00858 {
00859     m_widget->setLastFocusedView(AutoProjectWidget::SubprojectView);
00860 }
00861 
00862 #include "autosubprojectview.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:21 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003