|
|
|
/*
|
|
|
|
* Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org)
|
|
|
|
* Copyright (C) 2003 Alexander Dymo (cloudtemple@mksat.net)
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <tqlistview.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kdevgenericfactory.h>
|
|
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
|
|
|
|
#include <kdevcore.h>
|
|
|
|
#include <kdevmainwindow.h>
|
|
|
|
#include <kdevlanguagesupport.h>
|
|
|
|
#include <kcomboview.h>
|
|
|
|
#include <kdevpartcontroller.h>
|
|
|
|
#include <kdevproject.h>
|
|
|
|
#include <urlutil.h>
|
|
|
|
#include <kdevplugininfo.h>
|
|
|
|
|
|
|
|
#include <codemodel.h>
|
|
|
|
#include <codemodel_utils.h>
|
|
|
|
|
|
|
|
#include "classviewwidget.h"
|
|
|
|
#include "classviewpart.h"
|
|
|
|
#include "hierarchydlg.h"
|
|
|
|
#include "navigator.h"
|
|
|
|
|
|
|
|
#include "tdelistviewaction.h"
|
|
|
|
|
|
|
|
#include <tdetexteditor/document.h>
|
|
|
|
#include <tdetexteditor/editinterface.h>
|
|
|
|
#include <tdetexteditor/view.h>
|
|
|
|
#include <tdetexteditor/selectioninterface.h>
|
|
|
|
#include <tdetexteditor/viewcursorinterface.h>
|
|
|
|
#include <tdetexteditor/clipboardinterface.h>
|
|
|
|
|
|
|
|
|
|
|
|
class FunctionCompletion : public CustomCompleter {
|
|
|
|
public:
|
|
|
|
FunctionCompletion() {
|
|
|
|
setOrder( Insertion );
|
|
|
|
};
|
|
|
|
typedef TQMap<TQString, TQString> FuncMap;
|
|
|
|
FuncMap nameMap; /// real -> short
|
|
|
|
FuncMap revNameMap; /// short -> real
|
|
|
|
|
|
|
|
static const TQString processName( TQString function ) {
|
|
|
|
TQString args;
|
|
|
|
TQString fScope;
|
|
|
|
int cutpos;
|
|
|
|
|
|
|
|
if((cutpos = function.find('(')) != -1) {
|
|
|
|
args = function.right( function.length() - cutpos );
|
|
|
|
function = function.left( cutpos );
|
|
|
|
} else {
|
|
|
|
return function;
|
|
|
|
}
|
|
|
|
if((cutpos = function.findRev(':')) != -1 || (cutpos = function.findRev('.')) != -1) {
|
|
|
|
fScope = function.left( cutpos + 1 );
|
|
|
|
function = function.right( function.length() - cutpos - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return function;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void addItem ( const TQString &item ) {
|
|
|
|
TQString newItemName = item;
|
|
|
|
TDECompletion::addItem(newItemName);
|
|
|
|
TQString tx = processName( item );
|
|
|
|
tx += " \"" + item + "\"";
|
|
|
|
nameMap[item] = tx;
|
|
|
|
revNameMap[tx] = item;
|
|
|
|
if(tx.length() == 0) {
|
|
|
|
kdDebug() << "function-name-extraction failed with \"" << item << "\"" << endl;
|
|
|
|
}else{
|
|
|
|
TDECompletion::addItem( tx );
|
|
|
|
kdDebug() << "addding \"" << item << "\" as \"" << tx << "\"" << endl;
|
|
|
|
}
|
|
|
|
TDECompletion::addItem( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void removeItem ( const TQString &item ) {
|
|
|
|
FuncMap::iterator it = nameMap.find( item );
|
|
|
|
if( it != nameMap.end() ) {
|
|
|
|
TDECompletion::removeItem( *it );
|
|
|
|
revNameMap.remove( *it );
|
|
|
|
nameMap.remove( it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void clear() {
|
|
|
|
nameMap.clear();
|
|
|
|
revNameMap.clear();
|
|
|
|
TDECompletion::clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void postProcessMatch ( TQString *match ) const {
|
|
|
|
FuncMap::const_iterator it = revNameMap.find( *match );
|
|
|
|
if( it != revNameMap.end() ) {
|
|
|
|
*match = *it;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual void postProcessMatches ( TQStringList *matches ) const {
|
|
|
|
TQStringList::iterator it = matches->begin();
|
|
|
|
|
|
|
|
while( it != matches->end() ) {
|
|
|
|
postProcessMatch( &(*it) );
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void postProcessMatches ( TDECompletionMatches *matches ) const {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef KDevGenericFactory<ClassViewPart> ClassViewFactory;
|
|
|
|
static const KDevPluginInfo pluginData("kdevclassview");
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( libkdevclassview, ClassViewFactory( pluginData ) )
|
|
|
|
|
|
|
|
ClassViewPart::ClassViewPart(TQObject *parent, const char *name, const TQStringList& )
|
|
|
|
:/// KDevPlugin( &pluginData, parent, name ? name : "ClassViewPart" ),
|
|
|
|
KDevCodeBrowserFrontend( &pluginData, parent, name ? name : "ClassViewPart" ),
|
|
|
|
m_activeDocument(0), m_activeView(0), m_activeSelection(0), m_activeEditor(0), m_activeViewCursor(0), m_hierarchyDlg(0)
|
|
|
|
{
|
|
|
|
setInstance(ClassViewFactory::instance());
|
|
|
|
setXMLFile("kdevclassview.rc");
|
|
|
|
|
|
|
|
navigator = new Navigator(this);
|
|
|
|
|
|
|
|
setupActions();
|
|
|
|
|
|
|
|
m_widget = new ClassViewWidget(this);
|
|
|
|
m_widget->setIcon( SmallIcon("view_tree") );
|
|
|
|
m_widget->setCaption(i18n("Class Browser"));
|
|
|
|
mainWindow()->embedSelectView( m_widget, i18n("Classes"), i18n("Class browser") );
|
|
|
|
TQWhatsThis::add(m_widget, i18n("<b>Class browser</b><p>"
|
|
|
|
"The class browser shows all namespaces, classes and namespace and class members in a project."));
|
|
|
|
|
|
|
|
connect( core(), TQ_SIGNAL(projectOpened()), this, TQ_SLOT(slotProjectOpened()) );
|
|
|
|
connect( core(), TQ_SIGNAL(projectClosed()), this, TQ_SLOT(slotProjectClosed()) );
|
|
|
|
connect( core(), TQ_SIGNAL(languageChanged()), this, TQ_SLOT(slotProjectOpened()) );
|
|
|
|
connect( partController(), TQ_SIGNAL(activePartChanged(KParts::Part*)),
|
|
|
|
this, TQ_SLOT(activePartChanged(KParts::Part*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ClassViewPart::jumpedToItem( ItemDom item ) {
|
|
|
|
if(!m_widget) return false;
|
|
|
|
return m_widget->selectItem(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
ClassViewPart::~ClassViewPart()
|
|
|
|
{
|
|
|
|
mainWindow()->removeView( m_widget );
|
|
|
|
delete (ClassViewWidget*) m_widget;
|
|
|
|
delete m_hierarchyDlg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::slotProjectOpened( )
|
|
|
|
{
|
|
|
|
connect( languageSupport(), TQ_SIGNAL(updatedSourceInfo()), navigator, TQ_SLOT(refresh()) );
|
|
|
|
connect( languageSupport(), TQ_SIGNAL(addedSourceInfo(const TQString& )), navigator, TQ_SLOT(addFile(const TQString& )));
|
|
|
|
navigator->refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::slotProjectClosed( )
|
|
|
|
{
|
|
|
|
// navigator->refresh();
|
|
|
|
// disconnect( languageSupport(), TQ_SIGNAL(updatedSourceInfo()), navigator, TQ_SLOT(refresh()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::setupActions( )
|
|
|
|
{
|
|
|
|
m_functionsnav = new TDEListViewAction( new KComboView(true, 150, 0, "m_functionsnav_combo", new FunctionCompletion() ), i18n("Functions Navigation"), 0, 0, 0, actionCollection(), "functionsnav_combo", true );
|
|
|
|
connect(m_functionsnav->view(), TQ_SIGNAL(activated(TQListViewItem*)), navigator, TQ_SLOT(selectFunctionNav(TQListViewItem*)));
|
|
|
|
// m_functionsnav->view()->setEditable(false);
|
|
|
|
connect(m_functionsnav->view(), TQ_SIGNAL(focusGranted()), navigator, TQ_SLOT(functionNavFocused()));
|
|
|
|
connect(m_functionsnav->view(), TQ_SIGNAL(focusLost()), navigator, TQ_SLOT(functionNavUnFocused()));
|
|
|
|
m_functionsnav->setToolTip(i18n("Functions in file"));
|
|
|
|
m_functionsnav->setWhatsThis(i18n("<b>Function navigator</b><p>Navigates over functions contained in the file."));
|
|
|
|
// m_functionsnav->view()->setCurrentText(NAV_NODEFINITION);
|
|
|
|
m_functionsnav->view()->setDefaultText(NAV_NODEFINITION);
|
|
|
|
|
|
|
|
new TDEAction( i18n("Focus Navigator"), 0, this, TQ_SLOT(slotFocusNavbar()), actionCollection(), "focus_navigator" );
|
|
|
|
|
|
|
|
if (langHasFeature(KDevLanguageSupport::Classes))
|
|
|
|
{
|
|
|
|
TDEAction *ac = new TDEAction(i18n("Class Inheritance Diagram"), "view_tree", 0, this, TQ_SLOT(graphicalClassView()), actionCollection(), "inheritance_dia");
|
|
|
|
ac->setToolTip(i18n("Class inheritance diagram"));
|
|
|
|
ac->setWhatsThis(i18n("<b>Class inheritance diagram</b><p>Displays inheritance relationship between classes in project. "
|
|
|
|
"Note, it does not display classes outside inheritance hierarchy."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ClassViewPart::langHasFeature(KDevLanguageSupport::Features feature)
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
if (languageSupport())
|
|
|
|
result = (feature & languageSupport()->features());
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::graphicalClassView( )
|
|
|
|
{
|
|
|
|
if( !m_hierarchyDlg )
|
|
|
|
m_hierarchyDlg = new HierarchyDialog(this);
|
|
|
|
m_hierarchyDlg->refresh();
|
|
|
|
m_hierarchyDlg->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::refresh() {
|
|
|
|
if( navigator )
|
|
|
|
navigator->refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClassViewPart::activePartChanged( KParts::Part * part)
|
|
|
|
{
|
|
|
|
navigator->stopTimer();
|
|
|
|
if (m_activeView)
|
|
|
|
{
|
|
|
|
disconnect(m_activeView, TQ_SIGNAL(cursorPositionChanged()),
|
|
|
|
navigator, TQ_SLOT(slotCursorPositionChanged()));
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug() << "ClassViewPart::activePartChanged()" << endl;
|
|
|
|
|
|
|
|
m_activeDocument = dynamic_cast<KTextEditor::Document*>( part );
|
|
|
|
m_activeView = part ? dynamic_cast<KTextEditor::View*>( part->widget() ) : 0;
|
|
|
|
m_activeEditor = dynamic_cast<KTextEditor::EditInterface*>( part );
|
|
|
|
m_activeSelection = dynamic_cast<KTextEditor::SelectionInterface*>( part );
|
|
|
|
m_activeViewCursor = part ? dynamic_cast<KTextEditor::ViewCursorInterface*>( m_activeView ) : 0;
|
|
|
|
|
|
|
|
m_activeFileName = TQString();
|
|
|
|
|
|
|
|
if (m_activeDocument)
|
|
|
|
{
|
|
|
|
m_activeFileName = URLUtil::canonicalPath( m_activeDocument->url().path() );
|
|
|
|
navigator->refreshNavBars(m_activeFileName);
|
|
|
|
navigator->syncFunctionNavDelayed(200);
|
|
|
|
/* if ( languageSupport()->mimeTypes().find(
|
|
|
|
KMimeType::findByPath(m_activeFileName)) != languageSupport()->mimeTypes().end() )
|
|
|
|
m_activeFileName = TQString();*/
|
|
|
|
}
|
|
|
|
if( m_activeViewCursor )
|
|
|
|
{
|
|
|
|
connect(m_activeView, TQ_SIGNAL(cursorPositionChanged()),
|
|
|
|
navigator, TQ_SLOT(slotCursorPositionChanged()) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void ClassViewPart::slotFocusNavbar()
|
|
|
|
{
|
|
|
|
m_functionsnav->view()->setFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "classviewpart.moc"
|