1/*
2 * This file is part of the KDE Help Center
3 *
4 * Copyright (C) 2002 Frerich Raabe (raabe@kde.org)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include "infotree.h"
22
23#include "navigatoritem.h"
24#include "docentry.h"
25
26#include <KApplication>
27#include <KConfig>
28#include <KConfigGroup>
29#include <KDebug>
30#include <KIconLoader>
31#include <KGlobal>
32
33#include <KLocale>
34#include <KStandardDirs>
35#include <KUrl>
36
37#include <QFile>
38#include <QTextStream>
39#include <QPixmap>
40
41#include <stdlib.h> // for getenv()
42
43using namespace KHC;
44
45class InfoCategoryItem : public NavigatorItem
46{
47 public:
48 InfoCategoryItem( NavigatorItem *parent, const QString &text );
49
50 virtual void setExpanded( bool open );
51};
52
53class InfoNodeItem : public NavigatorItem
54{
55 public:
56 InfoNodeItem( InfoCategoryItem *parent, const QString &text );
57};
58
59InfoCategoryItem::InfoCategoryItem( NavigatorItem *parent, const QString &text )
60 : NavigatorItem( new DocEntry( text ), parent )
61{
62 setAutoDeleteDocEntry( true );
63 setExpanded( false );
64// kDebug(1400) << "Got category: " << text;
65}
66
67void InfoCategoryItem::setExpanded( bool open )
68{
69 NavigatorItem::setExpanded( open );
70
71 if ( open && childCount() > 0 ) setIcon( 0, SmallIcon( "help-contents" ) );
72// TODO: was contents2 -> needs to be changed to help-contents-alternate or similar
73 else setIcon( 0, SmallIcon( "help-contents" ) );
74}
75
76InfoNodeItem::InfoNodeItem( InfoCategoryItem *parent, const QString &text )
77 : NavigatorItem( new DocEntry( text ), parent )
78{
79 setAutoDeleteDocEntry( true );
80// kDebug( 1400 ) << "Created info node item: " << text;
81}
82
83InfoTree::InfoTree( QObject *parent )
84 : TreeBuilder( parent ),
85 m_parentItem( 0 )
86{
87}
88
89void InfoTree::build( NavigatorItem *parent )
90{
91 kDebug( 1400 ) << "Populating info tree.";
92
93 m_parentItem = parent;
94
95 DocEntry *entry = new DocEntry( i18n( "Alphabetically" ) );
96 m_alphabItem = new NavigatorItem( entry, parent );
97 m_alphabItem->setAutoDeleteDocEntry( true );
98 entry = new DocEntry( i18n( "By Category" ) );
99 m_categoryItem = new NavigatorItem( entry, parent );
100 m_categoryItem->setAutoDeleteDocEntry( true );
101
102 KConfigGroup cfg(KGlobal::config(), "Info pages");
103 QStringList infoDirFiles = cfg.readEntry( "Search paths" , QStringList() );
104 // Default paths taken fron kdebase/kioslave/info/kde-info2html.conf
105 if ( infoDirFiles.isEmpty() ) {
106 infoDirFiles << "/usr/share/info";
107 infoDirFiles << "/usr/info";
108 infoDirFiles << "/usr/lib/info";
109 infoDirFiles << "/usr/local/info";
110 infoDirFiles << "/usr/local/lib/info";
111 infoDirFiles << "/usr/X11R6/info";
112 infoDirFiles << "/usr/X11R6/lib/info";
113 infoDirFiles << "/usr/X11R6/lib/xemacs/info";
114 }
115
116 QString infoPath = ::getenv( "INFOPATH" );
117 if ( !infoPath.isEmpty() )
118 infoDirFiles += infoPath.split( ':');
119
120 QStringList::ConstIterator it = infoDirFiles.constBegin();
121 QStringList::ConstIterator end = infoDirFiles.constEnd();
122 for ( ; it != end; ++it ) {
123 QString infoDirFileName = *it + "/dir";
124 if ( QFile::exists( infoDirFileName ) )
125 parseInfoDirFile( infoDirFileName );
126 }
127
128 m_alphabItem->sortChildren( 0, Qt::AscendingOrder /* ascending */ );
129}
130
131void InfoTree::parseInfoDirFile( const QString &infoDirFileName )
132{
133 kDebug( 1400 ) << "Parsing info dir file " << infoDirFileName;
134
135 QFile infoDirFile( infoDirFileName );
136 if ( !infoDirFile.open( QIODevice::ReadOnly ) )
137 return;
138
139 QTextStream stream( &infoDirFile );
140 // Skip introduction blurb.
141 while ( !stream.atEnd() && !stream.readLine().startsWith( QLatin1String("* Menu:") ) ) {
142 ;
143 }
144
145 while ( !stream.atEnd() ) {
146 QString s = stream.readLine();
147 if ( s.trimmed().isEmpty() )
148 continue;
149
150 InfoCategoryItem *catItem = new InfoCategoryItem( m_categoryItem, s );
151 while ( !stream.atEnd() && !s.trimmed().isEmpty() ) {
152 s = stream.readLine();
153 if ( s[ 0 ] == '*' ) {
154 const int colon = s.indexOf( ":" );
155 const int openBrace = s.indexOf( "(", colon );
156 const int closeBrace = s.indexOf( ")", openBrace );
157 const int dot = s.indexOf( ".", closeBrace );
158
159 QString appName = s.mid( 2, colon - 2 );
160 QString url = "info:/" + s.mid( openBrace + 1, closeBrace - openBrace - 1 );
161 if ( dot - closeBrace > 1 )
162 url += QLatin1Char('/') + s.mid( closeBrace + 1, dot - closeBrace - 1 );
163 else
164 url += QLatin1String("/Top");
165
166 InfoNodeItem *item = new InfoNodeItem( catItem, appName );
167 item->entry()->setUrl( url );
168
169 InfoCategoryItem *alphabSection = 0;
170
171 QTreeWidgetItemIterator it( m_alphabItem );
172 while ( (*it) )
173 {
174 if ( (*it)->text( 0 ) == QString( appName[ 0 ].toUpper() ) )
175 {
176 alphabSection = static_cast<InfoCategoryItem *>( (*it) );
177 break;
178 }
179 ++it;
180 }
181
182 if ( alphabSection == 0 )
183 alphabSection = new InfoCategoryItem( m_alphabItem, QString( appName[ 0 ].toUpper() ) );
184
185 item = new InfoNodeItem( alphabSection, appName );
186 item->entry()->setUrl( url );
187 }
188 }
189 }
190 infoDirFile.close();
191}
192
193#include "infotree.moc"
194// vim:ts=2:sw=2:et
195