00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00186
00187
00188
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
00221
00222
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
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
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
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
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
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
00405 spitem->targets.setAutoDelete( true );
00406 spitem->targets.clear();
00407 delete( spitem );
00408 spitem = 0;
00409
00410
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
00456
00457 int pos = lhs.findRev( '_' );
00458 QString prefix = lhs.left( pos );
00459 QString primary = lhs.right( lhs.length() - pos - 1 );
00460
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
00482
00483
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
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
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 & , const QString & )
00568 {
00569
00570
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
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
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 & , const QString &rhs )
00652 {
00653
00654 QString subdirs = rhs;
00655 kdDebug( 9020 ) << "subdirs are " << subdirs << endl;
00656
00657
00658
00659
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
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
00686
00687
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
00696
00697
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
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
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 * )
00858 {
00859 m_widget->setLastFocusedView(AutoProjectWidget::SubprojectView);
00860 }
00861
00862 #include "autosubprojectview.moc"