/* tree.cc */ #include "tree.h" #include #include #include #include #include #include #include #include #include #include #ifdef PARSER #include "ast.h" #include "parser.h" #include "parsesession.h" #include "control.h" #include "rpp/chartools.h" #include "cppeditorintegrator.h" // #include "dumpchain.h" #include "default_visitor.h" #include "dumptree.h" #endif #include "trace.h" // using namespace KDevelop; /* ----------------------------------------------------------------------- */ namespace ConnectModule { /* ----------------------------------------------------------------------- */ TreeWidget::TreeWidget (QWidget* parent) : QWidget (parent), m_tree (new QTreeWidget (this)), m_doc (NULL), m_topContext (NULL), m_session (NULL) { setObjectName ("TreeView"); setWindowTitle (i18n ("Tree")); setWindowIcon (SmallIcon ("code-class")); m_tree->header()->hide(); m_tree->setIndentation (16); QVBoxLayout* vbox = new QVBoxLayout (this); vbox->setMargin (0); vbox->addWidget (m_tree); setLayout (vbox); setWhatsThis (i18n ("Properties")); connect (KDevelop::ICore::self()->documentController(), SIGNAL (documentActivated (KDevelop::IDocument*)), this, SLOT (documentActivated (KDevelop::IDocument*))); connect (KDevelop::ICore::self()->documentController(), SIGNAL (documentClosed (KDevelop::IDocument*)), this, SLOT (documentClosed (KDevelop::IDocument*))); connect (m_tree, SIGNAL (itemClicked (QTreeWidgetItem*, int)), this, SLOT (treeClick (QTreeWidgetItem*, int))); } TreeWidget::~TreeWidget() { } /* ----------------------------------------------------------------------- */ void TreeWidget::documentActivated (KDevelop::IDocument * doc) { display (); } void TreeWidget::documentClosed (KDevelop::IDocument * doc) { display (); } void TreeWidget::treeClick (QTreeWidgetItem * p_item, int column) { TreeItem * item = dynamic_cast (p_item); if (item != NULL) { KTextEditor::Range r = item->range; if (r.isValid ()) { KDevelop::ICore::self()->documentController()->openDocument (m_doc, r); } } } /* ----------------------------------------------------------------------- */ #ifdef PARSER class DumpTree : protected DefaultVisitor { public: DumpTree (); virtual ~ DumpTree (); void dump (AST * node, CppEditorIntegrator * p_editor, KDevelop::SimpleCursor p_position, QTreeWidgetItem * p_branch); protected: virtual void visit (AST * node); private: KTextEditor::Cursor convPosition (KDevelop::CursorInRevision cursor); private: CppEditorIntegrator * m_editor; KDevelop::SimpleCursor m_position; QTreeWidgetItem * m_branch; }; DumpTree::DumpTree () : m_editor (NULL), m_branch (NULL) { } DumpTree::~DumpTree () { } void DumpTree::dump (AST * node, CppEditorIntegrator * p_editor, KDevelop::SimpleCursor p_position, QTreeWidgetItem * p_branch) { m_editor = p_editor; m_position = p_position; m_branch = p_branch; visit (node); } KTextEditor::Cursor DumpTree::convPosition (KDevelop::CursorInRevision cursor) { KDevelop::SimpleCursor simple = cursor.castToSimpleCursor (); if (simple.line == 0) return KTextEditor::Cursor (m_position.line, m_position.column + simple.column); // add columns else return KTextEditor::Cursor (m_position.line + simple.line, simple.column); // add lines, keep column } void DumpTree::visit (AST * node) { if (node != NULL) { QString nodeText = m_editor->parseSession()->stringForNode (node); TreeItem * item = new TreeItem (); m_branch->addChild (item); item->setText (0, QString (names [node->kind]) + " : " + nodeText); KTextEditor::Cursor start = convPosition (m_editor->findPosition (node->start_token, CppEditorIntegrator::FrontEdge)); KTextEditor::Cursor stop = convPosition (m_editor->findPosition (node->end_token, CppEditorIntegrator::BackEdge)); item->range = KTextEditor::Range (start, stop); QTreeWidgetItem * save = m_branch; m_branch = item; DefaultVisitor::visit (node); m_branch = save; } } /* ----------------------------------------------------------------------- */ TreeItem * TreeWidget::showText (QTreeWidgetItem * branch, QString text) { TreeItem * item = new TreeItem (); branch->addChild (item); item->setText (0, text); return item; } TreeItem * TreeWidget::showAST (QTreeWidgetItem * branch, QString title, AST * ast) { // from kdevelop-4.5.1/languages/cpp/cppduchain/dumpchain.cpp QString nodeText = m_session->stringForNode (ast); return showText (branch, title + " : " + nodeText); } void TreeWidget::showInternalContext (QTreeWidgetItem * branch, const KDevelop::DUContext * context) { KDevelop::RangeInRevision r = context->range(); KDevelop::SimpleRange s = context->transformFromLocalRevision (r); KTextEditor::Range t = s.textRange(); QString src = m_doc->textDocument()->text(t); // from kdevelop/languages/cpp/cppduchain/expressionparser.cpp, ExpressionParser::evaluateType Control control; Parser parser (& control); QByteArray source = src.toAscii (); ParseSession session; session.setContentsAndGenerateLocationTable (tokenizeFromByteArray (source)); m_session = & session; AST * ast = parser.parseStatement (&session); if (ast) { CppEditorIntegrator editor (&session); DumpTree obj; obj.dump (ast, &editor, s.start, branch); } m_session = NULL; } #endif /* ----------------------------------------------------------------------- */ void TreeWidget::showDecl (QTreeWidgetItem * branch, const KDevelop::Declaration * decl) { if (decl != NULL) { TreeItem * item = new TreeItem; if (branch == NULL) m_tree->addTopLevelItem (item); else branch->addChild (item); item->setIcon (0, KDevelop::DUChainUtils::iconForDeclaration (decl)); item->setText (0, decl->toString()); // item->setToolTip (0, decl->comment()); { KDevelop::DUContext * context = decl->context(); if (context) item->range = context->transformFromLocalRevision (decl->range ()).textRange(); else item->range = KTextEditor::Range::invalid (); } #if 0 { KDevelop::AbstractType::Ptr type = decl->abstractType(); if (type) { TreeItem * type_item = new TreeItem; item->addChild (type_item); type_item->setText (0, "type: " + type->toString()); type_item->setTextColor (0, QColor::fromRgb (0, 0, 255)); type_item->range = KTextEditor::Range::invalid (); } } #endif // from kdevplatform/plugins/classbrowser/classmodelnode.cpp, ClassNode::updateClassDeclarations() KDevelop::DUContext * internal = decl->internalContext (); if (internal != NULL) { KDevelop::DUContext::ContextType type = internal->type (); if (type != KDevelop::DUContext::Other && type != KDevelop::DUContext::Function ) { foreach (const KDevelop::Declaration * sub, internal->localDeclarations ()) showDecl (item, sub); // foreach (KDevelop::DUContext * child, internal->childContexts()) // showDecl (item, child->owner()); } #ifdef PARSER if (type == KDevelop::DUContext::Other) { showInternalContext (item, internal); } #endif } } } /* ----------------------------------------------------------------------- */ void TreeWidget::display () { m_tree->clear (); KDevelop::DUChainReadLocker lock (KDevelop::DUChain::lock()); KDevelop::IDocument* doc = KDevelop::ICore::self()->documentController()->activeDocument(); m_doc = doc; m_topContext = NULL; if (doc && doc->textDocument() && doc->textDocument()->activeView()) { KDevelop::TopDUContext* topContext = KDevelop::DUChainUtils::standardContextForUrl (doc->url()); m_topContext = topContext; if (topContext != NULL) { foreach (KDevelop::DUContext * child, topContext->childContexts()) showDecl (NULL, child->owner ()); } } lock.unlock (); } /* ----------------------------------------------------------------------- */ } // end of namespace #include "tree.moc"