KDevelop API Documentation

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