00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00171 KDevLanguageSupport::Features features =
classTree()->
m_part->
languageSupport()->
features();
00172
00173
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00529
if (item->childCount() > 0)
00530 setOpen(item, !isOpen(item));
00531
00532
00533
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
00557
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"