diff --git a/src/mode/katemodeconfigpage.cpp b/src/mode/katemodeconfigpage.cpp index 39a7f76c..4423ac2a 100644 --- a/src/mode/katemodeconfigpage.cpp +++ b/src/mode/katemodeconfigpage.cpp @@ -1,303 +1,305 @@ /* This file is part of the KDE libraries and the Kate part. * * Copyright (C) 2001-2010 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. */ //BEGIN Includes #include "katemodeconfigpage.h" #include "katedocument.h" #include "kateconfig.h" #include "kateview.h" #include "kateglobal.h" #include "kateautoindent.h" #include "katesyntaxmanager.h" #include "ui_filetypeconfigwidget.h" #include #include "katepartdebug.h" #include #include #include #include #include #include #include #include #include //END Includes ModeConfigPage::ModeConfigPage(QWidget *parent) : KateConfigPage(parent) { m_lastType = -1; // This will let us have more separation between this page and // the QTabWidget edge (ereslibre) QVBoxLayout *layout = new QVBoxLayout; QWidget *newWidget = new QWidget(this); ui = new Ui::FileTypeConfigWidget(); ui->setupUi(newWidget); ui->cmbHl->addItem(i18n(""), QVariant(QString())); for (const auto &hl : KateHlManager::self()->modeList()) { if (hl.section().length() > 0) ui->cmbHl->addItem(hl.section() + QLatin1Char('/') + hl.translatedName(), QVariant(hl.name())); else { ui->cmbHl->addItem(hl.translatedName(), QVariant(hl.name())); } } QStringList indentationModes; indentationModes << i18n("Use Default"); indentationModes << KateAutoIndent::listModes(); ui->cmbIndenter->addItems(indentationModes); connect(ui->cmbFiletypes, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); connect(ui->btnNew, SIGNAL(clicked()), this, SLOT(newType())); connect(ui->btnDelete, SIGNAL(clicked()), this, SLOT(deleteType())); ui->btnMimeTypes->setIcon(QIcon::fromTheme(QStringLiteral("tools-wizard"))); connect(ui->btnMimeTypes, SIGNAL(clicked()), this, SLOT(showMTDlg())); reload(); connect(ui->edtName, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); connect(ui->edtSection, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); connect(ui->edtVariables, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); connect(ui->edtFileExtensions, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); connect(ui->edtMimeTypes, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); connect(ui->sbPriority, SIGNAL(valueChanged(int)), this, SLOT(slotChanged())); connect(ui->cmbHl, SIGNAL(activated(int)), this, SLOT(slotChanged())); connect(ui->cmbIndenter, SIGNAL(activated(int)), this, SLOT(slotChanged())); // make the context help a bit easier to access ui->sbPriority->setToolTip(ui->sbPriority->whatsThis()); layout->addWidget(newWidget); setLayout(layout); } ModeConfigPage::~ModeConfigPage() { qDeleteAll(m_types); delete ui; } void ModeConfigPage::apply() { if (!hasChanged()) { return; } save(); KTextEditor::EditorPrivate::self()->modeManager()->save(m_types); } void ModeConfigPage::reload() { qDeleteAll(m_types); m_types.clear(); // deep copy... - foreach (KateFileType *type, KTextEditor::EditorPrivate::self()->modeManager()->list()) { + const QList &modeList = KTextEditor::EditorPrivate::self()->modeManager()->list(); + m_types.reserve(modeList.size()); + for (KateFileType *type : modeList) { KateFileType *t = new KateFileType(); *t = *type; m_types.append(t); } update(); } void ModeConfigPage::reset() { reload(); } void ModeConfigPage::defaults() { reload(); } void ModeConfigPage::update() { m_lastType = -1; ui->cmbFiletypes->clear(); - foreach (KateFileType *type, m_types) { + for (KateFileType *type : qAsConst(m_types)) { if (!type->sectionTranslated().isEmpty()) { ui->cmbFiletypes->addItem(type->sectionTranslated() + QLatin1Char('/') + type->nameTranslated()); } else { ui->cmbFiletypes->addItem(type->nameTranslated()); } } // get current filetype from active view via the host application int currentIndex = 0; KTextEditor::ViewPrivate *kv = qobject_cast(KTextEditor::EditorPrivate::self()->application()->activeMainWindow()->activeView()); if (kv) { const QString filetypeName = kv->doc()->fileType(); for (int i = 0; i < m_types.size(); ++i) { if (filetypeName == m_types[i]->name) { currentIndex = i; break; } } } ui->cmbFiletypes->setCurrentIndex(currentIndex); typeChanged(currentIndex); ui->cmbFiletypes->setEnabled(ui->cmbFiletypes->count() > 0); } void ModeConfigPage::deleteType() { int type = ui->cmbFiletypes->currentIndex(); if (type > -1 && type < m_types.count()) { delete m_types[type]; m_types.removeAt(type); update(); } } void ModeConfigPage::newType() { QString newN = i18n("New Filetype"); for (int i = 0; i < m_types.count(); ++i) { KateFileType *type = m_types.at(i); if (type->name == newN) { ui->cmbFiletypes->setCurrentIndex(i); typeChanged(i); return; } } KateFileType *newT = new KateFileType(); newT->priority = 0; newT->name = newN; newT->hlGenerated = false; m_types.prepend(newT); update(); } void ModeConfigPage::save() { if (m_lastType != -1) { if (!m_types[m_lastType]->hlGenerated) { m_types[m_lastType]->name = ui->edtName->text(); m_types[m_lastType]->section = ui->edtSection->text(); } m_types[m_lastType]->varLine = ui->edtVariables->text(); m_types[m_lastType]->wildcards = ui->edtFileExtensions->text().split(QLatin1Char(';'), QString::SkipEmptyParts); m_types[m_lastType]->mimetypes = ui->edtMimeTypes->text().split(QLatin1Char(';'), QString::SkipEmptyParts); m_types[m_lastType]->priority = ui->sbPriority->value(); m_types[m_lastType]->hl = ui->cmbHl->itemData(ui->cmbHl->currentIndex()).toString(); if (ui->cmbIndenter->currentIndex() > 0) { m_types[m_lastType]->indenter = KateAutoIndent::modeName(ui->cmbIndenter->currentIndex() - 1); } else { m_types[m_lastType]->indenter = QString(); } } } void ModeConfigPage::typeChanged(int type) { save(); ui->cmbHl->setEnabled(true); ui->btnDelete->setEnabled(true); ui->edtName->setEnabled(true); ui->edtSection->setEnabled(true); if (type > -1 && type < m_types.count()) { KateFileType *t = m_types.at(type); ui->gbProperties->setTitle(i18n("Properties of %1", ui->cmbFiletypes->currentText())); ui->gbProperties->setEnabled(true); ui->btnDelete->setEnabled(true); ui->edtName->setText(t->nameTranslated()); ui->edtSection->setText(t->sectionTranslated()); ui->edtVariables->setText(t->varLine); ui->edtFileExtensions->setText(t->wildcards.join(QLatin1Char(';'))); ui->edtMimeTypes->setText(t->mimetypes.join(QLatin1Char(';'))); ui->sbPriority->setValue(t->priority); ui->cmbHl->setEnabled(!t->hlGenerated); ui->btnDelete->setEnabled(!t->hlGenerated); ui->edtName->setEnabled(!t->hlGenerated); ui->edtSection->setEnabled(!t->hlGenerated); // activate current hl... for (int i = 0; i < ui->cmbHl->count(); ++i) if (ui->cmbHl->itemData(i).toString() == t->hl) { ui->cmbHl->setCurrentIndex(i); } // activate the right indenter int indenterIndex = 0; if (!t->indenter.isEmpty()) { indenterIndex = KateAutoIndent::modeNumber(t->indenter) + 1; } ui->cmbIndenter->setCurrentIndex(indenterIndex); } else { ui->gbProperties->setTitle(i18n("Properties")); ui->gbProperties->setEnabled(false); ui->btnDelete->setEnabled(false); ui->edtName->clear(); ui->edtSection->clear(); ui->edtVariables->clear(); ui->edtFileExtensions->clear(); ui->edtMimeTypes->clear(); ui->sbPriority->setValue(0); ui->cmbHl->setCurrentIndex(0); ui->cmbIndenter->setCurrentIndex(0); } m_lastType = type; } void ModeConfigPage::showMTDlg() { QString text = i18n("Select the MimeTypes you want for this file type.\nPlease note that this will automatically edit the associated file extensions as well."); QStringList list = ui->edtMimeTypes->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts); KMimeTypeChooserDialog d(i18n("Select Mime Types"), text, list, QStringLiteral("text"), this); if (d.exec() == QDialog::Accepted) { // do some checking, warn user if mime types or patterns are removed. // if the lists are empty, and the fields not, warn. ui->edtFileExtensions->setText(d.chooser()->patterns().join(QLatin1Char(';'))); ui->edtMimeTypes->setText(d.chooser()->mimeTypes().join(QLatin1Char(';'))); } } QString ModeConfigPage::name() const { return i18n("Modes && Filetypes"); } diff --git a/src/mode/katemodemanager.cpp b/src/mode/katemodemanager.cpp index bde984d6..c4ced547 100644 --- a/src/mode/katemodemanager.cpp +++ b/src/mode/katemodemanager.cpp @@ -1,307 +1,308 @@ /* This file is part of the KDE libraries and the Kate part. * * Copyright (C) 2001-2010 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. */ //BEGIN Includes #include "katemodemanager.h" #include "katewildcardmatcher.h" #include "katedocument.h" #include "kateconfig.h" #include "kateview.h" #include "kateglobal.h" #include "katesyntaxmanager.h" #include "katepartdebug.h" #include #include //END Includes static QStringList vectorToList(const QVector &v) { QStringList l; l.reserve(v.size()); std::copy(v.begin(), v.end(), std::back_inserter(l)); return l; } KateModeManager::KateModeManager() { update(); } KateModeManager::~KateModeManager() { qDeleteAll(m_types); } bool compareKateFileType(const KateFileType *const left, const KateFileType *const right) { int comparison = left->translatedSection.compare(right->translatedSection, Qt::CaseInsensitive); if (comparison == 0) { comparison = left->translatedName.compare(right->translatedName, Qt::CaseInsensitive); } return comparison < 0; } // // read the types from config file and update the internal list // void KateModeManager::update() { KConfig config(QStringLiteral("katemoderc"), KConfig::NoGlobals); QStringList g(config.groupList()); qDeleteAll(m_types); m_types.clear(); m_name2Type.clear(); for (int z = 0; z < g.count(); z++) { KConfigGroup cg(&config, g[z]); KateFileType *type = new KateFileType(); type->number = z; type->name = g[z]; type->section = cg.readEntry(QStringLiteral("Section")); type->wildcards = cg.readXdgListEntry(QStringLiteral("Wildcards")); type->mimetypes = cg.readXdgListEntry(QStringLiteral("Mimetypes")); type->priority = cg.readEntry(QStringLiteral("Priority"), 0); type->varLine = cg.readEntry(QStringLiteral("Variables")); type->indenter = cg.readEntry(QStringLiteral("Indenter")); type->hl = cg.readEntry(QStringLiteral("Highlighting")); // only for generated types... type->hlGenerated = cg.readEntry(QStringLiteral("Highlighting Generated"), false); type->version = cg.readEntry(QStringLiteral("Highlighting Version")); // insert into the list + hash... m_types.append(type); m_name2Type.insert(type->name, type); } // try if the hl stuff is up to date... const auto modes = KateHlManager::self()->modeList(); for (int i = 0; i < modes.size(); ++i) { // filter out hidden languages; and // filter out "None" hl, we add that later as "normal" mode if (modes[i].isHidden() || modes[i].name() == QLatin1String("None")) { continue; } KateFileType *type = nullptr; bool newType = false; if (m_name2Type.contains(modes[i].name())) { type = m_name2Type[modes[i].name()]; } else { newType = true; type = new KateFileType(); type->name = modes[i].name(); type->priority = 0; m_types.append(type); m_name2Type.insert(type->name, type); } if (newType || type->version != QString::number(modes[i].version())) { type->name = modes[i].name(); type->section = modes[i].section(); type->wildcards = vectorToList(modes[i].extensions()); type->mimetypes = vectorToList(modes[i].mimeTypes()); type->priority = modes[i].priority(); type->version = QString::number(modes[i].version()); type->indenter = modes[i].indenter(); type->hl = modes[i].name(); type->hlGenerated = true; } type->translatedName = modes[i].translatedName(); type->translatedSection = modes[i].translatedSection(); } // sort the list... std::sort(m_types.begin(), m_types.end(), compareKateFileType); // add the none type... KateFileType *t = new KateFileType(); // marked by hlGenerated t->name = QStringLiteral("Normal"); t->translatedName = i18n("Normal"); t->hl = QStringLiteral("None"); t->hlGenerated = true; m_types.prepend(t); } // // save the given list to config file + update // void KateModeManager::save(const QList &v) { KConfig katerc(QStringLiteral("katemoderc"), KConfig::NoGlobals); QStringList newg; - foreach (const KateFileType *type, v) { + newg.reserve(v.size()); + for (const KateFileType *type : v) { KConfigGroup config(&katerc, type->name); config.writeEntry("Section", type->section); config.writeXdgListEntry("Wildcards", type->wildcards); config.writeXdgListEntry("Mimetypes", type->mimetypes); config.writeEntry("Priority", type->priority); config.writeEntry("Indenter", type->indenter); QString varLine = type->varLine; if (!varLine.contains(QLatin1String("kate:"))) { varLine.prepend(QLatin1String("kate: ")); } config.writeEntry("Variables", varLine); config.writeEntry("Highlighting", type->hl); // only for generated types... config.writeEntry("Highlighting Generated", type->hlGenerated); config.writeEntry("Highlighting Version", type->version); newg << type->name; } const auto groupNames = katerc.groupList(); for (const QString &groupName : groupNames) { if (newg.indexOf(groupName) == -1) { katerc.deleteGroup(groupName); } } katerc.sync(); update(); } QString KateModeManager::fileType(KTextEditor::DocumentPrivate *doc, const QString &fileToReadFrom) { if (!doc) { return QString(); } if (m_types.isEmpty()) { return QString(); } QString fileName = doc->url().toString(); int length = doc->url().toString().length(); QString result; // Try wildcards if (! fileName.isEmpty()) { static const QLatin1String commonSuffixes[] = { QLatin1String(".orig"), QLatin1String(".new"), QLatin1String("~"), QLatin1String(".bak"), QLatin1String(".BAK"), }; if (!(result = wildcardsFind(fileName)).isEmpty()) { return result; } QString backupSuffix = KateDocumentConfig::global()->backupSuffix(); if (fileName.endsWith(backupSuffix)) { if (!(result = wildcardsFind(fileName.left(length - backupSuffix.length()))).isEmpty()) { return result; } } for (auto& commonSuffix : commonSuffixes) { if (commonSuffix != backupSuffix && fileName.endsWith(commonSuffix)) { if (!(result = wildcardsFind(fileName.left(length - commonSuffix.size()))).isEmpty()) { return result; } } } } // either read the file passed to this function (pre-load) or use the normal mimeType() KF KTextEditor API QString mtName; if (!fileToReadFrom.isEmpty()) { mtName = QMimeDatabase().mimeTypeForFile(fileToReadFrom).name(); } else { mtName = doc->mimeType(); } QList types; - foreach (KateFileType *type, m_types) { + for (KateFileType *type : qAsConst(m_types)) { if (type->mimetypes.indexOf(mtName) > -1) { types.append(type); } } if (!types.isEmpty()) { int pri = -1; QString name; for (KateFileType *type : qAsConst(types)) { if (type->priority > pri) { pri = type->priority; name = type->name; } } return name; } return QString(); } QString KateModeManager::wildcardsFind(const QString &fileName) { KateFileType *match = nullptr; int minPrio = -1; - foreach (KateFileType *type, m_types) { + for (KateFileType *type : qAsConst(m_types)) { if (type->priority <= minPrio) { continue; } - foreach (const QString &wildcard, type->wildcards) { + for (const QString &wildcard : qAsConst(type->wildcards)) { if (KateWildcardMatcher::exactMatch(fileName, wildcard)) { match = type; minPrio = type->priority; break; } } } return (match == nullptr) ? QString() : match->name; } const KateFileType &KateModeManager::fileType(const QString &name) const { for (int i = 0; i < m_types.size(); ++i) if (m_types[i]->name == name) { return *m_types[i]; } static KateFileType notype; return notype; }