/*************************************************************************** * Copyright (C) 1999 by Jonas Nordin * * jonas.nordin@syncom.se * * Copyright (C) 2000-2001 by Bernd Gehrmann * * bernd@tdevelop.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. * * * ***************************************************************************/ #include "classtreebase.h" #include #include #include #include #include #include #include #include #include "kdevcore.h" #include "kdevlanguagesupport.h" #include "kdevmainwindow.h" #include "kdevpartcontroller.h" #include "classstore.h" #include "classviewpart.h" #include "classtooldlg.h" TDEPopupMenu *ClassTreeItem::createPopup() { if (!m_item || m_item->itemType() == PIT_SCOPE) return 0; KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features(); TDEPopupMenu *popup = new TDEPopupMenu(); if (features & KDevLanguageSupport::Declarations) popup->insertItem( i18n("Go to Declaration"), classTree(), TQT_SLOT(slotGotoDeclaration()) ); if (m_item->itemType() == PIT_METHOD) popup->insertItem( i18n("Go to Definition"), classTree(), TQT_SLOT(slotGotoImplementation()) ); TQString title; switch(m_item->itemType()) { case PIT_CLASS: { title = i18n("Class"); bool hasAddMethod = features & KDevLanguageSupport::AddMethod; bool hasAddAttribute = features & KDevLanguageSupport::AddAttribute; if (hasAddMethod) popup->insertItem( i18n("Add Method..."), classTree(), TQT_SLOT(slotAddMethod())); if (hasAddAttribute) popup->insertItem( i18n("Add Attribute..."), classTree(), TQT_SLOT(slotAddAttribute())); popup->insertSeparator(); popup->insertItem( i18n("Parent Classes..."), classTree(), TQT_SLOT(slotClassBaseClasses())); popup->insertItem( i18n("Child Classes..."), classTree(), TQT_SLOT(slotClassDerivedClasses())); popup->insertItem( i18n("Class Tool..."), classTree(), TQT_SLOT(slotClassTool())); } break; case PIT_STRUCT: title = i18n("Struct"); break; case PIT_ATTRIBUTE: if (m_item->isGlobal()) title = i18n("Variable"); else title = i18n("Attribute"); break; case PIT_METHOD: if (static_cast(m_item)->isSlot()) title = i18n("Slot"); else if (static_cast(m_item)->isSignal()) title = i18n("Signal"); else if (m_item->isGlobal()) title = i18n("Function"); else title = i18n("Method"); break; default: ; } popup->insertSeparator(); popup->insertTitle(title, -1, 0); return popup; } TQString ClassTreeItem::scopedText() const { if (m_item) return m_item->path(); return TQString(); } void ClassTreeItem::getDeclaration(TQString *toFile, int *toLine) { if (m_item) { *toFile = m_item->declaredInFile(); *toLine = m_item->declaredOnLine(); } } void ClassTreeItem::getImplementation(TQString *toFile, int *toLine) { if (m_item) { *toFile = m_item->definedInFile(); *toLine = m_item->definedOnLine(); } } TQString ClassTreeItem::text( int ) const { if (m_item) return m_item->asString(); return TQString(); } TQString ClassTreeItem::tipText() const { // Purposefully avoid virtual dispatch here return ClassTreeItem::text(0); } void ClassTreeOrganizerItem::init() { setExpandable(true); setPixmap(0, SmallIcon("folder")); } void ClassTreeScopeItem::init() { setExpandable(true); setPixmap(0, UserIcon("CVnamespace", TDEIcon::DefaultState, ClassViewFactory::instance())); } TQString ClassTreeScopeItem::text( int col ) const { if (!m_item) return TQString(); if (m_item->name().isEmpty()) return i18n("Global"); return ClassTreeItem::text( col ); } void ClassTreeScopeItem::setOpen(bool o) { if ( !m_item) return; kdDebug(9003) << (o? "Open scope item" : "Close scope item") << endl; if (o && childCount() == 0) { ParsedScopeContainer *pScope = static_cast(m_item); ClassTreeItem *lastItem = 0; // Ok, this is a hack... KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features(); // Add namespaces TQValueList scopeList = pScope->getSortedScopeList(); TQValueList::ConstIterator it; for (it = scopeList.begin(); it != scopeList.end(); ++it) lastItem = new ClassTreeScopeItem(this, lastItem, *it); if (features & KDevLanguageSupport::Classes) { // Add classes TQValueList classList = pScope->getSortedClassList(); TQValueList::ConstIterator it; for (it = classList.begin(); it != classList.end(); ++it) lastItem = new ClassTreeClassItem(this, lastItem, *it); } if (features & KDevLanguageSupport::Structs) { // Add structs TQValueList structList = pScope->getSortedStructList(); TQValueList::ConstIterator it; for (it = structList.begin(); it != structList.end(); ++it) lastItem = new ClassTreeClassItem(this, lastItem, *it, true); } if (features & KDevLanguageSupport::Functions) { // Add functions TQValueList methodList = pScope->getSortedMethodList(); TQValueList::ConstIterator it; for (it = methodList.begin(); it != methodList.end(); ++it) lastItem = new ClassTreeMethodItem(this, lastItem, *it); } if (features & KDevLanguageSupport::Variables) { // Add attributes TQValueList attrList = pScope->getSortedAttributeList(); TQValueList::ConstIterator it; for (it = attrList.begin(); it != attrList.end(); ++it) lastItem = new ClassTreeAttrItem(this, lastItem, *it); } } ClassTreeItem::setOpen(o); } void ClassTreeClassItem::init() { setExpandable(true); setPixmap(0, UserIcon(m_isStruct ? "CVstruct" : "CVclass", TDEIcon::DefaultState, ClassViewFactory::instance())); } void ClassTreeClassItem::setOpen(bool o) { if ( !m_item ) return; kdDebug(9003) << (o? "Open class item" : "Close class item") << endl; if (o && childCount() == 0) { ParsedClass *pClass = static_cast(m_item); ClassTreeItem *lastItem = 0; // Add nested classes TQValueList classList = pClass->getSortedClassList(); TQValueList::ConstIterator classIt; for (classIt = classList.begin(); classIt != classList.end(); ++classIt) lastItem = new ClassTreeClassItem(this, lastItem, *classIt); // Add nested structs TQValueList structList = pClass->getSortedStructList(); TQValueList::ConstIterator structIt; for (structIt = structList.begin(); structIt != structList.end(); ++structIt) lastItem = new ClassTreeClassItem(this, lastItem, *structIt, true); // Add methods TQValueList methodList = pClass->getSortedMethodList(); TQValueList::ConstIterator methodIt; for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt) lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt); // Add slots TQValueList slotList = pClass->getSortedSlotList(); TQValueList::ConstIterator slotIt; for (slotIt = slotList.begin(); slotIt != slotList.end(); ++slotIt) lastItem = new ClassTreeMethodItem(this, lastItem, *slotIt); // Add signals TQValueList signalList = pClass->getSortedSignalList(); TQValueList::ConstIterator signalIt; for (signalIt = signalList.begin(); signalIt != signalList.end(); ++signalIt) lastItem = new ClassTreeMethodItem(this, lastItem, *signalIt); // Add attributes TQValueList attrList = pClass->getSortedAttributeList(); TQValueList::ConstIterator attrIt; for (attrIt = attrList.begin(); attrIt != attrList.end(); ++attrIt) lastItem = new ClassTreeAttrItem(this, lastItem, *attrIt); } ClassTreeItem::setOpen(o); } ClassTreeMethodItem::ClassTreeMethodItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, ParsedMethod *parsedMethod) : ClassTreeItem(parent, lastSibling, parsedMethod) { TQString icon; if ( !parsedMethod ) return; if (parsedMethod->isSignal()) icon = "CVpublic_signal"; else if (parsedMethod->isSlot()) { if (parsedMethod->isPublic()) icon = "CVpublic_slot"; else if (parsedMethod->isProtected()) icon = "CVprotected_slot"; else icon = "CVprivate_slot"; } else if (parsedMethod->isPublic()) icon = "CVpublic_meth"; else if (parsedMethod->isProtected()) icon = "CVprotected_meth"; else if (parsedMethod->isPrivate()) icon = "CVprivate_meth"; else if (parsedMethod->isPackage()) icon = "CVpackage_meth"; else icon = "CVglobal_meth"; setPixmap(0, UserIcon(icon, TDEIcon::DefaultState, ClassViewFactory::instance())); } TQString ClassTreeMethodItem::text( int ) const { TQString str; if ( !m_item ) return TQString(); ParsedMethod* method = static_cast(m_item); str = method->name(); if( method->arguments.count() > 0 ) { str += "( "; for ( ParsedArgument *arg = method->arguments.first(); arg != NULL; arg = method->arguments.next() ) { if ( arg != method->arguments.getFirst() ) str += ", "; str += arg->toString(); } str += " )"; } else { str += "()"; } if( method->isConst() ) str += " const"; return str; } ClassTreeAttrItem::ClassTreeAttrItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, ParsedAttribute *parsedAttr) : ClassTreeItem(parent, lastSibling, parsedAttr) { TQString icon; if ( !parsedAttr ) return; if (parsedAttr->isPublic()) icon = "CVpublic_var"; else if (parsedAttr->isProtected()) icon = "CVprotected_var"; else if (parsedAttr->isPrivate()) icon = "CVprivate_var"; else if (parsedAttr->isPackage()) icon = "CVpackage_var"; else icon = "CVglobal_var"; setPixmap(0, UserIcon(icon, TDEIcon::DefaultState, ClassViewFactory::instance())); } TQString ClassTreeAttrItem::text( int ) const { if ( !m_item ) return TQString(); return m_item->name(); } ClassTreeScriptItem::ClassTreeScriptItem(ClassTreeItem *parent, ClassTreeItem *lastSibling, ParsedScript *parsedScript) : ClassTreeItem(parent, lastSibling, parsedScript) { TQString icon; if ( !parsedScript ) return; setExpandable(true); //need a icon for scripts icon = "CVpublic_var"; setPixmap(0, UserIcon(icon, TDEIcon::DefaultState, ClassViewFactory::instance())); } TQString ClassTreeScriptItem::text( int ) const { if ( !m_item ) return TQString(); return m_item->name(); } void ClassTreeScriptItem::setOpen(bool o) { if ( !m_item ) return; kdDebug(9003) << (o? "Open script item" : "Close script item") << endl; if (o && childCount() == 0) { ParsedScript *pClass = static_cast(m_item); ClassTreeItem *lastItem = 0; // Add methods TQValueList methodList = pClass->getSortedMethodList(); TQValueList::ConstIterator methodIt; for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt) lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt); // Add attributes TQValueList attrList = pClass->getSortedAttributeList(); TQValueList::ConstIterator attrIt; for (attrIt = attrList.begin(); attrIt != attrList.end(); ++attrIt) lastItem = new ClassTreeAttrItem(this, lastItem, *attrIt); } ClassTreeItem::setOpen(o); } class ClassToolTip : public TQToolTip { public: ClassToolTip( TQWidget *parent ) : TQToolTip(parent) {} protected: void maybeTip(const TQPoint &p); }; void ClassToolTip::maybeTip(const TQPoint &p) { ClassTreeBase *ctw = static_cast(parentWidget()); TQListViewItem *item = ctw->itemAt(p); TQRect r = ctw->itemRect(item); if (item && r.isValid()) { ClassTreeItem *ctitem = static_cast(item); TQString str = ctitem->tipText(); if (!str.isEmpty()) tip(r, str); } } ClassTreeBase::ClassTreeBase(ClassViewPart *part, TQWidget *parent, const char *name) : TDEListView(parent, name) { setFocusPolicy(ClickFocus); setRootIsDecorated(true); setResizeMode(TQListView::LastColumn); setSorting(-1); header()->hide(); addColumn(TQString()); (void) new ClassToolTip(this); connect( this, TQT_SIGNAL(executed(TQListViewItem*)), this, TQT_SLOT(slotItemExecuted(TQListViewItem*)) ); connect( this, TQT_SIGNAL(mouseButtonPressed(int, TQListViewItem*, const TQPoint&, int)), this, TQT_SLOT(slotItemPressed(int, TQListViewItem*)) ); connect( this, TQT_SIGNAL(returnPressed( TQListViewItem*)), TQT_SLOT( slotItemExecuted(TQListViewItem*)) ); connect( this, TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)), this, TQT_SLOT(slotContextMenuRequested(TQListViewItem*, const TQPoint&)) ); m_part = part; } ClassTreeBase::~ClassTreeBase() {} ClassTreeBase::TreeState ClassTreeBase::treeState() const { TreeState state; ClassTreeBase *that = const_cast(this); TQListViewItemIterator it(that); for (; it.current(); ++it) if (it.current()->isOpen()) { TQStringList path; TQListViewItem *item = it.current(); while (item) { path.prepend(item->text(0)); item = item->parent(); } state.append(path); } return state; } void ClassTreeBase::setTreeState(TreeState state) { TreeStateIterator tsit; for (tsit = state.begin(); tsit != state.end(); ++tsit) { TQListViewItemIterator it(this); for (; it.current(); ++it) { TQStringList path; TQListViewItem *item = it.current(); while (item) { path.prepend(item->text(0)); item = item->parent(); } if (*tsit == path) { it.current()->setOpen(true); break; } } } } void ClassTreeBase::slotItemExecuted( TQListViewItem* item ) { if (!item) return; // toggle open state for parents if (item->childCount() > 0) setOpen(item, !isOpen(item)); // We assume here that ALL (!) items in the list view // are ClassTreeItem's ClassTreeItem *ctitem = static_cast(item); if (ctitem->isOrganizer()) return; TQString toFile; int toLine = -1; if (dynamic_cast(item)) { ctitem->getDeclaration(&toFile, &toLine); } else { ctitem->getImplementation(&toFile, &toLine); } m_part->partController()->editDocument(toFile, toLine); m_part->mainWindow()->lowerView(this); } void ClassTreeBase::slotItemPressed(int button, TQListViewItem *item) { if (!item) return; // We assume here that ALL (!) items in the list view // are ClassTreeItem's ClassTreeItem *ctitem = static_cast(item); if (ctitem->isOrganizer()) return; if (button == MidButton) { TQString toFile; int toLine = -1; ctitem->getDeclaration(&toFile, &toLine); m_part->partController()->editDocument(toFile, toLine); m_part->mainWindow()->lowerView(this); } } void ClassTreeBase::slotContextMenuRequested(TQListViewItem *item, const TQPoint &p) { contextItem = static_cast(item); TDEPopupMenu *popup = createPopup(); popup->exec(p); delete popup; } void ClassTreeBase::slotGotoDeclaration() { TQString toFile; int toLine = -1; contextItem->getDeclaration(&toFile, &toLine); m_part->partController()->editDocument(toFile, toLine); } void ClassTreeBase::slotGotoImplementation() { TQString toFile; int toLine = -1; contextItem->getImplementation(&toFile, &toLine); m_part->partController()->editDocument(toFile, toLine); } void ClassTreeBase::slotAddMethod() { if (m_part->languageSupport()) m_part->languageSupport()->addMethod(contextItem->scopedText()); } void ClassTreeBase::slotAddAttribute() { if (m_part->languageSupport()) m_part->languageSupport()->addAttribute(contextItem->scopedText()); } void ClassTreeBase::slotClassBaseClasses() { ClassToolDialog *dlg = new ClassToolDialog(m_part); dlg->setClassName(contextItem->scopedText()); dlg->viewParents(); } void ClassTreeBase::slotClassDerivedClasses() { ClassToolDialog *dlg = new ClassToolDialog(m_part); dlg->setClassName(contextItem->scopedText()); dlg->viewChildren(); } void ClassTreeBase::slotClassTool() { ClassToolDialog *dlg = new ClassToolDialog(m_part); dlg->setClassName(contextItem->scopedText()); dlg->viewNone(); } #include "classtreebase.moc"