KDevelop API Documentation

parts/classview/classviewpart.cpp

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org) 00003 * Copyright (C) 2003 Alexander Dymo (cloudtemple@mksat.net) 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 * 00020 */ 00021 00022 #include <qwhatsthis.h> 00023 #include <qlistview.h> 00024 #include <qfileinfo.h> 00025 #include <qlineedit.h> 00026 00027 #include <kiconloader.h> 00028 #include <klocale.h> 00029 #include <kdevgenericfactory.h> 00030 #include <kpopupmenu.h> 00031 #include <kdebug.h> 00032 #include <kmimetype.h> 00033 00034 #include <kdevcore.h> 00035 #include <kdevmainwindow.h> 00036 #include <kdevlanguagesupport.h> 00037 #include <kcomboview.h> 00038 #include <kdevpartcontroller.h> 00039 #include <kdevproject.h> 00040 #include <urlutil.h> 00041 00042 #include <codemodel.h> 00043 #include <codemodel_utils.h> 00044 00045 #include "classviewwidget.h" 00046 #include "classviewpart.h" 00047 #include "hierarchydlg.h" 00048 00049 #include "klistviewaction.h" 00050 00051 #include <ktexteditor/document.h> 00052 #include <ktexteditor/editinterface.h> 00053 #include <ktexteditor/view.h> 00054 #include <ktexteditor/selectioninterface.h> 00055 #include <ktexteditor/viewcursorinterface.h> 00056 #include <ktexteditor/clipboardinterface.h> 00057 00058 typedef KDevGenericFactory<ClassViewPart> ClassViewFactory; 00059 static const KAboutData data("kdevclassview", I18N_NOOP("Class browser"), "1.0"); 00060 K_EXPORT_COMPONENT_FACTORY( libkdevclassview, ClassViewFactory( &data ) ) 00061 00062 ClassViewPart::ClassViewPart(QObject *parent, const char *name, const QStringList& ) 00063 : KDevPlugin("ClassView", "classview", parent, name ? name : "ClassViewPart" ), sync(false) 00064 { 00065 setInstance(ClassViewFactory::instance()); 00066 setXMLFile("kdevclassview.rc"); 00067 00068 setupActions(); 00069 00070 global_item = 0; 00071 00072 m_widget = new ClassViewWidget(this); 00073 m_widget->setIcon( SmallIcon("view_tree") ); 00074 mainWindow()->embedSelectView( m_widget, i18n("Classes"), i18n("Class browser") ); 00075 QWhatsThis::add(m_widget, i18n("<b>Class browser</b><p>" 00076 "The class browser shows all namespaces, classes and namespace and class members in a project.")); 00077 00078 connect( core(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) ); 00079 connect( core(), SIGNAL(projectClosed()), this, SLOT(slotProjectClosed()) ); 00080 connect( core(), SIGNAL(languageChanged()), this, SLOT(slotProjectOpened()) ); 00081 connect( partController(), SIGNAL(activePartChanged(KParts::Part*)), 00082 this, SLOT(activePartChanged(KParts::Part*))); 00083 connect( m_widget, SIGNAL(removedNamespace(const QString&)), this, SLOT(removeNamespace(const QString& ))); 00084 00085 m_classes->view()->setDefaultText(EmptyClasses); 00086 m_functions->view()->setDefaultText(EmptyFunctions); 00087 } 00088 00089 00090 ClassViewPart::~ClassViewPart() 00091 { 00092 m_namespaces->view()->clear(); 00093 m_classes->view()->clear(); 00094 m_functions->view()->clear(); 00095 00096 mainWindow()->removeView( m_widget ); 00097 delete (ClassViewWidget*) m_widget; 00098 } 00099 00100 void ClassViewPart::slotProjectOpened( ) 00101 { 00102 connect( languageSupport(), SIGNAL(updatedSourceInfo()), this, SLOT(refresh()) ); 00103 connect( languageSupport(), SIGNAL(aboutToRemoveSourceInfo(const QString& )), this, SLOT(removeFile(const QString&))); 00104 connect( languageSupport(), SIGNAL(addedSourceInfo(const QString& )), this, SLOT(addFile(const QString& ))); 00105 // connect( languageSupport(), SIGNAL(addedSourceInfo(const QString& )), this, SLOT(refresh())); 00106 } 00107 00108 void ClassViewPart::slotProjectClosed( ) 00109 { 00110 disconnect( languageSupport(), SIGNAL(updatedSourceInfo()), this, SLOT(refresh()) ); 00111 m_namespaces->view()->clear(); 00112 m_classes->view()->clear(); 00113 m_functions->view()->clear(); 00114 } 00115 00116 void ClassViewPart::setupActions( ) 00117 { 00118 m_followCode = new KAction(i18n("Synchronize"), "dirsynch", 0, this, SLOT(syncCombos()), actionCollection(), "sync_combos"); 00119 m_followCode->setToolTip(i18n("Synchronize selectors")); 00120 m_followCode->setWhatsThis(i18n("<b>Synchronize</b><p>Synchronize namespaces, classes and functions selectors with the current position in code.")); 00121 00122 m_namespaces = new KListViewAction( new KComboView(true, 150, 0, "m_namespaces_combo"), i18n("Namespaces"), 0, 0, 0, actionCollection(), "namespaces_combo", true ); 00123 connect( m_namespaces->view(), SIGNAL(activated(QListViewItem*)), this, SLOT(selectNamespace(QListViewItem*)) ); 00124 connect( m_namespaces->view(), SIGNAL(focusGranted()), this, SLOT(focusNamespaces()) ); 00125 connect( m_namespaces->view(), SIGNAL(focusLost()), this, SLOT(unfocusNamespaces()) ); 00126 m_namespaces->setToolTip(i18n("Namespaces")); 00127 m_namespaces->setWhatsThis(i18n("<b>Namespace selector</b><p>Select a namespace to view classes and functions contained in it.")); 00128 00129 m_classes = new KListViewAction( new KComboView(true, 150, 0, "m_classes_combo"), i18n("Classes"), 0, 0, 0, actionCollection(), "classes_combo", true ); 00130 connect( m_classes->view(), SIGNAL(activated(QListViewItem*)), this, SLOT(selectClass(QListViewItem*)) ); 00131 connect( m_classes->view(), SIGNAL(focusGranted()), this, SLOT(focusClasses()) ); 00132 connect( m_classes->view(), SIGNAL(focusLost()), this, SLOT(unfocusClasses()) ); 00133 m_classes->setToolTip(i18n("Classes")); 00134 m_classes->setWhatsThis(i18n("<b>Class selector</b><p>Select a class to view it's members.")); 00135 00136 m_functions = new KListViewAction( new KComboView(true, 300, 0, "m_functions_combo"), i18n("Functions"), 0, 0, 0, actionCollection(), "functions_combo", true ); 00137 connect( m_functions->view(), SIGNAL(activated(QListViewItem*)), this, SLOT(selectFunction(QListViewItem*)) ); 00138 connect( m_functions->view(), SIGNAL(focusGranted()), this, SLOT(focusFunctions()) ); 00139 connect( m_functions->view(), SIGNAL(focusLost()), this, SLOT(unfocusFunctions()) ); 00140 m_functions->setToolTip(i18n("Functions")); 00141 m_functions->setWhatsThis(i18n("<b>Function selector</b><p>Select a function to jump to it's definition or declaration.")); 00142 00143 // m_namespaces->view()->setMinimumWidth(150); 00144 // m_classes->view()->setMinimumWidth(150); 00145 // m_functions->view()->setMinimumWidth(300); 00146 00147 m_popupAction = new KToolBarPopupAction(i18n("Class Browser Actions"), "classwiz", 0, 00148 this, SLOT(switchedViewPopup()), 00149 actionCollection(), "view_popup"); 00150 m_popupAction->setToolTip(i18n("Class browser actions")); 00151 m_popupAction->setWhatsThis(i18n("<b>Class browser actions</b><p>A menu for commonly used class browser actions " 00152 "like switch between function declaration and definition, " 00153 "add classes, methods and attributes, " 00154 "inheritance diagram.")); 00155 m_popupAction->setDelayed(false); 00156 KPopupMenu *popup = m_popupAction->popupMenu(); 00157 //@todo check if language support has namespaces, classes, etc. 00158 // KDevLanguageSupport::Features features = languageSupport()->features(); 00159 int id = popup->insertItem(i18n("Go to Function Declaration"), this, SLOT(goToFunctionDeclaration())); 00160 popup->setWhatsThis(id, i18n("<b>Go to function declaration</b><p>Opens a file where the function is declared and jumps to the declaration line.")); 00161 id = popup->insertItem(i18n("Go to Function Definition"), this, SLOT(goToFunctionDefinition())); 00162 popup->setWhatsThis(id, i18n("<b>Go to function definition</b><p>Opens a file where the function is defined (implemented) and jumps to the definition line.")); 00163 id = popup->insertItem(i18n("Go to Class Declaration"), this, SLOT(goToClassDeclaration())); 00164 popup->setWhatsThis(id, i18n("<b>Go to class declaration</b><p>Opens a file where the class is declared and jumps to the declaration line.")); 00165 00166 //@todo not applicable to c++ but can be useful for ada and pascal where namespace is contained 00167 //in a single compilation unit 00169 // popup->insertItem(i18n("Go to Namespace Declaration"), this, SLOT(goToNamespaceDeclaration())); 00170 00171 bool hasAddMethod = langHasFeature(KDevLanguageSupport::AddMethod); 00172 bool hasAddAttribute = langHasFeature(KDevLanguageSupport::AddAttribute); 00173 bool hasNewClass = langHasFeature(KDevLanguageSupport::NewClass); 00174 if (hasAddMethod || hasAddAttribute || hasNewClass) 00175 popup->insertSeparator(); 00176 if (hasNewClass) 00177 { 00178 id = popup->insertItem(SmallIcon("classnew"), i18n("New Class..."), this, SLOT(selectedAddClass())); 00179 popup->setWhatsThis(id, i18n("<b>New class</b><p>Calls the <b>New Class</b> wizard.")); 00180 } 00181 #if 0 00182 if (hasAddMethod) 00183 { 00184 id = popup->insertItem(SmallIcon("methodnew"), i18n("Add Method..."), this, SLOT(selectedAddMethod())); 00185 popup->setWhatsThis(id, i18n("<b>Add method</b><p>Calls the <b>New Method</b> wizard.")); 00186 } 00187 if (hasAddAttribute) 00188 { 00189 id = popup->insertItem(SmallIcon("variablenew"), i18n("Add Attribute..."), this, SLOT(selectedAddAttribute())); 00190 popup->setWhatsThis(id, i18n("<b>Add attribute</b><p>Calls the <b>New Attribute</b> wizard.")); 00191 } 00192 #endif 00193 00194 popup->insertSeparator(); 00195 id = popup->insertItem(i18n("Inheritance Diagram"), this, SLOT(graphicalClassView())); 00196 popup->setWhatsThis(id, i18n("<b>Inheritance diagram</b><p>Displays inheritance relationship between classes in project. " 00197 "Note, it does not display classes outside inheritance hierarchy.")); 00198 } 00199 00200 void ClassViewPart::refresh( ) 00201 { 00202 kdDebug() << "ClassViewPart::refresh" << endl; 00203 ViewCombosOp::refreshNamespaces(this, m_namespaces->view()); 00204 } 00205 00206 void ClassViewPart::selectNamespace( QListViewItem * item ) 00207 { 00208 NamespaceItem *ni = dynamic_cast<NamespaceItem*>(item); 00209 if (!ni) 00210 return; 00211 ViewCombosOp::refreshClasses(this, m_classes->view(), ni->dom()->name()); 00212 ViewCombosOp::refreshFunctions(this, m_functions->view(), ni->dom()->name()); 00213 } 00214 00215 void ClassViewPart::selectClass( QListViewItem * item ) 00216 { 00217 ClassItem *ci = dynamic_cast<ClassItem*>(item); 00218 if (!ci) 00219 return; 00220 ViewCombosOp::refreshFunctions(this, m_functions->view(), ci->dom()); 00221 } 00222 00223 void ClassViewPart::selectFunction( QListViewItem * item ) 00224 { 00225 if (sync) 00226 { 00227 sync = false; 00228 return; 00229 } 00230 //adymo: this jumps to declaration - commented 00231 /* FunctionItem *fi = dynamic_cast<FunctionItem*>(item); 00232 if (!fi) 00233 return; 00234 int startLine, startColumn; 00236 //fi->dom()->getImplementationStartPosition( &startLine, &startColumn ); 00237 //if (startLine != 0) 00238 // partController()->editDocument( KURL(fi->dom()->implementedInFile()), startLine ); 00239 //else 00240 { 00241 fi->dom()->getStartPosition( &startLine, &startColumn ); 00242 partController()->editDocument( KURL(fi->dom()->fileName()), startLine ); 00243 }*/ 00244 00245 //adymo: this jumps to definition or declaration if the definition is not found 00246 FunctionItem *fi = dynamic_cast<FunctionItem*>(item); 00247 if (!fi) 00248 return; 00249 int startLine, startColumn; 00250 00251 FunctionDefinitionList lst; 00252 FileList fileList = codeModel()->fileList(); 00253 CodeModelUtils::findFunctionDefinitions( FindOp(fi->dom()), fileList, lst ); 00254 00255 if( lst.isEmpty() ) 00256 { //definition not found, try declaration instead 00257 int startLine, startColumn; 00258 fi->dom()->getStartPosition( &startLine, &startColumn ); 00259 partController()->editDocument( KURL(fi->dom()->fileName()), startLine ); 00260 } 00261 else 00262 { //jump to definition 00263 FunctionDefinitionDom fun = lst.front(); 00264 QString path = QFileInfo( fi->dom()->fileName() ).dirPath( true ); 00265 00266 for( FunctionDefinitionList::Iterator it=lst.begin(); it!=lst.end(); ++it ){ 00267 if( path == QFileInfo((*it)->fileName()).dirPath(true) ) 00268 fun = *it; 00269 } 00270 00271 fun->getStartPosition( &startLine, &startColumn ); 00272 partController()->editDocument( KURL(fun->fileName()), startLine ); 00273 } 00274 } 00275 00276 void ClassViewPart::switchedViewPopup( ) 00277 { 00278 } 00279 00280 bool ClassViewPart::langHasFeature(KDevLanguageSupport::Features feature) 00281 { 00282 bool result = false; 00283 if (languageSupport()) 00284 result = (feature & languageSupport()->features()); 00285 return result; 00286 } 00287 00288 void ClassViewPart::goToFunctionDeclaration( ) 00289 { 00290 if ( m_functions->view()->currentItem() ) 00291 { 00292 FunctionItem *fi = dynamic_cast<FunctionItem*>(m_functions->view()->currentItem()); 00293 if (!fi) 00294 return; 00295 int startLine, startColumn; 00296 fi->dom()->getStartPosition( &startLine, &startColumn ); 00297 partController()->editDocument( KURL(fi->dom()->fileName()), startLine ); 00298 } 00299 } 00300 00301 void ClassViewPart::goToFunctionDefinition( ) 00302 { 00303 if ( m_functions->view()->currentItem() ) 00304 { 00305 FunctionItem *fi = dynamic_cast<FunctionItem*>(m_functions->view()->currentItem()); 00306 if (!fi) 00307 return; 00308 int startLine, startColumn; 00309 00310 FunctionDefinitionList lst; 00311 FileList fileList = codeModel()->fileList(); 00312 CodeModelUtils::findFunctionDefinitions( FindOp(fi->dom()), fileList, lst ); 00313 00314 if( lst.isEmpty() ) 00315 return; 00316 00317 FunctionDefinitionDom fun = lst.front(); 00318 QString path = QFileInfo( fi->dom()->fileName() ).dirPath( true ); 00319 00320 for( FunctionDefinitionList::Iterator it=lst.begin(); it!=lst.end(); ++it ){ 00321 if( path == QFileInfo((*it)->fileName()).dirPath(true) ) 00322 fun = *it; 00323 } 00324 00325 fun->getStartPosition( &startLine, &startColumn ); 00326 partController()->editDocument( KURL(fun->fileName()), startLine ); 00327 00328 } 00329 } 00330 00331 void ClassViewPart::goToClassDeclaration( ) 00332 { 00333 if ( m_classes->view()->currentItem() ) 00334 { 00335 ClassItem *fi = dynamic_cast<ClassItem*>(m_classes->view()->currentItem()); 00336 if (!fi) 00337 return; 00338 int startLine, startColumn; 00339 fi->dom()->getStartPosition( &startLine, &startColumn ); 00340 partController()->editDocument( KURL(fi->dom()->fileName()), startLine ); 00341 } 00342 } 00343 00344 void ClassViewPart::goToNamespaceDeclaration( ) 00345 { 00346 if ( m_namespaces->view()->currentItem() ) 00347 { 00348 NamespaceItem *fi = dynamic_cast<NamespaceItem*>(m_namespaces->view()->currentItem()); 00349 if (!fi) 00350 return; 00351 int startLine, startColumn; 00352 fi->dom()->getStartPosition( &startLine, &startColumn ); 00353 partController()->editDocument( KURL(fi->dom()->fileName()), startLine ); 00354 } 00355 } 00356 00357 void ClassViewPart::selectedAddClass( ) 00358 { 00359 if (languageSupport()) 00360 languageSupport()->addClass(); 00361 } 00362 00363 void ClassViewPart::selectedAddMethod( ) 00364 { 00365 ClassItem *ci = dynamic_cast<ClassItem*>(m_classes->view()->currentItem()); 00366 if (!ci) 00367 return; 00368 if (languageSupport()) 00369 languageSupport()->addMethod(ci->dom()); 00370 } 00371 00372 void ClassViewPart::selectedAddAttribute( ) 00373 { 00374 ClassItem *ci = dynamic_cast<ClassItem*>(m_classes->view()->currentItem()); 00375 if (!ci) 00376 return; 00377 if (languageSupport()) 00378 languageSupport()->addAttribute(ci->dom()); 00379 } 00380 00381 void ClassViewPart::graphicalClassView( ) 00382 { 00383 HierarchyDialog dia(this); 00384 dia.exec(); 00385 } 00386 00387 void ClassViewPart::focusClasses( ) 00388 { 00389 if (m_classes->view()->currentText() == EmptyClasses) 00390 m_classes->view()->setCurrentText(""); 00391 // else 00392 // m_classes->view()->lineEdit()->selectAll(); 00393 } 00394 00395 void ClassViewPart::focusFunctions( ) 00396 { 00397 if (m_functions->view()->currentText() == EmptyFunctions) 00398 m_functions->view()->setCurrentText(""); 00399 // else 00400 // m_functions->view()->lineEdit()->selectAll(); 00401 } 00402 00403 void ClassViewPart::unfocusClasses( ) 00404 { 00405 if (m_classes->view()->currentText().isEmpty()) 00406 m_classes->view()->setCurrentText(EmptyClasses); 00407 // m_classes->view()->lineEdit()->deselect(); 00408 } 00409 00410 void ClassViewPart::unfocusFunctions( ) 00411 { 00412 if (m_functions->view()->currentText().isEmpty()) 00413 m_functions->view()->setCurrentText(EmptyFunctions); 00414 // m_functions->view()->lineEdit()->deselect(); 00415 } 00416 00417 void ClassViewPart::syncCombos( ) 00418 { 00419 kdDebug() << "ClassViewPart::syncCombos" << endl; 00420 if (m_activeFileName.isEmpty()) 00421 return; 00422 FileDom dom = codeModel()->fileByName(m_activeFileName); 00423 if (!dom.data()) 00424 return; 00425 // NamespaceDom nsdom = syncNamespaces(dom); 00426 // ClassDom cldom = syncClasses(nsdom); 00427 // FunctionDom fndom = syncFunctions(cldom); 00428 00429 kdDebug() << "ClassViewPart::syncCombos working on " << m_activeFileName << endl; 00430 unsigned int line; unsigned int column; 00431 m_activeViewCursor->cursorPosition(&line, &column); 00432 00433 //try to sync with declarations 00434 bool declarationFound = false; 00435 CodeModelUtils::AllFunctions functions = CodeModelUtils::allFunctionsDetailed(dom); 00436 FunctionDom fndom; 00437 for (FunctionList::Iterator it = functions.functionList.begin(); 00438 it != functions.functionList.end(); ++it) 00439 { 00440 int startLine; int startColumn; 00441 (*it)->getStartPosition(&startLine, &startColumn); 00442 int endLine; int endColumn; 00443 (*it)->getEndPosition(&endLine, &endColumn); 00444 00445 kdDebug() << "sync with " << (*it)->name() << " startLine " << startLine << 00446 " endLine " << endLine << " line " << line << endl; 00447 00448 if ( (int(line) >= startLine) && (int(line) <= endLine) ) 00449 { 00450 fndom = *it; 00451 break; 00452 } 00453 } 00454 00455 if (!fndom.data()) 00456 declarationFound = false; 00457 else 00458 { 00459 NamespaceDom nsdom = functions.relations[fndom].ns; 00460 if (nsdom.data()) 00461 kdDebug() << "namespace to try " << nsdom->name() << endl; 00462 else 00463 kdDebug() << "namespace data empty" << endl; 00464 00465 for (QMap<QString, NamespaceItem*>::const_iterator it = nsmap.begin(); 00466 it != nsmap.end(); ++it) 00467 { 00468 kdDebug() << " in nsmap " << it.key() << " data " << it.data() << endl; 00469 kdDebug() << " in nsmap " << it.key() << " data " << it.data()->text(0) << endl; 00470 } 00471 00472 kdDebug() << " in nsmap is ? " << nsdom.data() << endl; 00473 if (nsdom) 00474 { 00475 kdDebug() << " in nsmap is ? " << nsdom->name() << endl; 00476 if (nsdom->name() != "::") 00477 return; 00478 } 00479 00480 if (nsdom.data() && nsmap[nsdom->name()]) 00481 { 00482 kdDebug() << "trying namespace " << nsdom->name() << endl; 00483 m_namespaces->view()->setCurrentActiveItem(nsmap[nsdom->name()]); 00484 } 00485 else 00486 { 00487 kdDebug() << "trying global namespace " << endl; 00488 if (m_namespaces->view()->listView()->firstChild()) 00489 { 00490 kdDebug() << "firstChild exists - global ns" << endl; 00491 m_namespaces->view()->setCurrentActiveItem(m_namespaces->view()->listView()->firstChild()); 00492 } 00493 } 00494 ClassDom cldom = functions.relations[fndom].klass; 00495 if (cldom.data() && clmap[cldom.data()]) 00496 { 00497 kdDebug() << "trying class " << cldom->name() << endl; 00498 m_classes->view()->setCurrentActiveItem(clmap[cldom.data()]); 00499 } 00500 00501 kdDebug() << "trying function " << fndom->name() << endl; 00502 sync = true; 00503 m_functions->view()->setCurrentItem(fnmap[fndom.data()]); 00504 } 00505 00506 if (!declarationFound) 00507 { 00508 //try to sync with definitions 00509 00510 CodeModelUtils::AllFunctionDefinitions functions = CodeModelUtils::allFunctionDefinitionsDetailed(dom); 00511 FunctionDefinitionDom fndom; 00512 for (FunctionDefinitionList::Iterator it = functions.functionList.begin(); 00513 it != functions.functionList.end(); ++it) 00514 { 00515 int startLine; int startColumn; 00516 (*it)->getStartPosition(&startLine, &startColumn); 00517 int endLine; int endColumn; 00518 (*it)->getEndPosition(&endLine, &endColumn); 00519 00520 kdDebug() << "sync with " << (*it)->name() << " startLine " << startLine << 00521 " endLine " << endLine << " line " << line << endl; 00522 00523 if ( (int(line) >= startLine) && (int(line) <= endLine) ) 00524 { 00525 fndom = *it; 00526 break; 00527 } 00528 } 00529 00530 if (!fndom.data()) 00531 return; 00532 NamespaceDom nsdom = functions.relations[fndom].ns; 00533 if (nsdom.data()) 00534 kdDebug() << "namespace to try " << nsdom->name() << endl; 00535 else 00536 kdDebug() << "namespace data empty" << endl; 00537 00538 for (QMap<QString, NamespaceItem*>::const_iterator it = nsmap.begin(); 00539 it != nsmap.end(); ++it) 00540 { 00541 kdDebug() << " in nsmap " << it.key() << " data " << it.data() << endl; 00542 kdDebug() << " in nsmap " << it.key() << " data " << it.data()->text(0) << endl; 00543 } 00544 00545 kdDebug() << " in nsmap is ? " << nsdom.data() << endl; 00546 if (nsdom) 00547 { 00548 kdDebug() << " in nsmap is ? " << nsdom->name() << endl; 00549 if (nsdom->name() != "::") 00550 return; 00551 } 00552 00553 if (nsdom.data() && nsmap[nsdom->name()]) 00554 { 00555 kdDebug() << "trying namespace " << nsdom->name() << endl; 00556 m_namespaces->view()->setCurrentActiveItem(nsmap[nsdom->name()]); 00557 } 00558 else 00559 { 00560 kdDebug() << "trying global namespace " << endl; 00561 if (m_namespaces->view()->listView()->firstChild()) 00562 { 00563 kdDebug() << "firstChild exists - global ns" << endl; 00564 m_namespaces->view()->setCurrentActiveItem(m_namespaces->view()->listView()->firstChild()); 00565 00566 kdDebug() << "trying to find item using global namespace" << endl; 00567 if (codeModel()->globalNamespace()->hasFunction(fndom->name())) 00568 { 00569 sync = true; 00570 FunctionModel *mod = const_cast<FunctionModel *>( codeModel()->globalNamespace()->functionByName(fndom->name()).first().data() ); 00571 QListViewItem *it = fnmap[mod]; 00572 if (it) 00573 m_functions->view()->setCurrentItem(it); 00574 return; 00575 } 00576 } 00577 } 00578 ClassDom cldom = functions.relations[fndom].klass; 00579 if (cldom.data() && clmap[cldom.data()]) 00580 { 00581 kdDebug() << "trying class " << cldom->name() << endl; 00582 m_classes->view()->setCurrentActiveItem(clmap[cldom.data()]); 00583 00584 kdDebug() << "trying to find item using class " << cldom->name() << endl; 00585 00586 if (cldom->hasFunction(fndom->name())) 00587 { 00588 sync = true; 00589 QListViewItem *it = fnmap[cldom->functionByName(fndom->name()).first().data()]; 00590 if (it) 00591 m_functions->view()->setCurrentItem(it); 00592 return; 00593 } 00594 } 00595 00596 kdDebug() << "trying function definition " << fndom->name() 00597 << " with scope " << fndom->scope().join("::") << endl; 00598 00599 NamespaceDom currNs = codeModel()->globalNamespace(); 00600 ClassDom currClass; 00601 for (QStringList::const_iterator it = fndom->scope().begin(); 00602 it != fndom->scope().end(); ++it) 00603 { 00604 if (currNs->hasNamespace(*it)) 00605 { 00606 currNs = currNs->namespaceByName(*it); 00607 kdDebug() << "resolved namespace " << *it << endl; 00608 } 00609 else if (currNs->hasClass(*it)) 00610 { 00611 currClass = currNs->classByName(*it).first(); 00612 kdDebug() << "resolved class " << *it << endl; 00613 } 00614 else if (currClass.data() && currClass->hasClass(*it)) 00615 { 00616 currClass = currClass->classByName(*it).first(); 00617 kdDebug() << "resolved nested class " << *it << endl; 00618 } 00619 } 00620 if (currClass.data()) 00621 { 00622 kdDebug() << "trying to find item using resolved class " << currNs->name() << endl; 00623 if (currClass->hasFunction(fndom->name())) 00624 { 00625 sync = true; 00626 QListViewItem *it = fnmap[currClass->functionByName(fndom->name()).first().data()]; 00627 if (it) 00628 m_functions->view()->setCurrentItem(it); 00629 return; 00630 } 00631 } 00632 else if (currNs.data()) 00633 { 00634 kdDebug() << "trying to find item using resolved namespace " << currNs->name() << endl; 00635 if (currNs->hasFunction(fndom->name())) 00636 { 00637 sync = true; 00638 FunctionModel *mod= currNs->functionByName(fndom->name()).first().data(); 00639 QListViewItem *it = fnmap[mod]; 00640 if (it) 00641 m_functions->view()->setCurrentItem(it); 00642 return; 00643 } 00644 } 00645 00646 sync = true; 00647 // m_functions->view()->setCurrentItem(fnmap[fndom.data()]); 00648 } 00649 } 00650 // const NamespaceList nslist = dom->namespaceList(); 00651 // for (NamespaceList::const_iterator it = nslist->begin(); it != namespaceList.end(); ++it) 00652 // { 00653 // nsdom = syncNamespaces(*it); 00654 // } 00655 00656 void ClassViewPart::activePartChanged( KParts::Part * part) 00657 { 00658 kdDebug() << "ClassViewPart::activePartChanged()" << endl; 00659 00660 m_activeDocument = dynamic_cast<KTextEditor::Document*>( part ); 00661 m_activeView = part ? dynamic_cast<KTextEditor::View*>( part->widget() ) : 0; 00662 m_activeEditor = dynamic_cast<KTextEditor::EditInterface*>( part ); 00663 m_activeSelection = dynamic_cast<KTextEditor::SelectionInterface*>( part ); 00664 m_activeViewCursor = part ? dynamic_cast<KTextEditor::ViewCursorInterface*>( m_activeView ) : 0; 00665 00666 m_activeFileName = QString::null; 00667 00668 if (m_activeDocument) 00669 { 00670 m_activeFileName = URLUtil::canonicalPath( m_activeDocument->url().path() ); 00671 /* if ( languageSupport()->mimeTypes().find( 00672 KMimeType::findByPath(m_activeFileName)) != languageSupport()->mimeTypes().end() ) 00673 m_activeFileName = QString::null;*/ 00674 } 00675 } 00676 00677 NamespaceDom ClassViewPart::syncNamespaces( const FileDom & /*dom*/ ) 00678 { 00679 return NamespaceDom(); 00680 } 00681 00682 ClassDom ClassViewPart::syncClasses( const NamespaceDom & /*dom*/ ) 00683 { 00684 return ClassDom(); 00685 } 00686 00687 FunctionDom ClassViewPart::syncFunctions( const ClassDom & /*dom*/ ) 00688 { 00689 return FunctionDom(); 00690 } 00691 00692 void ClassViewPart::focusNamespaces( ) 00693 { 00694 //m_namespaces->view()->lineEdit()->selectAll(); 00695 } 00696 00697 void ClassViewPart::unfocusNamespaces( ) 00698 { 00699 // m_namespaces->view()->lineEdit()->deselect(); 00700 } 00701 00702 void ClassViewPart::removeFile( const QString & fileName ) 00703 { 00704 QString fn = URLUtil::canonicalPath( fileName ); 00705 if( !project()->isProjectFile(fn) ) 00706 return; 00707 00708 FileDom file = codeModel()->fileByName(fileName); 00709 if (!file) 00710 return; 00711 00712 if (ViewCombosOp::removeNamespacesItems(this, m_namespaces->view()->listView(), model_cast<NamespaceDom>(file))) 00713 { 00714 if (global_item) 00715 m_namespaces->view()->setCurrentActiveItem(global_item); 00716 } 00717 00718 ViewCombosOp::removeClassItems(this, m_namespaces->view()->listView(), model_cast<ClassDom>(file)); 00719 00720 ViewCombosOp::removeFunctionItems(this, m_namespaces->view()->listView(), model_cast<ClassDom>(file)); 00721 } 00722 00723 void ClassViewPart::addFile( const QString & fileName ) 00724 { 00725 QString fn = URLUtil::canonicalPath( fileName ); 00726 if( !project()->isProjectFile(fn) ) 00727 return; 00728 00729 FileDom file = codeModel()->fileByName(fileName); 00730 if (!file) 00731 return; 00732 00733 //check for namespaces in file 00734 NamespaceList namespaceList = file->namespaceList(); 00735 for (NamespaceList::const_iterator it = namespaceList.begin(); it != namespaceList.end(); ++it) 00736 { 00737 NamespaceDom nsdom = *it; 00738 if (nsmap.contains(nsdom->name())) 00739 { 00740 //namespace item exists - update 00741 NamespaceItem *ns = nsmap[nsdom->name()]; 00742 ns->setText(0, languageSupport()->formatModelItem(nsdom)); 00743 if (m_namespaces->view()->currentItem() == ns) 00744 { 00745 //reload this and dependent combos because namespace item is currently selected 00746 m_namespaces->view()->setCurrentText(languageSupport()->formatModelItem(nsdom)); 00747 00748 //check classes 00749 updateClassesForAdd(nsdom); 00750 //check functions 00751 updateFunctionsForAdd(model_cast<ClassDom>(nsdom)); 00752 } 00753 //refresh info about nested namespaces 00754 kdDebug() << "nested ns check for " << nsdom->name() << endl; 00755 ViewCombosOp::processNamespace(this, m_namespaces->view(), ns, ViewCombosOp::Refresh); 00756 } 00757 else 00758 { 00759 //namespace item does not exist - create 00760 NamespaceItem *item = new NamespaceItem(this, m_namespaces->view()->listView(), languageSupport()->formatModelItem(nsdom), nsdom); 00761 m_namespaces->view()->addItem(item); 00762 item->setOpen(true); 00763 ViewCombosOp::processNamespace(this, m_namespaces->view(), item); 00764 } 00765 } 00766 00767 if (m_namespaces->view()->currentItem()) 00768 { 00769 NamespaceItem *ni = dynamic_cast<NamespaceItem*>(m_namespaces->view()->currentItem()); 00770 if (ni && (ni->dom() == codeModel()->globalNamespace())) 00771 { 00772 //check for classes in file (global namespace) 00773 updateClassesForAdd(model_cast<NamespaceDom>(file)); 00774 00775 //check for funtions in file (global namespace); 00776 updateFunctionsForAdd(model_cast<ClassDom>(file)); 00777 } 00778 } 00779 } 00780 00781 void ClassViewPart::updateFunctionsForAdd( ClassDom cldom ) 00782 { 00783 FunctionList functionList = cldom->functionList(); 00784 for (FunctionList::const_iterator it3 = functionList.begin(); 00785 it3 != functionList.end(); ++it3) 00786 { 00787 FunctionDom fndom = *it3; 00788 if (fnmap.contains(fndom)) 00789 { 00790 //function item exists - update 00791 FunctionItem *fn = fnmap[fndom]; 00792 fn->setText(0, languageSupport()->formatModelItem(fndom, true)); 00793 fn->setup(); 00794 if (m_functions->view()->currentItem() == fn) 00795 { 00796 //reload this combo because function item is currently selected 00797 m_functions->view()->setCurrentText(languageSupport()->formatModelItem(fndom, true)); 00798 } 00799 //refresh info about nested functions 00800 ViewCombosOp::processFunction(this, m_functions->view(), fn, ViewCombosOp::Refresh); 00801 } 00802 else 00803 { 00804 //function item does not exists - create 00805 FunctionItem *item = new FunctionItem(this, m_functions->view()->listView(), languageSupport()->formatModelItem(fndom, true), fndom); 00806 m_functions->view()->addItem(item); 00807 item->setOpen(true); 00808 ViewCombosOp::processFunction(this, m_functions->view(), item); 00809 } 00810 } 00811 } 00812 00813 void ClassViewPart::updateClassesForAdd( NamespaceDom nsdom ) 00814 { 00815 ClassList classList = nsdom->classList(); 00816 for (ClassList::const_iterator it2 = classList.begin(); it2 != classList.end(); ++it2) 00817 { 00818 ClassDom cldom = *it2; 00819 if (clmap.contains(cldom)) 00820 { 00821 //class item exists - update 00822 ClassItem *cl = clmap[cldom]; 00823 cl->setText(0, languageSupport()->formatModelItem(cldom)); 00824 if (m_classes->view()->currentItem() == cl) 00825 { 00826 //reload this and dependent combos because class item is currently selected 00827 m_classes->view()->setCurrentText(languageSupport()->formatModelItem(cldom)); 00828 00829 //check functions 00830 updateFunctionsForAdd(cldom); 00831 } 00832 //refresh info about nested classes 00833 ViewCombosOp::processClass(this, m_classes->view(), cl, ViewCombosOp::Refresh); 00834 } 00835 else 00836 { 00837 //class item does not exists - create 00838 ClassItem *item = new ClassItem(this, m_classes->view()->listView(), languageSupport()->formatModelItem(cldom), cldom); 00839 m_classes->view()->addItem(item); 00840 item->setOpen(true); 00841 ViewCombosOp::processClass(this, m_classes->view(), item); 00842 } 00843 } 00844 } 00845 00846 void ClassViewPart::removeNamespace( const QString & name ) 00847 { 00848 if (nsmap.contains(name)) 00849 { 00850 NamespaceItem *i = nsmap[name]; 00851 if (i) 00852 { 00853 m_namespaces->view()->removeItem(i); 00854 if (global_item) 00855 m_namespaces->view()->setCurrentActiveItem(global_item); 00856 } 00857 } 00858 } 00859 00860 #include "classviewpart.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:50 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003