KDevelop API Documentation

parts/classview/classtreebase.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 1999 by Jonas Nordin * 00003 * jonas.nordin@syncom.se * 00004 * Copyright (C) 2000-2001 by Bernd Gehrmann * 00005 * bernd@kdevelop.org * 00006 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 ***************************************************************************/ 00013 00014 #include "classtreebase.h" 00015 00016 #include <qtooltip.h> 00017 #include <qheader.h> 00018 #include <qregexp.h> 00019 #include <kdebug.h> 00020 #include <kconfig.h> 00021 #include <kpopupmenu.h> 00022 #include <klocale.h> 00023 #include <kiconloader.h> 00024 00025 #include "kdevcore.h" 00026 #include "kdevlanguagesupport.h" 00027 #include "kdevmainwindow.h" 00028 #include "kdevpartcontroller.h" 00029 #include "classstore.h" 00030 00031 #include "classviewpart.h" 00032 #include "classtooldlg.h" 00033 00034 KPopupMenu *ClassTreeItem::createPopup() 00035 { 00036 if (!m_item || m_item->itemType() == PIT_SCOPE) 00037 return 0; 00038 00039 KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features(); 00040 00041 KPopupMenu *popup = new KPopupMenu(); 00042 if (features & KDevLanguageSupport::Declarations) 00043 popup->insertItem( i18n("Go to Declaration"), classTree(), SLOT(slotGotoDeclaration()) ); 00044 if (m_item->itemType() == PIT_METHOD) 00045 popup->insertItem( i18n("Go to Definition"), classTree(), SLOT(slotGotoImplementation()) ); 00046 00047 QString title; 00048 switch(m_item->itemType()) { 00049 case PIT_CLASS: 00050 { 00051 title = i18n("Class"); 00052 bool hasAddMethod = features & KDevLanguageSupport::AddMethod; 00053 bool hasAddAttribute = features & KDevLanguageSupport::AddAttribute; 00054 if (hasAddMethod) 00055 popup->insertItem( i18n("Add Method..."), classTree(), SLOT(slotAddMethod())); 00056 if (hasAddAttribute) 00057 popup->insertItem( i18n("Add Attribute..."), classTree(), SLOT(slotAddAttribute())); 00058 popup->insertSeparator(); 00059 popup->insertItem( i18n("Parent Classes..."), classTree(), SLOT(slotClassBaseClasses())); 00060 popup->insertItem( i18n("Child Classes..."), classTree(), SLOT(slotClassDerivedClasses())); 00061 popup->insertItem( i18n("Class Tool..."), classTree(), SLOT(slotClassTool())); 00062 } 00063 break; 00064 case PIT_STRUCT: 00065 title = i18n("Struct"); 00066 break; 00067 case PIT_ATTRIBUTE: 00068 if (m_item->isGlobal()) 00069 title = i18n("Variable"); 00070 else 00071 title = i18n("Attribute"); 00072 break; 00073 case PIT_METHOD: 00074 if (static_cast<ParsedMethod*>(m_item)->isSlot()) 00075 title = i18n("Slot"); 00076 else if (static_cast<ParsedMethod*>(m_item)->isSignal()) 00077 title = i18n("Signal"); 00078 else if (m_item->isGlobal()) 00079 title = i18n("Function"); 00080 else 00081 title = i18n("Method"); 00082 break; 00083 default: 00084 ; 00085 } 00086 popup->insertSeparator(); 00087 popup->insertTitle(title, -1, 0); 00088 00089 return popup; 00090 } 00091 00092 00093 QString ClassTreeItem::scopedText() const 00094 { 00095 if (m_item) 00096 return m_item->path(); 00097 00098 return QString::null; 00099 } 00100 00101 00102 void ClassTreeItem::getDeclaration(QString *toFile, int *toLine) 00103 { 00104 if (m_item) { 00105 *toFile = m_item->declaredInFile(); 00106 *toLine = m_item->declaredOnLine(); 00107 } 00108 } 00109 00110 00111 void ClassTreeItem::getImplementation(QString *toFile, int *toLine) 00112 { 00113 if (m_item) { 00114 *toFile = m_item->definedInFile(); 00115 *toLine = m_item->definedOnLine(); 00116 } 00117 } 00118 00119 00120 QString ClassTreeItem::text( int ) const 00121 { 00122 if (m_item) 00123 return m_item->asString(); 00124 return QString::null; 00125 } 00126 00127 00128 QString ClassTreeItem::tipText() const 00129 { 00130 // Purposefully avoid virtual dispatch here 00131 return ClassTreeItem::text(0); 00132 } 00133 00134 00135 void ClassTreeOrganizerItem::init() 00136 { 00137 setExpandable(true); 00138 setPixmap(0, SmallIcon("folder")); 00139 } 00140 00141 00142 void ClassTreeScopeItem::init() 00143 { 00144 setExpandable(true); 00145 setPixmap(0, UserIcon("CVnamespace", KIcon::DefaultState, ClassViewFactory::instance())); 00146 } 00147 00148 00149 QString ClassTreeScopeItem::text( int col ) const 00150 { 00151 if (!m_item) 00152 return QString::null; 00153 if (m_item->name().isEmpty()) 00154 return i18n("Global"); 00155 return ClassTreeItem::text( col ); 00156 } 00157 00158 00159 void ClassTreeScopeItem::setOpen(bool o) 00160 { 00161 if ( !m_item) 00162 return; 00163 00164 kdDebug(9003) << (o? "Open scope item" : "Close scope item") << endl; 00165 if (o && childCount() == 0) { 00166 00167 ParsedScopeContainer *pScope = static_cast<ParsedScopeContainer*>(m_item); 00168 ClassTreeItem *lastItem = 0; 00169 00170 // Ok, this is a hack... 00171 KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features(); 00172 00173 // Add namespaces 00174 QValueList<ParsedScopeContainer*> scopeList = pScope->getSortedScopeList(); 00175 QValueList<ParsedScopeContainer*>::ConstIterator it; 00176 for (it = scopeList.begin(); it != scopeList.end(); ++it) 00177 lastItem = new ClassTreeScopeItem(this, lastItem, *it); 00178 00179 if (features & KDevLanguageSupport::Classes) { 00180 // Add classes 00181 QValueList<ParsedClass*> classList = pScope->getSortedClassList(); 00182 QValueList<ParsedClass*>::ConstIterator it; 00183 for (it = classList.begin(); it != classList.end(); ++it) 00184 lastItem = new ClassTreeClassItem(this, lastItem, *it); 00185 } 00186 00187 if (features & KDevLanguageSupport::Structs) { 00188 // Add structs 00189 QValueList<ParsedClass*> structList = pScope->getSortedStructList(); 00190 QValueList<ParsedClass*>::ConstIterator it; 00191 for (it = structList.begin(); it != structList.end(); ++it) 00192 lastItem = new ClassTreeClassItem(this, lastItem, *it, true); 00193 } 00194 00195 if (features & KDevLanguageSupport::Functions) { 00196 // Add functions 00197 QValueList<ParsedMethod*> methodList = pScope->getSortedMethodList(); 00198 QValueList<ParsedMethod*>::ConstIterator it; 00199 for (it = methodList.begin(); it != methodList.end(); ++it) 00200 lastItem = new ClassTreeMethodItem(this, lastItem, *it); 00201 } 00202 00203 if (features & KDevLanguageSupport::Variables) { 00204 // Add attributes 00205 QValueList<ParsedAttribute*> attrList = pScope->getSortedAttributeList(); 00206 QValueList<ParsedAttribute*>::ConstIterator it; 00207 for (it = attrList.begin(); it != attrList.end(); ++it) 00208 lastItem = new ClassTreeAttrItem(this, lastItem, *it); 00209 } 00210 00211 } 00212 00213 ClassTreeItem::setOpen(o); 00214 } 00215 00216 00217 void ClassTreeClassItem::init() 00218 { 00219 setExpandable(true); 00220 setPixmap(0, UserIcon(m_isStruct ? "CVstruct" : "CVclass", KIcon::DefaultState, ClassViewFactory::instance())); 00221 } 00222 00223 00224 void ClassTreeClassItem::setOpen(bool o) 00225 { 00226 if ( !m_item ) 00227 return; 00228 kdDebug(9003) << (o? "Open class item" : "Close class item") << endl; 00229 if (o && childCount() == 0) { 00230 00231 ParsedClass *pClass = static_cast<ParsedClass*>(m_item); 00232 ClassTreeItem *lastItem = 0; 00233 00234 // Add nested classes 00235 QValueList<ParsedClass*> classList = pClass->getSortedClassList(); 00236 QValueList<ParsedClass*>::ConstIterator classIt; 00237 for (classIt = classList.begin(); classIt != classList.end(); ++classIt) 00238 lastItem = new ClassTreeClassItem(this, lastItem, *classIt); 00239 00240 // Add nested structs 00241 QValueList<ParsedClass*> structList = pClass->getSortedStructList(); 00242 QValueList<ParsedClass*>::ConstIterator structIt; 00243 for (structIt = structList.begin(); structIt != structList.end(); ++structIt) 00244 lastItem = new ClassTreeClassItem(this, lastItem, *structIt, true); 00245 00246 // Add methods 00247 QValueList<ParsedMethod*> methodList = pClass->getSortedMethodList(); 00248 QValueList<ParsedMethod*>::ConstIterator methodIt; 00249 for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt) 00250 lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt); 00251 00252 // Add slots 00253 QValueList<ParsedMethod*> slotList = pClass->getSortedSlotList(); 00254 QValueList<ParsedMethod*>::ConstIterator slotIt; 00255 for (slotIt = slotList.begin(); slotIt != slotList.end(); ++slotIt) 00256 lastItem = new ClassTreeMethodItem(this, lastItem, *slotIt); 00257 00258 // Add signals 00259 QValueList<ParsedMethod*> signalList = pClass->getSortedSignalList(); 00260 QValueList<ParsedMethod*>::ConstIterator signalIt; 00261 for (signalIt = signalList.begin(); signalIt != signalList.end(); ++signalIt) 00262 lastItem = new ClassTreeMethodItem(this, lastItem, *signalIt); 00263 00264 // Add attributes 00265 QValueList<ParsedAttribute*> attrList = pClass->getSortedAttributeList(); 00266 QValueList<ParsedAttribute*>::ConstIterator attrIt; 00267 for (attrIt = attrList.begin(); attrIt != attrList.end(); ++attrIt) 00268 lastItem = new ClassTreeAttrItem(this, lastItem, *attrIt); 00269 00270 } 00271 00272 ClassTreeItem::setOpen(o); 00273 } 00274 00275 ClassTreeMethodItem::ClassTreeMethodItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, 00276 ParsedMethod *parsedMethod) 00277 : ClassTreeItem(parent, lastSibling, parsedMethod) 00278 { 00279 QString icon; 00280 00281 if ( !parsedMethod ) 00282 return; 00283 00284 if (parsedMethod->isSignal()) 00285 icon = "CVpublic_signal"; 00286 else if (parsedMethod->isSlot()) { 00287 if (parsedMethod->isPublic()) 00288 icon = "CVpublic_slot"; 00289 else if (parsedMethod->isProtected()) 00290 icon = "CVprotected_slot"; 00291 else 00292 icon = "CVprivate_slot"; 00293 } 00294 else if (parsedMethod->isPublic()) 00295 icon = "CVpublic_meth"; 00296 else if (parsedMethod->isProtected()) 00297 icon = "CVprotected_meth"; 00298 else if (parsedMethod->isPrivate()) 00299 icon = "CVprivate_meth"; 00300 else if (parsedMethod->isPackage()) 00301 icon = "CVpackage_meth"; 00302 else 00303 icon = "CVglobal_meth"; 00304 00305 setPixmap(0, UserIcon(icon, KIcon::DefaultState, ClassViewFactory::instance())); 00306 } 00307 00308 QString ClassTreeMethodItem::text( int ) const 00309 { 00310 QString str; 00311 00312 if ( !m_item ) 00313 return QString::null; 00314 00315 ParsedMethod* method = static_cast<ParsedMethod*>(m_item); 00316 00317 str = method->name(); 00318 00319 if( method->arguments.count() > 0 ) { 00320 str += "( "; 00321 for ( ParsedArgument *arg = method->arguments.first(); arg != NULL; arg = method->arguments.next() ) { 00322 if ( arg != method->arguments.getFirst() ) 00323 str += ", "; 00324 00325 str += arg->toString(); 00326 } 00327 str += " )"; 00328 } else { 00329 str += "()"; 00330 } 00331 00332 if( method->isConst() ) 00333 str += " const"; 00334 00335 return str; 00336 } 00337 00338 00339 ClassTreeAttrItem::ClassTreeAttrItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, 00340 ParsedAttribute *parsedAttr) 00341 : ClassTreeItem(parent, lastSibling, parsedAttr) 00342 { 00343 QString icon; 00344 00345 if ( !parsedAttr ) 00346 return; 00347 00348 if (parsedAttr->isPublic()) 00349 icon = "CVpublic_var"; 00350 else if (parsedAttr->isProtected()) 00351 icon = "CVprotected_var"; 00352 else if (parsedAttr->isPrivate()) 00353 icon = "CVprivate_var"; 00354 else if (parsedAttr->isPackage()) 00355 icon = "CVpackage_var"; 00356 else 00357 icon = "CVglobal_var"; 00358 00359 setPixmap(0, UserIcon(icon, KIcon::DefaultState, ClassViewFactory::instance())); 00360 } 00361 00362 00363 QString ClassTreeAttrItem::text( int ) const 00364 { 00365 if ( !m_item ) 00366 return QString::null; 00367 return m_item->name(); 00368 } 00369 00370 ClassTreeScriptItem::ClassTreeScriptItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, 00371 ParsedScript *parsedScript) 00372 : ClassTreeItem(parent, lastSibling, parsedScript) 00373 { 00374 QString icon; 00375 00376 if ( !parsedScript ) 00377 return; 00378 00379 setExpandable(true); 00380 00381 //need a icon for scripts 00382 icon = "CVpublic_var"; 00383 setPixmap(0, UserIcon(icon, KIcon::DefaultState, ClassViewFactory::instance())); 00384 } 00385 00386 00387 QString ClassTreeScriptItem::text( int ) const 00388 { 00389 if ( !m_item ) 00390 return QString::null; 00391 return m_item->name(); 00392 } 00393 00394 void ClassTreeScriptItem::setOpen(bool o) 00395 { 00396 if ( !m_item ) 00397 return; 00398 kdDebug(9003) << (o? "Open script item" : "Close script item") << endl; 00399 if (o && childCount() == 0) { 00400 00401 ParsedScript *pClass = static_cast<ParsedScript*>(m_item); 00402 ClassTreeItem *lastItem = 0; 00403 00404 // Add methods 00405 QValueList<ParsedMethod*> methodList = pClass->getSortedMethodList(); 00406 QValueList<ParsedMethod*>::ConstIterator methodIt; 00407 for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt) 00408 lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt); 00409 00410 // Add attributes 00411 QValueList<ParsedAttribute*> attrList = pClass->getSortedAttributeList(); 00412 QValueList<ParsedAttribute*>::ConstIterator attrIt; 00413 for (attrIt = attrList.begin(); attrIt != attrList.end(); ++attrIt) 00414 lastItem = new ClassTreeAttrItem(this, lastItem, *attrIt); 00415 00416 } 00417 00418 ClassTreeItem::setOpen(o); 00419 } 00420 00421 00422 class ClassToolTip : public QToolTip 00423 { 00424 public: 00425 ClassToolTip( QWidget *parent ) 00426 : QToolTip(parent) 00427 {} 00428 00429 protected: 00430 void maybeTip(const QPoint &p); 00431 }; 00432 00433 00434 void ClassToolTip::maybeTip(const QPoint &p) 00435 { 00436 ClassTreeBase *ctw = static_cast<ClassTreeBase*>(parentWidget()); 00437 00438 QListViewItem *item = ctw->itemAt(p); 00439 QRect r = ctw->itemRect(item); 00440 00441 if (item && r.isValid()) { 00442 ClassTreeItem *ctitem = static_cast<ClassTreeItem*>(item); 00443 QString str = ctitem->tipText(); 00444 if (!str.isEmpty()) 00445 tip(r, str); 00446 } 00447 } 00448 00449 00450 ClassTreeBase::ClassTreeBase(ClassViewPart *part, QWidget *parent, const char *name) 00451 : KListView(parent, name) 00452 { 00453 setFocusPolicy(ClickFocus); 00454 setRootIsDecorated(true); 00455 setResizeMode(QListView::LastColumn); 00456 setSorting(-1); 00457 header()->hide(); 00458 addColumn(QString::null); 00459 00460 (void) new ClassToolTip(this); 00461 00462 connect( this, SIGNAL(executed(QListViewItem*)), 00463 this, SLOT(slotItemExecuted(QListViewItem*)) ); 00464 connect( this, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int)), 00465 this, SLOT(slotItemPressed(int, QListViewItem*)) ); 00466 connect( this, SIGNAL(returnPressed( QListViewItem*)), 00467 SLOT( slotItemExecuted(QListViewItem*)) ); 00468 connect( this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), 00469 this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&)) ); 00470 00471 m_part = part; 00472 } 00473 00474 00475 ClassTreeBase::~ClassTreeBase() 00476 {} 00477 00478 00479 ClassTreeBase::TreeState ClassTreeBase::treeState() const 00480 { 00481 TreeState state; 00482 00483 ClassTreeBase *that = const_cast<ClassTreeBase*>(this); 00484 QListViewItemIterator it(that); 00485 for (; it.current(); ++it) 00486 if (it.current()->isOpen()) { 00487 QStringList path; 00488 QListViewItem *item = it.current(); 00489 while (item) { 00490 path.prepend(item->text(0)); 00491 item = item->parent(); 00492 } 00493 state.append(path); 00494 } 00495 00496 return state; 00497 } 00498 00499 00500 void ClassTreeBase::setTreeState(TreeState state) 00501 { 00502 TreeStateIterator tsit; 00503 for (tsit = state.begin(); tsit != state.end(); ++tsit) { 00504 QListViewItemIterator it(this); 00505 for (; it.current(); ++it) { 00506 QStringList path; 00507 QListViewItem *item = it.current(); 00508 while (item) { 00509 path.prepend(item->text(0)); 00510 item = item->parent(); 00511 } 00512 if (*tsit == path) { 00513 it.current()->setOpen(true); 00514 break; 00515 } 00516 } 00517 } 00518 } 00519 00520 00521 00522 00523 void ClassTreeBase::slotItemExecuted( QListViewItem* item ) 00524 { 00525 if (!item) 00526 return; 00527 00528 // toggle open state for parents 00529 if (item->childCount() > 0) 00530 setOpen(item, !isOpen(item)); 00531 00532 // We assume here that ALL (!) items in the list view 00533 // are ClassTreeItem's 00534 ClassTreeItem *ctitem = static_cast<ClassTreeItem*>(item); 00535 if (ctitem->isOrganizer()) 00536 return; 00537 00538 QString toFile; 00539 int toLine = -1; 00540 if (dynamic_cast<ClassTreeClassItem*>(item)) { 00541 ctitem->getDeclaration(&toFile, &toLine); 00542 } 00543 else { 00544 ctitem->getImplementation(&toFile, &toLine); 00545 } 00546 m_part->partController()->editDocument(toFile, toLine); 00547 m_part->mainWindow()->lowerView(this); 00548 } 00549 00550 00551 void ClassTreeBase::slotItemPressed(int button, QListViewItem *item) 00552 { 00553 if (!item) 00554 return; 00555 00556 // We assume here that ALL (!) items in the list view 00557 // are ClassTreeItem's 00558 ClassTreeItem *ctitem = static_cast<ClassTreeItem*>(item); 00559 if (ctitem->isOrganizer()) 00560 return; 00561 00562 if (button == MidButton) { 00563 QString toFile; 00564 int toLine = -1; 00565 ctitem->getDeclaration(&toFile, &toLine); 00566 m_part->partController()->editDocument(toFile, toLine); 00567 m_part->mainWindow()->lowerView(this); 00568 } 00569 } 00570 00571 void ClassTreeBase::slotContextMenuRequested(QListViewItem *item, const QPoint &p) 00572 { 00573 contextItem = static_cast<ClassTreeItem*>(item); 00574 00575 KPopupMenu *popup = createPopup(); 00576 popup->exec(p); 00577 delete popup; 00578 } 00579 00580 void ClassTreeBase::slotGotoDeclaration() 00581 { 00582 QString toFile; 00583 int toLine = -1; 00584 00585 contextItem->getDeclaration(&toFile, &toLine); 00586 m_part->partController()->editDocument(toFile, toLine); 00587 } 00588 00589 00590 void ClassTreeBase::slotGotoImplementation() 00591 { 00592 QString toFile; 00593 int toLine = -1; 00594 00595 contextItem->getImplementation(&toFile, &toLine); 00596 m_part->partController()->editDocument(toFile, toLine); 00597 } 00598 00599 00600 void ClassTreeBase::slotAddMethod() 00601 { 00602 if (m_part->languageSupport()) 00603 m_part->languageSupport()->addMethod(contextItem->scopedText()); 00604 } 00605 00606 00607 void ClassTreeBase::slotAddAttribute() 00608 { 00609 if (m_part->languageSupport()) 00610 m_part->languageSupport()->addAttribute(contextItem->scopedText()); 00611 } 00612 00613 00614 void ClassTreeBase::slotClassBaseClasses() 00615 { 00616 ClassToolDialog *dlg = new ClassToolDialog(m_part); 00617 dlg->setClassName(contextItem->scopedText()); 00618 dlg->viewParents(); 00619 } 00620 00621 00622 void ClassTreeBase::slotClassDerivedClasses() 00623 { 00624 ClassToolDialog *dlg = new ClassToolDialog(m_part); 00625 dlg->setClassName(contextItem->scopedText()); 00626 dlg->viewChildren(); 00627 } 00628 00629 00630 void ClassTreeBase::slotClassTool() 00631 { 00632 ClassToolDialog *dlg = new ClassToolDialog(m_part); 00633 dlg->setClassName(contextItem->scopedText()); 00634 dlg->viewNone(); 00635 } 00636 00637 #include "classtreebase.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:10 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003