File indexing completed on 2024-04-28 05:49:17

0001 /***************************************************************************
0002  *                        plugin_katesymbolviewer.cpp  -  description
0003  *                           -------------------
0004  *  begin                : Apr 2 2003
0005  *  author               : 2003 Massimo Callegari
0006  *  email                : massimocallegari@yahoo.it
0007  *
0008  *  Changes:
0009  *  Nov 09 2004 v.1.3 - For changelog please refer to KDE CVS
0010  *  Nov 05 2004 v.1.2 - Choose parser from the current highlight. Minor i18n changes.
0011  *  Nov 28 2003 v.1.1 - Structured for multilanguage support
0012  *                      Added preliminary Tcl/Tk parser (thanks Rohit). To be improved.
0013  *                      Various bugfixing.
0014  *  Jun 19 2003 v.1.0 - Removed QTimer (polling is Evil(tm)... )
0015  *                      - Captured documentChanged() event to refresh symbol list
0016  *                      - Tooltips vanished into nowhere...sigh :(
0017  *  May 04 2003 v 0.6 - Symbol List becomes a K3ListView object. Removed Tooltip class.
0018  *                      Added a QTimer that every 200ms checks:
0019  *                      * if the list width has changed
0020  *                      * if the document has changed
0021  *                      Added an entry in the m_popup menu to switch between List and Tree mode
0022  *                      Various bugfixing.
0023  *  Apr 24 2003 v 0.5 - Added three check buttons in m_popup menu to show/hide symbols
0024  *  Apr 23 2003 v 0.4 - "View Symbol" moved in Settings menu. "Refresh List" is no
0025  *                      longer in Kate menu. Moved into a m_popup menu activated by a
0026  *                      mouse right button click. + Bugfixing.
0027  *  Apr 22 2003 v 0.3 - Added macro extraction + several bugfixing
0028  *  Apr 19 2003 v 0.2 - Added to CVS. Extract functions and structures
0029  *  Apr 07 2003 v 0.1 - First version.
0030  *
0031  *  SPDX-FileCopyrightText: 2014, 2018 Kåre Särs <kare.sars@iki.fi>
0032  *
0033  ***************************************************************************/
0034 /***************************************************************************
0035  *                                                                         *
0036  *   SPDX-License-Identifier: GPL-2.0-or-later
0037  *                                                                         *
0038  ***************************************************************************/
0039 
0040 #include "plugin_katesymbolviewer.h"
0041 
0042 #include <KConfigGroup>
0043 #include <KFuzzyMatcher>
0044 #include <KLineEdit>
0045 #include <KPluginFactory>
0046 #include <KSharedConfig>
0047 #include <KXMLGUIFactory>
0048 #include <QAction>
0049 #include <QKeyEvent>
0050 
0051 #include <ktexteditor/cursor.h>
0052 #include <ktexteditor/document.h>
0053 
0054 #include <QGroupBox>
0055 #include <QVBoxLayout>
0056 
0057 #include <QHeaderView>
0058 
0059 K_PLUGIN_FACTORY_WITH_JSON(KatePluginSymbolViewerFactory, "katesymbolviewerplugin.json", registerPlugin<KatePluginSymbolViewer>();)
0060 
0061 KatePluginSymbolViewerView::KatePluginSymbolViewerView(KatePluginSymbolViewer *plugin, KTextEditor::MainWindow *mw)
0062     : QObject(mw)
0063     , m_mainWindow(mw)
0064     , m_plugin(plugin)
0065 {
0066     // FIXME KF5 KGlobal::locale()->insertCatalog("katesymbolviewerplugin");
0067 
0068     KXMLGUIClient::setComponentName(QStringLiteral("katesymbolviewer"), i18n("SymbolViewer"));
0069     setXMLFile(QStringLiteral("ui.rc"));
0070 
0071     mw->guiFactory()->addClient(this);
0072     m_symbols = nullptr;
0073 
0074     // FIXME Let the parser decide which options are available and how they are named
0075     // because not all these options are supported by all parsers
0076     m_popup = new QMenu(m_symbols);
0077     m_treeOn = m_popup->addAction(i18n("Tree Mode"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0078     m_treeOn->setCheckable(true);
0079     m_expandOn = m_popup->addAction(i18n("Expand Tree"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0080     m_expandOn->setCheckable(true);
0081     m_sort = m_popup->addAction(i18n("Show Sorted"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0082     m_sort->setCheckable(true);
0083     m_popup->addSeparator();
0084     m_macro = m_popup->addAction(i18n("Show Macros"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0085     m_macro->setCheckable(true);
0086     m_struct = m_popup->addAction(i18n("Show Structures"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0087     m_struct->setCheckable(true);
0088     m_func = m_popup->addAction(i18n("Show Functions"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0089     m_func->setCheckable(true);
0090     m_typesOn = m_popup->addAction(i18n("Show Parameters"), this, &KatePluginSymbolViewerView::displayOptionChanged);
0091     m_typesOn->setCheckable(true);
0092 
0093     KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("PluginSymbolViewer"));
0094     m_typesOn->setChecked(config.readEntry(QStringLiteral("ViewTypes"), false));
0095     m_expandOn->setChecked(config.readEntry(QStringLiteral("ExpandTree"), false));
0096     m_treeOn->setChecked(config.readEntry(QStringLiteral("TreeView"), false));
0097     m_sort->setChecked(config.readEntry(QStringLiteral("SortSymbols"), false));
0098 
0099     m_macro->setChecked(true);
0100     m_struct->setChecked(true);
0101     m_func->setChecked(true);
0102 
0103     m_expandOn->setEnabled(m_treeOn->isChecked());
0104     m_typesOn->setEnabled(m_func->isChecked());
0105 
0106     m_updateTimer.setSingleShot(true);
0107     connect(&m_updateTimer, &QTimer::timeout, this, &KatePluginSymbolViewerView::parseSymbols);
0108 
0109     m_currItemTimer.setSingleShot(true);
0110     connect(&m_currItemTimer, &QTimer::timeout, this, &KatePluginSymbolViewerView::updateCurrTreeItem);
0111 
0112     m_toolview = m_mainWindow->createToolView(plugin,
0113                                               QStringLiteral("kate_plugin_symbolviewer"),
0114                                               KTextEditor::MainWindow::Left,
0115                                               QIcon::fromTheme(QStringLiteral("class")),
0116                                               i18n("Symbol List"));
0117 
0118     QWidget *container = new QWidget(m_toolview);
0119     QVBoxLayout *layout = new QVBoxLayout(container);
0120 
0121     m_symbols = new QTreeWidget();
0122     m_symbols->setFocusPolicy(Qt::NoFocus);
0123     m_symbols->setLayoutDirection(Qt::LeftToRight);
0124     layout->addWidget(m_symbols, 10);
0125     layout->setContentsMargins(0, 0, 0, 0);
0126 
0127     connect(m_symbols, &QTreeWidget::itemClicked, this, &KatePluginSymbolViewerView::goToSymbol);
0128     connect(m_symbols, &QTreeWidget::customContextMenuRequested, this, &KatePluginSymbolViewerView::slotShowContextMenu);
0129     connect(m_symbols, &QTreeWidget::itemExpanded, this, &KatePluginSymbolViewerView::updateCurrTreeItem);
0130     connect(m_symbols, &QTreeWidget::itemCollapsed, this, &KatePluginSymbolViewerView::updateCurrTreeItem);
0131 
0132     m_filter = new KLineEdit(container);
0133     m_filter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
0134     m_filter->setPlaceholderText(i18n("Filter..."));
0135     m_filter->setClearButtonEnabled(true);
0136     m_filter->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::TopEdge}));
0137     layout->addWidget(m_filter);
0138 
0139     connect(m_filter, &KLineEdit::textChanged, this, &KatePluginSymbolViewerView::slotFilterChange);
0140 
0141     connect(m_mainWindow, &KTextEditor::MainWindow::viewChanged, this, &KatePluginSymbolViewerView::slotDocChanged);
0142 
0143     QStringList titles;
0144     titles << i18nc("@title:column", "Symbols") << i18nc("@title:column", "Position");
0145     m_symbols->setColumnCount(2);
0146     m_symbols->setHeaderLabels(titles);
0147 
0148     m_symbols->setColumnHidden(1, true);
0149     m_symbols->setSortingEnabled(m_sort->isChecked());
0150     // Sets the default sorting order:
0151     m_symbols->sortByColumn(0, Qt::AscendingOrder);
0152     m_symbols->setRootIsDecorated(0);
0153     m_symbols->setContextMenuPolicy(Qt::CustomContextMenu);
0154     m_symbols->setIndentation(10);
0155 
0156     m_toolview->installEventFilter(this);
0157 
0158     // register view
0159     m_plugin->m_views.insert(this);
0160 }
0161 
0162 KatePluginSymbolViewerView::~KatePluginSymbolViewerView()
0163 {
0164     // un-register view
0165     m_plugin->m_views.remove(this);
0166 
0167     m_mainWindow->guiFactory()->removeClient(this);
0168     delete m_toolview;
0169     delete m_popup;
0170 }
0171 
0172 void KatePluginSymbolViewerView::slotDocChanged()
0173 {
0174     parseSymbols();
0175 
0176     KTextEditor::View *view = m_mainWindow->activeView();
0177     // qDebug()<<"Document changed !!!!" << view;
0178     if (view) {
0179         connect(view, &KTextEditor::View::cursorPositionChanged, this, &KatePluginSymbolViewerView::cursorPositionChanged, Qt::UniqueConnection);
0180 
0181         if (view->document()) {
0182             connect(view->document(), &KTextEditor::Document::textChanged, this, &KatePluginSymbolViewerView::slotDocEdited, Qt::UniqueConnection);
0183         }
0184     }
0185 }
0186 
0187 void KatePluginSymbolViewerView::slotDocEdited()
0188 {
0189     m_currItemTimer.stop(); // Avoid unneeded update
0190     m_updateTimer.start(500);
0191 }
0192 
0193 void KatePluginSymbolViewerView::cursorPositionChanged()
0194 {
0195     if (m_updateTimer.isActive()) {
0196         // No need for update, will come anyway
0197         return;
0198     }
0199 
0200     KTextEditor::View *editView = m_mainWindow->activeView();
0201     if (!editView) {
0202         return;
0203     }
0204     int currLine = editView->cursorPositionVirtual().line();
0205     if (currLine != m_oldCursorLine) {
0206         m_oldCursorLine = currLine;
0207         m_currItemTimer.start(100);
0208     }
0209 }
0210 
0211 void KatePluginSymbolViewerView::updateCurrTreeItem()
0212 {
0213     if (!m_mainWindow) {
0214         return;
0215     }
0216     KTextEditor::View *editView = m_mainWindow->activeView();
0217     if (!editView) {
0218         return;
0219     }
0220     KTextEditor::Document *doc = editView->document();
0221     if (!doc) {
0222         return;
0223     }
0224 
0225     int currLine = editView->cursorPositionVirtual().line();
0226 
0227     int newItemLine = 0;
0228     QTreeWidgetItem *newItem = nullptr;
0229     QTreeWidgetItem *tmp = nullptr;
0230     for (int i = 0; i < m_symbols->topLevelItemCount(); i++) {
0231         tmp = newActveItem(newItemLine, currLine, m_symbols->topLevelItem(i));
0232         if (tmp) {
0233             newItem = tmp;
0234         }
0235     }
0236 
0237     if (!newItem) {
0238         return;
0239     }
0240 
0241     // check if the item has a parent and if that parent is expanded.
0242     // if the parent is not expanded, set the parent as current item in stead of
0243     // expanding the tree. The tree was probably collapsed on purpose
0244     QTreeWidgetItem *parent = newItem->parent();
0245     if (parent && !parent->isExpanded()) {
0246         newItem = parent;
0247     }
0248 
0249     m_symbols->blockSignals(true);
0250     m_symbols->setCurrentItem(newItem);
0251     m_symbols->blockSignals(false);
0252 }
0253 
0254 QTreeWidgetItem *KatePluginSymbolViewerView::newActveItem(int &newItemLine, int currLine, QTreeWidgetItem *item)
0255 {
0256     QTreeWidgetItem *newItem = nullptr;
0257     QTreeWidgetItem *tmp = nullptr;
0258     int itemLine = item->data(1, Qt::DisplayRole).toInt();
0259     if ((itemLine <= currLine) && (itemLine >= newItemLine)) {
0260         newItemLine = itemLine;
0261         newItem = item;
0262     }
0263 
0264     for (int i = 0; i < item->childCount(); i++) {
0265         tmp = newActveItem(newItemLine, currLine, item->child(i));
0266         if (tmp) {
0267             newItem = tmp;
0268         }
0269     }
0270 
0271     return newItem;
0272 }
0273 
0274 bool KatePluginSymbolViewerView::eventFilter(QObject *obj, QEvent *event)
0275 {
0276     if (event->type() == QEvent::KeyPress) {
0277         QKeyEvent *ke = static_cast<QKeyEvent *>(event);
0278         if ((obj == m_toolview) && (ke->key() == Qt::Key_Escape)) {
0279             m_mainWindow->activeView()->setFocus();
0280             event->accept();
0281             return true;
0282         }
0283     } else if (event->type() == QEvent::Show) {
0284         slotDocChanged();
0285         return true;
0286     }
0287     return QObject::eventFilter(obj, event);
0288 }
0289 
0290 void KatePluginSymbolViewerView::slotShowContextMenu(const QPoint &pos)
0291 {
0292     m_popup->popup(m_symbols->viewport()->mapToGlobal(pos), m_treeOn);
0293 }
0294 
0295 /**
0296  * Each popup menu action is connected to this slot which offer the possibility
0297  * to modify the menu depended on current settings.
0298  */
0299 void KatePluginSymbolViewerView::displayOptionChanged()
0300 {
0301     m_expandOn->setEnabled(m_treeOn->isChecked());
0302     m_typesOn->setEnabled(m_func->isChecked());
0303     parseSymbols();
0304 }
0305 
0306 void KatePluginSymbolViewerView::parseSymbols()
0307 {
0308     if (!m_symbols) {
0309         return;
0310     }
0311 
0312     m_symbols->clear();
0313     // Qt docu recommends to populate view with disabled sorting
0314     // https://doc.qt.io/qt-5/qtreeview.html#sortingEnabled-prop
0315     m_symbols->setSortingEnabled(false);
0316     Qt::SortOrder sortOrder = m_symbols->header()->sortIndicatorOrder();
0317 
0318     if (!m_mainWindow->activeView()) {
0319         return;
0320     }
0321 
0322     KTextEditor::Document *doc = m_mainWindow->activeView()->document();
0323 
0324     // be sure we have some document around !
0325     if (!doc) {
0326         return;
0327     }
0328 
0329     /** Get the current highlighting mode */
0330     QString hlModeName = doc->mode();
0331 
0332     if (hlModeName.contains(QLatin1String("C++")) || hlModeName == QLatin1Char('C') || hlModeName == QLatin1String("ANSI C89")) {
0333         parseCppSymbols();
0334     } else if (hlModeName == QLatin1String("PHP (HTML)")) {
0335         parsePhpSymbols();
0336     } else if (hlModeName == QLatin1String("Tcl/Tk")) {
0337         parseTclSymbols();
0338     } else if (hlModeName.contains(QLatin1String("Fortran"))) {
0339         parseFortranSymbols();
0340     } else if (hlModeName == QLatin1String("Perl")) {
0341         parsePerlSymbols();
0342     } else if (hlModeName == QLatin1String("Python")) {
0343         parsePythonSymbols();
0344     } else if (hlModeName == QLatin1String("Ruby")) {
0345         parseRubySymbols();
0346     } else if (hlModeName == QLatin1String("Java")) {
0347         parseCppSymbols();
0348     } else if (hlModeName == QLatin1String("Groovy")) {
0349         parseCppSymbols();
0350     } else if (hlModeName == QLatin1String("xslt")) {
0351         parseXsltSymbols();
0352     } else if (hlModeName == QLatin1String("XML") || hlModeName == QLatin1String("HTML")) {
0353         parseXMLSymbols();
0354     } else if (hlModeName == QLatin1String("Bash")) {
0355         parseBashSymbols();
0356     } else if (hlModeName == QLatin1String("ActionScript 2.0") || hlModeName == QLatin1String("JavaScript") || hlModeName == QLatin1String("QML")) {
0357         parseEcmaSymbols();
0358     } else if (hlModeName == QLatin1String("Julia")) {
0359         parseJuliaSymbols();
0360     } else {
0361         QTreeWidgetItem *node = new QTreeWidgetItem(m_symbols);
0362         node->setText(0, i18n("Sorry, not supported yet!"));
0363         // Setting invalid line number avoid jump to top of document when clicked
0364         node->setText(1, QStringLiteral("-1"));
0365         node = new QTreeWidgetItem(m_symbols);
0366         node->setText(0, i18n("File type: %1", hlModeName));
0367         node->setText(1, QStringLiteral("-1"));
0368     }
0369 
0370     m_oldCursorLine = -1;
0371     updateCurrTreeItem();
0372     if (m_sort->isChecked()) {
0373         m_symbols->setSortingEnabled(true);
0374         m_symbols->sortItems(0, sortOrder);
0375     }
0376 
0377     slotFilterChange(m_filter->text());
0378 }
0379 
0380 void KatePluginSymbolViewerView::goToSymbol(QTreeWidgetItem *it)
0381 {
0382     KTextEditor::View *kv = m_mainWindow->activeView();
0383 
0384     // be sure we really have a view !
0385     if (!kv) {
0386         return;
0387     }
0388 
0389     // qDebug()<<"Slot Activated at pos: "<<m_symbols->indexOfTopLevelItem(it);
0390     if (!it || it->text(1).isEmpty()) {
0391         return;
0392     }
0393 
0394     kv->setCursorPosition(KTextEditor::Cursor(it->text(1).toInt(nullptr, 10), 0));
0395 }
0396 
0397 void KatePluginSymbolViewerView::slotFilterChange(const QString &text)
0398 {
0399     QString filter = text.trimmed();
0400     for (int i = 0; i < m_symbols->invisibleRootItem()->childCount(); ++i) {
0401         QTreeWidgetItem *group_item = m_symbols->invisibleRootItem()->child(i);
0402         filterSymbols(group_item, filter);
0403         for (int j = 0; j < group_item->childCount(); ++j) {
0404             filterSymbols(group_item->child(j), filter);
0405         }
0406     }
0407 }
0408 
0409 bool KatePluginSymbolViewerView::filterSymbols(QTreeWidgetItem *item, const QString &filter)
0410 {
0411     bool at_least_one_child_shown = false;
0412     for (int i = 0; i < item->childCount(); ++i) {
0413         if (filterSymbols(item->child(i), filter)) {
0414             at_least_one_child_shown = true;
0415         }
0416     }
0417     bool is_item_match = KFuzzyMatcher::matchSimple(filter, item->text(0));
0418     bool is_item_shown = at_least_one_child_shown || filter.isEmpty() || is_item_match;
0419     item->setHidden(!is_item_shown);
0420     return is_item_shown;
0421 }
0422 
0423 KatePluginSymbolViewer::KatePluginSymbolViewer(QObject *parent, const QVariantList &)
0424     : KTextEditor::Plugin(parent)
0425 {
0426     // qDebug()<<"KatePluginSymbolViewer";
0427 }
0428 
0429 KatePluginSymbolViewer::~KatePluginSymbolViewer()
0430 {
0431     // qDebug()<<"~KatePluginSymbolViewer";
0432 }
0433 
0434 QObject *KatePluginSymbolViewer::createView(KTextEditor::MainWindow *mainWindow)
0435 {
0436     return new KatePluginSymbolViewerView(this, mainWindow);
0437 }
0438 
0439 KTextEditor::ConfigPage *KatePluginSymbolViewer::configPage(int, QWidget *parent)
0440 {
0441     KatePluginSymbolViewerConfigPage *p = new KatePluginSymbolViewerConfigPage(this, parent);
0442 
0443     KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("PluginSymbolViewer"));
0444     p->viewReturns->setChecked(config.readEntry(QStringLiteral("ViewTypes"), false));
0445     p->expandTree->setChecked(config.readEntry(QStringLiteral("ExpandTree"), false));
0446     p->treeView->setChecked(config.readEntry(QStringLiteral("TreeView"), false));
0447     p->sortSymbols->setChecked(config.readEntry(QStringLiteral("SortSymbols"), false));
0448     connect(p, &KatePluginSymbolViewerConfigPage::configPageApplyRequest, this, &KatePluginSymbolViewer::applyConfig);
0449     return static_cast<KTextEditor::ConfigPage *>(p);
0450 }
0451 
0452 void KatePluginSymbolViewer::applyConfig(KatePluginSymbolViewerConfigPage *p)
0453 {
0454     KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("PluginSymbolViewer"));
0455     config.writeEntry(QStringLiteral("ViewTypes"), p->viewReturns->isChecked());
0456     config.writeEntry(QStringLiteral("ExpandTree"), p->expandTree->isChecked());
0457     config.writeEntry(QStringLiteral("TreeView"), p->treeView->isChecked());
0458     config.writeEntry(QStringLiteral("SortSymbols"), p->sortSymbols->isChecked());
0459 
0460     for (auto view : qAsConst(m_views)) {
0461         view->m_typesOn->setChecked(p->viewReturns->isChecked());
0462         view->m_expandOn->setChecked(p->expandTree->isChecked());
0463         view->m_treeOn->setChecked(p->treeView->isChecked());
0464         view->m_sort->setChecked(p->sortSymbols->isChecked());
0465 
0466         view->m_expandOn->setEnabled(view->m_treeOn->isChecked());
0467         view->m_typesOn->setEnabled(view->m_func->isChecked());
0468     }
0469 }
0470 
0471 // BEGIN KatePluginSymbolViewerConfigPage
0472 KatePluginSymbolViewerConfigPage::KatePluginSymbolViewerConfigPage(QObject * /*parent*/ /*= 0L*/, QWidget *parentWidget /*= 0L*/)
0473     : KTextEditor::ConfigPage(parentWidget)
0474 {
0475     QVBoxLayout *lo = new QVBoxLayout(this);
0476     // int spacing = KDialog::spacingHint();
0477     // lo->setSpacing( spacing );
0478 
0479     viewReturns = new QCheckBox(i18n("Display functions parameters"));
0480     expandTree = new QCheckBox(i18n("Automatically expand nodes in tree mode"));
0481     treeView = new QCheckBox(i18n("Always display symbols in tree mode"));
0482     sortSymbols = new QCheckBox(i18n("Always sort symbols"));
0483 
0484     QGroupBox *parserGBox = new QGroupBox(i18n("Parser Options"), this);
0485     QVBoxLayout *top = new QVBoxLayout(parserGBox);
0486     top->addWidget(viewReturns);
0487     top->addWidget(expandTree);
0488     top->addWidget(treeView);
0489     top->addWidget(sortSymbols);
0490 
0491     // QGroupBox* generalGBox = new QGroupBox( i18n("General Options"), this);
0492     // QVBoxLayout* genLay = new QVBoxLayout(generalGBox);
0493     // genLay->addWidget(  );
0494 
0495     lo->addWidget(parserGBox);
0496     // lo->addWidget( generalGBox );
0497     lo->addStretch(1);
0498 
0499     //  throw signal changed
0500     connect(viewReturns, &QCheckBox::toggled, this, &KatePluginSymbolViewerConfigPage::changed);
0501     connect(expandTree, &QCheckBox::toggled, this, &KatePluginSymbolViewerConfigPage::changed);
0502     connect(treeView, &QCheckBox::toggled, this, &KatePluginSymbolViewerConfigPage::changed);
0503     connect(sortSymbols, &QCheckBox::toggled, this, &KatePluginSymbolViewerConfigPage::changed);
0504 }
0505 
0506 KatePluginSymbolViewerConfigPage::~KatePluginSymbolViewerConfigPage()
0507 {
0508 }
0509 
0510 QString KatePluginSymbolViewerConfigPage::name() const
0511 {
0512     return i18n("Symbol Viewer");
0513 }
0514 
0515 QString KatePluginSymbolViewerConfigPage::fullName() const
0516 {
0517     return i18n("Symbol Viewer Configuration Page");
0518 }
0519 
0520 QIcon KatePluginSymbolViewerConfigPage::icon() const
0521 {
0522     return QIcon::fromTheme(QLatin1String("code-class"));
0523 }
0524 
0525 void KatePluginSymbolViewerConfigPage::apply()
0526 {
0527     Q_EMIT configPageApplyRequest(this);
0528 }
0529 // END KatePluginSymbolViewerConfigPage
0530 
0531 // BEGIN parsers
0532 #include "bash_parser.cpp"
0533 #include "cpp_parser.cpp"
0534 #include "ecma_parser.cpp"
0535 #include "fortran_parser.cpp"
0536 #include "julia_parser.cpp"
0537 #include "perl_parser.cpp"
0538 #include "php_parser.cpp"
0539 #include "python_parser.cpp"
0540 #include "ruby_parser.cpp"
0541 #include "tcl_parser.cpp"
0542 #include "xml_parser.cpp"
0543 #include "xslt_parser.cpp"
0544 // END parsers
0545 
0546 #include "moc_plugin_katesymbolviewer.cpp"
0547 #include "plugin_katesymbolviewer.moc"