/*************************************************************************** * Copyright (C) 2001 by Bernd Gehrmann * * bernd@kdevelop.org * * Copyright (C) 2000-2001 by Trolltech AS. * * info@trolltech.com * * Copyright (C) 2002 by Jakob Simon-Gaarde * * jakob@jsg.dk * * Copyright (C) 2002-2003 by Alexander Dymo * * cloudtemple@mksat.net * * Copyright (C) 2003 by Thomas Hasart * * thasart@gmx.de * * Copyright (C) 2006 by Andreas Pakulat * * apaku@gmx.de * * * * Part of this file is taken from TQt Designer. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "trollprojectwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kdevcore.h" #include "kdevpartcontroller.h" #include "kdevmainwindow.h" #include "trollprojectpart.h" #include "kdevappfrontend.h" #include "kdevmakefrontend.h" #include "kdevlanguagesupport.h" #include "kdevcreatefile.h" #include "subclassesdlg.h" #include "addfilesdialog.h" #include "urlutil.h" #include "trolllistview.h" #include "projectconfigurationdlg.h" #include "qmakescopeitem.h" #include "scope.h" #include "createscopedlg.h" #include "disablesubprojectdlg.h" #include TrollProjectWidget::TrollProjectWidget( TrollProjectPart *part ) : TQVBox( 0, "troll project widget" ), m_shownSubproject( 0 ), m_rootSubproject( 0 ), m_rootScope ( 0 ), m_part ( part ), m_configDlg( 0 ), m_filesCached(false) { TQSplitter * splitter = new TQSplitter(Qt::Vertical, this ); ////////////////// // PROJECT VIEW // ////////////////// overviewContainer = new TQVBox( splitter, "Projects" ); overviewContainer->setMargin ( 2 ); overviewContainer->setSpacing ( 2 ); // overviewContainer->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Minimum); // splitter->setResizeMode(overviewContainer, TQSplitter::FollowSizeHint); projectTools = new TQHBox( overviewContainer, "Project buttons" ); projectTools->setMargin ( 2 ); projectTools->setSpacing ( 2 ); // Add subdir addSubdirButton = new TQToolButton ( projectTools, "Add subproject button" ); addSubdirButton->setPixmap ( SmallIcon ( "folder-new" ) ); addSubdirButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, addSubdirButton->sizePolicy().hasHeightForWidth() ) ); addSubdirButton->setEnabled ( true ); TQToolTip::add( addSubdirButton, i18n( "Add subproject" ) ); TQWhatsThis::add( addSubdirButton, i18n( "Add subproject

Creates a new or adds an existing subproject to a currently selected subproject. " "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); // Create scope createScopeButton = new TQToolButton ( projectTools, "Create scope button" ); createScopeButton->setPixmap ( SmallIcon ( "qmake_scopenew" ) ); createScopeButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, createScopeButton->sizePolicy().hasHeightForWidth() ) ); createScopeButton->setEnabled ( true ); TQToolTip::add( createScopeButton, i18n( "Create scope" ) ); TQWhatsThis::add( createScopeButton, i18n( "Create scope

Creates TQMake scope in the project file in case the subproject is selected or creates nested scope in case the scope is selected." ) ); // build buildProjectButton = new TQToolButton ( projectTools, "Make button" ); buildProjectButton->setPixmap ( SmallIcon ( "make_tdevelop" ) ); buildProjectButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, buildProjectButton->sizePolicy().hasHeightForWidth() ) ); buildProjectButton->setEnabled ( true ); TQToolTip::add( buildProjectButton, i18n( "Build project" ) ); TQWhatsThis::add( buildProjectButton, i18n( "Build project

Runs make from the project directory.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); // rebuild rebuildProjectButton = new TQToolButton ( projectTools, "Rebuild button" ); rebuildProjectButton->setPixmap ( SmallIcon ( "rebuild" ) ); rebuildProjectButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, rebuildProjectButton->sizePolicy().hasHeightForWidth() ) ); rebuildProjectButton->setEnabled ( true ); TQToolTip::add( rebuildProjectButton, i18n( "Rebuild project" ) ); TQWhatsThis::add( rebuildProjectButton, i18n( "Rebuild project

Runs make clean and then make from the project directory.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); // run executeProjectButton = new TQToolButton ( projectTools, "Run button" ); executeProjectButton->setPixmap ( SmallIcon ( "application-x-executable" ) ); executeProjectButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, executeProjectButton->sizePolicy().hasHeightForWidth() ) ); executeProjectButton->setEnabled ( true ); TQToolTip::add( executeProjectButton, i18n( "Execute main program" ) ); TQWhatsThis::add( executeProjectButton, i18n( "Execute main program

Executes the main program specified in project settings, Run Options tab." ) ); // spacer TQWidget *spacer = new TQWidget( projectTools ); projectTools->setStretchFactor( spacer, 1 ); // Project configuration projectconfButton = new TQToolButton ( projectTools, "Project configuration button" ); projectconfButton->setPixmap ( SmallIcon ( "configure" ) ); projectconfButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, projectconfButton->sizePolicy().hasHeightForWidth() ) ); projectconfButton->setEnabled ( true ); TQToolTip::add( projectconfButton, i18n( "Subproject settings" ) ); TQWhatsThis::add( projectconfButton, i18n( "Subproject settings

Opens TQMake Subproject Configuration dialog for the currently selected subproject. " "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " "external libraries,
build order,
intermediate files locations,
compiler options." ) ); // Project button connections connect ( addSubdirButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotAddSubproject () ) ); connect ( createScopeButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotCreateScope () ) ); connect ( buildProjectButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotBuildProject () ) ); connect ( rebuildProjectButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotRebuildProject () ) ); connect ( executeProjectButton, TQT_SIGNAL ( clicked () ), m_part, TQT_SLOT ( slotBuildAndExecuteProject () ) ); connect ( projectconfButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotConfigureProject () ) ); // Project tree overview = new TrollListView( this, overviewContainer, SubprojectView, "project overview widget" ); // overview->setResizeMode( TQListView::LastColumn ); overview->setSorting( -1 ); overview->header() ->hide(); overview->addColumn( TQString() ); // Project tree connections connect( overview, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), this, TQT_SLOT( slotOverviewSelectionChanged( TQListViewItem* ) ) ); connect( overview, TQT_SIGNAL( contextMenu( TDEListView*, TQListViewItem*, const TQPoint& ) ), this, TQT_SLOT( slotOverviewContextMenu( TDEListView*, TQListViewItem*, const TQPoint& ) ) ); ///////////////// // DETAIL VIEW // ///////////////// // Details tree detailContainer = new TQVBox( splitter, "Details" ); detailContainer->setMargin ( 2 ); detailContainer->setSpacing ( 2 ); // detailContainer->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding); // Details Toolbar fileTools = new TQHBox( detailContainer, "Detail buttons" ); fileTools->setMargin ( 2 ); fileTools->setSpacing ( 2 ); // Add new file button newfileButton = new TQToolButton ( fileTools, "Create new file" ); newfileButton->setPixmap ( SmallIcon ( "document-new" ) ); newfileButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, newfileButton->sizePolicy().hasHeightForWidth() ) ); newfileButton->setEnabled ( true ); TQToolTip::add( newfileButton, i18n( "Create new file" ) ); TQWhatsThis::add( newfileButton, i18n( "Create new file

Creates a new file and adds it to a currently selected group." ) ); // Add existing files button addfilesButton = new TQToolButton ( fileTools, "Add existing files" ); addfilesButton->setPixmap ( SmallIcon ( "fileimport" ) ); addfilesButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, addfilesButton->sizePolicy().hasHeightForWidth() ) ); addfilesButton->setEnabled ( true ); TQToolTip::add( addfilesButton, i18n( "Add existing files" ) ); TQWhatsThis::add( addfilesButton, i18n( "Add existing files

Adds existing files to a currently selected group. It is " "possible to copy files to a current subproject directory, create symbolic links or " "add them with the relative path." ) ); // remove file button removefileButton = new TQToolButton ( fileTools, "Remove file" ); removefileButton->setPixmap ( SmallIcon ( "button_cancel" ) ); removefileButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, removefileButton->sizePolicy().hasHeightForWidth() ) ); removefileButton->setEnabled ( true ); TQToolTip::add( removefileButton, i18n( "Remove file" ) ); TQWhatsThis::add( removefileButton, i18n( "Remove file

Removes file from a current group. Does not remove file from disk." ) ); // build selected file buildFileButton = new TQToolButton ( fileTools, "Make file button" ); buildFileButton->setPixmap ( SmallIcon ( "compfile" ) ); buildFileButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, buildFileButton->sizePolicy().hasHeightForWidth() ) ); buildFileButton->setEnabled ( true ); TQToolTip::add( buildFileButton, i18n( "Compile file" ) ); TQWhatsThis::add( buildFileButton, i18n( "Compile file

Runs make filename.o command from the directory where 'filename' is the name of currently opened file.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); // build buildTargetButton = new TQToolButton ( fileTools, "Make sp button" ); buildTargetButton->setPixmap ( SmallIcon ( "make_tdevelop" ) ); buildTargetButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, buildTargetButton->sizePolicy().hasHeightForWidth() ) ); buildTargetButton->setEnabled ( true ); TQToolTip::add( buildTargetButton, i18n( "Build subproject" ) ); TQWhatsThis::add( buildTargetButton, i18n( "Build subproject

Runs make from the current subproject directory. " "Current subproject is a subproject selected in TQMake manager 'overview' window.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); // rebuild rebuildTargetButton = new TQToolButton ( fileTools, "Rebuild sp button" ); rebuildTargetButton->setPixmap ( SmallIcon ( "rebuild" ) ); rebuildTargetButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, rebuildTargetButton->sizePolicy().hasHeightForWidth() ) ); rebuildTargetButton->setEnabled ( true ); TQToolTip::add( rebuildTargetButton, i18n( "Rebuild subproject" ) ); TQWhatsThis::add( rebuildTargetButton, i18n( "Rebuild subproject

Runs make clean and then make from the current subproject directory. " "Current subproject is a subproject selected in TQMake manager 'overview' window.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); // run executeTargetButton = new TQToolButton ( fileTools, "Run sp button" ); executeTargetButton->setPixmap ( SmallIcon ( "application-x-executable" ) ); executeTargetButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, executeTargetButton->sizePolicy().hasHeightForWidth() ) ); executeTargetButton->setEnabled ( true ); TQToolTip::add( executeTargetButton, i18n( "Execute subproject" ) ); TQWhatsThis::add( executeTargetButton, i18n( "Execute subproject

Executes the target program for the currently selected subproject. " "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); // spacer spacer = new TQWidget( fileTools ); projectTools->setStretchFactor( spacer, 1 ); // Configure file button excludeFileFromScopeButton = new TQToolButton ( fileTools, "Exclude file" ); excludeFileFromScopeButton->setPixmap ( SmallIcon ( "configure_file" ) ); excludeFileFromScopeButton->setSizePolicy ( TQSizePolicy ( ( TQSizePolicy::SizeType ) 0, ( TQSizePolicy::SizeType ) 0, 0, 0, excludeFileFromScopeButton->sizePolicy().hasHeightForWidth() ) ); excludeFileFromScopeButton->setEnabled ( true ); TQToolTip::add( excludeFileFromScopeButton , i18n( "Exclude file" ) ); TQWhatsThis::add( excludeFileFromScopeButton , i18n( "Exclude file

Exclude the selected file from this scope." ) ); // detail tree details = new TrollListView( this, detailContainer, DetailsView, "details widget" ); details->setRootIsDecorated( true ); details->setResizeMode( TQListView::LastColumn ); details->setSorting( -1 ); details->header() ->hide(); details->addColumn( TQString() ); // Detail button connections connect ( addfilesButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotAddFiles () ) ); connect ( newfileButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotNewFile () ) ); connect ( removefileButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotRemoveFile () ) ); connect ( buildFileButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotBuildSelectedFile () ) ); connect ( excludeFileFromScopeButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotExcludeFileFromScopeButton() ) ); // Detail tree connections connect( details, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), this, TQT_SLOT( slotDetailsSelectionChanged( TQListViewItem* ) ) ); connect( details, TQT_SIGNAL( executed( TQListViewItem* ) ), this, TQT_SLOT( slotDetailsExecuted( TQListViewItem* ) ) ); connect( details, TQT_SIGNAL( contextMenu( TDEListView*, TQListViewItem*, const TQPoint& ) ), this, TQT_SLOT( slotDetailsContextMenu( TDEListView*, TQListViewItem*, const TQPoint& ) ) ); connect ( buildTargetButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotBuildTarget () ) ); connect ( rebuildTargetButton, TQT_SIGNAL ( clicked () ), this, TQT_SLOT ( slotRebuildTarget () ) ); connect ( executeTargetButton, TQT_SIGNAL ( clicked () ), m_part, TQT_SLOT ( slotBuildAndExecuteTarget () ) ); buildTargetButton->setEnabled( false ); rebuildTargetButton->setEnabled( false ); executeTargetButton->setEnabled( false ); m_configDlg = new ProjectConfigurationDlg( overview, this, this ); connect( m_part->dirWatch(), TQT_SIGNAL( dirty(const TQString&) ), this, TQT_SLOT( slotProjectDirty(const TQString&) ) ); } TrollProjectWidget::~TrollProjectWidget() { delete m_configDlg; } void TrollProjectWidget::openProject( const TQString &dirName ) { TQDomDocument & dom = *( m_part->projectDom() ); m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); TQString projectfile = DomUtil::readEntry( dom, "/kdevtrollproject/qmake/projectfile", "" ); m_showFilenamesOnly = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/enableFilenamesOnly", false ); m_showVariablesInTree = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/showVariablesInTree", true ); TQString proname; if( projectfile.isEmpty() ) { TQFileInfo fi( dirName ); TQDir dir( dirName ); // TQString proname = item->path + "/" + fi.baseName() + ".pro"; TQStringList l = dir.entryList( "*.pro" ); TQString profile; if( l.count() && l.findIndex( m_part->projectName() + ".pro") != -1 ) profile = m_part->projectName()+".pro"; else if( l.isEmpty() || ( l.count() && l.findIndex( fi.baseName() + ".pro") != -1 ) ) profile = fi.baseName()+".pro"; else profile = l[0]; proname = dirName + TQString( TQChar( TQDir::separator() ) ) + profile; } else { proname = projectfile; } kdDebug( 9024 ) << "Parsing " << proname << endl; m_rootScope = new Scope( qmakeEnvironment(), proname, m_part ); if( m_rootScope->scopeType() != Scope::InvalidScope ) { m_rootSubproject = new QMakeScopeItem( overview, m_rootScope->scopeName(), m_rootScope, this ); m_rootSubproject->setOpen( true ); if ( m_rootSubproject->firstChild() && m_rootSubproject->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) { overview->setSelected( m_rootSubproject->firstChild(), true ); } else { overview->setSelected( m_rootSubproject, true ); } }else { delete m_rootScope; m_rootScope = 0; } // kdDebug(9024) << "Adding " << allFiles().count() << " Files" << endl; // kdDebug(9024) << allFiles() << endl; } void TrollProjectWidget::createQMakeScopeItems() { } void TrollProjectWidget::closeProject() { m_rootSubproject = 0; overview->clear(); details->clear(); delete m_rootScope; } TQStringList TrollProjectWidget::allFiles() { if( !m_rootScope ) return TQStringList(); if( m_filesCached ) return m_allFilesCache; m_allFilesCache = m_rootScope->allFiles( m_rootScope->projectDir() ); m_filesCached = true; return m_allFilesCache; } TQString TrollProjectWidget::projectDirectory() { if ( !m_rootScope ) return TQString(); //confused return m_rootScope->projectDir(); } TQString TrollProjectWidget::subprojectDirectory() { if ( !m_shownSubproject ) return TQString(); return m_shownSubproject->scope->projectDir(); } void TrollProjectWidget::setupContext() { if ( !m_shownSubproject ) return ; bool buildable = true; bool runable = true; bool fileconfigurable = true; bool hasSourceFiles = true; bool hasSubdirs = false; TQStringList tmpl = m_shownSubproject->scope->variableValues( "TEMPLATE" ); if ( tmpl.findIndex( "lib" ) != -1 ) { runable = false; } else if ( tmpl.findIndex( "subdirs" ) != -1 ) { hasSubdirs = true; runable = false; hasSourceFiles = false; fileconfigurable = false; } if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) { runable = false; buildable = false; } // Setup toolbars according to context addSubdirButton->setEnabled( hasSubdirs ); buildTargetButton->setEnabled( buildable ); m_part->actionCollection() ->action( "build_build_target" ) ->setEnabled( buildable ); rebuildTargetButton->setEnabled( buildable ); m_part->actionCollection() ->action( "build_rebuild_target" ) ->setEnabled( buildable ); executeTargetButton->setEnabled( runable ); m_part->actionCollection() ->action( "build_execute_target" ) ->setEnabled( runable ); excludeFileFromScopeButton->setEnabled( !hasSubdirs ); newfileButton->setEnabled( !hasSubdirs ); removefileButton->setEnabled( !hasSubdirs ); addfilesButton->setEnabled( !hasSubdirs ); buildFileButton->setEnabled( !hasSubdirs ); details->setEnabled( hasSourceFiles ); } void TrollProjectWidget::slotOverviewSelectionChanged( TQListViewItem *item ) { TQString olddir = m_part->activeDirectory(); if ( !item ) { kdDebug(9024) << "Trying to select a non-existing item" << endl; return ; } cleanDetailView( m_shownSubproject ); m_shownSubproject = static_cast( item ); setupContext(); buildProjectDetailTree( m_shownSubproject, details ); TQDomDocument &dom = *( m_part->projectDom() ); DomUtil::writeEntry( dom, "/kdevtrollproject/general/activedir", m_shownSubproject->relativePath() ); if ( m_configDlg && m_configDlg->isShown() ) { m_configDlg->updateSubproject( m_shownSubproject ); } emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); } TQString TrollProjectWidget::getCurrentTarget() { if ( !m_shownSubproject ) return ""; TQString destdir = getCurrentDestDir(); if ( destdir.isEmpty() ) return getCurrentOutputFilename(); else return destdir + TQString( TQChar( TQDir::separator() ) ) + getCurrentOutputFilename(); } TQString TrollProjectWidget::getCurrentDestDir() { if ( !m_shownSubproject ) return ""; TQStringList destdir = m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ); return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ).front()); } TQString TrollProjectWidget::getCurrentOutputFilename() { if ( !m_shownSubproject ) return ""; if ( m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).isEmpty() ) { TQString exe = m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->fileName()); return exe.replace( TQRegExp( "\\.pro$" ), "" ); } else { return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).front()); } } void TrollProjectWidget::cleanDetailView( QMakeScopeItem *item ) { // If no children in detailview // it is a subdir template if ( item && details->childCount() ) { TQListViewItem* i = details->firstChild(); while( i ) { TQListViewItem* old = i; i = i->nextSibling(); details->takeItem(old); } // TQMapIterator it1 = item->groups.begin() ; // for ( ; it1 != item->groups.end(); ++it1 ) // { // // After AddTargetDialog, it can happen that an // // item is not yet in the list view, so better check... // if ( it1.data() ->parent() ) // while ( it1.data() ->firstChild() ) // it1.data() ->takeItem( it1.data() ->firstChild() ); // details->takeItem( it1.data() ); // } } } void TrollProjectWidget::buildProjectDetailTree( QMakeScopeItem *item, TDEListView *listviewControl ) { // Insert all GroupItems and all of their children into the view if ( !listviewControl || item->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) return ; TQMapIterator it2 = item->groups.begin(); TQListViewItem* lastItem = 0; for ( ; it2 != item->groups.end(); ++it2 ) { listviewControl->insertItem( it2.data() ); if(lastItem) it2.data()->moveItem(lastItem); lastItem = it2.data(); if ( it2.key() == GroupItem::InstallRoot ) { TQListViewItem* lastinstallitem = 0; TQPtrListIterator it3( it2.data() ->installs ); for ( ; it3.current(); ++it3 ) { it2.data() ->insertItem( *it3 ); if ( lastinstallitem ) it3.current()->moveItem(lastinstallitem); lastinstallitem = it3.current(); TQPtrListIterator it4( ( *it3 ) ->files ); TQListViewItem* lastfileitem = 0; for ( ; it4.current(); ++it4 ) { ( *it3 ) ->insertItem( *it4 ); if ( lastfileitem ) it4.current()->moveItem(lastfileitem); lastfileitem = it4.current(); } ( *it3 ) ->setOpen( true ); ( *it3 ) ->sortChildItems( 0, true ); } it2.data() ->setOpen( true ); it2.data() ->sortChildItems( 0, true ); } else { TQPtrListIterator it3( it2.data() ->files ); TQListViewItem* lastfileitem = 0; for ( ; it3.current(); ++it3 ) { it2.data() ->insertItem( *it3 ); if ( lastfileitem ) it3.current()->moveItem(lastfileitem); lastfileitem = it3.current(); } it2.data() ->setOpen( true ); it2.data() ->sortChildItems( 0, true ); } } listviewControl->setSelected( listviewControl->selectedItem(), false ); listviewControl->setCurrentItem( 0 ); } void TrollProjectWidget::slotDetailsExecuted( TQListViewItem *item ) { if ( !item ) return ; // We assume here that ALL items in both list views // are qProjectItem's qProjectItem *pvitem = static_cast( item ); if ( pvitem->type() != qProjectItem::File ) return ; FileItem *fitem = static_cast( pvitem ); TQString filePath; if( m_shownSubproject->scope->scopeType() == Scope::IncludeScope ) { filePath = m_shownSubproject->scope->parent()->projectDir(); }else { filePath = m_shownSubproject->scope->projectDir(); } filePath += TQChar( TQDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ); bool isUiFile = TQFileInfo( fitem->text( 0 ) ).extension() == "ui"; kdDebug(9024) << "Opening file: " << filePath << endl; if ( isTMakeProject() && isUiFile ) { // start designer in your PATH KShellProcess proc; proc << "designer" << filePath; proc.start( TDEProcess::DontCare, TDEProcess::NoCommunication ); } else m_part->partController() ->editDocument( KURL( filePath ) ); } void TrollProjectWidget::slotConfigureProject() { m_configDlg->updateSubproject( m_shownSubproject ); m_configDlg->show(); } void TrollProjectWidget::slotExecuteTarget() { //m_part->slotExecute(); // no subproject selected if ( !m_shownSubproject ) return ; // can't build from scope if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) return ; // Only run application projects if ( !m_shownSubproject->scope->variableValues( "TEMPLATE" ).isEmpty() && m_shownSubproject->scope->variableValues( "TEMPLATE" ).findIndex( "app" ) == -1 ) return ; //only run once if (m_part->appFrontend()->isRunning()) { if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) return; m_part->appFrontend()->stopApplication(); while(m_part->appFrontend()->isRunning()) { TDEApplication::kApplication()->processEvents(); usleep(100); } } TQString program = TDEProcess::quote( "." + TQString( TQChar( TQDir::separator() ) ) + getCurrentOutputFilename() ); // Build environment variables to prepend to the executable path TQString runEnvVars = TQString(); DomUtil::PairList list = DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); DomUtil::PairList::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) { const DomUtil::Pair &pair = ( *it ); if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) runEnvVars += pair.first + "=" + pair.second + " "; } program.prepend( runEnvVars ); program.append( " " + m_part->runArguments() + " " ); // std::cerr<execute(dircmd + "./"+program); // m_part->appFrontend()->startAppCommand(dircmd +"./"+program,true); bool inTerminal = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/run/terminal" ); m_part->appFrontend() ->startAppCommand( subprojectDirectory() + TQString( TQChar( TQDir::separator() ) ) + getCurrentDestDir(), program, inTerminal ); } void TrollProjectWidget::slotBuildProject() { if ( m_part->partController() ->saveAllFiles() == false ) return ; //user cancelled TQString dir = projectDirectory(); if ( !m_rootSubproject ) return ; createMakefileIfMissing( dir, m_rootSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ); m_part->queueCmd( dir, dircmd + buildcmd ); } void TrollProjectWidget::slotInstallProject() { if ( m_part->partController() ->saveAllFiles() == false ) return ; //user cancelled TQString dir = projectDirectory(); if ( !m_rootSubproject ) return ; createMakefileIfMissing( dir, m_rootSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " install"; m_part->queueCmd( dir, dircmd + buildcmd ); } void TrollProjectWidget::slotBuildTarget() { // no subproject selected m_part->partController() ->saveAllFiles(); if ( !m_shownSubproject ) return ; // can't build from scope if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) return ; TQString dir = subprojectDirectory(); createMakefileIfMissing( dir, m_shownSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ); m_part->queueCmd( dir, dircmd + buildcmd ); } void TrollProjectWidget::slotInstallTarget() { // no subproject selected m_part->partController() ->saveAllFiles(); if ( !m_shownSubproject ) return ; // can't build from scope if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) return ; TQString dir = subprojectDirectory(); createMakefileIfMissing( dir, m_shownSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " install"; m_part->queueCmd( dir, dircmd + buildcmd ); } void TrollProjectWidget::slotRebuildProject() { m_part->partController() ->saveAllFiles(); TQString dir = this-> projectDirectory(); if ( !m_rootSubproject ) return ; createMakefileIfMissing( dir, m_rootSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString rebuildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " clean && " + constructMakeCommandLine( m_rootSubproject->scope ); m_part->queueCmd( dir, dircmd + rebuildcmd ); } void TrollProjectWidget::slotRebuildTarget() { // no subproject selected m_part->partController() ->saveAllFiles(); if ( !m_shownSubproject ) return ; // can't build from scope if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) return ; TQString dir = subprojectDirectory(); createMakefileIfMissing( dir, m_shownSubproject ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString rebuildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " clean && " + constructMakeCommandLine( m_shownSubproject->scope ); m_part->queueCmd( dir, dircmd + rebuildcmd ); } void TrollProjectWidget::slotCreateScope( QMakeScopeItem *spitem ) { if ( spitem == 0 && m_shownSubproject == 0 ) return ; else spitem = m_shownSubproject; CreateScopeDlg dlg( spitem, this ); if ( dlg.exec() == TQDialog::Accepted ) { spitem->scope->saveToFile( ); spitem->sortChildItems( 0, true ); } return ; } void TrollProjectWidget::slotAddSubproject( QMakeScopeItem *spitem ) { if ( spitem == 0 && m_shownSubproject == 0 ) return ; else spitem = m_shownSubproject; m_filesCached = false; m_allFilesCache.clear(); TQString projectdir = spitem->scope->projectDir(); KURLRequesterDlg dialog( i18n( "Add Subproject" ), i18n( "Please enter a name for the subproject: " ), this, 0 ); KURLRequester* req = dialog.urlRequester(); req->setMode( KFile::Directory | KFile::File | KFile::LocalOnly ); req->setFilter( "*.pro|TQMake Project Files (*.pro)" ); req->setURL( TQString() ); req->fileDialog()->setURL( KURL::fromPathOrURL( projectdir ) ); req->completionObject() ->setDir( projectdir ); if ( dialog.exec() == TQDialog::Accepted && !dialog.urlRequester() ->url().isEmpty() ) { TQString subdirname; if ( !TQDir::isRelativePath( dialog.urlRequester() ->url() ) ) subdirname = URLUtil::getRelativePath( projectdir, dialog.urlRequester()->url() ); else subdirname = dialog.urlRequester()->url(); while( subdirname.endsWith( TQString(TQChar(TQDir::separator())) ) ) subdirname = subdirname.left(subdirname.length()-1); if( !subdirname.endsWith(".pro") ) { kdDebug(9024) << "Cleaned subdirname: " << subdirname << endl; TQDir dir( projectdir ); TQString realdir = spitem->scope->resolveVariables( subdirname ); if ( !dir.exists( realdir ) ) { if ( !dir.mkdir( realdir ) ) { KMessageBox::error( this, i18n( "Failed to create subdirectory. " "Do you have write permission " "in the project folder?" ) ); return ; }else { TQFile f( dir.absPath()+"/"+realdir+"/"+realdir+".pro" ); f.open( IO_WriteOnly ); f.close(); } } }else { TQString realdir = spitem->scope->resolveVariables( subdirname ); TQFile f( projectdir+"/"+realdir ); f.open( IO_WriteOnly ); f.close(); } addSubprojectToItem( spitem, subdirname ); } } void TrollProjectWidget::addSubprojectToItem( QMakeScopeItem* spitem, const TQString& subdirname ) { TQListViewItem* item = spitem->firstChild(); while( item ) { QMakeScopeItem* sitem = static_cast(item); if( sitem->scope->scopeName() == subdirname ) { if( sitem->scope->isEnabled() ) { return; }else { spitem->scope->removeFromMinusOp( "SUBDIRS", subdirname ); delete item; if( spitem->scope->variableValues( "SUBDIRS" ).findIndex( subdirname ) != -1 ) return; } } item = item->nextSibling(); } Scope* subproject = spitem->scope->createSubProject( subdirname ); if( subproject ) { new QMakeScopeItem( spitem, subproject->scopeName(), subproject ); // TQListViewItem* lastitem = spitem->firstChild(); // while( lastitem->nextSibling() != 0 ) // lastitem = lastitem->nextSibling(); // newitem->moveItem( lastitem ); }else { KMessageBox::error(this, i18n("Could not create subproject. This means that either the project you wanted" " to add a subproject to is not parsed correctly, or it is not a" " subdirs-project."), i18n("Subproject creation failed") ); } spitem->scope->saveToFile(); spitem->sortChildItems( 0, true ); } void TrollProjectWidget::slotRemoveSubproject( QMakeScopeItem *spitem ) { if ( spitem == 0 && m_shownSubproject == 0 ) return ; else if ( ( spitem = dynamic_cast( m_shownSubproject->parent() ) ) != NULL ) { m_filesCached = false; m_allFilesCache.clear(); bool delsubdir = false; if ( KMessageBox::warningYesNo( this, i18n( "Delete the file/directory of the subproject from disk?" ), i18n( "Delete subdir?" ) ) == KMessageBox::Yes ) delsubdir = true; if( !spitem->scope->deleteSubProject( m_shownSubproject->scope->getNum(), delsubdir ) ) { KMessageBox::error(this, i18n("Could not delete subproject.\nThis is an internal error, please write a" " bug report to bugs.trinitydesktop.org and include the output of tdevelop when run" "from a shell."),i18n("Subproject Deletion failed")); return; } delete m_shownSubproject; m_shownSubproject = spitem; spitem->scope->saveToFile( ); overview->setCurrentItem( m_shownSubproject ); overview->setSelected( m_shownSubproject, true ); } } void TrollProjectWidget::slotOverviewContextMenu( TDEListView *, TQListViewItem *item, const TQPoint &p ) { if ( !item ) return ; QMakeScopeItem *spitem = static_cast( item ); TDEPopupMenu popup( this ); popup.insertTitle( i18n( "Subproject %1" ).arg( item->text( 0 ) ) ); int idBuild = -2; int idRebuild = -2; int idClean = -2; int idInstall = -2; int idDistClean = -2; int idQmake = -2; int idQmakeRecursive = -2; int idProjectConfiguration = -2; int idAddSubproject = -2; int idRemoveSubproject = -2; int idDisableSubproject = -2; int idRemoveScope = -2; int idAddScope = -2; if ( spitem->scope->scopeType() == Scope::ProjectScope && ( !spitem->scope->parent() || spitem->scope->parent()->scopeType() == Scope::ProjectScope ) ) { idBuild = popup.insertItem( SmallIcon( "make_tdevelop" ), i18n( "Build" ) ); popup.setWhatsThis( idBuild, i18n( "Build

Runs make from the selected subproject directory.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); idInstall = popup.insertItem( i18n( "Install" ) ); popup.setWhatsThis( idBuild, i18n( "Install

Runs make install from the selected subproject directory.
" "Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); idClean = popup.insertItem( i18n( "Clean" ) ); popup.setWhatsThis( idBuild, i18n( "Clean project

Runs make clean command from the project " "directory.
Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); idDistClean = popup.insertItem( i18n( "Dist-Clean" ) ); popup.setWhatsThis( idBuild, i18n( "Dist-Clean project

Runs make distclean command from the project " "directory.
Environment variables and make arguments can be specified " "in the project settings dialog, Make Options tab." ) ); idRebuild = popup.insertItem( SmallIcon( "rebuild" ), i18n( "Rebuild" ) ); popup.setWhatsThis( idRebuild, i18n( "Rebuild project

Runs make clean and then make from " "the project directory.
Environment variables and make arguments can be " "specified in the project settings dialog, Make Options tab." ) ); idQmake = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake" ) ); popup.setWhatsThis( idQmake, i18n( "Run qmake

Runs qmake from the selected subproject directory. This creates or regenerates Makefile." ) ); idQmakeRecursive = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake recursively" ) ); popup.setWhatsThis( idQmakeRecursive, i18n( "Run qmake recursively

Runs qmake from the selected " "subproject directory and recurses into all subproject directories. " "This creates or regenerates Makefile." ) ); popup.insertSeparator(); idAddSubproject = popup.insertItem( SmallIcon( "folder-new" ), i18n( "Add Subproject..." ) ); popup.setWhatsThis( idAddSubproject, i18n( "Add subproject

Creates a new or adds an existing subproject to a currently selected subproject. " "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) popup.setItemEnabled( idAddSubproject, false ); idRemoveSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Remove Subproject..." ) ); popup.setWhatsThis( idRemoveSubproject, i18n( "Remove subproject

Removes currently selected subproject. Does not delete any file from disk. Deleted subproject can be later added by calling 'Add Subproject' action." ) ); if ( spitem->parent() == NULL ) popup.setItemEnabled( idRemoveSubproject, false ); idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); popup.setWhatsThis( idAddScope, i18n( "Create scope

Creates TQMake scope in the project file of the currently selected subproject." ) ); popup.insertSeparator(); idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Subproject Settings" ) ); popup.setWhatsThis( idProjectConfiguration, i18n( "Subproject settings

Opens TQMake Subproject Configuration dialog. " "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " "external libraries,
build order,
intermediate files locations,
compiler options." ) ); } else { idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); popup.setWhatsThis( idAddScope, i18n( "Create Scope

Creates TQMake scope in the currently selected scope." ) ); idRemoveScope = popup.insertItem( SmallIcon( "edit-delete" ), i18n( "Remove Scope" ) ); popup.setWhatsThis( idRemoveScope, i18n( "Remove Scope

Removes currently selected scope." ) ); popup.insertSeparator(); idAddSubproject = popup.insertItem( SmallIcon( "folder-new" ), i18n( "Add Subproject..." ) ); popup.setWhatsThis( idAddSubproject, i18n( "Add subproject

Creates a new or adds an existing subproject to the currently selected scope. " "This action is allowed only if the type of the subproject is 'subdirectories'. The type of the subproject can be " "defined in the Subproject Settings dialog (open it from the subproject context menu)." ) ); if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) popup.setItemEnabled( idAddSubproject, false ); idDisableSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Disable Subproject..." ) ); popup.setWhatsThis( idRemoveSubproject, i18n( "Disable subproject

Disables the currently selected subproject when this scope is active. Does not delete the directory from disk. The deleted subproject can be later added by using the 'Add Subproject' action." ) ); if( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 && spitem->scope->parent()->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) popup.setItemEnabled( idDisableSubproject, false ); popup.insertSeparator(); idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Scope Settings" ) ); popup.setWhatsThis( idProjectConfiguration, i18n( "Scope settings

Opens TQMake Subproject Configuration dialog. " "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " "external libraries,
build order,
intermediate files locations,
compiler options." ) ); } int r = popup.exec( p ); TQString relpath = spitem->relativePath(); if ( r == idAddSubproject ) { slotAddSubproject( spitem ); } if ( r == idRemoveSubproject ) { slotRemoveSubproject( spitem ); } if ( r == idDisableSubproject ) { slotDisableSubproject( spitem ); } if ( r == idAddScope ) { slotCreateScope( spitem ); } else if ( r == idRemoveScope ) { slotRemoveScope( spitem ); } else if ( r == idBuild ) { slotBuildTarget(); // m_part->startMakeCommand(projectDirectory() + relpath, TQString::fromLatin1("")); } else if ( r == idInstall ) { slotInstallTarget(); // m_part->startMakeCommand(projectDirectory() + relpath, TQString::fromLatin1("")); } else if ( r == idRebuild ) { slotRebuildTarget(); } else if ( r == idClean ) { slotCleanTarget(); } else if ( r == idDistClean ) { slotDistCleanTarget(); } else if ( r == idQmake ) { m_part->startTQMakeCommand( projectDirectory() + TQString(TQChar(TQDir::separator())) + relpath ); } else if ( r == idQmakeRecursive ) { runTQMakeRecursive( spitem ); } else if ( r == idProjectConfiguration ) { m_configDlg->updateSubproject( spitem ); m_configDlg->show(); } } void TrollProjectWidget::addFileToCurrentSubProject( GroupItem *titem, const TQString &filename ) { m_filesCached = false; m_allFilesCache.clear(); titem->addFileToScope( filename ); } void TrollProjectWidget::addFileToCurrentSubProject( GroupItem::GroupType gtype, const TQString &filename ) { if ( !m_shownSubproject ) return ; m_filesCached = false; m_allFilesCache.clear(); GroupItem *gitem = 0; if ( m_shownSubproject->groups.contains( gtype ) ) gitem = m_shownSubproject->groups[ gtype ]; if ( !gitem ) return ; gitem->addFileToScope( filename ); } /** * Method adds a file to the current project by grouped * by file extension */ void TrollProjectWidget::addFiles( TQStringList &files, bool relativeToProjectRoot ) { if ( !m_shownSubproject ) return ; kdDebug(9024) << "Files to add:"<scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) != -1 && !fileName.endsWith(".pro") ) { ChooseSubprojectDlg dlg( this, 0 ); if ( dlg.exec() == TQDialog::Accepted ) { if ( dlg.selectedSubproject() && dlg.selectedSubproject()->scope->variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) { fileName = URLUtil::getRelativePath( dlg.selectedSubproject()->scope->projectDir() , TQDir::cleanDirPath( m_shownSubproject->scope->projectDir()+ TQString(TQChar(TQDir::separator()))+ fileName ) ); overview->setCurrentItem( dlg.selectedSubproject() ); } } else { KMessageBox::error( this, i18n("You did not select a subproject to add the file to, or select a subproject that has subdirs."), i18n( "File adding aborted" ) ); } } TQFileInfo info( fileName ); TQString ext = info.extension( false ).simplifyWhiteSpace(); TQString noPathFileName; if( relativeToProjectRoot ) noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), TQDir::cleanDirPath(projectDirectory()+TQString(TQChar(TQDir::separator()))+fileName ) ); else noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), TQDir::cleanDirPath(m_shownSubproject->scope->projectDir()+TQString(TQChar(TQDir::separator()))+fileName ) ); if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/replacePaths", false ) ) { TQString var = m_shownSubproject->scope->findCustomVarForPath( TQFileInfo( noPathFileName ).dirPath() ); if( !var.isEmpty() ) { noPathFileName = "$${"+var+"}"+TQString( TQChar( TQDir::separator() ) )+TQFileInfo( noPathFileName ).fileName(); } } kdDebug(9024) << "calc filename:" << noPathFileName << endl; // GroupItem *gitem = 0; // GroupItem::GroupType gtype = GroupItem::groupTypeForExtension( ext ); // if ( m_shownSubproject->groups.contains( gtype ) ) // gitem = m_shownSubproject->groups[ gtype ]; if( ext == "pro" ) { addSubprojectToItem( findSubprojectForPath( TQFileInfo( fileName ).dirPath() ), TQFileInfo( fileName ).fileName() ); }else { addFileToCurrentSubProject( GroupItem::groupTypeForExtension( ext ), noPathFileName ); slotOverviewSelectionChanged( m_shownSubproject ); kdDebug(9024) << "emitting" << relativeToProjectRoot << " " << fileName << endl; if( relativeToProjectRoot ) emitAddedFile ( projectDirectory()+TQString( TQChar( TQDir::separator() ) ) + fileName ); else emitAddedFile ( m_shownSubproject->scope->projectDir()+TQString( TQChar( TQDir::separator() ) ) + fileName ); } } } void TrollProjectWidget::slotAddFiles() { static KURL lastVisited; TQString cleanSubprojectDir = TQDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); TQString title, filter; TQString otherTitle, otherFilter; GroupItem* item = dynamic_cast( details->selectedItem() ); GroupItem::GroupType type = item ? item->groupType : GroupItem::NoType; GroupItem::groupTypeMeanings( type, title, filter ); filter += "|" + title; m_filesCached = false; m_allFilesCache.clear(); for ( int i = GroupItem::NoType + 1; i < GroupItem::MaxTypeEnum; ++i ) { if ( type != i ) { GroupItem::groupTypeMeanings( static_cast( i ), otherTitle, otherFilter ); filter += "\n" + otherFilter + "|" + otherTitle; } } filter += "\n*|" + i18n( "All Files" ); AddFilesDialog *dialog = new AddFilesDialog( cleanSubprojectDir, filter, this, "Insert existing files", true, new TQComboBox( false ) ); dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); if ( !lastVisited.isEmpty() ) { dialog->setURL( lastVisited ); } dialog->exec(); TQStringList files = dialog->selectedFiles(); lastVisited = dialog->baseURL(); for ( unsigned int i = 0; i < files.count(); i++ ) { switch ( dialog->mode() ) { case AddFilesDialog::Copy: { // Copy selected files to current subproject folder // and add them to the filelist TQString filename = KURL( files[ i ] ).fileName(); TDEIO::NetAccess::file_copy( files[ i ], cleanSubprojectDir + TQString( TQChar( TQDir::separator() ) ) + filename, -1, false, false, this ); TQFile testExist( cleanSubprojectDir + TQString( TQChar( TQDir::separator() ) ) + filename ); if ( testExist.exists() ) { TQStringList files( filename ); addFiles( files, false ); } } break; case AddFilesDialog::Link: { // Link selected files to current subproject folder TDEProcess *proc = new TDEProcess( TQT_TQOBJECT(this) ); *proc << "ln"; *proc << "-s"; *proc << files[ i ]; *proc << cleanSubprojectDir; proc->start(TDEProcess::Block); TQString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); // and add them to the filelist TQFile testExist( cleanSubprojectDir + TQString( TQChar( TQDir::separator() ) ) + filename ); if ( testExist.exists() ) { TQStringList files( filename ); addFiles( files, false ); } } break; case AddFilesDialog::Relative: { // Form relative path to current subproject folder TQString theFile = files[ i ]; TQStringList files( URLUtil::relativePathToFile( cleanSubprojectDir , theFile ) ); addFiles( files, false ); } break; } } } GroupItem* TrollProjectWidget::getInstallRoot( QMakeScopeItem* item ) { if ( item->groups.contains( GroupItem::InstallRoot ) ) return item->groups[ GroupItem::InstallRoot ]; return 0; } GroupItem* TrollProjectWidget::getInstallObject( QMakeScopeItem* item, const TQString& objectname ) { GroupItem * instroot = getInstallRoot( item ); if ( !instroot ) return 0; TQPtrListIterator it( instroot->installs ); for ( ;it.current();++it ) { if ( ( *it ) ->groupType == GroupItem::InstallObject && ( *it ) ->text( 0 ) == objectname ) return * it; } return 0; } void TrollProjectWidget::slotNewFile() { GroupItem * gitem = dynamic_cast( details->currentItem() ); m_filesCached = false; m_allFilesCache.clear(); if( !gitem ) { gitem = dynamic_cast( details->currentItem()->parent() ); } if ( gitem ) { if ( gitem->groupType == GroupItem::InstallObject ) { // TQString relpath = m_shownSubproject->path.mid(projectDirectory().length()); bool ok = FALSE; TQString filepattern = KInputDialog::getText( i18n( "Insert New Filepattern" ), i18n( "Please enter a filepattern relative the current " "subproject (example docs/*.html):" ), TQString(), &ok, this ); if ( ok && !filepattern.isEmpty() ) { addFileToCurrentSubProject( gitem, filepattern ); slotOverviewSelectionChanged( m_shownSubproject ); } return ; } if ( gitem->groupType == GroupItem::InstallRoot ) { // TQString relpath = m_shownSubproject->path.mid(projectDirectory().length()); bool ok = FALSE; TQString install_obj = KInputDialog::getText( i18n( "Insert New Install Object" ), i18n( "Please enter a name for the new object:" ), TQString(), &ok, this ); if ( ok && !install_obj.isEmpty() ) { gitem->addInstallObject( install_obj ); //GroupItem * institem = createGroupItem( GroupItem::InstallObject, install_obj , m_shownSubproject ); //gitem->owner->scope->addToPlusOp("INSTALLS", install_obj); gitem->owner->scope->saveToFile(); slotOverviewSelectionChanged( m_shownSubproject ); } return ; } } KDevCreateFile * createFileSupport = m_part->extension( "TDevelop/CreateFile" ); TQString fcext; if( gitem ) { switch ( gitem->groupType ) { case GroupItem::Sources: fcext = "cpp"; break; case GroupItem::Headers: fcext = "h"; break; case GroupItem::Forms: if ( !m_part->isTQt4Project() ) fcext = "ui-widget"; else fcext = "ui-widget-qt4"; break; case GroupItem::Translations: fcext = "ts"; break; case GroupItem::Lexsources: fcext = "l"; break; case GroupItem::Yaccsources: fcext = "y"; break; case GroupItem::Resources: fcext = "qrc"; break; default: fcext = TQString(); } } KDevCreateFile::CreatedFile crFile = createFileSupport->createNewFile( fcext, projectDirectory() + TQString(TQChar(TQDir::separator()))+ m_shownSubproject->relativePath() ); } void TrollProjectWidget::slotRemoveFile() { TQListViewItem * selectedItem = details->currentItem(); if ( !selectedItem ) return ; m_filesCached = false; m_allFilesCache.clear(); qProjectItem *pvitem = static_cast( selectedItem ); // Check that it is a file (just in case) if ( pvitem->type() != qProjectItem::File ) return ; FileItem *fitem = static_cast( pvitem ); removeFile( m_shownSubproject, fitem ); } void TrollProjectWidget::slotExcludeFileFromScopeButton() { TQListViewItem * selectedItem = details->currentItem(); if ( !selectedItem ) return ; qProjectItem *pvitem = static_cast( selectedItem ); // Check that it is a file (just in case) if ( pvitem->type() != qProjectItem::File ) return ; FileItem *fitem = static_cast( pvitem ); GroupItem *gitem = static_cast( fitem->parent() ); gitem->removeFileFromScope( fitem->text( 0 ) ); } void TrollProjectWidget::slotDetailsSelectionChanged( TQListViewItem *item ) { if ( !item ) { removefileButton->setEnabled( false ); excludeFileFromScopeButton->setEnabled( false ); return ; } removefileButton->setEnabled( false ); excludeFileFromScopeButton->setEnabled( false ); qProjectItem *pvitem = static_cast( item ); if ( pvitem->type() == qProjectItem::Group ) { GroupItem * gitem = static_cast( item ); if ( gitem->groupType == GroupItem::InstallObject ) { excludeFileFromScopeButton->setEnabled( true ); newfileButton->setEnabled( true ); } else if ( gitem->groupType == GroupItem::InstallRoot ) { newfileButton->setEnabled( true ); } else { addfilesButton->setEnabled( true ); newfileButton->setEnabled( true ); } } else if ( pvitem->type() == qProjectItem::File ) { removefileButton->setEnabled( true ); excludeFileFromScopeButton->setEnabled( true ); /* buildTargetButton->setEnabled(true); rebuildTargetButton->setEnabled(true); executeTargetButton->setEnabled(true);*/ } } void TrollProjectWidget::slotDetailsContextMenu( TDEListView *, TQListViewItem *item, const TQPoint &p ) { if ( !item ) return ; qProjectItem *pvitem = static_cast( item ); if ( pvitem->type() == qProjectItem::Group ) { GroupItem * titem = static_cast( pvitem ); TQString title, ext; GroupItem::groupTypeMeanings( titem->groupType, title, ext ); TDEPopupMenu popup( this ); popup.insertTitle( title ); int idInsExistingFile = -2; int idInsNewFile = -2; int idInsInstallObject = -2; int idInsNewFilepatternItem = -2; int idSetInstObjPath = -2; int idLUpdate = -2; int idLRelease = -2; int idRemoveFile = -2; // int idFileProperties = popup.insertItem(SmallIconSet("document-new"),i18n("Properties...")); if ( titem->groupType == GroupItem::InstallRoot ) { idInsInstallObject = popup.insertItem( SmallIconSet( "document-open" ), i18n( "Add Install Object..." ) ); popup.setWhatsThis( idInsInstallObject, i18n( "Add install object

Creates TQMake install object. " "It is possible to define a list of files to install and installation locations for each object. Warning! " "Install objects without path specified will not be saved to a project file." ) ); } else if ( titem->groupType == GroupItem::InstallObject ) { idSetInstObjPath = popup.insertItem( SmallIconSet( "document-open" ), i18n( "Install Path..." ) ); popup.setWhatsThis( idSetInstObjPath, i18n( "Install path

Allows to choose the installation path for the current install object." ) ); idInsNewFilepatternItem = popup.insertItem( SmallIconSet( "document-open" ), i18n( "Add Pattern of Files to Install..." ) ); popup.setWhatsThis( idInsNewFilepatternItem, i18n( "Add pattern of files to install

Defines the pattern to match files which will be installed. " "It is possible to use wildcards and relative paths like docs/*." ) ); idRemoveFile = popup.insertItem( SmallIconSet( "edit-delete" ), i18n( "Remove Install Object" ) ); popup.setWhatsThis( idRemoveFile, i18n( "Remove install object

Removes the install object the current group." ) ); } else if ( titem->groupType == GroupItem::Translations ) { idInsNewFile = popup.insertItem( SmallIconSet( "document-new" ), i18n( "Create New File..." ) ); popup.setWhatsThis( idInsNewFile, i18n( "Create new file

Creates a new translation file and adds it to a currently selected TRANSLATIONS group." ) ); idInsExistingFile = popup.insertItem( SmallIconSet( "document-open" ), i18n( "Add Existing Files..." ) ); popup.setWhatsThis( idInsExistingFile, i18n( "Add existing files

Adds existing translation (*.ts) files to a currently selected TRANSLATIONS group. It is " "possible to copy files to a current subproject directory, create symbolic links or " "add them with the relative path." ) ); idLUpdate = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Update Translation Files" ) ); popup.setWhatsThis( idLUpdate, i18n( "Update Translation Files

Runs lupdate command from the current subproject directory. It collects translatable " "messages and saves them into translation files." ) ); idLRelease = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Release Binary Translations" ) ); popup.setWhatsThis( idLRelease, i18n( "Release Binary Translations

Runs lrelease command from the current subproject directory. It creates binary " "translation files that are ready to be loaded at program execution." ) ); } else // File group containing files { idInsNewFile = popup.insertItem( SmallIconSet( "document-new" ), i18n( "Create New File..." ) ); popup.setWhatsThis( idInsNewFile, i18n( "Create new file

Creates a new file and adds it to a currently selected group." ) ); idInsExistingFile = popup.insertItem( SmallIconSet( "document-open" ), i18n( "Add Existing Files..." ) ); popup.setWhatsThis( idInsExistingFile, i18n( "Add existing files

Adds existing files to a currently selected group. It is " "possible to copy files to a current subproject directory, create symbolic links or " "add them with the relative path." ) ); } int r = popup.exec( p ); TQString cleanSubprojectPath = TQDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); if ( r == idSetInstObjPath ) { KURLRequesterDlg dialog( i18n( "Choose Install Path" ), i18n( "Enter a path " "(example /usr/local/share/... ):" ), this, 0 ); dialog.urlRequester() ->setMode( KFile::Directory ); dialog.urlRequester() ->setURL( titem->owner->scope->variableValues( titem->text( 0 ) + ".path" ).front() ); if ( dialog.exec() == TQDialog::Accepted ) { titem->owner->scope->setEqualOp( titem->text( 0 ) + ".path", dialog.urlRequester() ->url() ); titem->owner->scope->saveToFile( ); } } else if ( r == idInsNewFilepatternItem ) { bool ok = FALSE; TQString filepattern = KInputDialog::getText( i18n( "Add Pattern of Files to Install" ), i18n( "Enter a pattern relative to the current " "subproject (example docs/*.html):" ), TQString(), &ok, this ); if ( ok && !filepattern.isEmpty() ) { addFileToCurrentSubProject( titem, filepattern ); slotOverviewSelectionChanged( m_shownSubproject ); } } else if ( r == idInsExistingFile ) { AddFilesDialog * dialog = new AddFilesDialog( cleanSubprojectPath, ext + "|" + title + " (" + ext + ")", this, "Add existing files", true, new TQComboBox( false ) ); dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); if ( dialog->exec() == TQDialog::Rejected ) return ; TQStringList files = dialog->selectedFiles(); for ( unsigned int i = 0;i < files.count();++i ) { switch ( dialog->mode() ) { case AddFilesDialog::Copy: { // Copy selected files to current subproject folder // and add them to the filelist TQString filename = KURL( files[ i ] ).fileName(); TDEIO::NetAccess::file_copy( files[ i ], cleanSubprojectPath + TQString( TQChar( TQDir::separator() ) ) + filename, -1, false, false, this ); TQFile testExist( cleanSubprojectPath + TQString( TQChar( TQDir::separator() ) ) + filename ); if ( testExist.exists() ) { TQStringList files( filename ); addFiles( files, false ); } } break; case AddFilesDialog::Link: { // Link selected files to current subproject folder TDEProcess *proc = new TDEProcess( TQT_TQOBJECT(this) ); *proc << "ln"; *proc << "-s"; *proc << files[ i ]; *proc << cleanSubprojectPath; proc->start(TDEProcess::Block); TQString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); // and add them to the filelist TQFile testExist( cleanSubprojectPath + TQString( TQChar( TQDir::separator() ) ) + filename ); if ( testExist.exists() ) { TQStringList files( filename ); addFiles( files, false ); } } break; case AddFilesDialog::Relative: { // Form relative path to current subproject folder TQString theFile = files[ i ]; TQStringList files( URLUtil::relativePathToFile( cleanSubprojectPath, theFile ) ); addFiles( files, false ); } break; } } // Update project file if ( titem && titem->owner ) { titem->owner->scope->saveToFile( ); } // Update subprojectview slotOverviewSelectionChanged( m_shownSubproject ); } else if ( r == idInsNewFile ) { KDevCreateFile * createFileSupport = m_part->extension( "TDevelop/CreateFile" ); TQString fcext; switch ( titem->groupType ) { case GroupItem::Sources: fcext = "cpp"; break; case GroupItem::Headers: fcext = "h"; break; case GroupItem::Forms: if ( !m_part->isTQt4Project() ) fcext = "ui-widget"; else fcext = "ui-widget-qt4"; break; case GroupItem::Translations: fcext = "ts"; break; case GroupItem::Lexsources: fcext = "l"; break; case GroupItem::Yaccsources: fcext = "y"; break; case GroupItem::Resources: fcext = "qrc"; break; default: fcext = TQString(); } KDevCreateFile::CreatedFile crFile = createFileSupport->createNewFile( fcext, cleanSubprojectPath ); } else if ( r == idInsInstallObject ) { bool ok = FALSE; TQString install_obj = KInputDialog::getText( i18n( "Add Install Object" ), i18n( "Enter a name for the new object:" ), TQString(), &ok, this ); if ( ok && !install_obj.isEmpty() ) { titem->addInstallObject( install_obj ); slotOverviewSelectionChanged( m_shownSubproject ); } } else if ( r == idLUpdate ) { TQString cmd = "lupdate "; cmd += m_shownSubproject->scope->fileName(); m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); } else if ( r == idLRelease ) { TQString cmd = "lrelease "; cmd += m_shownSubproject->scope->fileName(); m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); }else if( r == idRemoveFile ) { static_cast(titem->parent())->removeInstallObject( titem ); slotOverviewSelectionChanged( m_shownSubproject ); } } else if ( pvitem->type() == qProjectItem::File ) { removefileButton->setEnabled( true ); FileItem *fitem = static_cast( pvitem ); GroupItem* gitem = static_cast( item->parent() ); TDEPopupMenu popup( this ); if ( !( gitem->groupType == GroupItem::InstallObject ) ) popup.insertTitle( i18n( "File: %1" ).arg( fitem->text( 0 ) ) ); else popup.insertTitle( i18n( "Pattern: %1" ).arg( fitem->text( 0 ) ) ); int idRemoveFile = -2; int idSubclassWidget = -2; int idUpdateWidgetclass = -2; int idBuildFile = -2; int idUISubclasses = -2; int idViewUIH = -2; int idFileProperties = -2; int idEditInstallPattern = -2; if ( !fitem->uiFileLink.isEmpty() ) { idUpdateWidgetclass = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Edit ui-Subclass..." ) ); popup.setWhatsThis( idUpdateWidgetclass, i18n( "Edit ui-subclass

Launches Subclassing wizard " "and prompts to implement missing in childclass slots and functions." ) ); } if ( fitem->text( 0 ).contains( ".ui" ) ) { idSubclassWidget = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Subclassing Wizard..." ) ); popup.setWhatsThis( idSubclassWidget, i18n( "Subclass widget

Launches Subclassing wizard. " "It allows to create a subclass from the class defined in .ui file. " "There is also possibility to implement slots and functions defined in the base class." ) ); if ( !m_part->isTQt4Project() ) { idViewUIH = popup.insertItem( SmallIconSet( "qmake_ui_h" ), i18n( "Open ui.h File" ) ); popup.setWhatsThis( idViewUIH, i18n( "Open ui.h file

Opens .ui.h file associated with the selected .ui." ) ); } idUISubclasses = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "List of Subclasses..." ) ); popup.setWhatsThis( idUISubclasses, i18n( "List of subclasses

Shows subclasses list editor. " "There is possibility to add or remove subclasses from the list." ) ); } if ( !( gitem->groupType == GroupItem::InstallObject ) ) { idRemoveFile = popup.insertItem( SmallIconSet( "edit-delete" ), i18n( "Remove File" ) ); popup.setWhatsThis( idRemoveFile, i18n( "Remove file

Removes file from a current group. For sources, this also removes the subclassing information." ) ); idFileProperties = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Exclude File" ) ); popup.setWhatsThis( idFileProperties, i18n( "Exclude File

Excludes the file from this Scope. Does not touch subclassing information" ) ); } else { idEditInstallPattern = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Edit Pattern" ) ); popup.setWhatsThis( idEditInstallPattern, i18n( "Edit pattern

Allows to edit install files pattern." ) ); idRemoveFile = popup.insertItem( SmallIconSet( "edit-delete" ), i18n( "Remove Pattern" ) ); popup.setWhatsThis( idRemoveFile, i18n( "Remove pattern

Removes install files pattern from the current install object." ) ); } if ( !( gitem->groupType == GroupItem::InstallObject ) ) { KURL::List urls; urls.append( m_shownSubproject->scope->projectDir() + TQChar( TQDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ) ); FileContext context( urls ); m_part->core() ->fillContextMenu( &popup, &context ); } if ( gitem->groupType == GroupItem::Sources ) { idBuildFile = popup.insertItem( SmallIconSet( "make_tdevelop" ), i18n( "Build File" ) ); popup.setWhatsThis( idBuildFile, i18n( "Build File

Builds the object file for this source file." ) ); } int r = popup.exec( p ); if ( r == idRemoveFile ) removeFile( m_shownSubproject, fitem ); else if ( r == idFileProperties ) { slotExcludeFileFromScopeButton(); } else if ( r == idViewUIH ) { kdDebug(9024) << "Opening:" << fitem->text(0) << ";" << fitem->text(0).replace(".ui","") << endl; m_part->partController() ->editDocument( KURL( m_shownSubproject->scope->projectDir() + TQChar( TQDir::separator() ) + fitem->localFilePath.replace(".ui","") + ".h" ) ); } else if ( r == idSubclassWidget ) { TQStringList newFileNames; newFileNames = m_part->languageSupport() ->subclassWidget( m_shownSubproject->scope->projectDir() + TQChar( TQDir::separator() ) + fitem->localFilePath ); kdDebug(9024) << "got new filenames: " << newFileNames << endl; if ( !newFileNames.empty() ) { TQDomDocument & dom = *( m_part->projectDom() ); for ( uint i = 0; i < newFileNames.count(); ++i ) { TQString srcfile_relpath = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), newFileNames[ i ] ) ; newFileNames[i] = URLUtil::getRelativePath( projectDirectory(), newFileNames[ i ] ) ; TQString uifile_relpath = m_shownSubproject->relativePath() + TQChar( TQDir::separator() ) + fitem->localFilePath; DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); list << DomUtil::Pair( srcfile_relpath, uifile_relpath ); DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); // newFileNames[i] = newFileNames[i].replace(TQRegExp(projectDirectory()+"/"),""); tqWarning( "new file: %s", newFileNames[ i ].latin1() ); } m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); m_part->addFiles( newFileNames ); } } else if ( r == idUpdateWidgetclass ) { TQString noext = fitem->text( 0 ); if ( noext.findRev( '.' ) > -1 ) noext = noext.left( noext.findRev( '.' ) ); TQStringList dummy; TQString uifile = fitem->uiFileLink; if ( uifile.findRev( TQString( TQChar( TQDir::separator() ) ) ) > -1 ) { TQStringList uisplit = TQStringList::split( TQString( TQChar( TQDir::separator() ) ), uifile ); uifile = uisplit[ uisplit.count() - 1 ]; } m_part->languageSupport() ->updateWidget( m_shownSubproject->scope->projectDir() + TQString( TQChar( TQDir::separator() ) ) + uifile, noext ); } else if ( r == idUISubclasses ) { TQDomDocument & dom = *( m_part->projectDom() ); DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); SubclassesDlg *sbdlg = new SubclassesDlg( m_shownSubproject->relativePath() + TQChar( TQDir::separator() ) + fitem->localFilePath, list, projectDirectory() ); if ( sbdlg->exec() ) { TQDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); TQDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); if ( ( !el.isNull() ) && ( !el2.isNull() ) ) { el.removeChild( el2 ); } DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); } } else if ( r == idEditInstallPattern ) { GroupItem * titem = static_cast( item->parent() ); bool ok = FALSE; TQString filepattern = KInputDialog::getText( i18n( "Edit Pattern" ), i18n( "Enter a pattern relative to the current " "subproject (example docs/*.html):" ), fitem->text( 0 ) , &ok, this ); if ( ok && !filepattern.isEmpty() ) { removeFile( m_shownSubproject, fitem ); addFileToCurrentSubProject( titem, filepattern ); slotOverviewSelectionChanged( m_shownSubproject ); } } else if ( r == idBuildFile ) { buildFile( m_shownSubproject, fitem ); } } } void TrollProjectWidget::removeFile( QMakeScopeItem *spitem, FileItem *fitem ) { GroupItem * gitem = static_cast( fitem->parent() ); m_filesCached = false; m_allFilesCache.clear(); TQString realfilename = spitem->scope->resolveVariables( fitem->localFilePath ); if ( KMessageBox::warningYesNo( this, "" + i18n( "Do you want to delete the file %1 from the project and your disk?" ) .arg( fitem->text( 0 ) ) + "", i18n( "Remove File" ), KStdGuiItem::remove(), KStdGuiItem::no(), "deleteFileFromTQMakeProject" ) == KMessageBox::No ) { return; }else { kdDebug(9024) << "Deleting file as the user wished: " << spitem->scope->projectDir() + TQString( TQChar( TQDir::separator() ) ) + realfilename << endl; TDEIO::NetAccess::del( KURL::fromPathOrURL( spitem->scope->projectDir() + TQString( TQChar( TQDir::separator() ) ) + realfilename ), 0 ); } if ( gitem->groupType != GroupItem::InstallObject ) { TQString removedFileName = spitem->relativePath() + TQString( TQChar( TQDir::separator() ) ) + realfilename; if ( removedFileName.startsWith( TQDir::rootDirPath() ) ) removedFileName = removedFileName.mid( 1 ); emitRemovedFile( removedFileName ); } //remove subclassing info TQDomDocument &dom = *( m_part->projectDom() ); DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , "subclass", "sourcefile", "uifile" ); TQPtrList pairsToRemove; DomUtil::PairList::iterator it; for ( it = list.begin(); it != list.end(); ++it ) { if ( ( ( *it ).first == realfilename ) || ( ( *it ).second == realfilename ) ) { pairsToRemove.append( &( *it ) ); } } DomUtil::Pair *pair; for ( pair = pairsToRemove.first(); pair; pair = pairsToRemove.next() ) { list.remove( *pair ); } TQDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); TQDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); if ( ( !el.isNull() ) && ( !el2.isNull() ) ) { el.removeChild( el2 ); } DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); gitem->removeFileFromScope( fitem->text( 0 ) ); } void TrollProjectWidget::emitAddedFile( const TQString &fileName ) { emit m_part->addedFilesToProject( TQStringList( fileName ) ); } void TrollProjectWidget::emitRemovedFile( const TQString &fileName ) { emit m_part->removedFilesFromProject( TQStringList( fileName ) ); } TQString TrollProjectWidget::getUiFileLink( const TQString &relpath, const TQString& filename ) { DomUtil::PairList::iterator it; for ( it = m_subclasslist.begin();it != m_subclasslist.end(); ++it ) { if ( ( *it ).first == relpath + filename ) return ( *it ).second; } return ""; } void TrollProjectWidget::slotBuildOpenFile() { KParts::ReadWritePart * part = dynamic_cast( m_part->partController() ->activePart() ); if ( !part || !part->url().isLocalFile() ) return ; TQString fileName = part->url().path(); TQFileInfo fi( fileName ); TQString sourceDir = fi.dirPath(); TQString baseName = fi.baseName( true ); kdDebug( 9024 ) << "Compiling " << fileName << "in dir " << sourceDir << " with baseName " << baseName << endl; TQString buildDir = sourceDir; TQString target = baseName + ".o"; m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); // m_part->startMakeCommand(buildDir, target); TQPtrList list = findSubprojectForFile( fi ); QMakeScopeItem *spitem; for ( spitem = list.first(); spitem; spitem = list.next() ) { TQString buildcmd = constructMakeCommandLine( spitem->scope ); TQString dircmd = "cd " + TDEProcess::quote( spitem->scope->projectDir() ) + " && " ; kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); } // startMakeCommand(buildDir, target); } void TrollProjectWidget::slotExecuteProject() { TQString program = m_part->mainProgram(); if ( program.isEmpty() ) { KMessageBox::sorry( this, i18n( "Please specify the executable name in the " "project options dialog or select an application subproject in the TQMake Manager." ), i18n( "No Executable Found" ) ); return ; } //only run once if (m_part->appFrontend()->isRunning()) { if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) return; m_part->appFrontend()->stopApplication(); while(m_part->appFrontend()->isRunning()) { TDEApplication::kApplication()->processEvents(); usleep(100); } } if ( !program.startsWith( TQDir::rootDirPath() ) ) program.prepend( "." + TQString( TQChar( TQDir::separator() ) ) ); // Build environment variables to prepend to the executable path TQString runEnvVars = TQString(); DomUtil::PairList list = DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); DomUtil::PairList::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) { const DomUtil::Pair &pair = ( *it ); if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) runEnvVars += pair.first + "=" + pair.second + " "; } program.prepend( runEnvVars ); program.append( " " + m_part->runArguments() + " " ); bool inTerminal = DomUtil::readBoolEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/terminal" ); m_part->appFrontend() ->startAppCommand( m_part->runDirectory(), program, inTerminal ); } void TrollProjectWidget::slotCleanProject() { runClean(m_rootSubproject, "clean"); } void TrollProjectWidget::slotCleanTarget() { runClean(m_shownSubproject, "clean"); } void TrollProjectWidget::slotDistCleanProject() { runClean(m_rootSubproject, "distclean"); } void TrollProjectWidget::slotDistCleanTarget() { runClean(m_shownSubproject, "distclean"); } void TrollProjectWidget::runClean( QMakeScopeItem* item, const TQString& cleantargetname ) { // no subproject selected m_part->partController() ->saveAllFiles(); if ( !item ) return ; // can't build from scope if ( item->scope->scopeType() != Scope::ProjectScope ) return ; TQString dir = item->scope->projectDir(); createMakefileIfMissing( dir, item ); m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); TQString dircmd = "cd " + TDEProcess::quote( dir ) + " && " ; TQString rebuildcmd = constructMakeCommandLine( item->scope ) + " "+cleantargetname; m_part->queueCmd( dir, dircmd + rebuildcmd ); } TQString TrollProjectWidget::constructMakeCommandLine( Scope* s ) { TQString makeFileName; if ( s ) makeFileName = s->resolveVariables( s->variableValues( "MAKEFILE", true, true, true ).front() ); TQDomDocument & dom = *( m_part->projectDom() ); TQString cmdline = DomUtil::readEntry( dom, "/kdevtrollproject/make/makebin" ); if ( cmdline.isEmpty() ) cmdline = MAKE_COMMAND; if ( !makeFileName.isEmpty() ) { cmdline += " -f " + makeFileName; } if ( !DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/abortonerror" ) ) cmdline += " -k"; bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/runmultiplejobs"); int jobs = DomUtil::readIntEntry( dom, "/kdevtrollproject/make/numberofjobs" ); if ( jobs != 0 && runmultiple ) { cmdline += " -j"; cmdline += TQString::number( jobs ); } if ( DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/dontact" ) ) cmdline += " -n"; cmdline += " "; cmdline.prepend( m_part->makeEnvironment() ); return cmdline; } void TrollProjectWidget::createMakefileIfMissing( const TQString &dir, QMakeScopeItem *item ) { TQFileInfo fi; TQFileInfo fi2; kdDebug(9024) << "Makefile:" << item->scope->variableValues( "MAKEFILE", true, true, true ) << endl; if ( item->scope->variableValues( "MAKEFILE", true, true, true ).isEmpty() ) { fi.setFile( dir + TQString( TQChar( TQDir::separator() ) ) + "Makefile" ); fi2.setFile( dir + TQString( TQChar( TQDir::separator() ) ) + "makefile" ); } else { TQString realmf = item->scope->resolveVariables( item->scope->variableValues( "MAKEFILE", true, true, true ).front() ); fi.setFile( realmf ); fi2.setFile( dir + TQString( TQChar( TQDir::separator() ) ) + realmf ); } if ( !fi.exists() && !fi2.exists() ) { int r = KMessageBox::questionYesNo( this, i18n( "There is no Makefile in this directory. Run qmake first?" ), TQString(), i18n( "Run qmake" ), i18n( "Do Not Run" ) ); if ( r == KMessageBox::No ) return ; m_part->startTQMakeCommand( dir ); } } QMakeScopeItem* TrollProjectWidget::findSubprojectForPath( const TQString& relPath ) { if( !m_rootSubproject ) return 0; TQStringList dirs = TQStringList::split("/", relPath); QMakeScopeItem* pitem = static_cast(m_rootSubproject); for( TQStringList::iterator it = dirs.begin(); it != dirs.end(); ++it) { TQListViewItem* item = pitem->firstChild(); while( item ) { QMakeScopeItem* sitem = static_cast(item); if( TQFileInfo( sitem->scope->projectDir() ).fileName() == *it ) { pitem = sitem; break; } } } return pitem; } TQPtrList TrollProjectWidget::findSubprojectForFile( TQFileInfo fi ) { TQPtrList list; findSubprojectForFile( list, m_rootSubproject, fi.absFilePath() ); return list; } void TrollProjectWidget::findSubprojectForFile( TQPtrList &list, QMakeScopeItem * item, TQString absFilePath ) { if( !item ) return; TQDir d( item->scope->projectDir() ); TQStringList vars = item->scope->variableValues( "SOURCES" ); for ( TQStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) { TQFileInfo fi2( d, item->scope->resolveVariables( *it ) ); if ( absFilePath == fi2.absFilePath() ) list.append( item ); } vars = item->scope->variableValues( "HEADERS" ); for ( TQStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) { TQFileInfo fi2( d, item->scope->resolveVariables( *it ) ); if ( absFilePath == fi2.absFilePath() ) list.append( item ); } TQListViewItem * child = item->firstChild(); while ( child ) { QMakeScopeItem * spitem = dynamic_cast( child ); if ( spitem ) { findSubprojectForFile( list, spitem, absFilePath ); } child = child->nextSibling(); } } void TrollProjectWidget::slotRemoveScope( QMakeScopeItem * spitem ) { if ( spitem == 0 && m_shownSubproject == 0 ) return ; else { m_filesCached = false; m_allFilesCache.clear(); QMakeScopeItem* pitem = dynamic_cast( spitem->parent() ); if ( pitem != 0 ) { switch ( spitem->scope->scopeType() ) { case Scope::FunctionScope: if( !pitem->scope->deleteFunctionScope( spitem->scope->getNum() ) ) { KMessageBox::error(this, i18n("Could not delete Function Scope.\nThis is an internal error, please write a bug report to bugs.trinitydesktop.org and include the output of tdevelop when run from a shell."),i18n("Function Scope Deletion failed")); return; } // pitem->scopes.remove( spitem ); break; case Scope::IncludeScope: if( !pitem->scope->deleteIncludeScope( spitem->scope->getNum() ) ) { KMessageBox::error(this, i18n("Could not delete Include Scope.\nThis is an internal error, please write a bug report to bugs.trinitydesktop.org and include the output of tdevelop when run from a shell."),i18n("Include Scope Deletion failed")); return; } // pitem->scopes.remove( spitem ); delete spitem; spitem = pitem; pitem = dynamic_cast( pitem->parent() ); // pitem->scopes.remove(spitem); break; case Scope::SimpleScope: if( !pitem->scope->deleteSimpleScope( spitem->scope->getNum() ) ) { KMessageBox::error(this, i18n("Could not delete Scope.\nThis is an internal error, please write a bug report to bugs.trinitydesktop.org and include the output of tdevelop when run from a shell."),i18n("Scope Deletion failed")); return; } // pitem->scopes.remove( spitem ); break; default: break; } pitem->scope->saveToFile(); delete spitem; m_shownSubproject = pitem; overview->setCurrentItem ( m_shownSubproject ); overview->setSelected( m_shownSubproject, true ); slotOverviewSelectionChanged( m_shownSubproject ); } } } QMakeScopeItem * TrollProjectWidget::findSubprojectForScope( QMakeScopeItem * scope ) { if ( ( scope == 0 ) || ( scope->parent() == 0 ) ) return 0; if ( scope->scope->scopeType() == Scope::ProjectScope ) return scope; return findSubprojectForScope( dynamic_cast( scope->parent() ) ); } void TrollProjectWidget::focusInEvent( TQFocusEvent * /*e*/ ) { switch ( m_lastFocusedView ) { case DetailsView: details->setFocus(); break; case SubprojectView: default: overview->setFocus(); } } void TrollProjectWidget::setLastFocusedView( TrollProjectView view ) { m_lastFocusedView = view; } void TrollProjectWidget::runTQMakeRecursive( QMakeScopeItem* proj ) { if( m_part->isTQt4Project() ) { m_part->startTQMakeCommand( proj->scope->projectDir(), true ); }else { if ( proj->scope->scopeType() == Scope::ProjectScope ) { m_part->startTQMakeCommand( proj->scope->projectDir() ); } QMakeScopeItem* item = static_cast( proj->firstChild() ); while ( item ) { runTQMakeRecursive( item ); item = static_cast( item->nextSibling() ); } } } void TrollProjectWidget::slotBuildSelectedFile() { TQListViewItem * selectedItem = details->currentItem(); if ( !selectedItem ) return ; qProjectItem *pvitem = static_cast( selectedItem ); // Check that it is a file (just in case) if ( pvitem->type() != qProjectItem::File ) return ; FileItem *fitem = static_cast( pvitem ); buildFile( m_shownSubproject, fitem ); } void TrollProjectWidget::buildFile( QMakeScopeItem* spitem, FileItem* fitem ) { TQFileInfo fi( spitem->scope->projectDir() + TQChar( TQDir::separator() ) + spitem->scope->resolveVariables( fitem->localFilePath ) ); TQString sourceDir = fi.dirPath(); TQString baseName = fi.baseName( true ); kdDebug( 9024 ) << "Compiling " << spitem->scope->resolveVariables( fitem->text( 0 ) ) << "in dir " << sourceDir << " with baseName " << baseName << endl; TQString buildDir = sourceDir; TQString target = baseName + ".o"; if( !spitem->scope->variableValues("OBJECTS_DIR").isEmpty() ) target = spitem->scope->resolveVariables( spitem->scope->variableValues("OBJECTS_DIR").first() )+ TQString( TQChar( TQDir::separator() ) )+target; kdDebug( 9024 ) << "builddir " << buildDir << ", target " << target << endl; m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); // m_part->startMakeCommand(buildDir, target); TQString buildcmd = constructMakeCommandLine( spitem->scope ); TQString dircmd = "cd " + TDEProcess::quote( spitem->scope->projectDir() ) + " && " ; kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); // startMakeCommand(buildDir, target); } TrollProjectWidget::SaveType TrollProjectWidget::dialogSaveBehaviour() const { switch ( DomUtil::readIntEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/savebehaviour", 2 ) ) { case 0: return AlwaysSave; break; case 1: return NeverSave; break; case 2: default: return Ask; break; } } bool TrollProjectWidget::isTMakeProject() { return m_part->isTMakeProject(); } void TrollProjectWidget::slotDisableSubproject( QMakeScopeItem* spitem ) { m_filesCached = false; m_allFilesCache.clear(); if( spitem->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) { TQStringList subdirs = spitem->scope->variableValues( "SUBDIRS" ); DisableSubprojectDlg dlg( subdirs ); if( dlg.exec() ) { TQStringList values = dlg.selectedProjects(); TQListViewItem* item = spitem->firstChild(); while( item ) { if( values.findIndex( item->text(0) ) != -1 ) delete item; item = item->nextSibling(); } spitem->disableSubprojects( values ); spitem->scope->saveToFile(); m_shownSubproject = spitem; slotOverviewSelectionChanged( m_shownSubproject ); } }else { QMakeScopeItem* parent = static_cast(spitem->parent()); parent->disableSubprojects( TQStringList( spitem->scope->scopeName() ) ); delete spitem; parent->scope->saveToFile(); m_shownSubproject = parent; slotOverviewSelectionChanged( m_shownSubproject ); } } void TrollProjectWidget::slotProjectDirty(const TQString& path) { kdDebug(9024) << "File is dirty:" << path << " using method " << endl; if( KMessageBox::warningYesNo(this, i18n("The project file \"%1\" has changed on disk\n(Or you have \"%2\" opened in the editor, which also triggers a reload when you change something in the TQMake Manager).\n\nDo you want to reload it?").arg(path).arg(path), i18n("Project File Changed"), i18n("Reload"), i18n("Do Not Reload"), "trollproject_reload_project_file" ) != KMessageBox::No ) { m_part->dirWatch()->stopScan(); TQListViewItemIterator it(m_rootSubproject); TQValueList itemstoreload; while( it.current() ) { QMakeScopeItem* projectitem = static_cast( it.current() ); if( projectitem->scope->scopeType() == Scope::ProjectScope || projectitem->scope->scopeType() == Scope::IncludeScope ) { TQString projectfile = projectitem->scope->projectDir() + TQString(TQChar(TQDir::separator())) + projectitem->scope->fileName(); if( projectfile == path ) { itemstoreload.append(projectitem); } } it++; } TQValueList::const_iterator reloadit = itemstoreload.begin(); for( ; reloadit != itemstoreload.end() ; ++reloadit ) { (*reloadit)->reloadProject(); if( m_shownSubproject == (*reloadit) ) { cleanDetailView(*reloadit); setupContext(); buildProjectDetailTree( *reloadit, details ); } if( m_configDlg->isShown() && m_configDlg->currentProjectItem() == (*reloadit) ) { m_configDlg->reject(); m_configDlg->updateSubproject(m_shownSubproject); m_configDlg->show(); } } m_part->dirWatch()->startScan(); } } QMakeScopeItem* TrollProjectWidget::currentSubproject() { return m_shownSubproject; } bool TrollProjectWidget::showFilenamesOnly() const { return m_showFilenamesOnly; } bool TrollProjectWidget::showVariablesInTree() const { return m_showVariablesInTree; } TQMap TrollProjectWidget::qmakeEnvironment() const { TQMap map; DomUtil::PairList envvars = DomUtil::readPairListEntry(*m_part->projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); TQString environstr; DomUtil::PairList::ConstIterator it; bool hasTQtDir = false; for (it = envvars.begin(); it != envvars.end(); ++it) { if( (*it).first == "QTDIR" ) hasTQtDir = true; map[(*it).first] = (*it).second; } if( !hasTQtDir && !m_part->isTQt4Project() && !DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) { map["QTDIR="] = DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", ""); map["PATH"] = map["PATH"].prepend( DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "") +"/bin" ); } return map; } #include "trollprojectwidget.moc" //kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on