diff --git a/addons/filebrowser/katefilebrowserconfig.cpp b/addons/filebrowser/katefilebrowserconfig.cpp index 11755988a..998557b30 100644 --- a/addons/filebrowser/katefilebrowserconfig.cpp +++ b/addons/filebrowser/katefilebrowserconfig.cpp @@ -1,192 +1,192 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2001 Joseph Wenninger Copyright (C) 2001 Anders Lund Copyright (C) 2007 Mirko Stocker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library 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 Library General Public License along with this library; 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 "katefilebrowserconfig.h" #include "katefilebrowser.h" #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include //BEGIN ACtionLBItem /* QListboxItem that can store and return a string, used for the toolbar action selector. */ class ActionLBItem : public QListWidgetItem { public: ActionLBItem( QListWidget *lb = nullptr, const QIcon &pm = QIcon(), const QString &text = QString(), const QString &str = QString() ) : QListWidgetItem(pm, text, lb, 0 ), _str(str) {} QString idstring() { return _str; } private: QString _str; }; //END ActionLBItem //BEGIN KateFileBrowserConfigPage KateFileBrowserConfigPage::KateFileBrowserConfigPage( QWidget *parent, KateFileBrowser *kfb ) : KTextEditor::ConfigPage( parent ), fileBrowser( kfb ), m_changed( false ) { QVBoxLayout *lo = new QVBoxLayout( this ); int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); lo->setSpacing( spacing ); lo->setMargin(0); // Toolbar - a lot for a little... QGroupBox *gbToolbar = new QGroupBox(i18n("Toolbar"), this ); acSel = new KActionSelector( gbToolbar ); acSel->setAvailableLabel( i18n("A&vailable actions:") ); acSel->setSelectedLabel( i18n("S&elected actions:") ); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(acSel); gbToolbar->setLayout(vbox); lo->addWidget( gbToolbar ); connect(acSel, &KActionSelector::added, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::removed, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::movedUp, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::movedDown, this, &KateFileBrowserConfigPage::slotMyChanged); // make it look nice lo->addStretch( 1 ); init(); } QString KateFileBrowserConfigPage::name() const { return i18n("Filesystem Browser"); } QString KateFileBrowserConfigPage::fullName() const { return i18n("Filesystem Browser Settings"); } QIcon KateFileBrowserConfigPage::icon() const { return QIcon::fromTheme(QStringLiteral("document-open")); } void KateFileBrowserConfigPage::apply() { if ( ! m_changed ) return; m_changed = false; KConfigGroup config(KSharedConfig::openConfig(), "filebrowser"); QStringList l; ActionLBItem *aItem; QList list = acSel->selectedListWidget()->findItems(QStringLiteral("*"), Qt::MatchWildcard); foreach(QListWidgetItem *item, list) { aItem = static_cast(item); l << aItem->idstring(); } config.writeEntry( "toolbar actions", l ); fileBrowser->setupToolbar(); } void KateFileBrowserConfigPage::reset() { // hmm, what is this supposed to do, actually?? init(); m_changed = false; } void KateFileBrowserConfigPage::init() { KConfigGroup config(KSharedConfig::openConfig(), "filebrowser"); // toolbar QStringList l = config.readEntry( "toolbar actions", QStringList() ); if ( l.isEmpty() ) // default toolbar l << QStringLiteral("back") << QStringLiteral("forward") << QStringLiteral("bookmarks") << QStringLiteral("sync_dir") << QStringLiteral("configure"); // actions from diroperator + two of our own QStringList allActions; allActions << QStringLiteral("up") << QStringLiteral("back") << QStringLiteral("forward") << QStringLiteral("home") << QStringLiteral("reload") << QStringLiteral("mkdir") << QStringLiteral("delete") << QStringLiteral("short view") << QStringLiteral("detailed view") << QStringLiteral("tree view") << QStringLiteral("detailed tree view") << QStringLiteral("show hidden") /*<< QStringLiteral("view menu") << QStringLiteral("properties")*/ << QStringLiteral("bookmarks") << QStringLiteral("sync_dir") << QStringLiteral("configure"); - QRegExp re(QStringLiteral ("&(?=[^&])")); + QRegularExpression re(QStringLiteral("&(?=[^&])")); QAction *ac = nullptr; QListWidget *lb; for ( QStringList::Iterator it = allActions.begin(); it != allActions.end(); ++it ) { lb = l.contains( *it ) ? acSel->selectedListWidget() : acSel->availableListWidget(); if ( *it == QStringLiteral ("bookmarks") || *it == QStringLiteral ("sync_dir") || *it == QStringLiteral ("configure") ) ac = fileBrowser->actionCollection()->action( *it ); else ac = fileBrowser->dirOperator()->actionCollection()->action( *it ); if ( ac ) { QString text = ac->text().remove( re ); // CJK languages need a filtering message for action texts in lists, // to remove special accelerators that they use. // The exact same filtering message exists in kdelibs; hence, // avoid extraction here and let it be sourced from kdelibs. #define i18ncX i18nc text = i18ncX( "@item:intable Action name in toolbar editor", "%1", text ); new ActionLBItem( lb, ac->icon(), text, *it ); } } } void KateFileBrowserConfigPage::slotMyChanged() { m_changed = true; emit changed(); } //END KateFileBrowserConfigPage // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/addons/kate-ctags/kate_ctags_view.cpp b/addons/kate-ctags/kate_ctags_view.cpp index 4abe72318..cbdbd9d47 100644 --- a/addons/kate-ctags/kate_ctags_view.cpp +++ b/addons/kate-ctags/kate_ctags_view.cpp @@ -1,643 +1,643 @@ /* Description : Kate CTags plugin * * Copyright (C) 2008-2011 by Kare Sars * * 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.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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 * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see . */ #include "kate_ctags_view.h" #include "kate_ctags_plugin.h" #include "kate_ctags_debug.h" #include #include #include #include #include #include #include #include #include #include #include /******************************************************************/ KateCTagsView::KateCTagsView(KTextEditor::Plugin *plugin, KTextEditor::MainWindow *mainWin) : QObject(mainWin) , m_proc(nullptr) { KXMLGUIClient::setComponentName (QStringLiteral("katectags"), i18n ("Kate CTag")); setXMLFile( QStringLiteral("ui.rc") ); m_toolView = mainWin->createToolView(plugin, QStringLiteral("kate_plugin_katectagsplugin"), KTextEditor::MainWindow::Bottom, QIcon::fromTheme(QStringLiteral("application-x-ms-dos-executable")), i18n("CTags")); m_mWin = mainWin; QAction *back = actionCollection()->addAction(QStringLiteral("ctags_return_step")); back->setText(i18n("Jump back one step")); connect(back, &QAction::triggered, this, &KateCTagsView::stepBack); QAction *decl = actionCollection()->addAction(QStringLiteral("ctags_lookup_current_as_declaration")); decl->setText(i18n("Go to Declaration")); connect(decl, &QAction::triggered, this, &KateCTagsView::gotoDeclaration); QAction *defin = actionCollection()->addAction(QStringLiteral("ctags_lookup_current_as_definition")); defin->setText(i18n("Go to Definition")); connect(defin, &QAction::triggered, this, &KateCTagsView::gotoDefinition); QAction *lookup = actionCollection()->addAction(QStringLiteral("ctags_lookup_current")); lookup->setText(i18n("Lookup Current Text")); connect(lookup, &QAction::triggered, this, &KateCTagsView::lookupTag); QAction *updateDB = actionCollection()->addAction(QStringLiteral("ctags_update_global_db")); updateDB->setText(i18n("Configure ...")); connect(updateDB, &QAction::triggered, this, [this, plugin] (bool) { if (m_mWin) { KateCTagsPlugin *p = static_cast(plugin); QDialog *confWin = new QDialog(m_mWin->window()); confWin->setAttribute(Qt::WA_DeleteOnClose); auto confPage = p->configPage(0, confWin); auto controls = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, Qt::Horizontal, confWin); connect(confWin, &QDialog::accepted, confPage, &KTextEditor::ConfigPage::apply); connect(controls, &QDialogButtonBox::accepted, confWin, &QDialog::accept); connect(controls, &QDialogButtonBox::rejected, confWin, &QDialog::reject); auto layout = new QVBoxLayout(confWin); layout->addWidget(confPage); layout->addWidget(controls); confWin->setLayout(layout); confWin->setWindowTitle(i18nc("@title:window", "Configure CTags Plugin")); confWin->setWindowIcon(confPage->icon()); confWin->show(); confWin->exec(); } }); // popup menu m_menu = new KActionMenu(i18n("CTags"), this); actionCollection()->addAction(QStringLiteral("popup_ctags"), m_menu); m_gotoDec=m_menu->menu()->addAction(i18n("Go to Declaration: %1",QString()), this, &KateCTagsView::gotoDeclaration); m_gotoDef=m_menu->menu()->addAction(i18n("Go to Definition: %1",QString()), this, &KateCTagsView::gotoDefinition); m_lookup=m_menu->menu()->addAction(i18n("Lookup: %1",QString()), this, &KateCTagsView::lookupTag); connect(m_menu->menu(), &QMenu::aboutToShow, this, &KateCTagsView::aboutToShow); QWidget *ctagsWidget = new QWidget(m_toolView.data()); m_ctagsUi.setupUi(ctagsWidget); m_ctagsUi.cmdEdit->setText(DEFAULT_CTAGS_CMD); m_ctagsUi.addButton->setToolTip(i18n("Add a directory to index.")); m_ctagsUi.addButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); m_ctagsUi.delButton->setToolTip(i18n("Remove a directory.")); m_ctagsUi.delButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); m_ctagsUi.updateButton->setToolTip(i18n("(Re-)generate the session specific CTags database.")); m_ctagsUi.updateButton->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); m_ctagsUi.updateButton2->setToolTip(i18n("(Re-)generate the session specific CTags database.")); m_ctagsUi.updateButton2->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); m_ctagsUi.resetCMD->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); m_ctagsUi.tagsFile->setToolTip(i18n("Select new or existing database file.")); m_ctagsUi.tagsFile->setMode(KFile::File); connect(m_ctagsUi.resetCMD, &QToolButton::clicked, this, &KateCTagsView::resetCMD); connect(m_ctagsUi.addButton, &QPushButton::clicked, this, &KateCTagsView::addTagTarget); connect(m_ctagsUi.delButton, &QPushButton::clicked, this, &KateCTagsView::delTagTarget); connect(m_ctagsUi.updateButton, &QPushButton::clicked, this, &KateCTagsView::updateSessionDB); connect(m_ctagsUi.updateButton2, &QPushButton::clicked, this, &KateCTagsView::updateSessionDB); connect(&m_proc, static_cast(&QProcess::finished), this, &KateCTagsView::updateDone); connect(m_ctagsUi.inputEdit, &QLineEdit::textChanged, this, &KateCTagsView::startEditTmr); m_editTimer.setSingleShot(true); connect(&m_editTimer, &QTimer::timeout, this, &KateCTagsView::editLookUp); connect(m_ctagsUi.tagTreeWidget, &QTreeWidget::itemActivated, this, &KateCTagsView::tagHitClicked); connect(m_mWin, &KTextEditor::MainWindow::unhandledShortcutOverride, this, &KateCTagsView::handleEsc); m_toolView->layout()->addWidget(ctagsWidget); m_toolView->installEventFilter(this); m_mWin->guiFactory()->addClient(this); m_commonDB = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1String("/katectags/common_db"); } /******************************************************************/ KateCTagsView::~KateCTagsView() { if (m_mWin && m_mWin->guiFactory()) { m_mWin->guiFactory()->removeClient( this ); } if (m_toolView) { delete m_toolView; } } /******************************************************************/ void KateCTagsView::aboutToShow() { QString currWord = currentWord(); if (currWord.isEmpty()) { return; } if (Tags::hasTag(m_commonDB, currWord) || Tags::hasTag(m_ctagsUi.tagsFile->text(), currWord)) { QString squeezed = KStringHandler::csqueeze(currWord, 30); m_gotoDec->setText(i18n("Go to Declaration: %1",squeezed)); m_gotoDef->setText(i18n("Go to Definition: %1",squeezed)); m_lookup->setText(i18n("Lookup: %1",squeezed)); } } /******************************************************************/ void KateCTagsView::readSessionConfig (const KConfigGroup& cg) { m_ctagsUi.cmdEdit->setText(cg.readEntry("TagsGenCMD", DEFAULT_CTAGS_CMD)); int numEntries = cg.readEntry("SessionNumTargets", 0); QString nr; QString target; for (int i=0; isetText(sessionDB); } /******************************************************************/ void KateCTagsView::writeSessionConfig (KConfigGroup& cg) { cg.writeEntry("TagsGenCMD", m_ctagsUi.cmdEdit->text()); cg.writeEntry("SessionNumTargets", m_ctagsUi.targetList->count()); QString nr; for (int i=0; icount(); i++) { nr = QStringLiteral("%1").arg(i,3); cg.writeEntry(QStringLiteral("SessionTarget_%1").arg(nr), m_ctagsUi.targetList->item(i)->text()); } cg.writeEntry("SessionDatabase", m_ctagsUi.tagsFile->text()); cg.sync(); } /******************************************************************/ void KateCTagsView::stepBack() { if (m_jumpStack.isEmpty()) { return; } TagJump back; back = m_jumpStack.pop(); m_mWin->openUrl(back.url); m_mWin->activeView()->setCursorPosition(back.cursor); m_mWin->activeView()->setFocus(); } /******************************************************************/ void KateCTagsView::lookupTag( ) { QString currWord = currentWord(); if (currWord.isEmpty()) { return; } setNewLookupText(currWord); Tags::TagList list = Tags::getExactMatches(m_ctagsUi.tagsFile->text(), currWord); if (list.size() == 0) list = Tags::getExactMatches(m_commonDB, currWord); displayHits(list); // activate the hits tab m_ctagsUi.tabWidget->setCurrentIndex(0); m_mWin->showToolView(m_toolView); } /******************************************************************/ void KateCTagsView::editLookUp() { Tags::TagList list = Tags::getPartialMatches(m_ctagsUi.tagsFile->text(), m_ctagsUi.inputEdit->text()); if (list.size() == 0) list = Tags::getPartialMatches(m_commonDB, m_ctagsUi.inputEdit->text()); displayHits(list); } /******************************************************************/ void KateCTagsView::gotoDefinition( ) { QString currWord = currentWord(); if (currWord.isEmpty()) { return; } QStringList types; types << QStringLiteral("S") << QStringLiteral("d") << QStringLiteral("f") << QStringLiteral("t") << QStringLiteral("v"); gotoTagForTypes(currWord, types); } /******************************************************************/ void KateCTagsView::gotoDeclaration( ) { QString currWord = currentWord(); if (currWord.isEmpty()) { return; } QStringList types; types << QStringLiteral("L") << QStringLiteral("c") << QStringLiteral("e") << QStringLiteral("g") << QStringLiteral("m") << QStringLiteral("n") << QStringLiteral("p") << QStringLiteral("s") << QStringLiteral("u") << QStringLiteral("x"); gotoTagForTypes(currWord, types); } /******************************************************************/ void KateCTagsView::gotoTagForTypes(const QString &word, const QStringList &types) { Tags::TagList list = Tags::getMatches(m_ctagsUi.tagsFile->text(), word, false, types); if (list.size() == 0) list = Tags::getMatches(m_commonDB, word, false, types); //qCDebug(KTECTAGS) << "found" << list.count() << word << types; setNewLookupText(word); if ( list.count() < 1) { m_ctagsUi.tagTreeWidget->clear(); new QTreeWidgetItem(m_ctagsUi.tagTreeWidget, QStringList(i18n("No hits found"))); m_ctagsUi.tabWidget->setCurrentIndex(0); m_mWin->showToolView(m_toolView); return; } displayHits(list); if (list.count() == 1) { Tags::TagEntry tag = list.first(); jumpToTag(tag.file, tag.pattern, word); } else { Tags::TagEntry tag = list.first(); jumpToTag(tag.file, tag.pattern, word); m_ctagsUi.tabWidget->setCurrentIndex(0); m_mWin->showToolView(m_toolView); } } /******************************************************************/ void KateCTagsView::setNewLookupText(const QString &newString) { m_ctagsUi.inputEdit->blockSignals( true ); m_ctagsUi.inputEdit->setText(newString); m_ctagsUi.inputEdit->blockSignals( false ); } /******************************************************************/ void KateCTagsView::displayHits(const Tags::TagList &list) { m_ctagsUi.tagTreeWidget->clear(); if (list.isEmpty()) { new QTreeWidgetItem(m_ctagsUi.tagTreeWidget, QStringList(i18n("No hits found"))); return; } m_ctagsUi.tagTreeWidget->setSortingEnabled(false); for (int i=0; isetText(0, list[i].tag); item->setText(1, list[i].type); item->setText(2, list[i].file); item->setData(0, Qt::UserRole, list[i].pattern); QString pattern = list[i].pattern; pattern.replace( QStringLiteral("\\/"), QStringLiteral("/")); pattern = pattern.mid(2, pattern.length() - 4); pattern = pattern.trimmed(); item->setData(0, Qt::ToolTipRole, pattern); item->setData(1, Qt::ToolTipRole, pattern); item->setData(2, Qt::ToolTipRole, pattern); } m_ctagsUi.tagTreeWidget->setSortingEnabled(true); } /******************************************************************/ void KateCTagsView::tagHitClicked(QTreeWidgetItem *item) { // get stuff const QString file = item->data(2, Qt::DisplayRole).toString(); const QString pattern = item->data(0, Qt::UserRole).toString(); const QString word = item->data(0, Qt::DisplayRole).toString(); jumpToTag(file, pattern, word); } /******************************************************************/ QString KateCTagsView::currentWord( ) { KTextEditor::View *kv = m_mWin->activeView(); if (!kv) { qCDebug(KTECTAGS) << "no KTextEditor::View" << endl; return QString(); } if (kv->selection() && kv->selectionRange().onSingleLine()) { return kv->selectionText(); } if (!kv->cursorPosition().isValid()) { qCDebug(KTECTAGS) << "cursor not valid!" << endl; return QString(); } int line = kv->cursorPosition().line(); int col = kv->cursorPosition().column(); bool includeColon = m_ctagsUi.cmdEdit->text().contains(QLatin1String("--extra=+q")); QString linestr = kv->document()->line(line); int startPos = qMax(qMin(col, linestr.length()-1), 0); int endPos = startPos; while (startPos >= 0 && (linestr[startPos].isLetterOrNumber() || (linestr[startPos] == QLatin1Char(':') && includeColon) || linestr[startPos] == QLatin1Char('_') || linestr[startPos] == QLatin1Char('~'))) { startPos--; } while (endPos < (int)linestr.length() && (linestr[endPos].isLetterOrNumber() || (linestr[endPos] == QLatin1Char(':') && includeColon) || linestr[endPos] == QLatin1Char('_'))) { endPos++; } if (startPos == endPos) { qCDebug(KTECTAGS) << "no word found!" << endl; return QString(); } linestr = linestr.mid(startPos+1, endPos-startPos-1); while (linestr.endsWith(QLatin1Char(':'))) { linestr.remove(linestr.size()-1, 1); } while (linestr.startsWith(QLatin1Char(':'))) { linestr.remove(0, 1); } //qCDebug(KTECTAGS) << linestr; return linestr; } /******************************************************************/ void KateCTagsView::jumpToTag(const QString &file, const QString &pattern, const QString &word) { if (pattern.isEmpty()) return; // generate a regexp from the pattern // ctags interestingly escapes "/", but apparently nothing else. lets revert that QString unescaped = pattern; unescaped.replace( QStringLiteral("\\/"), QStringLiteral("/") ); // most of the time, the ctags pattern has the form /^foo$/ // but this isn't true for some macro definitions // where the form is only /^foo/ // I have no idea if this is a ctags bug or not, but we have to deal with it QString reduced; QString escaped; QString re_string; if (unescaped.endsWith(QStringLiteral("$/"))) { reduced = unescaped.mid(2, unescaped.length() - 4); - escaped = QRegExp::escape(reduced); + escaped = QRegularExpression::escape(reduced); re_string = QStringLiteral("^%1$").arg(escaped); } else { reduced = unescaped.mid( 2, unescaped.length() -3 ); - escaped = QRegExp::escape(reduced); + escaped = QRegularExpression::escape(reduced); re_string = QStringLiteral("^%1").arg(escaped); } - QRegExp re(re_string); + QRegularExpression re(re_string); // save current location TagJump from; from.url = m_mWin->activeView()->document()->url(); from.cursor = m_mWin->activeView()->cursorPosition(); m_jumpStack.push(from); // open/activate the new file QFileInfo fInfo(file); //qCDebug(KTECTAGS) << pattern << file << fInfo.absoluteFilePath(); m_mWin->openUrl(QUrl::fromLocalFile(fInfo.absoluteFilePath())); // any view active? if (!m_mWin->activeView()) { return; } // look for the line QString linestr; int line; for (line =0; line < m_mWin->activeView()->document()->lines(); line++) { linestr = m_mWin->activeView()->document()->line(line); if (linestr.indexOf(re) > -1) break; } // activate the line if (line != m_mWin->activeView()->document()->lines()) { // line found now look for the column int column = linestr.indexOf(word) + (word.length()/2); m_mWin->activeView()->setCursorPosition(KTextEditor::Cursor(line, column)); } m_mWin->activeView()->setFocus(); } /******************************************************************/ void KateCTagsView::startEditTmr() { if (m_ctagsUi.inputEdit->text().size() > 3) { m_editTimer.start(500); } } /******************************************************************/ void KateCTagsView::updateSessionDB() { if (m_proc.state() != QProcess::NotRunning) { return; } QString targets; QString target; for (int i=0; icount(); i++) { target = m_ctagsUi.targetList->item(i)->text(); if (target.endsWith(QLatin1Char('/')) || target.endsWith(QLatin1Char('\\'))) { target = target.left(target.size() - 1); } targets += target + QLatin1Char(' '); } QString pluginFolder = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1String("/katectags"); QDir().mkpath(pluginFolder); if (m_ctagsUi.tagsFile->text().isEmpty()) { // FIXME we need a way to get the session name pluginFolder += QLatin1String("/session_db_"); pluginFolder += QDateTime::currentDateTimeUtc().toString(QStringLiteral("yyyyMMdd_hhmmss")); m_ctagsUi.tagsFile->setText(pluginFolder); } if (targets.isEmpty()) { KMessageBox::error(nullptr, i18n("No folders or files to index")); QFile::remove(m_ctagsUi.tagsFile->text()); return; } QString command = QStringLiteral("%1 -f %2 %3").arg(m_ctagsUi.cmdEdit->text(), m_ctagsUi.tagsFile->text(), targets); m_proc.start(command); if(!m_proc.waitForStarted(500)) { KMessageBox::error(nullptr, i18n("Failed to run \"%1\". exitStatus = %2", command, m_proc.exitStatus())); return; } QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); m_ctagsUi.updateButton->setDisabled(true); m_ctagsUi.updateButton2->setDisabled(true); } /******************************************************************/ void KateCTagsView::updateDone(int exitCode, QProcess::ExitStatus status) { if (status == QProcess::CrashExit) { KMessageBox::error(m_toolView, i18n("The CTags executable crashed.")); } else if (exitCode != 0) { KMessageBox::error(m_toolView, i18n("The CTags program exited with code %1: %2" , exitCode , QString::fromLocal8Bit(m_proc.readAllStandardError()))); } m_ctagsUi.updateButton->setDisabled(false); m_ctagsUi.updateButton2->setDisabled(false); QApplication::restoreOverrideCursor(); } /******************************************************************/ void KateCTagsView::addTagTarget() { QFileDialog dialog; dialog.setDirectory(QFileInfo(m_mWin->activeView()->document()->url().path()).path()); dialog.setFileMode(QFileDialog::Directory); // i18n("CTags Database Location")); if (dialog.exec() != QDialog::Accepted) { return; } QStringList urls = dialog.selectedFiles(); for (int i=0; icurrentItem (); } /******************************************************************/ bool KateCTagsView::listContains(const QString &target) { for (int i=0; icount(); i++) { if (m_ctagsUi.targetList->item(i)->text() == target) { return true; } } return false; } /******************************************************************/ bool KateCTagsView::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(event); if ((obj == m_toolView) && (ke->key() == Qt::Key_Escape)) { m_mWin->hideToolView(m_toolView); event->accept(); return true; } } return QObject::eventFilter(obj, event); } /******************************************************************/ void KateCTagsView::resetCMD() { m_ctagsUi.cmdEdit->setText(DEFAULT_CTAGS_CMD); } /******************************************************************/ void KateCTagsView::handleEsc(QEvent *e) { if (!m_mWin) return; QKeyEvent *k = static_cast(e); if (k->key() == Qt::Key_Escape && k->modifiers() == Qt::NoModifier) { if (m_toolView->isVisible()) { m_mWin->hideToolView(m_toolView); } } } diff --git a/addons/project/kateprojectworker.cpp b/addons/project/kateprojectworker.cpp index 8bc1febed..7328b0671 100644 --- a/addons/project/kateprojectworker.cpp +++ b/addons/project/kateprojectworker.cpp @@ -1,507 +1,507 @@ /* This file is part of the Kate project. * * Copyright (C) 2012 Christoph Cullmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 Library General Public License * along with this library; 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 "kateprojectworker.h" #include "kateproject.h" #include #include #include #include #include #include #include #include #include KateProjectWorker::KateProjectWorker(const QString &baseDir, const QVariantMap &projectMap) : QObject() , ThreadWeaver::Job() , m_baseDir(baseDir) , m_projectMap(projectMap) { Q_ASSERT(!m_baseDir.isEmpty()); } void KateProjectWorker::run(ThreadWeaver::JobPointer, ThreadWeaver::Thread *) { /** * Create dummy top level parent item and empty map inside shared pointers * then load the project recursively */ KateProjectSharedQStandardItem topLevel(new QStandardItem()); KateProjectSharedQMapStringItem file2Item(new QMap ()); loadProject(topLevel.data(), m_projectMap, file2Item.data()); /** * create some local backup of some data we need for further processing! */ QStringList files = file2Item->keys(); emit loadDone(topLevel, file2Item); /** * load index */ loadIndex(files); } void KateProjectWorker::loadProject(QStandardItem *parent, const QVariantMap &project, QMap *file2Item) { /** * recurse to sub-projects FIRST */ QVariantList subGroups = project[QStringLiteral("projects")].toList(); for (const QVariant &subGroupVariant: subGroups) { /** * convert to map and get name, else skip */ QVariantMap subProject = subGroupVariant.toMap(); const QString keyName = QStringLiteral("name"); if (subProject[keyName].toString().isEmpty()) { continue; } /** * recurse */ QStandardItem *subProjectItem = new KateProjectItem(KateProjectItem::Project, subProject[keyName].toString()); loadProject(subProjectItem, subProject, file2Item); parent->appendRow(subProjectItem); } /** * load all specified files */ const QString keyFiles = QStringLiteral("files"); QVariantList files = project[keyFiles].toList(); for (const QVariant &fileVariant : files) { loadFilesEntry(parent, fileVariant.toMap(), file2Item); } } /** * small helper to construct directory parent items * @param dir2Item map for path => item * @param path current path we need item for * @return correct parent item for given path, will reuse existing ones */ static QStandardItem *directoryParent(QMap &dir2Item, QString path) { /** * throw away simple / */ if (path == QStringLiteral("/")) { path = QString(); } /** * quick check: dir already seen? */ if (dir2Item.contains(path)) { return dir2Item[path]; } /** * else: construct recursively */ int slashIndex = path.lastIndexOf(QLatin1Char('/')); /** * no slash? * simple, no recursion, append new item toplevel */ if (slashIndex < 0) { dir2Item[path] = new KateProjectItem(KateProjectItem::Directory, path); dir2Item[QString()]->appendRow(dir2Item[path]); return dir2Item[path]; } /** * else, split and recurse */ const QString leftPart = path.left(slashIndex); const QString rightPart = path.right(path.size() - (slashIndex + 1)); /** * special handling if / with nothing on one side are found */ if (leftPart.isEmpty() || rightPart.isEmpty()) { return directoryParent(dir2Item, leftPart.isEmpty() ? rightPart : leftPart); } /** * else: recurse on left side */ dir2Item[path] = new KateProjectItem(KateProjectItem::Directory, rightPart); directoryParent(dir2Item, leftPart)->appendRow(dir2Item[path]); return dir2Item[path]; } void KateProjectWorker::loadFilesEntry(QStandardItem *parent, const QVariantMap &filesEntry, QMap *file2Item) { QDir dir(m_baseDir); if (!dir.cd(filesEntry[QStringLiteral("directory")].toString())) { return; } QStringList files = findFiles(dir, filesEntry); if (files.isEmpty()) { return; } files.sort(); /** * construct paths first in tree and items in a map */ QMap dir2Item; dir2Item[QString()] = parent; QList > item2ParentPath; for (const QString &filePath : files) { /** * skip dupes */ if (file2Item->contains(filePath)) { continue; } /** * get file info and skip NON-files */ QFileInfo fileInfo(filePath); if (!fileInfo.isFile()) { continue; } /** * construct the item with right directory prefix * already hang in directories in tree */ KateProjectItem *fileItem = new KateProjectItem(KateProjectItem::File, fileInfo.fileName()); fileItem->setData(filePath, Qt::ToolTipRole); // get the directory's relative path to the base directory QString dirRelPath = dir.relativeFilePath(fileInfo.absolutePath()); // if the relative path is ".", clean it up if (dirRelPath == QStringLiteral(".")) { dirRelPath = QString(); } item2ParentPath.append(QPair(fileItem, directoryParent(dir2Item, dirRelPath))); fileItem->setData(filePath, Qt::UserRole); (*file2Item)[filePath] = fileItem; } /** * plug in the file items to the tree */ auto i = item2ParentPath.constBegin(); while (i != item2ParentPath.constEnd()) { i->second->appendRow(i->first); ++i; } } QStringList KateProjectWorker::findFiles(const QDir &dir, const QVariantMap& filesEntry) { const bool recursive = !filesEntry.contains(QStringLiteral("recursive")) || filesEntry[QStringLiteral("recursive")].toBool(); if (filesEntry[QStringLiteral("git")].toBool()) { return filesFromGit(dir, recursive); } else if (filesEntry[QStringLiteral("hg")].toBool()) { return filesFromMercurial(dir, recursive); } else if (filesEntry[QStringLiteral("svn")].toBool()) { return filesFromSubversion(dir, recursive); } else if (filesEntry[QStringLiteral("darcs")].toBool()) { return filesFromDarcs(dir, recursive); } else { QStringList files = filesEntry[QStringLiteral("list")].toStringList(); if (files.empty()) { QStringList filters = filesEntry[QStringLiteral("filters")].toStringList(); files = filesFromDirectory(dir, recursive, filters); } return files; } } QStringList KateProjectWorker::filesFromGit(const QDir &dir, bool recursive) { QStringList relFiles = gitLsFiles(dir); relFiles << gitSubmodulesFiles(dir); QStringList files; for (const QString &relFile : relFiles) { if (!recursive && (relFile.indexOf(QStringLiteral("/")) != -1)) { continue; } files.append(dir.absolutePath() + QLatin1Char('/') + relFile); } return files; } QStringList KateProjectWorker::gitLsFiles(const QDir &dir) { QStringList files; // git ls-files -z results a bytearray where each entry is \0-terminated. // NOTE: Without -z, Umlauts such as "Der Bäcker/Das Brötchen.txt" do not work (#389415) QStringList args; args << QStringLiteral("ls-files") << QStringLiteral("-z") << QStringLiteral("."); QProcess git; git.setWorkingDirectory(dir.absolutePath()); git.start(QStringLiteral("git"), args); if (!git.waitForStarted() || !git.waitForFinished(-1)) { return files; } const QList byteArrayList = git.readAllStandardOutput().split('\0'); for (const QByteArray & byteArray : byteArrayList) { files << QString::fromUtf8(byteArray); } return files; } QStringList KateProjectWorker::gitSubmodulesFiles(const QDir &dir) { /** * git submodule command gives little to use for reliable file listing * so reading the .gitmodule file directly. After the module paths are found * just treat the new repositories as the main one. */ QStringList files; QString modulesPath = dir.filePath(QStringLiteral(".gitmodules")); if (!QFile::exists(modulesPath)) { return files; } QSettings config(modulesPath, QSettings::IniFormat); for (const QString &module: config.childGroups()) { QString path = config.value(module + QStringLiteral("/path")).toString(); QDir moduleDir = dir.filePath(path); QStringList relFiles = gitLsFiles(moduleDir); for (const QString &file: relFiles) { files << path + QLatin1Char('/') + file; } } return files; } QStringList KateProjectWorker::filesFromMercurial(const QDir &dir, bool recursive) { QStringList files; QProcess hg; hg.setWorkingDirectory(dir.absolutePath()); QStringList args; args << QStringLiteral("manifest") << QStringLiteral("."); hg.start(QStringLiteral("hg"), args); if (!hg.waitForStarted() || !hg.waitForFinished(-1)) { return files; } - const QStringList relFiles = QString::fromLocal8Bit(hg.readAllStandardOutput()).split(QRegExp(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); + const QStringList relFiles = QString::fromLocal8Bit(hg.readAllStandardOutput()).split(QRegularExpression(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); for (const QString &relFile : relFiles) { if (!recursive && (relFile.indexOf(QStringLiteral("/")) != -1)) { continue; } files.append(dir.absolutePath() + QLatin1Char('/') + relFile); } return files; } QStringList KateProjectWorker::filesFromSubversion(const QDir &dir, bool recursive) { QStringList files; QProcess svn; svn.setWorkingDirectory(dir.absolutePath()); QStringList args; args << QStringLiteral("status") << QStringLiteral("--verbose") << QStringLiteral("."); if (recursive) { args << QStringLiteral("--depth=infinity"); } else { args << QStringLiteral("--depth=files"); } svn.start(QStringLiteral("svn"), args); if (!svn.waitForStarted() || !svn.waitForFinished(-1)) { return files; } /** * get output and split up into lines */ - const QStringList lines = QString::fromLocal8Bit(svn.readAllStandardOutput()).split(QRegExp(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); + const QStringList lines = QString::fromLocal8Bit(svn.readAllStandardOutput()).split(QRegularExpression(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); /** * remove start of line that is no filename, sort out unknown and ignore */ bool first = true; int prefixLength = -1; for (const QString &line : lines) { /** * get length of stuff to cut */ if (first) { /** * try to find ., else fail */ prefixLength = line.lastIndexOf(QStringLiteral(".")); if (prefixLength < 0) { break; } /** * skip first */ first = false; continue; } /** * get file, if not unknown or ignored * prepend directory path */ if ((line.size() > prefixLength) && line[0] != QLatin1Char('?') && line[0] != QLatin1Char('I')) { files.append(dir.absolutePath() + QLatin1Char('/') + line.right(line.size() - prefixLength)); } } return files; } QStringList KateProjectWorker::filesFromDarcs(const QDir &dir, bool recursive) { QStringList files; const QString cmd = QStringLiteral("darcs"); QString root; { QProcess darcs; darcs.setWorkingDirectory(dir.absolutePath()); QStringList args; args << QStringLiteral("list") << QStringLiteral("repo"); darcs.start(cmd, args); if (!darcs.waitForStarted() || !darcs.waitForFinished(-1)) return files; auto str = QString::fromLocal8Bit(darcs.readAllStandardOutput()); QRegularExpression exp(QStringLiteral("Root: ([^\\n\\r]*)")); auto match = exp.match(str); if(!match.hasMatch()) return files; root = match.captured(1); } QStringList relFiles; { QProcess darcs; QStringList args; darcs.setWorkingDirectory(dir.absolutePath()); args << QStringLiteral("list") << QStringLiteral("files") << QStringLiteral("--no-directories") << QStringLiteral("--pending"); darcs.start(cmd, args); if(!darcs.waitForStarted() || !darcs.waitForFinished(-1)) return files; relFiles = QString::fromLocal8Bit(darcs.readAllStandardOutput()) .split(QRegularExpression(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); } for (const QString &relFile: relFiles) { const QString path = dir.relativeFilePath(root + QStringLiteral("/") + relFile); if ((!recursive && (relFile.indexOf(QStringLiteral("/")) != -1)) || (recursive && (relFile.indexOf(QStringLiteral("..")) == 0)) ) { continue; } files.append(dir.absoluteFilePath(path)); } return files; } QStringList KateProjectWorker::filesFromDirectory(const QDir &_dir, bool recursive, const QStringList &filters) { QStringList files; QDir dir(_dir); dir.setFilter(QDir::Files); if (!filters.isEmpty()) { dir.setNameFilters(filters); } /** * construct flags for iterator */ QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; if (recursive) { flags = flags | QDirIterator::Subdirectories; } /** * create iterator and collect all files */ QDirIterator dirIterator(dir, flags); while (dirIterator.hasNext()) { dirIterator.next(); files.append(dirIterator.filePath()); } return files; } void KateProjectWorker::loadIndex(const QStringList &files) { /** * create new index, this will do the loading in the constructor * wrap it into shared pointer for transfer to main thread */ const QString keyCtags = QStringLiteral("ctags"); KateProjectSharedProjectIndex index(new KateProjectIndex(files, m_projectMap[keyCtags].toMap())); emit loadIndexDone(index); } diff --git a/addons/project/tools/kateprojectcodeanalysistoolcppcheck.cpp b/addons/project/tools/kateprojectcodeanalysistoolcppcheck.cpp index 835cee0ac..b8a4ff884 100644 --- a/addons/project/tools/kateprojectcodeanalysistoolcppcheck.cpp +++ b/addons/project/tools/kateprojectcodeanalysistoolcppcheck.cpp @@ -1,99 +1,99 @@ /* This file is part of the Kate project. * * Copyright (C) 2017 Héctor Mesa Jiménez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 Library General Public License * along with this library; 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 "kateprojectcodeanalysistoolcppcheck.h" #include #include KateProjectCodeAnalysisToolCppcheck::KateProjectCodeAnalysisToolCppcheck(QObject *parent) : KateProjectCodeAnalysisTool(parent) { } KateProjectCodeAnalysisToolCppcheck::~KateProjectCodeAnalysisToolCppcheck() { } QString KateProjectCodeAnalysisToolCppcheck::name() const { return i18n("Cppcheck (C++)"); } QString KateProjectCodeAnalysisToolCppcheck::description() const { return i18n("Cppcheck is a static analysis tool for C/C++ code"); } QString KateProjectCodeAnalysisToolCppcheck::fileExtensions() const { return QStringLiteral("cpp|cxx|cc|c++|c|tpp|txx"); } QStringList KateProjectCodeAnalysisToolCppcheck::filter(const QStringList &files) const { // c++ files return files.filter(QRegularExpression(QStringLiteral("\\.(") + fileExtensions().replace(QStringLiteral("+"), QStringLiteral("\\+")) + QStringLiteral(")$"))); } QString KateProjectCodeAnalysisToolCppcheck::path() const { return QStringLiteral("cppcheck"); } QStringList KateProjectCodeAnalysisToolCppcheck::arguments() { QStringList _args; _args << QStringLiteral("-q") << QStringLiteral("--inline-suppr") << QStringLiteral("--enable=all") << QStringLiteral("--template={file}////{line}////{severity}////{message}") << QStringLiteral("--file-list=-"); return _args; } QString KateProjectCodeAnalysisToolCppcheck::notInstalledMessage() const { return i18n("Please install 'cppcheck'."); } QStringList KateProjectCodeAnalysisToolCppcheck::parseLine(const QString &line) const { - return line.split(QRegExp(QStringLiteral("////")), QString::SkipEmptyParts); + return line.split(QRegularExpression(QStringLiteral("////")), QString::SkipEmptyParts); } QString KateProjectCodeAnalysisToolCppcheck::stdinMessages() { // filenames are written to stdin (--file-list=-) if (!m_project) { return QString(); } auto&& fileList = filter(m_project->files()); setActualFilesCount(fileList.size()); return fileList.join(QStringLiteral("\n")); } diff --git a/addons/project/tools/kateprojectcodeanalysistoolflake8.cpp b/addons/project/tools/kateprojectcodeanalysistoolflake8.cpp index 6c45c5048..2ebc349e0 100644 --- a/addons/project/tools/kateprojectcodeanalysistoolflake8.cpp +++ b/addons/project/tools/kateprojectcodeanalysistoolflake8.cpp @@ -1,101 +1,101 @@ /* This file is part of the Kate project. * * Copyright (C) 2017 Héctor Mesa Jiménez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 Library General Public License * along with this library; 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 "kateprojectcodeanalysistoolflake8.h" #include #include KateProjectCodeAnalysisToolFlake8::KateProjectCodeAnalysisToolFlake8(QObject *parent) : KateProjectCodeAnalysisTool(parent) { } KateProjectCodeAnalysisToolFlake8::~KateProjectCodeAnalysisToolFlake8() { } QString KateProjectCodeAnalysisToolFlake8::name() const { return i18n("Flake8 (Python)"); } QString KateProjectCodeAnalysisToolFlake8::description() const { return i18n("Flake8: Your Tool For Style Guide Enforcement for Python"); } QString KateProjectCodeAnalysisToolFlake8::fileExtensions() const { return QStringLiteral("py"); } QStringList KateProjectCodeAnalysisToolFlake8::filter(const QStringList &files) const { // for now we expect files with extension return files.filter(QRegularExpression(QStringLiteral("\\.(") + fileExtensions() + QStringLiteral(")$"))); } QString KateProjectCodeAnalysisToolFlake8::path() const { /* * for now, only the executable in the path can be called, * but it would be great to be able to specify a version * installed in a virtual environment */ return QStringLiteral("flake8"); } QStringList KateProjectCodeAnalysisToolFlake8::arguments() { QStringList _args; _args << QStringLiteral("--exit-zero") /* * translating a flake8 code to a severity level is subjective, * so the code is provided as a severity level. */ << QStringLiteral("--format=%(path)s////%(row)d////%(code)s////%(text)s"); if (m_project) { auto&& fileList = filter(m_project->files()); setActualFilesCount(fileList.size()); _args.append(fileList); } return _args; } QString KateProjectCodeAnalysisToolFlake8::notInstalledMessage() const { return i18n("Please install 'flake8'."); } QStringList KateProjectCodeAnalysisToolFlake8::parseLine(const QString &line) const { - return line.split(QRegExp(QStringLiteral("////")), QString::SkipEmptyParts); + return line.split(QRegularExpression(QStringLiteral("////")), QString::SkipEmptyParts); } QString KateProjectCodeAnalysisToolFlake8::stdinMessages() { return QString(); } diff --git a/addons/symbolviewer/bash_parser.cpp b/addons/symbolviewer/bash_parser.cpp index 2c6621e15..17705f279 100644 --- a/addons/symbolviewer/bash_parser.cpp +++ b/addons/symbolviewer/bash_parser.cpp @@ -1,106 +1,106 @@ /*************************************************************************** bash_parser.cpp - description ------------------- begin : dec 12 2008 author : Daniel Dumitrache email : daniel.dumitrache@gmail.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. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***************************************************************************/ #include "plugin_katesymbolviewer.h" void KatePluginSymbolViewerView::parseBashSymbols(void) { if (!m_mainWindow->activeView()) return; QString currline; QString funcStr(QStringLiteral("function ")); int i; //bool mainprog; QTreeWidgetItem *node = nullptr; QTreeWidgetItem *funcNode = nullptr; QTreeWidgetItem *lastFuncNode = nullptr; QPixmap func( ( const char** ) class_xpm ); //It is necessary to change names m_func->setText(i18n("Show Functions")); if(m_treeOn->isChecked()) { funcNode = new QTreeWidgetItem(m_symbols, QStringList(i18n("Functions") ) ); funcNode->setIcon(0, QIcon(func)); if (m_expandOn->isChecked()) { m_symbols->expandItem(funcNode); } lastFuncNode = funcNode; m_symbols->setRootIsDecorated(1); } else m_symbols->setRootIsDecorated(0); KTextEditor::Document *kDoc = m_mainWindow->activeView()->document(); for (i = 0; i < kDoc->lines(); i++) { currline = kDoc->line(i); currline = currline.trimmed(); currline = currline.simplified(); bool comment = false; //qDebug(13000)<isChecked()) { QString funcName; // skip line if no function defined // note: function name must match regex: [a-zA-Z0-9-_]+ - if(!currline.contains(QRegExp(QLatin1String("^(function )*[a-zA-Z0-9-_]+ *\\( *\\)"))) - && !currline.contains(QRegExp(QLatin1String("^function [a-zA-Z0-9-_]+")))) + if(!currline.contains(QRegularExpression(QLatin1String("^(function )*[a-zA-Z0-9-_]+ *\\( *\\)"))) + && !currline.contains(QRegularExpression(QLatin1String("^function [a-zA-Z0-9-_]+")))) continue; // strip everything unneeded and get the function's name - currline.remove(QRegExp(QLatin1String("^(function )*"))); - funcName = currline.split(QRegExp(QLatin1String("((\\( *\\))|[^a-zA-Z0-9-_])")))[0].simplified(); + currline.remove(QRegularExpression(QLatin1String("^(function )*"))); + funcName = currline.split(QRegularExpression(QLatin1String("((\\( *\\))|[^a-zA-Z0-9-_])")))[0].simplified(); if(!funcName.size()) continue; funcName.append(QLatin1String("()")); if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(funcNode, lastFuncNode); lastFuncNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, funcName); node->setIcon(0, QIcon(func)); node->setText(1, QString::number( i, 10)); } } //for i loop } diff --git a/addons/symbolviewer/perl_parser.cpp b/addons/symbolviewer/perl_parser.cpp index 8a6f5381e..b786a6dd8 100644 --- a/addons/symbolviewer/perl_parser.cpp +++ b/addons/symbolviewer/perl_parser.cpp @@ -1,142 +1,142 @@ /*************************************************************************** perl_parser.cpp - description ------------------- begin : Apr 2 2003 author : 2003 Massimo Callegari email : massimocallegari@yahoo.it ***************************************************************************/ /*************************************************************************** * * * 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 "plugin_katesymbolviewer.h" void KatePluginSymbolViewerView::parsePerlSymbols(void) { if (!m_mainWindow->activeView()) return; m_macro->setText(i18n("Show Uses")); m_struct->setText(i18n("Show Pragmas")); m_func->setText(i18n("Show Subroutines")); QString cl; // Current Line QString stripped; char comment = 0; QPixmap cls( ( const char** ) class_xpm ); QPixmap sct( ( const char** ) struct_xpm ); QPixmap mcr( ( const char** ) macro_xpm ); QPixmap cls_int( ( const char** ) class_int_xpm ); QTreeWidgetItem *node = nullptr; QTreeWidgetItem *mcrNode = nullptr, *sctNode = nullptr, *clsNode = nullptr; QTreeWidgetItem *lastMcrNode = nullptr, *lastSctNode = nullptr, *lastClsNode = nullptr; KTextEditor::Document *kv = m_mainWindow->activeView()->document(); //kdDebug(13000)<<"Lines counted :"<numLines()<isChecked()) { mcrNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Uses") ) ); sctNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Pragmas") ) ); clsNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Subroutines") ) ); mcrNode->setIcon(0, QIcon(mcr)); sctNode->setIcon(0, QIcon(sct)); clsNode->setIcon(0, QIcon(cls)); if (m_expandOn->isChecked()) { m_symbols->expandItem(mcrNode); m_symbols->expandItem(sctNode); m_symbols->expandItem(clsNode); } lastMcrNode = mcrNode; lastSctNode = sctNode; lastClsNode = clsNode; m_symbols->setRootIsDecorated(1); } else m_symbols->setRootIsDecorated(0); for (int i=0; ilines(); i++) { cl = kv->line(i); //qDebug()<< "Line " << i << " : "<< cl; if(cl.isEmpty() || cl.at(0) == QLatin1Char('#')) continue; - if(cl.indexOf(QRegExp(QLatin1String("^=[a-zA-Z]"))) >= 0) comment = 1; - if(cl.indexOf(QRegExp(QLatin1String("^=cut$"))) >= 0) + if(cl.indexOf(QRegularExpression(QLatin1String("^=[a-zA-Z]"))) >= 0) comment = 1; + if(cl.indexOf(QRegularExpression(QLatin1String("^=cut$"))) >= 0) { comment = 0; continue; } if (comment==1) continue; cl = cl.trimmed(); //qDebug()<<"Trimmed line " << i << " : "<< cl; - if(cl.indexOf(QRegExp(QLatin1String("^use +[A-Z]"))) == 0 && m_macro->isChecked()) + if(cl.indexOf(QRegularExpression(QLatin1String("^use +[A-Z]"))) == 0 && m_macro->isChecked()) { - QString stripped=cl.remove( QRegExp(QLatin1String("^use +")) ); - //stripped=stripped.replace( QRegExp(QLatin1String(";$")), "" ); // Doesn't work ?? + QString stripped=cl.remove( QRegularExpression(QLatin1String("^use +")) ); + //stripped=stripped.replace( QRegularExpression(QLatin1String(";$")), "" ); // Doesn't work ?? stripped = stripped.left(stripped.indexOf(QLatin1Char(';'))); if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(mcrNode, lastMcrNode); lastMcrNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(mcr)); node->setText(1, QString::number( i, 10)); } #if 1 - if(cl.indexOf(QRegExp(QLatin1String("^use +[a-z]"))) == 0 && m_struct->isChecked()) + if(cl.indexOf(QRegularExpression(QLatin1String("^use +[a-z]"))) == 0 && m_struct->isChecked()) { - QString stripped=cl.remove( QRegExp(QLatin1String("^use +")) ); - stripped=stripped.remove( QRegExp(QLatin1String(";$")) ); + QString stripped=cl.remove( QRegularExpression(QLatin1String("^use +")) ); + stripped=stripped.remove( QRegularExpression(QLatin1String(";$")) ); if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(sctNode, lastSctNode); lastMcrNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(sct)); node->setText(1, QString::number( i, 10)); } #endif #if 1 - if(cl.indexOf(QRegExp(QLatin1String("^sub +")))==0 && m_func->isChecked()) + if(cl.indexOf(QRegularExpression(QLatin1String("^sub +")))==0 && m_func->isChecked()) { - QString stripped=cl.remove( QRegExp(QLatin1String("^sub +")) ); - stripped=stripped.remove( QRegExp(QLatin1String("[{;] *$")) ); + QString stripped=cl.remove( QRegularExpression(QLatin1String("^sub +")) ); + stripped=stripped.remove( QRegularExpression(QLatin1String("[{;] *$")) ); if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(clsNode, lastClsNode); lastClsNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); if (!stripped.isEmpty() && stripped.at(0)==QLatin1Char('_')) node->setIcon(0, QIcon(cls_int)); else node->setIcon(0, QIcon(cls)); node->setText(1, QString::number( i, 10)); } #endif } } diff --git a/addons/symbolviewer/python_parser.cpp b/addons/symbolviewer/python_parser.cpp index ad627fa8a..dca928bcd 100644 --- a/addons/symbolviewer/python_parser.cpp +++ b/addons/symbolviewer/python_parser.cpp @@ -1,165 +1,165 @@ /*************************************************************************** python_parser.cpp - description ------------------- begin : Apr 2 2003 author : 2003 Massimo Callegari email : massimocallegari@yahoo.it ***************************************************************************/ /*************************************************************************** * * * 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 "plugin_katesymbolviewer.h" void KatePluginSymbolViewerView::parsePythonSymbols(void) { if (!m_mainWindow->activeView()) return; m_macro->setText(i18n("Show Globals")); m_struct->setText(i18n("Show Methods")); m_func->setText(i18n("Show Classes")); QString cl; // Current Line QPixmap cls( ( const char** ) class_xpm ); QPixmap mtd( ( const char** ) method_xpm ); QPixmap mcr( ( const char** ) macro_xpm ); int in_class = 0, state = 0, j; QString name; QTreeWidgetItem *node = nullptr; QTreeWidgetItem *mcrNode = nullptr, *mtdNode = nullptr, *clsNode = nullptr; QTreeWidgetItem *lastMcrNode = nullptr, *lastMtdNode = nullptr, *lastClsNode = nullptr; KTextEditor::Document *kv = m_mainWindow->activeView()->document(); //kdDebug(13000)<<"Lines counted :"<numLines()<isChecked()) { clsNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Classes") ) ); mcrNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Globals") ) ); mcrNode->setIcon(0, QIcon(mcr)); clsNode->setIcon(0, QIcon(cls)); if (m_expandOn->isChecked()) { m_symbols->expandItem(mcrNode); m_symbols->expandItem(clsNode); } lastClsNode = clsNode; lastMcrNode = mcrNode; mtdNode = clsNode; lastMtdNode = clsNode; m_symbols->setRootIsDecorated(1); } else m_symbols->setRootIsDecorated(0); for (int i=0; ilines(); i++) { int line=i; cl = kv->line(i); // concatenate continued lines and remove continuation marker if (cl.length()==0) continue; while (cl[cl.length()-1]==QLatin1Char('\\')) { cl=cl.left(cl.length()-1); i++; if (ilines()) cl+=kv->line(i); else break; } - if(cl.indexOf( QRegExp(QLatin1String("^class [a-zA-Z0-9_,\\s\\(\\).]+:")) ) >= 0) in_class = 1; + if(cl.indexOf( QRegularExpression(QLatin1String("^class [a-zA-Z0-9_,\\s\\(\\).]+:")) ) >= 0) in_class = 1; - //if(cl.find( QRegExp(QLatin1String("[\\s]+def [a-zA-Z_]+[^#]*:")) ) >= 0) in_class = 2; - if(cl.indexOf( QRegExp(QLatin1String("^def\\s+[a-zA-Z_]+[^#]*:")) ) >= 0 ) in_class = 0; + //if(cl.find( QRegularExpression(QLatin1String("[\\s]+def [a-zA-Z_]+[^#]*:")) ) >= 0) in_class = 2; + if(cl.indexOf( QRegularExpression(QLatin1String("^def\\s+[a-zA-Z_]+[^#]*:")) ) >= 0 ) in_class = 0; if (cl.indexOf(QLatin1String("def ")) >= 0 || (cl.indexOf(QLatin1String("class ")) >= 0 && in_class == 1)) { if (cl.indexOf(QLatin1String("def ")) >= 0 && in_class == 1) in_class = 2; state = 1; if (cl.indexOf(QLatin1Char(':')) >= 0) state = 3; // found in the same line. Done else if (cl.indexOf(QLatin1Char('(')) >= 0) state = 2; if (state == 2 || state == 3) name = cl.left (cl.indexOf (QLatin1Char('('))); } if (state > 0 && state < 3) { for (j = 0; j < cl.length(); j++) { if (cl.at(j) == QLatin1Char('(')) state = 2; else if (cl.at(j) == QLatin1Char(':')) { state = 3; break; } if (state == 1) name += cl.at(j); } } if (state == 3) { //qDebug(13000)<<"Function -- Inserted : "<isChecked() && in_class == 1) { if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(clsNode, lastClsNode); if (m_expandOn->isChecked()) m_symbols->expandItem(node); lastClsNode = node; mtdNode = lastClsNode; lastMtdNode = lastClsNode; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, name); node->setIcon(0, QIcon(cls)); node->setText(1, QString::number( line, 10)); } if (m_struct->isChecked() && in_class == 2) { if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(mtdNode, lastMtdNode); lastMtdNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, name); node->setIcon(0, QIcon(mtd)); node->setText(1, QString::number( line, 10)); } if (m_macro->isChecked() && in_class == 0) { if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(mcrNode, lastMcrNode); lastMcrNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, name); node->setIcon(0, QIcon(mcr)); node->setText(1, QString::number( line, 10)); } state = 0; name.clear(); } } } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/addons/symbolviewer/ruby_parser.cpp b/addons/symbolviewer/ruby_parser.cpp index e0d0e1967..8ede9dec8 100644 --- a/addons/symbolviewer/ruby_parser.cpp +++ b/addons/symbolviewer/ruby_parser.cpp @@ -1,106 +1,106 @@ /*************************************************************************** ruby_parser.cpp - description ------------------- begin : May 9th 2007 author : 2007 Massimo Callegari email : massimocallegari@yahoo.it ***************************************************************************/ /*************************************************************************** * * * 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 "plugin_katesymbolviewer.h" void KatePluginSymbolViewerView::parseRubySymbols(void) { if (!m_mainWindow->activeView()) return; m_macro->setText(i18n("Show Globals")); m_struct->setText(i18n("Show Methods")); m_func->setText(i18n("Show Classes")); QString cl; // Current Line QPixmap cls( ( const char** ) class_xpm ); QPixmap mtd( ( const char** ) method_xpm ); QPixmap mcr( ( const char** ) macro_xpm ); int i; QString name; QTreeWidgetItem *node = nullptr; QTreeWidgetItem *mtdNode = nullptr, *clsNode = nullptr; QTreeWidgetItem *lastMtdNode = nullptr, *lastClsNode = nullptr; KTextEditor::Document *kv = m_mainWindow->activeView()->document(); //kdDebug(13000)<<"Lines counted :"<numLines()<isChecked()) { clsNode = new QTreeWidgetItem(m_symbols); clsNode->setText(0, i18n("Classes")); clsNode->setIcon(0, QIcon(cls)); if (m_expandOn->isChecked()) m_symbols->expandItem(clsNode); lastClsNode = clsNode; mtdNode = clsNode; lastMtdNode = clsNode; m_symbols->setRootIsDecorated(1); } else m_symbols->setRootIsDecorated(0); for (i=0; ilines(); i++) { cl = kv->line(i); cl = cl.trimmed(); - if (cl.indexOf( QRegExp(QLatin1String("^class [a-zA-Z0-9]+[^#]")) ) >= 0) + if (cl.indexOf( QRegularExpression(QLatin1String("^class [a-zA-Z0-9]+[^#]")) ) >= 0) { if (m_func->isChecked()) { if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(clsNode, lastClsNode); if (m_expandOn->isChecked()) m_symbols->expandItem(node); lastClsNode = node; mtdNode = lastClsNode; lastMtdNode = lastClsNode; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, cl.mid(6)); node->setIcon(0, QIcon(cls)); node->setText(1, QString::number( i, 10)); } } - if (cl.indexOf( QRegExp(QLatin1String("^def [a-zA-Z_]+[^#]")) ) >= 0 ) + if (cl.indexOf( QRegularExpression(QLatin1String("^def [a-zA-Z_]+[^#]")) ) >= 0 ) { if (m_struct->isChecked()) { if (m_treeOn->isChecked()) { node = new QTreeWidgetItem(mtdNode, lastMtdNode); lastMtdNode = node; } else node = new QTreeWidgetItem(m_symbols); name = cl.mid(4); node->setToolTip(0, name); if (!m_typesOn->isChecked()) { name = name.left(name.indexOf(QLatin1Char('('))); } node->setText(0, name); node->setIcon(0, QIcon(mtd)); node->setText(1, QString::number( i, 10)); } } } } diff --git a/addons/symbolviewer/xslt_parser.cpp b/addons/symbolviewer/xslt_parser.cpp index fe621bf96..307b5f80f 100644 --- a/addons/symbolviewer/xslt_parser.cpp +++ b/addons/symbolviewer/xslt_parser.cpp @@ -1,158 +1,158 @@ /*************************************************************************** xslt_parser.cpp - description ------------------- begin : Mar 28 2007 author : 2007 jiri Tyr email : jiri.tyr@vslib.cz ***************************************************************************/ /*************************************************************************** * * * 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 "plugin_katesymbolviewer.h" void KatePluginSymbolViewerView::parseXsltSymbols(void) { if (!m_mainWindow->activeView()) return; m_macro->setText(i18n("Show Params")); m_struct->setText(i18n("Show Variables")); m_func->setText(i18n("Show Templates")); QString cl; // Current Line QString stripped; char comment = 0; char templ = 0; int i; QPixmap cls( ( const char** ) class_xpm ); QPixmap sct( ( const char** ) struct_xpm ); QPixmap mcr( ( const char** ) macro_xpm ); QPixmap cls_int( ( const char** ) class_int_xpm ); QTreeWidgetItem *node = nullptr; QTreeWidgetItem *mcrNode = nullptr, *sctNode = nullptr, *clsNode = nullptr; QTreeWidgetItem *lastMcrNode = nullptr, *lastSctNode = nullptr, *lastClsNode = nullptr; KTextEditor::Document *kv = m_mainWindow->activeView()->document(); //kdDebug(13000)<<"Lines counted :"<numLines()<isChecked()) { mcrNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Params") ) ); sctNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Variables") ) ); clsNode = new QTreeWidgetItem(m_symbols, QStringList( i18n("Templates") ) ); mcrNode->setIcon(0, QIcon(mcr)); sctNode->setIcon(0, QIcon(sct)); clsNode->setIcon(0, QIcon(cls)); if (m_expandOn->isChecked()) { m_symbols->expandItem(mcrNode); m_symbols->expandItem(sctNode); m_symbols->expandItem(clsNode); } lastMcrNode = mcrNode; lastSctNode = sctNode; lastClsNode = clsNode; m_symbols->setRootIsDecorated(1); } else { m_symbols->setRootIsDecorated(0); } for (i=0; ilines(); i++) { cl = kv->line(i); cl = cl.trimmed(); - if(cl.indexOf(QRegExp(QLatin1String(""))) >= 0) { comment = 0; continue; } + if(cl.indexOf(QRegularExpression(QLatin1String(""))) >= 0) { comment = 0; continue; } - if(cl.indexOf(QRegExp(QLatin1String("^"))) >= 0) { templ = 0; continue; } + if(cl.indexOf(QRegularExpression(QLatin1String("^"))) >= 0) { templ = 0; continue; } if (comment==1) { continue; } if (templ==1) { continue; } - if(cl.indexOf(QRegExp(QLatin1String("^isChecked()) + if(cl.indexOf(QRegularExpression(QLatin1String("^isChecked()) { - QString stripped = cl.remove(QRegExp(QLatin1String("^isChecked()) { node = new QTreeWidgetItem(mcrNode, lastMcrNode); lastMcrNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(mcr)); node->setText(1, QString::number( i, 10)); } - if(cl.indexOf(QRegExp(QLatin1String("^isChecked()) + if(cl.indexOf(QRegularExpression(QLatin1String("^isChecked()) { - QString stripped = cl.remove(QRegExp(QLatin1String("^isChecked()) { node = new QTreeWidgetItem(sctNode, lastSctNode); lastSctNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(sct)); node->setText(1, QString::number( i, 10)); } - if(cl.indexOf(QRegExp(QLatin1String("^isChecked()) { node = new QTreeWidgetItem(clsNode, lastClsNode); lastClsNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(cls_int)); node->setText(1, QString::number( i, 10)); } - if(cl.indexOf(QRegExp(QLatin1String("^isChecked()) { node = new QTreeWidgetItem(clsNode, lastClsNode); lastClsNode = node; } else node = new QTreeWidgetItem(m_symbols); node->setText(0, stripped); node->setIcon(0, QIcon(cls)); node->setText(1, QString::number( i, 10)); } - if(cl.indexOf(QRegExp(QLatin1String("= 0) + if(cl.indexOf(QRegularExpression(QLatin1String("= 0) { templ = 1; } } } diff --git a/addons/xmltools/pseudo_dtd.cpp b/addons/xmltools/pseudo_dtd.cpp index 9c9719844..cb04cd3ff 100644 --- a/addons/xmltools/pseudo_dtd.cpp +++ b/addons/xmltools/pseudo_dtd.cpp @@ -1,448 +1,448 @@ /*************************************************************************** pseudoDtd.cpp copyright : (C) 2001-2002 by Daniel Naber email : daniel.naber@t-online.de ***************************************************************************/ /*************************************************************************** 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ #include "pseudo_dtd.h" #include #include #include #include PseudoDTD::PseudoDTD() { // "SGML support" only means case-insensivity, because HTML is case-insensitive up to version 4: m_sgmlSupport = true; // TODO: make this an run-time option ( maybe automatically set ) } PseudoDTD::~PseudoDTD() { } void PseudoDTD::analyzeDTD(QString &metaDtdUrl, QString &metaDtd) { QDomDocument doc(QStringLiteral("dtdIn_xml")); if (! doc.setContent(metaDtd)) { KMessageBox::error(nullptr, i18n("The file '%1' could not be parsed. " "Please check that the file is well-formed XML.", metaDtdUrl), i18n("XML Plugin Error")); return; } if (doc.doctype().name() != QLatin1String("dtd")) { KMessageBox::error(nullptr, i18n("The file '%1' is not in the expected format. " "Please check that the file is of this type:\n" "-//Norman Walsh//DTD DTDParse V2.0//EN\n" "You can produce such files with dtdparse. " "See the Kate Plugin documentation for more information.", metaDtdUrl), i18n("XML Plugin Error")); return; } uint listLength = 0; listLength += doc.elementsByTagName(QStringLiteral("entity")).count(); listLength += doc.elementsByTagName(QStringLiteral("element")).count(); // count this twice, as it will be iterated twice ( TODO: optimize that? ): listLength += doc.elementsByTagName(QStringLiteral("attlist")).count() * 2; QProgressDialog progress(i18n("Analyzing meta DTD..."), i18n("Cancel"), 0, listLength); progress.setMinimumDuration(400); progress.setValue(0); // Get information from meta DTD and put it in Qt data structures for fast access: if (! parseEntities(&doc, &progress)) { return; } if (! parseElements(&doc, &progress)) { return; } if (! parseAttributes(&doc, &progress)) { return; } if (! parseAttributeValues(&doc, &progress)) { return; } progress.setValue(listLength); // just to make sure the dialog disappears } // ======================================================================== // DOM stuff: /** * Iterate through the XML to get a mapping which sub-elements are allowed for * all elements. */ bool PseudoDTD::parseElements(QDomDocument *doc, QProgressDialog *progress) { m_elementsList.clear(); // We only display a list, i.e. we pretend that the content model is just // a set, so we use a map. This is necessary e.g. for xhtml 1.0's head element, // which would otherwise display some elements twice. QMap subelementList; // the bool is not used QDomNodeList list = doc->elementsByTagName(QStringLiteral("element")); uint listLength = list.count(); // speedup (really! ) for (uint i = 0; i < listLength; i++) { if (progress->wasCanceled()) { return false; } progress->setValue(progress->value() + 1); // FIXME!: //qApp->processEvents(); subelementList.clear(); QDomNode node = list.item(i); QDomElement elem = node.toElement(); if (!elem.isNull()) { // Enter the expanded content model, which may also include stuff not allowed. // We do not care if it's a or whatever. QDomNodeList contentModelList = elem.elementsByTagName(QStringLiteral("content-model-expanded")); QDomNode contentModelNode = contentModelList.item(0); QDomElement contentModelElem = contentModelNode.toElement(); if (! contentModelElem.isNull()) { // check for : QDomNodeList pcdataList = contentModelElem.elementsByTagName(QStringLiteral("pcdata")); // check for other sub elements: QDomNodeList subList = contentModelElem.elementsByTagName(QStringLiteral("element-name")); uint subListLength = subList.count(); for (uint l = 0; l < subListLength; l++) { QDomNode subNode = subList.item(l); QDomElement subElem = subNode.toElement(); if (!subElem.isNull()) { subelementList[subElem.attribute(QStringLiteral("name"))] = true; } } // anders: check if this is an EMPTY element, and put "__EMPTY" in the // sub list, so that we can insert tags in empty form if required. QDomNodeList emptyList = elem.elementsByTagName(QStringLiteral("empty")); if (emptyList.count()) { subelementList[QStringLiteral("__EMPTY")] = true; } } // Now remove the elements not allowed (e.g. is explicitly not allowed in // in the HTML 4.01 Strict DTD): QDomNodeList exclusionsList = elem.elementsByTagName(QStringLiteral("exclusions")); if (exclusionsList.length() > 0) { // sometimes there are no exclusions ( e.g. in XML DTDs there are never exclusions ) QDomNode exclusionsNode = exclusionsList.item(0); QDomElement exclusionsElem = exclusionsNode.toElement(); if (! exclusionsElem.isNull()) { QDomNodeList subList = exclusionsElem.elementsByTagName(QStringLiteral("element-name")); uint subListLength = subList.count(); for (uint l = 0; l < subListLength; l++) { QDomNode subNode = subList.item(l); QDomElement subElem = subNode.toElement(); if (!subElem.isNull()) { QMap::Iterator it = subelementList.find(subElem.attribute(QStringLiteral("name"))); if (it != subelementList.end()) { subelementList.erase(it); } } } } } // turn the map into a list: QStringList subelementListTmp; QMap::Iterator it; for (it = subelementList.begin(); it != subelementList.end(); ++it) { subelementListTmp.append(it.key()); } m_elementsList.insert(elem.attribute(QStringLiteral("name")), subelementListTmp); } } // end iteration over all nodes return true; } /** * Check which elements are allowed inside a parent element. This returns * a list of allowed elements, but it doesn't care about order or if only a certain * number of occurrences is allowed. */ QStringList PseudoDTD::allowedElements(const QString &parentElement) { if (m_sgmlSupport) { // find the matching element, ignoring case: QMap::Iterator it; for (it = m_elementsList.begin(); it != m_elementsList.end(); ++it) { if (it.key().compare(parentElement, Qt::CaseInsensitive) == 0) { return it.value(); } } } else if (m_elementsList.contains(parentElement)) { return m_elementsList[parentElement]; } return QStringList(); } /** * Iterate through the XML to get a mapping which attributes are allowed inside * all elements. */ bool PseudoDTD::parseAttributes(QDomDocument *doc, QProgressDialog *progress) { m_attributesList.clear(); // QStringList allowedAttributes; QDomNodeList list = doc->elementsByTagName(QStringLiteral("attlist")); uint listLength = list.count(); for (uint i = 0; i < listLength; i++) { if (progress->wasCanceled()) { return false; } progress->setValue(progress->value() + 1); // FIXME!! //qApp->processEvents(); ElementAttributes attrs; QDomNode node = list.item(i); QDomElement elem = node.toElement(); if (!elem.isNull()) { QDomNodeList attributeList = elem.elementsByTagName(QStringLiteral("attribute")); uint attributeListLength = attributeList.count(); for (uint l = 0; l < attributeListLength; l++) { QDomNode attributeNode = attributeList.item(l); QDomElement attributeElem = attributeNode.toElement(); if (! attributeElem.isNull()) { if (attributeElem.attribute(QStringLiteral("type")) == QLatin1String("#REQUIRED")) { attrs.requiredAttributes.append(attributeElem.attribute(QStringLiteral("name"))); } else { attrs.optionalAttributes.append(attributeElem.attribute(QStringLiteral("name"))); } } } m_attributesList.insert(elem.attribute(QStringLiteral("name")), attrs); } } return true; } /** Check which attributes are allowed for an element. */ QStringList PseudoDTD::allowedAttributes(const QString &element) { if (m_sgmlSupport) { // find the matching element, ignoring case: QMap::Iterator it; for (it = m_attributesList.begin(); it != m_attributesList.end(); ++it) { if (it.key().compare(element, Qt::CaseInsensitive) == 0) { return it.value().optionalAttributes + it.value().requiredAttributes; } } } else if (m_attributesList.contains(element)) { return m_attributesList[element].optionalAttributes + m_attributesList[element].requiredAttributes; } return QStringList(); } QStringList PseudoDTD::requiredAttributes(const QString &element) const { if (m_sgmlSupport) { QMap::ConstIterator it; for (it = m_attributesList.begin(); it != m_attributesList.end(); ++it) { if (it.key().compare(element, Qt::CaseInsensitive) == 0) { return it.value().requiredAttributes; } } } else if (m_attributesList.contains(element)) { return m_attributesList[element].requiredAttributes; } return QStringList(); } /** * Iterate through the XML to get a mapping which attribute values are allowed * for all attributes inside all elements. */ bool PseudoDTD::parseAttributeValues(QDomDocument *doc, QProgressDialog *progress) { m_attributevaluesList.clear(); // 1 element : n possible attributes QMap attributevaluesTmp; // 1 attribute : n possible values QDomNodeList list = doc->elementsByTagName(QStringLiteral("attlist")); uint listLength = list.count(); for (uint i = 0; i < listLength; i++) { if (progress->wasCanceled()) { return false; } progress->setValue(progress->value() + 1); // FIXME! //qApp->processEvents(); attributevaluesTmp.clear(); QDomNode node = list.item(i); QDomElement elem = node.toElement(); if (!elem.isNull()) { // Enter the list of : QDomNodeList attributeList = elem.elementsByTagName(QStringLiteral("attribute")); uint attributeListLength = attributeList.count(); for (uint l = 0; l < attributeListLength; l++) { QDomNode attributeNode = attributeList.item(l); QDomElement attributeElem = attributeNode.toElement(); if (! attributeElem.isNull()) { QString value = attributeElem.attribute(QStringLiteral("value")); attributevaluesTmp.insert(attributeElem.attribute(QStringLiteral("name")), value.split(QChar(' '))); } } m_attributevaluesList.insert(elem.attribute(QStringLiteral("name")), attributevaluesTmp); } } return true; } /** * Check which attributes values are allowed for an attribute in an element * (the element is necessary because e.g. "href" inside could be different * to an "href" inside ): */ QStringList PseudoDTD::attributeValues(const QString &element, const QString &attribute) { // Direct access would be faster than iteration of course but not always correct, // because we need to be case-insensitive. if (m_sgmlSupport) { // first find the matching element, ignoring case: QMap< QString, QMap >::Iterator it; for (it = m_attributevaluesList.begin(); it != m_attributevaluesList.end(); ++it) { if (it.key().compare(element, Qt::CaseInsensitive) == 0) { QMap attrVals = it.value(); QMap::Iterator itV; // then find the matching attribute for that element, ignoring case: for (itV = attrVals.begin(); itV != attrVals.end(); ++itV) { if (itV.key().compare(attribute, Qt::CaseInsensitive) == 0) { return(itV.value()); } } } } } else if (m_attributevaluesList.contains(element)) { QMap attrVals = m_attributevaluesList[element]; if (attrVals.contains(attribute)) { return attrVals[attribute]; } } // no predefined values available: return QStringList(); } /** * Iterate through the XML to get a mapping of all entity names and their expanded * version, e.g. nbsp =>  . Parameter entities are ignored. */ bool PseudoDTD::parseEntities(QDomDocument *doc, QProgressDialog *progress) { m_entityList.clear(); QDomNodeList list = doc->elementsByTagName(QStringLiteral("entity")); uint listLength = list.count(); for (uint i = 0; i < listLength; i++) { if (progress->wasCanceled()) { return false; } progress->setValue(progress->value() + 1); //FIXME!! //qApp->processEvents(); QDomNode node = list.item(i); QDomElement elem = node.toElement(); if (!elem.isNull() && elem.attribute(QStringLiteral("type")) != QLatin1String("param")) { // TODO: what's cdata <-> gen ? QDomNodeList expandedList = elem.elementsByTagName(QStringLiteral("text-expanded")); QDomNode expandedNode = expandedList.item(0); QDomElement expandedElem = expandedNode.toElement(); if (! expandedElem.isNull()) { QString exp = expandedElem.text(); // TODO: support more than one &#...; in the expanded text /* TODO include do this when the unicode font problem is solved: - if( exp.contains(QRegExp("^&#x[a-zA-Z0-9]+;$")) ) { + if( exp.contains(QRegularExpression("^&#x[a-zA-Z0-9]+;$")) ) { // hexadecimal numbers, e.g. "ȶ" uint end = exp.find( ";" ); exp = exp.mid( 3, end-3 ); exp = QChar(); - } else if( exp.contains(QRegExp("^&#[0-9]+;$")) ) { + } else if( exp.contains(QRegularExpression("^&#[0-9]+;$")) ) { // decimal numbers, e.g. "ì" uint end = exp.find( ";" ); exp = exp.mid( 2, end-2 ); exp = QChar( exp.toInt() ); } */ m_entityList.insert(elem.attribute(QStringLiteral("name")), exp); } else { m_entityList.insert(elem.attribute(QStringLiteral("name")), QString()); } } } return true; } /** * Get a list of all ( non-parameter ) entities that start with a certain string. */ QStringList PseudoDTD::entities(const QString &start) { QStringList entities; QMap::Iterator it; for (it = m_entityList.begin(); it != m_entityList.end(); ++it) { if ((*it).startsWith(start)) { QString str = it.key(); /* TODO: show entities as unicode character if( !it.data().isEmpty() ) { //str += " -- " + it.data(); QRegExp re( "&#(\\d+);" ); if( re.search(it.data()) != -1 ) { uint ch = re.cap( 1).toUInt(); str += " -- " + QChar( ch).decomposition(); } //qDebug() << "#" << it.data(); } */ entities.append(str); // TODO: later use a table view } } return entities; } // kate: space-indent on; indent-width 4; replace-tabs on; mixed-indent off;