File indexing completed on 2025-01-26 04:50:46

0001 /*
0002     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "dommodel.h"
0008 
0009 #include <KItinerary/HtmlDocument>
0010 
0011 #include <KColorScheme>
0012 #include <KLocalizedString>
0013 
0014 DOMModel::DOMModel(QObject *parent)
0015     : QStandardItemModel(parent)
0016 {
0017 }
0018 
0019 DOMModel::~DOMModel() = default;
0020 
0021 void DOMModel::setDocument(KItinerary::HtmlDocument *doc)
0022 {
0023     m_highlightNodeSet.clear();
0024     clear();
0025     m_document = doc;
0026     if (!doc)
0027         return;
0028 
0029     addNode(nullptr, doc->root());
0030     setHorizontalHeaderLabels({i18n("Element"), i18n("Content")});
0031 }
0032 
0033 KItinerary::HtmlDocument * DOMModel::document() const
0034 {
0035     return m_document;
0036 }
0037 
0038 QVariant DOMModel::data(const QModelIndex &index, int role) const
0039 {
0040     if (role == Qt::BackgroundRole) {
0041         const auto elem = index.sibling(index.row(), 0).data(Qt::UserRole).value<KItinerary::HtmlElement>();
0042         if (std::find(m_highlightNodeSet.begin(), m_highlightNodeSet.end(), elem) != m_highlightNodeSet.end()) {
0043             return KColorScheme(QPalette::Normal).background(KColorScheme::PositiveBackground);
0044         }
0045     }
0046 
0047     return QStandardItemModel::data(index, role);
0048 }
0049 
0050 void DOMModel::setHighlightNodeSet(const QVariantList &nodeSet)
0051 {
0052     m_highlightNodeSet.clear();
0053     m_highlightNodeSet.reserve(nodeSet.size());
0054     std::transform(nodeSet.begin(), nodeSet.end(), std::back_inserter(m_highlightNodeSet), [](const QVariant &v) { return v.value<KItinerary::HtmlElement>(); });
0055 }
0056 
0057 void DOMModel::addNode(QStandardItem *parent, KItinerary::HtmlElement elem)
0058 {
0059     auto i1 = new QStandardItem;
0060     i1->setText(elem.name());
0061     i1->setData(QVariant::fromValue(elem), Qt::UserRole);
0062     i1->setFlags(i1->flags() & ~Qt::ItemIsEditable);
0063 
0064     if (elem.hasAttribute(QLatin1String("itemtype")) || elem.hasAttribute(QLatin1String("itemprop")) || elem.hasAttribute(QLatin1String("itemscope"))) {
0065         i1->setIcon(QIcon::fromTheme(QLatin1String("comment-symbolic")));
0066     } else if (elem.hasAttribute(QLatin1String("id")) || elem.hasAttribute(QLatin1String("class"))) {
0067         i1->setIcon(QIcon::fromTheme(QLatin1String("code-context")));
0068     }
0069 
0070     auto i2 = new QStandardItem;
0071     i2->setText(elem.content().left(200).replace(QLatin1Char('\n'), QLatin1Char(' ')));
0072     i2->setToolTip(elem.content());
0073     i2->setFlags(i2->flags() & ~Qt::ItemIsEditable);
0074 
0075     if (parent)
0076         parent->appendRow({i1, i2});
0077     else
0078         appendRow({i1, i2});
0079 
0080     for (auto child = elem.firstChild(); !child.isNull(); child = child.nextSibling())
0081         addNode(i1, child);
0082 }
0083 
0084 DOMFilterModel::DOMFilterModel(QObject *parent)
0085     : QSortFilterProxyModel(parent)
0086 {
0087 }
0088 
0089 DOMFilterModel::~DOMFilterModel() = default;
0090 
0091 bool DOMFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
0092 {
0093     for (int i = 0; i < sourceModel()->columnCount(source_parent); ++i) {
0094         const auto str = sourceModel()->data(sourceModel()->index(source_row, i, source_parent), Qt::DisplayRole).toString();
0095 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0096         if (filterRegExp().indexIn(str) >= 0) {
0097 #else
0098         if (str.contains(filterRegularExpression())) {
0099 #endif
0100             return true;
0101         }
0102     }
0103 
0104     return false;
0105 }