summaryrefslogtreecommitdiffstats
path: root/parts/classview/classtreebase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/classview/classtreebase.cpp')
-rw-r--r--parts/classview/classtreebase.cpp637
1 files changed, 637 insertions, 0 deletions
diff --git a/parts/classview/classtreebase.cpp b/parts/classview/classtreebase.cpp
new file mode 100644
index 00000000..f5c0f4b9
--- /dev/null
+++ b/parts/classview/classtreebase.cpp
@@ -0,0 +1,637 @@
+/***************************************************************************
+ * Copyright (C) 1999 by Jonas Nordin *
+ * Copyright (C) 2000-2001 by Bernd Gehrmann *
+ * *
+ * 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 <qtooltip.h>
+#include <qheader.h>
+#include <qregexp.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "kdevcore.h"
+#include "kdevlanguagesupport.h"
+#include "kdevmainwindow.h"
+#include "kdevpartcontroller.h"
+#include "classstore.h"
+
+#include "classviewpart.h"
+#include "classtooldlg.h"
+
+KPopupMenu *ClassTreeItem::createPopup()
+{
+ if (!m_item || m_item->itemType() == PIT_SCOPE)
+ return 0;
+
+ KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features();
+
+ KPopupMenu *popup = new KPopupMenu();
+ if (features & KDevLanguageSupport::Declarations)
+ popup->insertItem( i18n("Go to Declaration"), classTree(), SLOT(slotGotoDeclaration()) );
+ if (m_item->itemType() == PIT_METHOD)
+ popup->insertItem( i18n("Go to Definition"), classTree(), SLOT(slotGotoImplementation()) );
+
+ QString 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(), SLOT(slotAddMethod()));
+ if (hasAddAttribute)
+ popup->insertItem( i18n("Add Attribute..."), classTree(), SLOT(slotAddAttribute()));
+ popup->insertSeparator();
+ popup->insertItem( i18n("Parent Classes..."), classTree(), SLOT(slotClassBaseClasses()));
+ popup->insertItem( i18n("Child Classes..."), classTree(), SLOT(slotClassDerivedClasses()));
+ popup->insertItem( i18n("Class Tool..."), classTree(), 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<ParsedMethod*>(m_item)->isSlot())
+ title = i18n("Slot");
+ else if (static_cast<ParsedMethod*>(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;
+}
+
+
+QString ClassTreeItem::scopedText() const
+{
+ if (m_item)
+ return m_item->path();
+
+ return QString::null;
+}
+
+
+void ClassTreeItem::getDeclaration(QString *toFile, int *toLine)
+{
+ if (m_item) {
+ *toFile = m_item->declaredInFile();
+ *toLine = m_item->declaredOnLine();
+ }
+}
+
+
+void ClassTreeItem::getImplementation(QString *toFile, int *toLine)
+{
+ if (m_item) {
+ *toFile = m_item->definedInFile();
+ *toLine = m_item->definedOnLine();
+ }
+}
+
+
+QString ClassTreeItem::text( int ) const
+{
+ if (m_item)
+ return m_item->asString();
+ return QString::null;
+}
+
+
+QString 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", KIcon::DefaultState, ClassViewFactory::instance()));
+}
+
+
+QString ClassTreeScopeItem::text( int col ) const
+{
+ if (!m_item)
+ return QString::null;
+ 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<ParsedScopeContainer*>(m_item);
+ ClassTreeItem *lastItem = 0;
+
+ // Ok, this is a hack...
+ KDevLanguageSupport::Features features = classTree()->m_part->languageSupport()->features();
+
+ // Add namespaces
+ QValueList<ParsedScopeContainer*> scopeList = pScope->getSortedScopeList();
+ QValueList<ParsedScopeContainer*>::ConstIterator it;
+ for (it = scopeList.begin(); it != scopeList.end(); ++it)
+ lastItem = new ClassTreeScopeItem(this, lastItem, *it);
+
+ if (features & KDevLanguageSupport::Classes) {
+ // Add classes
+ QValueList<ParsedClass*> classList = pScope->getSortedClassList();
+ QValueList<ParsedClass*>::ConstIterator it;
+ for (it = classList.begin(); it != classList.end(); ++it)
+ lastItem = new ClassTreeClassItem(this, lastItem, *it);
+ }
+
+ if (features & KDevLanguageSupport::Structs) {
+ // Add structs
+ QValueList<ParsedClass*> structList = pScope->getSortedStructList();
+ QValueList<ParsedClass*>::ConstIterator it;
+ for (it = structList.begin(); it != structList.end(); ++it)
+ lastItem = new ClassTreeClassItem(this, lastItem, *it, true);
+ }
+
+ if (features & KDevLanguageSupport::Functions) {
+ // Add functions
+ QValueList<ParsedMethod*> methodList = pScope->getSortedMethodList();
+ QValueList<ParsedMethod*>::ConstIterator it;
+ for (it = methodList.begin(); it != methodList.end(); ++it)
+ lastItem = new ClassTreeMethodItem(this, lastItem, *it);
+ }
+
+ if (features & KDevLanguageSupport::Variables) {
+ // Add attributes
+ QValueList<ParsedAttribute*> attrList = pScope->getSortedAttributeList();
+ QValueList<ParsedAttribute*>::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", KIcon::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<ParsedClass*>(m_item);
+ ClassTreeItem *lastItem = 0;
+
+ // Add nested classes
+ QValueList<ParsedClass*> classList = pClass->getSortedClassList();
+ QValueList<ParsedClass*>::ConstIterator classIt;
+ for (classIt = classList.begin(); classIt != classList.end(); ++classIt)
+ lastItem = new ClassTreeClassItem(this, lastItem, *classIt);
+
+ // Add nested structs
+ QValueList<ParsedClass*> structList = pClass->getSortedStructList();
+ QValueList<ParsedClass*>::ConstIterator structIt;
+ for (structIt = structList.begin(); structIt != structList.end(); ++structIt)
+ lastItem = new ClassTreeClassItem(this, lastItem, *structIt, true);
+
+ // Add methods
+ QValueList<ParsedMethod*> methodList = pClass->getSortedMethodList();
+ QValueList<ParsedMethod*>::ConstIterator methodIt;
+ for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt)
+ lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt);
+
+ // Add slots
+ QValueList<ParsedMethod*> slotList = pClass->getSortedSlotList();
+ QValueList<ParsedMethod*>::ConstIterator slotIt;
+ for (slotIt = slotList.begin(); slotIt != slotList.end(); ++slotIt)
+ lastItem = new ClassTreeMethodItem(this, lastItem, *slotIt);
+
+ // Add signals
+ QValueList<ParsedMethod*> signalList = pClass->getSortedSignalList();
+ QValueList<ParsedMethod*>::ConstIterator signalIt;
+ for (signalIt = signalList.begin(); signalIt != signalList.end(); ++signalIt)
+ lastItem = new ClassTreeMethodItem(this, lastItem, *signalIt);
+
+ // Add attributes
+ QValueList<ParsedAttribute*> attrList = pClass->getSortedAttributeList();
+ QValueList<ParsedAttribute*>::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)
+{
+ QString 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, KIcon::DefaultState, ClassViewFactory::instance()));
+}
+
+QString ClassTreeMethodItem::text( int ) const
+{
+ QString str;
+
+ if ( !m_item )
+ return QString::null;
+
+ ParsedMethod* method = static_cast<ParsedMethod*>(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)
+{
+ QString 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, KIcon::DefaultState, ClassViewFactory::instance()));
+}
+
+
+QString ClassTreeAttrItem::text( int ) const
+{
+ if ( !m_item )
+ return QString::null;
+ return m_item->name();
+}
+
+ClassTreeScriptItem::ClassTreeScriptItem(ClassTreeItem *parent, ClassTreeItem *lastSibling,
+ ParsedScript *parsedScript)
+ : ClassTreeItem(parent, lastSibling, parsedScript)
+{
+ QString icon;
+
+ if ( !parsedScript )
+ return;
+
+ setExpandable(true);
+
+ //need a icon for scripts
+ icon = "CVpublic_var";
+ setPixmap(0, UserIcon(icon, KIcon::DefaultState, ClassViewFactory::instance()));
+}
+
+
+QString ClassTreeScriptItem::text( int ) const
+{
+ if ( !m_item )
+ return QString::null;
+ 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<ParsedScript*>(m_item);
+ ClassTreeItem *lastItem = 0;
+
+ // Add methods
+ QValueList<ParsedMethod*> methodList = pClass->getSortedMethodList();
+ QValueList<ParsedMethod*>::ConstIterator methodIt;
+ for (methodIt = methodList.begin(); methodIt != methodList.end(); ++methodIt)
+ lastItem = new ClassTreeMethodItem(this, lastItem, *methodIt);
+
+ // Add attributes
+ QValueList<ParsedAttribute*> attrList = pClass->getSortedAttributeList();
+ QValueList<ParsedAttribute*>::ConstIterator attrIt;
+ for (attrIt = attrList.begin(); attrIt != attrList.end(); ++attrIt)
+ lastItem = new ClassTreeAttrItem(this, lastItem, *attrIt);
+
+ }
+
+ ClassTreeItem::setOpen(o);
+}
+
+
+class ClassToolTip : public QToolTip
+{
+public:
+ ClassToolTip( QWidget *parent )
+ : QToolTip(parent)
+ {}
+
+protected:
+ void maybeTip(const QPoint &p);
+};
+
+
+void ClassToolTip::maybeTip(const QPoint &p)
+{
+ ClassTreeBase *ctw = static_cast<ClassTreeBase*>(parentWidget());
+
+ QListViewItem *item = ctw->itemAt(p);
+ QRect r = ctw->itemRect(item);
+
+ if (item && r.isValid()) {
+ ClassTreeItem *ctitem = static_cast<ClassTreeItem*>(item);
+ QString str = ctitem->tipText();
+ if (!str.isEmpty())
+ tip(r, str);
+ }
+}
+
+
+ClassTreeBase::ClassTreeBase(ClassViewPart *part, QWidget *parent, const char *name)
+ : KListView(parent, name)
+{
+ setFocusPolicy(ClickFocus);
+ setRootIsDecorated(true);
+ setResizeMode(QListView::LastColumn);
+ setSorting(-1);
+ header()->hide();
+ addColumn(QString::null);
+
+ (void) new ClassToolTip(this);
+
+ connect( this, SIGNAL(executed(QListViewItem*)),
+ this, SLOT(slotItemExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int)),
+ this, SLOT(slotItemPressed(int, QListViewItem*)) );
+ connect( this, SIGNAL(returnPressed( QListViewItem*)),
+ SLOT( slotItemExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&)) );
+
+ m_part = part;
+}
+
+
+ClassTreeBase::~ClassTreeBase()
+{}
+
+
+ClassTreeBase::TreeState ClassTreeBase::treeState() const
+{
+ TreeState state;
+
+ ClassTreeBase *that = const_cast<ClassTreeBase*>(this);
+ QListViewItemIterator it(that);
+ for (; it.current(); ++it)
+ if (it.current()->isOpen()) {
+ QStringList path;
+ QListViewItem *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) {
+ QListViewItemIterator it(this);
+ for (; it.current(); ++it) {
+ QStringList path;
+ QListViewItem *item = it.current();
+ while (item) {
+ path.prepend(item->text(0));
+ item = item->parent();
+ }
+ if (*tsit == path) {
+ it.current()->setOpen(true);
+ break;
+ }
+ }
+ }
+}
+
+
+
+
+void ClassTreeBase::slotItemExecuted( QListViewItem* 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<ClassTreeItem*>(item);
+ if (ctitem->isOrganizer())
+ return;
+
+ QString toFile;
+ int toLine = -1;
+ if (dynamic_cast<ClassTreeClassItem*>(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, QListViewItem *item)
+{
+ if (!item)
+ return;
+
+ // We assume here that ALL (!) items in the list view
+ // are ClassTreeItem's
+ ClassTreeItem *ctitem = static_cast<ClassTreeItem*>(item);
+ if (ctitem->isOrganizer())
+ return;
+
+ if (button == MidButton) {
+ QString toFile;
+ int toLine = -1;
+ ctitem->getDeclaration(&toFile, &toLine);
+ m_part->partController()->editDocument(toFile, toLine);
+ m_part->mainWindow()->lowerView(this);
+ }
+}
+
+void ClassTreeBase::slotContextMenuRequested(QListViewItem *item, const QPoint &p)
+{
+ contextItem = static_cast<ClassTreeItem*>(item);
+
+ KPopupMenu *popup = createPopup();
+ popup->exec(p);
+ delete popup;
+}
+
+void ClassTreeBase::slotGotoDeclaration()
+{
+ QString toFile;
+ int toLine = -1;
+
+ contextItem->getDeclaration(&toFile, &toLine);
+ m_part->partController()->editDocument(toFile, toLine);
+}
+
+
+void ClassTreeBase::slotGotoImplementation()
+{
+ QString 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"