1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/*
SPDX-FileCopyrightText: 2002 Frerich Raabe <raabe@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "infotree.h"
#include "docentry.h"
#include "khc_debug.h"
#include "navigatoritem.h"
#include <KLocalizedString>
#include <QFile>
#include <QIcon>
#include <QTextStream>
#include <prefs.h>
using namespace KHC;
class InfoCategoryItem : public NavigatorItem
{
public:
InfoCategoryItem(NavigatorItem *parent, const QString &text);
void itemExpanded(bool open) override;
};
class InfoNodeItem : public NavigatorItem
{
public:
InfoNodeItem(InfoCategoryItem *parent, const QString &text);
};
InfoCategoryItem::InfoCategoryItem(NavigatorItem *parent, const QString &text)
: NavigatorItem(new DocEntry(text), parent)
{
setAutoDeleteDocEntry(true);
setExpanded(false);
setIcon(0, QIcon::fromTheme(QStringLiteral("help-contents")));
// qCDebug(KHC_LOG) << "Got category: " << text;
}
void InfoCategoryItem::itemExpanded(bool open)
{
NavigatorItem::itemExpanded(open);
if (open && childCount() > 0)
setIcon(0, QIcon::fromTheme(QStringLiteral("help-contents")));
// TODO: was contents2 -> needs to be changed to help-contents-alternate or similar
else
setIcon(0, QIcon::fromTheme(QStringLiteral("help-contents")));
}
InfoNodeItem::InfoNodeItem(InfoCategoryItem *parent, const QString &text)
: NavigatorItem(new DocEntry(text), parent)
{
setAutoDeleteDocEntry(true);
// qCDebug(KHC_LOG) << "Created info node item: " << text;
}
InfoTree::InfoTree(QObject *parent)
: TreeBuilder(parent)
, m_parentItem(nullptr)
{
}
void InfoTree::build(NavigatorItem *parent)
{
qCDebug(KHC_LOG) << "Populating info tree.";
m_parentItem = parent;
DocEntry *entry = new DocEntry(i18n("Alphabetically"));
m_alphabItem = new NavigatorItem(entry, parent);
m_alphabItem->setAutoDeleteDocEntry(true);
entry = new DocEntry(i18n("By Category"));
m_categoryItem = new NavigatorItem(entry, parent);
m_categoryItem->setAutoDeleteDocEntry(true);
QStringList infoDirFiles = Prefs::searchpaths();
const QString infoPath = QFile::decodeName(qgetenv("INFOPATH"));
if (!infoPath.isEmpty())
infoDirFiles += infoPath.split(QLatin1Char(':'));
QStringList::ConstIterator it = infoDirFiles.constBegin();
QStringList::ConstIterator end = infoDirFiles.constEnd();
for (; it != end; ++it) {
QString infoDirFileName = *it + QStringLiteral("/dir");
if (QFile::exists(infoDirFileName))
parseInfoDirFile(infoDirFileName);
}
m_alphabItem->sortChildren(0, Qt::AscendingOrder /* ascending */);
}
void InfoTree::parseInfoDirFile(const QString &infoDirFileName)
{
qCDebug(KHC_LOG) << "Parsing info dir file " << infoDirFileName;
QFile infoDirFile(infoDirFileName);
if (!infoDirFile.open(QIODevice::ReadOnly))
return;
QTextStream stream(&infoDirFile);
// Skip introduction blurb.
while (!stream.atEnd() && !stream.readLine().startsWith(QLatin1String("* Menu:"))) {
;
}
QHash<QChar, InfoCategoryItem *> alphabSections;
while (!stream.atEnd()) {
QString s = stream.readLine();
if (s.trimmed().isEmpty())
continue;
InfoCategoryItem *catItem = new InfoCategoryItem(m_categoryItem, s);
while (!stream.atEnd()) {
s = stream.readLine();
if (s.isEmpty())
break;
if (s.at(0) == QLatin1Char('*')) {
const int colon = s.indexOf(QLatin1Char(':'));
const int openBrace = s.indexOf(QLatin1Char('('), colon);
const int closeBrace = s.indexOf(QLatin1Char(')'), openBrace);
const int dot = s.indexOf(QLatin1Char('.'), closeBrace);
QString appName = s.mid(2, colon - 2);
QString url = QStringLiteral("info:/") + s.mid(openBrace + 1, closeBrace - openBrace - 1);
if (dot - closeBrace > 1)
url += QLatin1Char('/') + s.mid(closeBrace + 1, dot - closeBrace - 1);
else
url += QLatin1String("/Top");
InfoNodeItem *item = new InfoNodeItem(catItem, appName);
item->entry()->setUrl(url);
const QChar first = appName.at(0).toUpper();
InfoCategoryItem *alphabSection = alphabSections.value(first);
if (alphabSection == nullptr) {
alphabSection = new InfoCategoryItem(m_alphabItem, QString(first));
alphabSections.insert(first, alphabSection);
}
item = new InfoNodeItem(alphabSection, appName);
item->entry()->setUrl(url);
}
}
catItem->sortChildren(0, Qt::AscendingOrder);
}
infoDirFile.close();
for (InfoCategoryItem *item : std::as_const(alphabSections)) {
item->sortChildren(0, Qt::AscendingOrder);
}
m_alphabItem->sortChildren(0, Qt::AscendingOrder);
m_categoryItem->sortChildren(0, Qt::AscendingOrder);
}
#include "moc_infotree.cpp"
// vim:ts=2:sw=2:et
|