/*************************************************************************** kpybrowser.cpp - description ------------------- begin : Fri Aug 24 15:11:58 MST 2001 copyright : (C) 2001 by Christian Bird email : chrisb@lineo.com ***************************************************************************/ /*************************************************************************** * * * 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 "kpybrowser.h" #include #include #include #include #include "kpybrowser.moc" #include static const char *container_xpm[] = { "16 16 119 2", " c None", ". c #020202", "+ c #484848", "@ c #141414", "# c #CBCBCB", "$ c #E9E9E9", "% c #2F2F2F", "& c #3E3E3E", "* c #006B9E", "= c #003D5A", "- c #757575", "; c #A4A4A4", "> c #727272", ", c #282828", "' c #C1E1ED", ") c #D3EDF6", "! c #79BFD6", "~ c #E4E4E4", "{ c #202121", "] c #3CB9ED", "^ c #3AA3C5", "/ c #77BCD6", "( c #82C3D9", "_ c #0873A5", ": c #003C5B", "< c #464646", "[ c #1E1E1E", "} c #19AFEE", "| c #0787B6", "1 c #38A2C5", "2 c #5DB1D0", "3 c #76BBD5", "4 c #81C2D8", "5 c #85C4D9", "6 c #0770A1", "7 c #4F4F4F", "8 c #169ACB", "9 c #106CA1", "0 c #127CAD", "a c #0784B2", "b c #56B0CD", "c c #72B9D4", "d c #91C9DB", "e c #3F3F3F", "f c #2B2B2B", "g c #1380B2", "h c #0B5482", "i c #0E5E91", "j c #0E6597", "k c #116FA0", "l c #127FB1", "m c #58AECD", "n c #70B8D3", "o c #454545", "p c #FCFCFC", "q c #E9E4E4", "r c #8AA9B9", "s c #296C8E", "t c #0E5C8D", "u c #0F6698", "v c #1175A4", "w c #404040", "x c #444444", "y c #F6F6F6", "z c #F1F1F1", "A c #EBEBEB", "B c #EAEAEA", "C c #DBD7D6", "D c #81A0B0", "E c #286C8F", "F c #0F6596", "G c #1172A4", "H c #57A1C0", "I c #424242", "J c #EEEEEE", "K c #E6E6E6", "L c #E1E1E1", "M c #DCDCDC", "N c #D5D5D5", "O c #D7D7D7", "P c #CBC9C8", "Q c #88A6B5", "R c #276C8C", "S c #276892", "T c #363636", "U c #C4C4C4", "V c #DFDFDF", "W c #DEDEDE", "X c #DBDBDB", "Y c #D6D6D6", "Z c #D1D1D1", "` c #CCCCCC", " . c #C5C5C5", ".. c #BFBFBF", "+. c #C1BEBE", "@. c #6E6D6D", "#. c #686868", "$. c #C0C0C0", "%. c #CECECE", "&. c #CACACA", "*. c #C6C6C6", "=. c #BBBBBB", "-. c #B6B6B6", ";. c #AEAEAE", ">. c #323232", ",. c #606060", "'. c #AFAFAF", "). c #B5B5B5", "!. c #B0B0B0", "~. c #AAAAAA", "{. c #6C6B6B", "]. c #2E2E2E", "^. c #585858", "/. c #9D9D9D", "(. c #A7A7A7", "_. c #6A6969", ":. c #393939", "<. c #292929", "[. c #3A3835", " . + ", " @ # $ + + % ", " & * = - ; # $ + . + > . ", " , ' ) ! * = - ; # ~ $ $ . ", " { ] ^ / ' ) ( _ : - ; # $ < ", " [ } | 1 2 3 4 ' ) 5 6 = - 7 ", " [ 8 9 0 a | 1 b c d ' ) ! e ", " f g h i j k l | | 1 m n ' e ", " o p q r s h t u v 0 | | n w ", " x y z A B C D E h i F G H w ", " I J B K L M N O P Q R h S w ", " T U V W X Y Z ` ... .+.@.o ", " . T #.$.%.&.*.$.=.-.;.@.< ", " . >.,.'.=.).!.~.{.o ", " . ].^./.(._.:.", " . <.[. " }; void getOpenNodes (TQValueList < TQString > *open_nodes, PyBrowseNode * node) { if (node == NULL) return; if (node->isOpen ()) { open_nodes->append (node->getQualifiedName ()); } getOpenNodes (open_nodes, dynamic_cast < PyBrowseNode * >(node->firstChild ())); getOpenNodes (open_nodes, dynamic_cast < PyBrowseNode * >(node->nextSibling ())); } KPyBrowser::KPyBrowser (TQWidget * tqparent, const char *name): KListView (tqparent, name) { addColumn(i18n("Name")); header ()->hide (); class_root = new PyBrowseNode (this, TQString ("Classes"), i18n("Classes"), PYOTHER); class_root->setPixmap (0, TQPixmap (container_xpm)); function_root = new PyBrowseNode (this, TQString ("Globals"), i18n("Globals"), PYOTHER); function_root->setPixmap (0, TQPixmap (container_xpm)); setRootIsDecorated (1); connect (this, TQT_SIGNAL (executed (TQListViewItem *)), this, TQT_SLOT (nodeSelected (TQListViewItem *))); setTooltipColumn (1); setShowToolTips (1); tooltip = new KPBToolTip (this); } KPyBrowser::~KPyBrowser () { } void KPyBrowser::nodeSelected (TQListViewItem * node) { PyBrowseNode *browse_node = dynamic_cast < PyBrowseNode * >(node); if (!browse_node) { return; } TQString method_name; int line_no; line_no = browse_node->getLine(); method_name = browse_node->getName(); if (browse_node->getType () == PYCLASS) { method_name = TQString ("class ") + browse_node->getName (); } else if (browse_node->getType () == PYMETHOD || browse_node->getType () == PYFUNCTION) { method_name = TQString ("def ") + browse_node->getName (); } emit selected(method_name, line_no); } void KPyBrowser::parseText (TQString & pytext) { TQRegExp class_rx (TQString ("^class [a-zA-Z0-9_,\\s\\(\\).]+:")); TQRegExp function_rx (TQString ("^def [a-zA-Z_]+[^#]*:")); TQRegExp method_rx (TQString ("[\\s]+def [a-zA-Z_]+[^#]*:")); int paren_i; TQStringList lines = TQStringList::split ("\n", pytext, TRUE); TQStringList::Iterator iter; TQString *line; TQString class_name, method_name, function_name, class_sig, method_sig, function_sig; PyBrowseNode *last_class_node = NULL; PyBrowseNode *last_method_node = NULL; PyBrowseNode *last_function_node = NULL; TQValueList < TQString > open_nodes; getOpenNodes (&open_nodes, class_root); getOpenNodes (&open_nodes, function_root); int line_no, state = 0; if (class_root != NULL) { delete class_root; } if (function_root != NULL) { delete function_root; } class_root = new PyBrowseNode (this, TQString ("Classes"), i18n("Classes"), PYOTHER); class_root->setPixmap (0, TQPixmap (container_xpm)); function_root = new PyBrowseNode (this, TQString ("Globals"), i18n("Globals"), PYOTHER); function_root->setPixmap (0, TQPixmap (container_xpm)); node_dict.insert (class_root->getQualifiedName (), class_root); node_dict.insert (function_root->getQualifiedName (), function_root); line_no = 0; for (iter = lines.begin(); iter != lines.end(); ++iter) { line_no++; line = &(*iter); if (class_rx.search(*line) >= 0) { //KMessageBox::information(this, *line, TQString("Found class on line %1").tqarg(line_no)); //strip out the beginning class and ending colon class_sig = line->stripWhiteSpace ().mid (6); class_sig = class_sig.left (class_sig.length () - 1); paren_i = class_sig.tqfind ("("); class_name = class_sig.left (paren_i); last_class_node = new PyBrowseNode (class_root, class_name, class_sig, PYCLASS); last_class_node->setLine (line_no); last_class_node->setClass (class_name); node_dict.insert (last_class_node->getQualifiedName (), last_class_node); state = 1; } if ((method_rx.search(*line) >= 0) && (state == 1)) { //strip off the leading def and the ending colon method_sig = line->stripWhiteSpace ().mid (4); method_sig = method_sig.left (method_sig.tqfind (":")); paren_i = method_sig.tqfind ("("); method_name = method_sig.left (paren_i); last_method_node = new PyBrowseNode (last_class_node, method_name, method_sig, PYMETHOD); last_method_node->setLine (line_no); last_method_node->setClass (last_class_node->getClass ()); node_dict.insert (last_method_node->getQualifiedName (), last_method_node); } if ((function_rx.search(*line) >= 0)) { //KMessageBox::information(this, *line, TQString("Found function on line %1").tqarg(line_no)); function_sig = line->stripWhiteSpace ().mid (4); function_sig = function_sig.left (function_sig.tqfind (":")); paren_i = function_sig.tqfind ("("); function_name = function_sig.left (paren_i); last_function_node = new PyBrowseNode (function_root, function_name, function_sig, PYFUNCTION); last_function_node->setLine (line_no); node_dict.insert (last_function_node->getQualifiedName (), last_function_node); state = 0; } } //now go through the list of old open nodes and open them in the new //tree. For each node name in the open_nodes list, attempt to find that //node and in the new dict and open it. TQValueList::iterator it; PyBrowseNode *tmp_node; for (it=open_nodes.begin(); it != open_nodes.end(); ++it) { tmp_node = node_dict[(*it)]; if (tmp_node) { tmp_node->setOpen(1); } } } void KPyBrowser::tip (const TQPoint & p, TQRect & r, TQString & str) { TQListViewItem *item = (TQListViewItem *) itemAt (p); if (item == NULL) { str = ""; return; } r = tqitemRect (item); //r.setY(r.y() + 10); PyBrowseNode *browse_node = dynamic_cast < PyBrowseNode * >(item); if (browse_node) { if (r.isValid ()) str = browse_node->getSig (); else str = ""; } else { str = item->text (0); } } ///////////////////////////////////////////////////////////////////// // KateFileList::KFLToolTip implementation KPyBrowser::KPBToolTip::KPBToolTip (TQWidget * tqparent):TQToolTip (tqparent) { } void KPyBrowser::KPBToolTip::maybeTip (const TQPoint & p) { TQString str; TQRect r; ((KPyBrowser *) parentWidget ())->tip (p, r, str); if (!str.isEmpty () && r.isValid ()) tip (r, str); }