1 | /* |
2 | * This file is part of the KDE Help Center |
3 | * |
4 | * Copyright (C) 1999 Matthias Elter (me@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 "scrollkeepertreebuilder.h" |
22 | |
23 | #include "navigatoritem.h" |
24 | #include "docentry.h" |
25 | |
26 | #include <KApplication> |
27 | #include <KConfig> |
28 | #include <KDebug> |
29 | #include <KGlobal> |
30 | #include <KLocale> |
31 | #include <KProcess> |
32 | #include <KConfigGroup> |
33 | |
34 | #include <QtXml/QtXml> |
35 | #include <QFile> |
36 | #include <QRegExp> |
37 | |
38 | using namespace KHC; |
39 | |
40 | ScrollKeeperTreeBuilder::ScrollKeeperTreeBuilder( QObject *parent, const char *name ) |
41 | : QObject( parent ) |
42 | { |
43 | setObjectName( name ); |
44 | |
45 | loadConfig(); |
46 | } |
47 | |
48 | void ScrollKeeperTreeBuilder::loadConfig() |
49 | { |
50 | KConfigGroup configGroup( KGlobal::config(), "ScrollKeeper" ); |
51 | mShowEmptyDirs = configGroup.readEntry( "ShowEmptyDirs" , false); |
52 | } |
53 | |
54 | NavigatorItem *ScrollKeeperTreeBuilder::build( NavigatorItem *parent, |
55 | NavigatorItem *after ) |
56 | { |
57 | QString lang = KGlobal::locale()->language(); |
58 | |
59 | kDebug(1400) << "ScrollKeeper language: " << lang; |
60 | |
61 | KProcess proc; |
62 | proc << "scrollkeeper-get-content-list" ; |
63 | proc << lang; |
64 | |
65 | proc.setOutputChannelMode(KProcess::OnlyStdoutChannel); |
66 | proc.start(); |
67 | if ( !proc.waitForFinished() ) { |
68 | kDebug(1400) << "Could not execute scrollkeeper-get-content-list" ; |
69 | return 0; |
70 | } |
71 | mContentsList = proc.readAllStandardOutput().trimmed(); |
72 | |
73 | if (!QFile::exists(mContentsList)) { |
74 | kDebug(1400) << "Scrollkeeper contents file '" << mContentsList |
75 | << "' does not exist." << endl; |
76 | return 0; |
77 | } |
78 | |
79 | QDomDocument doc("ScrollKeeperContentsList" ); |
80 | QFile f(mContentsList); |
81 | if ( !f.open( QIODevice::ReadOnly ) ) |
82 | return 0; |
83 | if ( !doc.setContent( &f ) ) { |
84 | f.close(); |
85 | return 0; |
86 | } |
87 | f.close(); |
88 | |
89 | // Create top-level item |
90 | mItems.append(parent); |
91 | |
92 | QDomElement docElem = doc.documentElement(); |
93 | |
94 | NavigatorItem *result = 0; |
95 | |
96 | QDomNode n = docElem.firstChild(); |
97 | while( !n.isNull() ) { |
98 | QDomElement e = n.toElement(); |
99 | if( !e.isNull() ) { |
100 | if (e.tagName() == "sect" ) { |
101 | NavigatorItem *createdItem; |
102 | insertSection( parent, after, e, createdItem ); |
103 | if ( createdItem ) result = createdItem; |
104 | } |
105 | } |
106 | n = n.nextSibling(); |
107 | } |
108 | |
109 | return result; |
110 | } |
111 | |
112 | int ScrollKeeperTreeBuilder::insertSection( NavigatorItem *parent, |
113 | NavigatorItem *after, |
114 | const QDomNode §Node, |
115 | NavigatorItem *§Item ) |
116 | { |
117 | // TODO: was contents2 -> needs to be changed to help-contents-alternate or similar |
118 | DocEntry *entry = new DocEntry( "" , "" , "help-contents" ); |
119 | sectItem = new NavigatorItem( entry, parent, after ); |
120 | sectItem->setAutoDeleteDocEntry( true ); |
121 | mItems.append( sectItem ); |
122 | |
123 | int numDocs = 0; // Number of docs created in this section |
124 | |
125 | QDomNode n = sectNode.firstChild(); |
126 | while( !n.isNull() ) { |
127 | QDomElement e = n.toElement(); |
128 | if( !e.isNull() ) { |
129 | if ( e.tagName() == "title" ) { |
130 | entry->setName( e.text() ); |
131 | sectItem->updateItem(); |
132 | } else if (e.tagName() == "sect" ) { |
133 | NavigatorItem *created; |
134 | numDocs += insertSection( sectItem, 0, e, created ); |
135 | } else if (e.tagName() == "doc" ) { |
136 | insertDoc(sectItem,e); |
137 | ++numDocs; |
138 | } |
139 | } |
140 | n = n.nextSibling(); |
141 | } |
142 | |
143 | // Remove empty sections |
144 | if (!mShowEmptyDirs && numDocs == 0) { |
145 | delete sectItem; |
146 | sectItem = 0; |
147 | } |
148 | |
149 | return numDocs; |
150 | } |
151 | |
152 | void ScrollKeeperTreeBuilder::insertDoc( NavigatorItem *parent, |
153 | const QDomNode &docNode ) |
154 | { |
155 | DocEntry *entry = new DocEntry( "" , "" , "text-plain" ); |
156 | NavigatorItem *docItem = new NavigatorItem( entry, parent ); |
157 | docItem->setAutoDeleteDocEntry( true ); |
158 | mItems.append( docItem ); |
159 | |
160 | QString url; |
161 | |
162 | QDomNode n = docNode.firstChild(); |
163 | while( !n.isNull() ) { |
164 | QDomElement e = n.toElement(); |
165 | if( !e.isNull() ) { |
166 | if ( e.tagName() == "doctitle" ) { |
167 | entry->setName( e.text() ); |
168 | docItem->updateItem(); |
169 | } else if ( e.tagName() == "docsource" ) { |
170 | url.append( e.text() ); |
171 | } else if ( e.tagName() == "docformat" ) { |
172 | QString mimeType = e.text(); |
173 | if ( mimeType == "text/html" ) { |
174 | // Let the HTML part figure out how to get the doc |
175 | } else if ( mimeType == "application/xml" |
176 | || mimeType == "text/xml" /*deprecated name*/ ) { |
177 | if ( url.left( 5 ) == "file:" ) url = url.mid( 5 ); |
178 | url.prepend( "ghelp:" ); |
179 | #if 0 |
180 | url.replace( QRegExp( ".xml$" ), ".html" ); |
181 | #endif |
182 | } else if ( mimeType == "text/sgml" ) { |
183 | // GNOME docs use this type. We don't have a real viewer for this. |
184 | url.prepend( "file:" ); |
185 | } else if ( mimeType.left(5) == "text/" ) { |
186 | url.prepend( "file:" ); |
187 | } |
188 | } |
189 | } |
190 | n = n.nextSibling(); |
191 | } |
192 | |
193 | entry->setUrl( url ); |
194 | } |
195 | |
196 | #include "scrollkeepertreebuilder.moc" |
197 | // vim:sw=2:ts=2:et |
198 | |