00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "classbrowser_part.h"
00013 #include "classbrowser_widget.h"
00014
00015 #include <catalog.h>
00016 #include <kdevlanguagesupport.h>
00017 #include <kdevproject.h>
00018 #include <kdevcoderepository.h>
00019 #include <kdevlanguagesupport.h>
00020 #include <kdevpartcontroller.h>
00021
00022 #include <kparts/part.h>
00023
00024 #include <klibloader.h>
00025 #include <kurl.h>
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <klistview.h>
00029 #include <kcombobox.h>
00030 #include <klineedit.h>
00031 #include <kstandarddirs.h>
00032 #include <kdevcore.h>
00033 #include <kpushbutton.h>
00034
00035 #include <qlabel.h>
00036 #include <qheader.h>
00037 #include <qfileinfo.h>
00038
00039 class TagListViewItem: public KListViewItem
00040 {
00041 public:
00042 TagListViewItem( KListView* parent, const Tag& tag, Catalog* c )
00043 : KListViewItem( parent ), m_tag( tag ), m_catalog( c ) { init(); }
00044 TagListViewItem( KListViewItem* parent, const Tag& tag, Catalog* c )
00045 : KListViewItem( parent ), m_tag( tag ), m_catalog( c ) { init(); }
00046
00047 void init()
00048 {
00049 if( m_tag.kind() == Tag::Kind_Namespace || m_tag.kind() == Tag::Kind_Class ){
00050 setExpandable( true );
00051 }
00052
00053 QString fileName = m_tag.fileName();
00054 if( fileName.isEmpty() )
00055 fileName = "<nofile>";
00056
00057 setText( 0, languageSupport()->formatTag(m_tag) );
00058 setText( 1, fileName );
00059 int line, column;
00060 m_tag.getStartPosition( &line, &column );
00061 setText( 2, QString::number(line+1) );
00062 setText( 3, QString::number(column+1) );
00063 }
00064
00065 bool needRefresh()
00066 {
00067 return true;
00068 }
00069
00070 void refresh()
00071 {
00072 if( needRefresh() ){
00073 clear();
00074 computeChilds();
00075 }
00076 }
00077
00078 void computeChilds()
00079 {
00080 QStringList scope;
00081 scope += m_tag.scope();
00082 scope << m_tag.name();
00083
00084 QValueList<Catalog::QueryArgument> args;
00085 args << Catalog::QueryArgument( "scope", scope );
00086 args << Catalog::QueryArgument( "kind", Tag::Kind_Class );
00087 if( m_tag.kind() == Tag::Kind_Class )
00088 args << Catalog::QueryArgument( "fileName", m_tag.fileName() );
00089 QValueList<Tag> tags = m_catalog->query( args );
00090
00091 args.clear();
00092 args << Catalog::QueryArgument( "scope", scope );
00093 args << Catalog::QueryArgument( "kind", Tag::Kind_Namespace );
00094 tags += ClassBrowserUtils::simplifyNamespaces( m_catalog->query(args) );
00095
00096 args.clear();
00097 args << Catalog::QueryArgument( "scope", scope );
00098 args << Catalog::QueryArgument( "kind", Tag::Kind_FunctionDeclaration );
00099 if( m_tag.kind() == Tag::Kind_Class )
00100 args << Catalog::QueryArgument( "fileName", m_tag.fileName() );
00101 tags += m_catalog->query( args );
00102
00103 args.clear();
00104 args << Catalog::QueryArgument( "scope", scope );
00105 args << Catalog::QueryArgument( "kind", Tag::Kind_Variable );
00106 if( m_tag.kind() == Tag::Kind_Class )
00107 args << Catalog::QueryArgument( "fileName", m_tag.fileName() );
00108 tags += m_catalog->query( args );
00109
00110 QValueList<Tag>::Iterator it = tags.begin();
00111 while( it != tags.end() ){
00112 const Tag& tag = *it;
00113 ++it;
00114
00115 if( !tag.name().isEmpty() ){
00116 TagListViewItem* i = new TagListViewItem( this, tag, m_catalog );
00117 if( m_removedItems.contains(i->text(0)) )
00118 i->setOpen( true );
00119 }
00120 }
00121 }
00122
00123 void setOpen( bool opened )
00124 {
00125 if( opened == true ){
00126 refresh();
00127 }
00128 KListViewItem::setOpen( opened );
00129 }
00130
00131 void clear()
00132 {
00133 m_removedItems.clear();
00134 while( firstChild() ){
00135 if( firstChild()->isOpen() )
00136 m_removedItems << firstChild()->text( 0 );
00137
00138 delete firstChild();
00139 }
00140 }
00141
00142 Catalog* catalog()
00143 {
00144 return m_catalog;
00145 }
00146
00147 KDevLanguageSupport* languageSupport()
00148 {
00149 ClassBrowserWidget* cb = static_cast<ClassBrowserWidget*>( listView() );
00150 return cb->languageSupport();
00151 }
00152
00153 private:
00154 Tag m_tag;
00155 Catalog* m_catalog;
00156 QStringList m_removedItems;
00157 };
00158
00159 class CatalogListViewItem: public KListViewItem
00160 {
00161 public:
00162 CatalogListViewItem( KListView* parent, Catalog* c )
00163 : KListViewItem( parent ), m_catalog( c )
00164 {
00165 QFileInfo info( m_catalog->dbName() );
00166 setText( 0, info.fileName() );
00167 }
00168
00169 bool needRefresh()
00170 {
00171 return true;
00172 }
00173
00174 void refresh()
00175 {
00176 if( needRefresh() ){
00177 clear();
00178 computeChilds();
00179 }
00180 }
00181
00182 void computeChilds()
00183 {
00184 QValueList<Catalog::QueryArgument> args;
00185 args << Catalog::QueryArgument( "scope", QStringList() );
00186 args << Catalog::QueryArgument( "kind", Tag::Kind_Class );
00187 QValueList<Tag> tags = m_catalog->query( args );
00188
00189 args.clear();
00190 args << Catalog::QueryArgument( "scope", QStringList() );
00191 args << Catalog::QueryArgument( "kind", Tag::Kind_Namespace );
00192 tags += ClassBrowserUtils::simplifyNamespaces( m_catalog->query(args) );
00193
00194 QValueList<Tag>::Iterator it = tags.begin();
00195 while( it != tags.end() ){
00196 const Tag& tag = *it;
00197 ++it;
00198
00199 if( !tag.name().isEmpty() ){
00200 TagListViewItem* i = new TagListViewItem( this, tag, m_catalog );
00201 if( m_removedItems.contains(i->text(0)) )
00202 i->setOpen( true );
00203 }
00204 }
00205 }
00206
00207 void setOpen( bool opened )
00208 {
00209 if( opened == true ){
00210 refresh();
00211 }
00212 KListViewItem::setOpen( opened );
00213 }
00214
00215 void clear()
00216 {
00217 m_removedItems.clear();
00218 while( firstChild() ){
00219 if( firstChild()->isOpen() )
00220 m_removedItems << firstChild()->text( 0 );
00221
00222 delete firstChild();
00223 }
00224 }
00225
00226 Catalog* catalog()
00227 {
00228 return m_catalog;
00229 }
00230
00231 private:
00232 Catalog* m_catalog;
00233 QStringList m_removedItems;
00234 };
00235
00236 ClassBrowserWidget::ClassBrowserWidget( ClassBrowserPart* part )
00237 : KListView( 0, "ClassBrowserWidget" ), m_part( part )
00238 {
00239
00240
00241 this->addColumn( i18n("Symbol") );
00242
00243
00244
00245 this->header()->hide();
00246
00247 this->setRootIsDecorated( true );
00248
00249 init();
00250
00251 connect( m_part->codeRepository(), SIGNAL(catalogRegistered(Catalog*)),
00252 this, SLOT(addCatalog(Catalog*)) );
00253 connect( m_part->codeRepository(), SIGNAL(catalogUnemoved(Catalog*)),
00254 this, SLOT(removeCatalog(Catalog*)) );
00255 connect( m_part->codeRepository(), SIGNAL(catalogChanged(Catalog*)),
00256 this, SLOT(slotCatalogChanged(Catalog*)) );
00257
00258 connect( this, SIGNAL(executed(QListViewItem*)),
00259 this, SLOT(slotItemExecuted(QListViewItem*)) );
00260 }
00261
00262 ClassBrowserWidget::~ClassBrowserWidget()
00263 {
00264 }
00265
00266 void ClassBrowserWidget::slotStartSearch( )
00267 {
00268 }
00269
00270 void ClassBrowserWidget::init( )
00271 {
00272 }
00273
00274 void ClassBrowserWidget::addCatalog( Catalog * catalog )
00275 {
00276 KListViewItem* item = new CatalogListViewItem( this, catalog );
00277 item->setExpandable( true );
00278 m_items.insert( catalog, item );
00279 }
00280
00281 void ClassBrowserWidget::removeCatalog( Catalog * catalog )
00282 {
00283 m_items.remove( catalog );
00284 }
00285
00286 void ClassBrowserWidget::slotCatalogChanged( Catalog * catalog )
00287 {
00288 kdDebug(9000) << "ClassBrowserWidget::slotCatalogChanged()" << endl;
00289
00290 CatalogListViewItem* item = static_cast< CatalogListViewItem* >( m_items[catalog] );
00291 if( !item || !item->isOpen() )
00292 return;
00293
00294 item->refresh();
00295 }
00296
00297 KDevLanguageSupport* ClassBrowserWidget::languageSupport()
00298 {
00299 return m_part->languageSupport();
00300 }
00301
00302 void ClassBrowserWidget::slotItemExecuted( QListViewItem* item )
00303 {
00304 m_part->partController()->editDocument( KURL(item->text(1)), item->text(2).toInt() );
00305 }
00306
00307 #include "classbrowser_widget.moc"