/* * Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org) * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Partially based on KDE Studio ClassListView http://www.thekompany.com/projects/kdestudio/ */ #include "classviewpart.h" #include "classviewwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // namespace ?!? ClassViewWidget::ClassViewWidget( ClassViewPart * part ) : TDEListView( 0, "ClassViewWidget" ), TQToolTip( viewport() ), m_part( part ), m_projectDirectoryLength( 0 ) { addColumn( "" ); header()->hide(); setSorting( 0 ); setRootIsDecorated( true ); setAllColumnsShowFocus( true ); m_projectItem = 0; connect( this, TQT_SIGNAL(returnPressed(TQListViewItem*)), this, TQT_SLOT(slotExecuted(TQListViewItem*)) ); connect( this, TQT_SIGNAL(executed(TQListViewItem*)), this, TQT_SLOT(slotExecuted(TQListViewItem*)) ); connect( m_part->core(), TQT_SIGNAL(projectOpened()), this, TQT_SLOT(slotProjectOpened()) ); connect( m_part->core(), TQT_SIGNAL(projectClosed()), this, TQT_SLOT(slotProjectClosed()) ); connect( m_part->core(), TQT_SIGNAL(languageChanged()), this, TQT_SLOT(slotProjectOpened()) ); TQStringList lst; lst << i18n( "Group by Directories" ) << i18n( "Plain List" ) << i18n( "Java Like Mode" ); m_actionViewMode = new TDESelectAction( i18n("View Mode"), TDEShortcut(), m_part->actionCollection(), "classview_mode" ); m_actionViewMode->setItems( lst ); m_actionViewMode->setWhatsThis(i18n("View mode

Class browser items can be grouped by directories, listed in a plain or java like view.")); m_actionNewClass = new TDEAction( i18n("New Class..."), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotNewClass()), m_part->actionCollection(), "classview_new_class" ); m_actionNewClass->setWhatsThis(i18n("New class

Calls the New Class wizard.")); m_actionCreateAccessMethods = new TDEAction( i18n("Create get/set Methods"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotCreateAccessMethods()), m_part->actionCollection(), "classview_create_access_methods" ); m_actionAddMethod = new TDEAction( i18n("Add Method..."), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotAddMethod()), m_part->actionCollection(), "classview_add_method" ); m_actionAddMethod->setWhatsThis(i18n("Add method

Calls the New Method wizard.")); m_actionAddAttribute = new TDEAction( i18n("Add Attribute..."), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotAddAttribute()), m_part->actionCollection(), "classview_add_attribute" ); m_actionAddAttribute->setWhatsThis(i18n("Add attribute

Calls the New Attribute wizard.")); m_actionOpenDeclaration = new TDEAction( i18n("Open Declaration"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotOpenDeclaration()), m_part->actionCollection(), "classview_open_declaration" ); m_actionOpenDeclaration->setWhatsThis(i18n("Open declaration

Opens a file where the selected item is declared and jumps to the declaration line.")); m_actionOpenImplementation = new TDEAction( i18n("Open Implementation"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotOpenImplementation()), m_part->actionCollection(), "classview_open_implementation" ); m_actionOpenImplementation->setWhatsThis(i18n("Open implementation

Opens a file where the selected item is defined (implemented) and jumps to the definition line.")); m_actionFollowEditor = new TDEToggleAction( i18n("Follow Editor"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotFollowEditor()), m_part->actionCollection(), "classview_follow_editor" ); TDEConfig* config = m_part->instance()->config(); config->setGroup( "General" ); setViewMode( config->readNumEntry( "ViewMode", KDevelop3ViewMode ) ); m_doFollowEditor = config->readBoolEntry( "FollowEditor", false ); } ClassViewWidget::~ClassViewWidget( ) { TDEConfig* config = m_part->instance()->config(); config->setGroup( "General" ); config->writeEntry( "ViewMode", viewMode() ); config->writeEntry( "FollowEditor", m_doFollowEditor ); config->sync(); } template static bool selectItemG( ItemDom item, const TQMap, ListItemType*>& map ) { ModelType* c = dynamic_cast( &(*item) ); if( c ) { TDESharedPtr d( c ); typename TQMap, ListItemType*>::ConstIterator it = map.find(d); if( it != map.end() ) { ( *it )->select(); return true; } } return false; } void ClassViewWidget::slotExecuted( TQListViewItem* item ) { if( ClassViewItem* cbitem = dynamic_cast( item ) ){ if( cbitem->hasImplementation() ) cbitem->openImplementation(); else cbitem->openDeclaration(); } } void ClassViewWidget::clear( ) { TDEListView::clear(); removedText.clear(); m_projectItem = 0; } void restoreOpenNodes( TQStringList & list, TQListViewItem * item ) { if ( item && !list.isEmpty() ) { if ( item->text( 0 ) == list.first() ) { item->setOpen( true ); list.pop_front(); restoreOpenNodes( list, item->firstChild() ); } else { restoreOpenNodes( list, item->nextSibling() ); } } } void storeOpenNodes( TQValueList & openNodes, TQStringList const & list, TQListViewItem * item ) { if ( item ) { if ( item->isOpen() ) { TQStringList mylist( list ); mylist << item->text( 0 ); openNodes << mylist; storeOpenNodes( openNodes, mylist, item->firstChild() ); } storeOpenNodes( openNodes, list, item->nextSibling() ); } } void ClassViewWidget::refresh() { if( !m_part->project() ) return; TQValueList openNodes; storeOpenNodes( openNodes, TQStringList(), firstChild() ); int scrollbarPos = verticalScrollBar()->value(); clear(); m_projectItem = new FolderBrowserItem( this, this, m_part->project()->projectName() ); m_projectItem->setOpen( true ); blockSignals( true ); FileList fileList = m_part->codeModel()->fileList(); FileList::Iterator it = fileList.begin(); while( it != fileList.end() ){ insertFile( (*it)->name() ); ++it; } TQValueList::iterator itt = openNodes.begin(); while ( itt != openNodes.end() ) { restoreOpenNodes ( *itt, firstChild() ); ++itt; } verticalScrollBar()->setValue( scrollbarPos ); blockSignals( false ); } void ClassViewWidget::slotProjectOpened( ) { m_projectItem = new FolderBrowserItem( this, this, m_part->project()->projectName() ); m_projectItem->setOpen( true ); m_projectDirectory = URLUtil::canonicalPath( m_part->project()->projectDirectory() ); if( m_projectDirectory.isEmpty() ) m_projectDirectory = m_part->project()->projectDirectory(); m_projectDirectoryLength = m_projectDirectory.length() + 1; connect( m_part->languageSupport(), TQT_SIGNAL(updatedSourceInfo()), this, TQT_SLOT(refresh()) ); connect( m_part->languageSupport(), TQT_SIGNAL(aboutToRemoveSourceInfo(const TQString&)), this, TQT_SLOT(removeFile(const TQString&)) ); connect( m_part->languageSupport(), TQT_SIGNAL(addedSourceInfo(const TQString&)), this, TQT_SLOT(insertFile(const TQString&)) ); } void ClassViewWidget::slotProjectClosed( ) { } void ClassViewWidget::insertFile( const TQString& fileName ) { TQString fn = URLUtil::canonicalPath( fileName ); //kdDebug() << "======================== insertFile(" << fn << ")" << endl; FileDom dom = m_part->codeModel()->fileByName( fn ); if( !dom ) return; fn = URLUtil::relativePathToFile(m_part->project()->projectDirectory(), fn); TQStringList path; switch( viewMode() ) { case KDevelop3ViewMode: { path = TQStringList::split( "/", fn ); path.pop_back(); } break; case TDevelop2ViewMode: { } break; case JavaLikeViewMode: { TQStringList l = TQStringList::split( "/", fn ); l.pop_back(); TQString package = l.join("."); if( !package.isEmpty() ) path.push_back( package ); } break; } m_projectItem->processFile( dom, path ); } void ClassViewWidget::removeFile( const TQString& fileName ) { TQString fn = URLUtil::canonicalPath( fileName ); //kdDebug() << "======================== removeFile(" << fn << ")" << endl; FileDom dom = m_part->codeModel()->fileByName( fn ); if( !dom ) return; fn = URLUtil::relativePathToFile(m_part->project()->projectDirectory(), fn); TQStringList path; switch( viewMode() ) { case KDevelop3ViewMode: { path = TQStringList::split( "/", fn ); path.pop_back(); } break; case TDevelop2ViewMode: { } break; case JavaLikeViewMode: { TQStringList l = TQStringList::split( "/", fn ); l.pop_back(); TQString package = l.join("."); if( !package.isEmpty() ) path.push_back( package ); } break; } m_projectItem->processFile( dom, path, true ); } void ClassViewWidget::contentsContextMenuEvent( TQContextMenuEvent * ev ) { TDEPopupMenu menu( this ); ClassViewItem* item = dynamic_cast( selectedItem() ); m_actionFollowEditor->plug( &menu ); m_actionFollowEditor->setChecked( m_doFollowEditor ); menu.insertSeparator(); m_actionOpenDeclaration->setEnabled( item && item->hasDeclaration() ); m_actionOpenImplementation->setEnabled( item && item->hasImplementation() ); m_actionOpenDeclaration->plug( &menu ); m_actionOpenImplementation->plug( &menu ); menu.insertSeparator(); bool sep = false; if( item && item->isClass() ){ if( m_part->langHasFeature(TDevLanguageSupport::AddMethod) ) { m_actionAddMethod->plug( &menu ); sep = true; } if( m_part->langHasFeature(TDevLanguageSupport::AddAttribute) ) { m_actionAddAttribute->plug( &menu ); sep = true; } } if (item && item->isVariable()){ if( m_part->langHasFeature(TDevLanguageSupport::CreateAccessMethods) ) m_actionCreateAccessMethods->plug( &menu ); } if( item && item->model() ){ CodeModelItemContext context( item->model() ); m_part->core()->fillContextMenu( &menu, &context ); // sep = true; } if (sep) menu.insertSeparator(); int oldViewMode = viewMode(); m_actionViewMode->plug( &menu ); menu.exec( ev->globalPos() ); if( viewMode() != oldViewMode ) refresh(); ev->consume(); } void ClassViewWidget::setViewMode( int mode ) { m_actionViewMode->setCurrentItem( mode ); } int ClassViewWidget::viewMode( ) const { return m_actionViewMode->currentItem(); } TQString ClassViewItem::comment() { return TQString(); } void ClassViewItem::select( ) { setOpen(true); listView()->setCurrentItem(this); TQListViewItem* c = firstChild(); int size = 0; if(c != 0) { while(c->nextSibling()) { c = c->nextSibling(); size++; } listView()->ensureItemVisible(c); } listView()->ensureItemVisible(this); } bool ClassViewWidget::selectItem( ItemDom item ) { if(!m_projectItem || !isVisible()) return false; if(item->isFunctionDefinition() && dynamic_cast(&(*item)) != 0) { FunctionList lst; FileList fileList = m_part->codeModel()->fileList(); CodeModelUtils::findFunctionDeclarations( FindOp2(FunctionDefinitionDom( (FunctionDefinitionModel*)&(*item) )), fileList, lst ); if(lst.isEmpty()) return false; item = *lst.begin(); } return m_projectItem->selectItem( item ); } TQString NamespaceDomBrowserItem::comment() { return m_dom->comment(); } bool FolderBrowserItem::selectItem(ItemDom item) { if(item->kind() == CodeModelItem::Class) { if( selectItemG ( item, m_classes ) ) return true; } if(item->kind() == CodeModelItem::Function) { if( selectItemG ( item, m_functions ) ) return true; } if(item->kind() == CodeModelItem::TypeAlias) { if( selectItemG ( item, m_typeAliases ) ) return true; } if(item->kind() == CodeModelItem::Variable) { if( selectItemG ( item, m_variables ) ) return true; } if(item->kind() == CodeModelItem::Namespace) { ///searching for namespaces is currently not supported and not useful } for( TQMap::Iterator it = m_classes.begin(); it != m_classes.end(); ++it ) { if( (*it)->selectItem(item) ) return true; } for( TQMap::Iterator it = m_namespaces.begin(); it != m_namespaces.end(); ++it ) { if( (*it)->selectItem(item) ) return true; } for( TQMap::Iterator it = m_folders.begin(); it != m_folders.end(); ++it ) { if( (*it)->selectItem(item) ) { return true; } } return false; } void FolderBrowserItem::processFile( FileDom file, TQStringList& path, bool remove ) { if( path.isEmpty() ){ NamespaceList namespaceList = file->namespaceList(); ClassList classList = file->classList(); TypeAliasList typeAliasList = file->typeAliasList(); FunctionList functionList = file->functionList(); VariableList variableList = file->variableList(); for( NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it ) processNamespace( *it, remove ); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) processVariable( *it, remove ); return; } TQString current = path.front(); path.pop_front(); FolderBrowserItem* item = m_folders.contains( current ) ? m_folders[ current ] : 0; if( !item ){ if( remove ) return; item = new FolderBrowserItem( m_widget, this, current ); if( listView()->removedText.contains(current) ) item->setOpen( true ); m_folders.insert( current, item ); } item->processFile( file, path, remove ); if( remove && item->childCount() == 0 ){ m_folders.remove( current ); if( item->isOpen() ){ listView()->removedText << current; } delete( item ); item = 0; } } void FolderBrowserItem::processNamespace( NamespaceDom ns, bool remove ) { NamespaceDomBrowserItem* item = m_namespaces.contains( ns->name() ) ? m_namespaces[ ns->name() ] : 0; if( !item ){ if( remove ) return; item = new NamespaceDomBrowserItem( this, ns ); if( listView()->removedText.contains(ns->name()) ) item->setOpen( true ); m_namespaces.insert( ns->name(), item ); } NamespaceList namespaceList = ns->namespaceList(); ClassList classList = ns->classList(); TypeAliasList typeAliasList = ns->typeAliasList(); FunctionList functionList = ns->functionList(); VariableList variableList = ns->variableList(); for( NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it ) item->processNamespace( *it, remove ); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) item->processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) item->processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) item->processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) item->processVariable( *it, remove ); if( remove && item->childCount() == 0 ){ m_namespaces.remove( ns->name() ); if( item->isOpen() ){ listView()->removedText << ns->name(); } delete( item ); item = 0; } } void FolderBrowserItem::processClass( ClassDom klass, bool remove ) { ClassDomBrowserItem* item = m_classes.contains( klass ) ? m_classes[ klass ] : 0; if( !item ){ if( remove ) return; item = new ClassDomBrowserItem( this, klass ); if( listView()->removedText.contains(klass->name()) ) item->setOpen( true ); m_classes.insert( klass, item ); } ClassList classList = klass->classList(); TypeAliasList typeAliasList = klass->typeAliasList(); FunctionList functionList = klass->functionList(); VariableList variableList = klass->variableList(); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) item->processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) item->processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) item->processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) item->processVariable( *it, remove ); if( remove && item->childCount() == 0 ){ m_classes.remove( klass ); if( item->isOpen() ){ listView()->removedText << klass->name(); } delete( item ); item = 0; } } void FolderBrowserItem::processTypeAlias( TypeAliasDom typeAlias, bool remove ) { TypeAliasDomBrowserItem* item = m_typeAliases.contains( typeAlias ) ? m_typeAliases[ typeAlias ] : 0; if( !item ){ if( remove ) return; item = new TypeAliasDomBrowserItem( this, typeAlias ); if( listView()->removedText.contains(typeAlias->name()) ) item->setOpen( true ); m_typeAliases.insert( typeAlias, item ); } if( remove && item->childCount() == 0 ){ m_typeAliases.remove( typeAlias ); if( item->isOpen() ){ listView()->removedText << typeAlias->name(); } delete( item ); item = 0; } } void FolderBrowserItem::processFunction( FunctionDom fun, bool remove ) { FunctionDomBrowserItem* item = m_functions.contains( fun ) ? m_functions[ fun ] : 0; if( !item ){ if( remove ) return; item = new FunctionDomBrowserItem( this, fun ); m_functions.insert( fun, item ); } if( remove ){ m_functions.remove( fun ); delete( item ); item = 0; } } void FolderBrowserItem::processVariable( VariableDom var, bool remove ) { VariableDomBrowserItem* item = m_variables.contains( var ) ? m_variables[ var ] : 0; if( !item ){ if( remove ) return; item = new VariableDomBrowserItem( this, var ); m_variables.insert( var, item ); } if( remove ){ m_variables.remove( var ); delete( item ); item = 0; } } // ------------------------------------------------------------------------ bool NamespaceDomBrowserItem::selectItem( ItemDom item) { if(item->kind() == CodeModelItem::Class) { if( selectItemG ( item, m_classes ) ) return true; } if(item->kind() == CodeModelItem::Function) { if( selectItemG ( item, m_functions ) ) return true; } if(item->kind() == CodeModelItem::TypeAlias) { if( selectItemG ( item, m_typeAliases ) ) return true; } if(item->kind() == CodeModelItem::Variable) { if( selectItemG ( item, m_variables ) ) return true; } if(item->kind() == CodeModelItem::Namespace) { ///currently not neccessary.. } for(TQMap::Iterator it = m_classes.begin(); it != m_classes.end(); ++it) { if( (*it)->selectItem(item) ) return true; } for(TQMap::Iterator it = m_namespaces.begin(); it != m_namespaces.end(); ++it) { if( (*it)->selectItem(item) ) return true; } return false; } void NamespaceDomBrowserItem::processNamespace( NamespaceDom ns, bool remove ) { NamespaceDomBrowserItem* item = m_namespaces.contains( ns->name() ) ? m_namespaces[ ns->name() ] : 0; if( !item ){ if( remove ) return; item = new NamespaceDomBrowserItem( this, ns ); if( listView()->removedText.contains(ns->name()) ) item->setOpen( true ); m_namespaces.insert( ns->name(), item ); } NamespaceList namespaceList = ns->namespaceList(); ClassList classList = ns->classList(); TypeAliasList typeAliasList = ns->typeAliasList(); FunctionList functionList = ns->functionList(); VariableList variableList = ns->variableList(); for( NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it ) item->processNamespace( *it, remove ); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) item->processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) item->processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) item->processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) item->processVariable( *it, remove ); if( remove && item->childCount() == 0 ){ m_namespaces.remove( ns->name() ); if( item->isOpen() ){ listView()->removedText << ns->name(); } delete( item ); item = 0; } } void NamespaceDomBrowserItem::processClass( ClassDom klass, bool remove ) { ClassDomBrowserItem* item = m_classes.contains( klass ) ? m_classes[ klass ] : 0; if( !item ){ if( remove ) return; item = new ClassDomBrowserItem( this, klass ); if( listView()->removedText.contains(klass->name()) ) item->setOpen( true ); m_classes.insert( klass, item ); } ClassList classList = klass->classList(); TypeAliasList typeAliasList = klass->typeAliasList(); FunctionList functionList = klass->functionList(); VariableList variableList = klass->variableList(); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) item->processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) item->processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) item->processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) item->processVariable( *it, remove ); if( remove && item->childCount() == 0 ){ m_classes.remove( klass ); if( item->isOpen() ){ listView()->removedText << klass->name(); } delete( item ); item = 0; } } void NamespaceDomBrowserItem::processTypeAlias( TypeAliasDom typeAlias, bool remove ) { TypeAliasDomBrowserItem* item = m_typeAliases.contains( typeAlias ) ? m_typeAliases[ typeAlias ] : 0; if( !item ){ if( remove ) return; item = new TypeAliasDomBrowserItem( this, typeAlias ); if( listView()->removedText.contains(typeAlias->name()) ) item->setOpen( true ); m_typeAliases.insert( typeAlias, item ); } if( remove && item->childCount() == 0 ){ m_typeAliases.remove( typeAlias ); if( item->isOpen() ){ listView()->removedText << typeAlias->name(); } delete( item ); item = 0; } } void NamespaceDomBrowserItem::processFunction( FunctionDom fun, bool remove ) { FunctionDomBrowserItem* item = m_functions.contains( fun ) ? m_functions[ fun ] : 0; if( !item ){ if( remove ) return; item = new FunctionDomBrowserItem( this, fun ); m_functions.insert( fun, item ); } if( remove ){ m_functions.remove( fun ); delete( item ); item = 0; } } void NamespaceDomBrowserItem::processVariable( VariableDom var, bool remove ) { VariableDomBrowserItem* item = m_variables.contains( var ) ? m_variables[ var ] : 0; if( !item ){ if( remove ) return; item = new VariableDomBrowserItem( this, var ); m_variables.insert( var, item ); } if( remove ){ m_variables.remove( var ); delete( item ); item = 0; } } // ------------------------------------------------------------------------ bool ClassDomBrowserItem::selectItem(ItemDom item) { if(item->kind() == CodeModelItem::Class) { if( selectItemG ( item, m_classes ) ) return true; } if(item->kind() == CodeModelItem::Function) { if( selectItemG ( item, m_functions ) ) return true; } if(item->kind() == CodeModelItem::TypeAlias) { if( selectItemG ( item, m_typeAliases ) ) return true; } if(item->kind() == CodeModelItem::Variable) { if( selectItemG ( item, m_variables ) ) return true; } for(TQMap::Iterator it = m_classes.begin(); it != m_classes.end(); ++it) { if( (*it)->selectItem(item) ) return true; } return false; } void ClassDomBrowserItem::processClass( ClassDom klass, bool remove ) { ClassDomBrowserItem* item = m_classes.contains( klass ) ? m_classes[ klass ] : 0; if( !item ){ if( remove ) return; item = new ClassDomBrowserItem( this, klass ); if( listView()->removedText.contains(klass->name()) ) item->setOpen( true ); m_classes.insert( klass, item ); } ClassList classList = klass->classList(); TypeAliasList typeAliasList = klass->typeAliasList(); FunctionList functionList = klass->functionList(); VariableList variableList = klass->variableList(); for( ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it ) item->processClass( *it, remove ); for( TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it ) item->processTypeAlias( *it, remove ); for( FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it ) item->processFunction( *it, remove ); for( VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it ) item->processVariable( *it, remove ); if( remove && item->childCount() == 0 ){ m_classes.remove( klass ); if( item->isOpen() ){ listView()->removedText << klass->name(); } delete( item ); item = 0; } } void ClassDomBrowserItem::processTypeAlias( TypeAliasDom typeAlias, bool remove ) { TypeAliasDomBrowserItem* item = m_typeAliases.contains( typeAlias ) ? m_typeAliases[ typeAlias ] : 0; if( !item ){ if( remove ) return; item = new TypeAliasDomBrowserItem( this, typeAlias ); if( listView()->removedText.contains(typeAlias->name()) ) item->setOpen( true ); m_typeAliases.insert( typeAlias, item ); } if( remove && item->childCount() == 0 ){ m_typeAliases.remove( typeAlias ); if( item->isOpen() ){ listView()->removedText << typeAlias->name(); } delete( item ); item = 0; } } void ClassDomBrowserItem::processFunction( FunctionDom fun, bool remove ) { FunctionDomBrowserItem* item = m_functions.contains( fun ) ? m_functions[ fun ] : 0; if( !item ){ if( remove ) return; item = new FunctionDomBrowserItem( this, fun ); m_functions.insert( fun, item ); } if( remove ){ m_functions.remove( fun ); delete( item ); item = 0; } } void ClassDomBrowserItem::processVariable( VariableDom var, bool remove ) { VariableDomBrowserItem* item = m_variables.contains( var ) ? m_variables[ var ] : 0; if( !item ){ if( remove ) return; item = new VariableDomBrowserItem( this, var ); m_variables.insert( var, item ); } if( remove ){ m_variables.remove( var ); delete( item ); item = 0; } } void FolderBrowserItem::setup( ) { ClassViewItem::setup(); setPixmap( 0, SmallIcon("folder") ); setExpandable( true ); } void NamespaceDomBrowserItem::setup( ) { ClassViewItem::setup(); setPixmap( 0, UserIcon("CVnamespace", TDEIcon::DefaultState, listView()->m_part->instance()) ); setExpandable( true ); TQString txt = listView()->m_part->languageSupport()->formatModelItem(m_dom.data(), true); setText( 0, txt ); } void ClassDomBrowserItem::setup( ) { ClassViewItem::setup(); setPixmap( 0, UserIcon("CVclass", TDEIcon::DefaultState, listView()->m_part->instance()) ); setExpandable( true ); TQString txt = listView()->m_part->languageSupport()->formatModelItem(m_dom.data(), true); setText( 0, txt ); } void TypeAliasDomBrowserItem::setup( ) { ClassViewItem::setup(); setPixmap( 0, UserIcon("CVtypedef", TDEIcon::DefaultState, listView()->m_part->instance()) ); setExpandable( false ); TQString txt = listView()->m_part->languageSupport()->formatModelItem(m_dom.data(), true); setText( 0, txt ); } void FunctionDomBrowserItem::setup( ) { ClassViewItem::setup(); TQString iconName; TQString methodType; if ( m_dom->isSignal() ) methodType = "signal"; else if (m_dom->isSlot() ) methodType = "slot"; else methodType = "meth"; if( m_dom->access() == CodeModelItem::Private ) iconName = "CVprivate_" + methodType; else if( m_dom->access() == CodeModelItem::Protected ) iconName = "CVprotected_" + methodType; else iconName = "CVpublic_" + methodType; setPixmap( 0, UserIcon(iconName, TDEIcon::DefaultState, listView()->m_part->instance()) ); TQString txt = listView()->m_part->languageSupport()->formatModelItem(m_dom.data(), true); item() = highlightFunctionName(txt, 1, m_styles); } void FunctionDomBrowserItem::openDeclaration() { int startLine, startColumn; m_dom->getStartPosition( &startLine, &startColumn ); listView()->m_part->partController()->editDocument( KURL(m_dom->fileName()), startLine ); } void FunctionDomBrowserItem::openImplementation() { FunctionDefinitionList lst; FileList fileList = listView()->m_part->codeModel()->fileList(); CodeModelUtils::findFunctionDefinitions( FindOp(m_dom), fileList, lst ); if( lst.isEmpty() ) return; FunctionDefinitionDom fun; TQFileInfo fileInfo( m_dom->fileName() ); TQString path = fileInfo.dirPath( true ); for( FunctionDefinitionList::Iterator it=lst.begin(); it!=lst.end(); ++it ) { TQFileInfo defFileInfo( (*it)->fileName() ); TQString defPath = defFileInfo.dirPath( true ); if( path != defPath ) continue; if( defFileInfo.baseName() == fileInfo.baseName() ) { fun = *it; } else if( !fun ) { fun = *it; } } if( !fun ) { fun = lst.front(); } int startLine, startColumn; fun->getStartPosition( &startLine, &startColumn ); listView()->m_part->partController()->editDocument( KURL(fun->fileName()), startLine ); } void VariableDomBrowserItem::setup( ) { ClassViewItem::setup(); TQString iconName; if( m_dom->access() == CodeModelItem::Private ) iconName = "CVprivate_var"; else if( m_dom->access() == CodeModelItem::Protected ) iconName = "CVprotected_var"; else iconName = "CVpublic_var"; setPixmap( 0, UserIcon(iconName, TDEIcon::DefaultState, listView()->m_part->instance()) ); TQString txt = listView()->m_part->languageSupport()->formatModelItem(m_dom.data(), true); setText( 0, txt ); } void VariableDomBrowserItem::openDeclaration() { int startLine, startColumn; m_dom->getStartPosition( &startLine, &startColumn ); listView()->m_part->partController()->editDocument( KURL(m_dom->fileName()), startLine ); } void VariableDomBrowserItem::openImplementation() { } TQString FolderBrowserItem::key( int , bool ) const { return "0 " + text( 0 ); } TQString NamespaceDomBrowserItem::key( int , bool ) const { return "1 " + text( 0 ); } TQString ClassDomBrowserItem::key( int , bool ) const { return "2 " + text( 0 ); } TQString TypeAliasDomBrowserItem::key( int , bool ) const { return "3 " + text( 0 ); } TQString FunctionDomBrowserItem::key( int , bool ) const { return "4 " + text( 0 ); } TQString VariableDomBrowserItem::key( int , bool ) const { return "5 " + text( 0 ); } void ClassViewWidget::slotNewClass( ) { if( m_part->languageSupport()->features() & TDevLanguageSupport::NewClass ) m_part->languageSupport()->addClass(); } void ClassViewWidget::slotAddMethod( ) { if ( !selectedItem() ) return; if( m_part->languageSupport()->features() & TDevLanguageSupport::AddMethod ) m_part->languageSupport()->addMethod( static_cast( selectedItem() )->dom() ); } void ClassViewWidget::slotAddAttribute( ) { if ( !selectedItem() ) return; if( m_part->languageSupport()->features() & TDevLanguageSupport::AddAttribute ) m_part->languageSupport()->addAttribute( static_cast( selectedItem() )->dom() ); } void ClassViewWidget::slotOpenDeclaration( ) { if ( !selectedItem() ) return; static_cast( selectedItem() )->openDeclaration(); } void ClassViewWidget::slotOpenImplementation( ) { if ( !selectedItem() ) return; static_cast( selectedItem() )->openImplementation(); } void ClassDomBrowserItem::openDeclaration( ) { int startLine, startColumn; m_dom->getStartPosition( &startLine, &startColumn ); listView()->m_part->partController()->editDocument( KURL(m_dom->fileName()), startLine ); } void TypeAliasDomBrowserItem::openDeclaration( ) { int startLine, startColumn; m_dom->getStartPosition( &startLine, &startColumn ); listView()->m_part->partController()->editDocument( KURL(m_dom->fileName()), startLine ); } bool FunctionDomBrowserItem::hasImplementation() const { FunctionDefinitionList lst; FileList fileList = listView()->m_part->codeModel()->fileList(); CodeModelUtils::findFunctionDefinitions( FindOp(m_dom), fileList, lst ); return !lst.isEmpty(); } void ClassViewWidget::maybeTip( TQPoint const & p ) { ClassViewItem * item = dynamic_cast( itemAt( p ) ); if ( !item ) return; TQString tooltip; if ( item->isNamespace() ) { NamespaceDomBrowserItem * nitem = dynamic_cast( item ); if ( nitem ) { tooltip = nitem->dom()->scope().join("::") + "::" + nitem->dom()->name(); } } else if ( item->isClass() ) { ClassDomBrowserItem * citem = dynamic_cast( item ); if ( citem ) { tooltip = citem->dom()->scope().join("::") + "::" + citem->dom()->name() + " : " + citem->dom()->baseClassList().join(", "); } } else if ( item->isFunction() ) { FunctionDomBrowserItem * fitem = dynamic_cast( item ); if ( fitem ) { TQString access; if ( fitem->dom()->access() == CodeModelItem::Private ) access = "[private] "; else if ( fitem->dom()->access() == CodeModelItem::Protected ) access = "[protected] "; else if ( fitem->dom()->access() == CodeModelItem::Public ) access = "[public] "; TQStringList arguments; ArgumentList const & list = fitem->dom()->argumentList(); ArgumentList::ConstIterator it( list.begin() ); while ( it != list.end() ) { arguments << ((*it)->type() + " " + (*it)->name()); ++it; } TQString strstatic = fitem->dom()->isStatic() ? TQString( "[static] " ) : TQString(); TQString strsignal = fitem->dom()->isSignal() ? TQString( "[signal] " ) : TQString(); TQString strslot = fitem->dom()->isSlot() ? TQString( "[slot] " ) : TQString(); TQString strresult = !fitem->dom()->resultType().isEmpty() ? fitem->dom()->resultType() + " " : TQString(); TQString strconstant = fitem->dom()->isConstant() ? TQString( " [const]" ) : TQString(); TQString strabstract = fitem->dom()->isAbstract() ? TQString( " [abstract]" ) : TQString(); tooltip = access + strstatic + strsignal + strslot + strresult + fitem->dom()->scope().join("::") + "::" + fitem->dom()->name() + "(" + arguments.join(", ") + ")" + strconstant + strabstract; } } else if ( item->isVariable() ) { VariableDomBrowserItem * vitem = dynamic_cast( item ); if ( vitem ) { TQString access; if ( vitem->dom()->access() == CodeModelItem::Private ) access = "[private] "; else if ( vitem->dom()->access() == CodeModelItem::Protected ) access = "[protected] "; else if ( vitem->dom()->access() == CodeModelItem::Public ) access = "[public] "; TQString strstatic = vitem->dom()->isStatic() ? TQString( "[static] " ) : TQString(); tooltip = access + strstatic + vitem->dom()->type() + " " + vitem->dom()->name(); } } else if ( item->isTypeAlias() ) { if( TypeAliasDomBrowserItem * titem = dynamic_cast( item ) ) { tooltip = TQString( "[Type] " ) + titem->dom()->type() + " " + titem->dom()->name(); } } const int maxCommentSize = 300; if( !item->comment().isEmpty() ) { tooltip += "\n"; tooltip += item->comment().length() > maxCommentSize ? item->comment().left( maxCommentSize ) + " [...]" : item->comment(); } kdDebug(0) << tooltip << endl; TQRect r = itemRect( item ); if ( item && r.isValid() && !tooltip.isEmpty() ) { tip( r, TQString("

") + TQStyleSheet::escape( tooltip ) + TQString("
") ); } } void ClassViewWidget::slotCreateAccessMethods( ) { if ( !selectedItem() ) return; if( m_part->languageSupport()->features() & TDevLanguageSupport::CreateAccessMethods ) { VariableDomBrowserItem* item = dynamic_cast( selectedItem() ); if (item == 0) return; m_part->languageSupport()->createAccessMethods(static_cast(static_cast(item->parent())->dom()),static_cast(item->dom())); } } void ClassViewWidget::slotFollowEditor() { m_doFollowEditor = m_actionFollowEditor->isChecked(); } bool ClassViewWidget::doFollowEditor() { return m_doFollowEditor; } #include "classviewwidget.moc"