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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
|
Design for a possible reimplementation of the KDE help center
=============================================================
Preludium
---------
This document presents an alternative design for a 'help center' applicaiton
in KDE. Lines which start with a # are supposed to be thoughts I had while
writing this, much like the stuff you write on the side of a page when reading
a book.
Lines starting with ## were added by my as further comments - Cornelius
And I'll have the ### lines - Lauri
General
-------
- main() instantiates a KHC::Application
- KHC::Application() deals with parsing the commandline parameters and
instantiates a KHC::MainWindow
- KHC::MainWindow creates the main UI, setting up actions, using a QSplitter
as it's mainwidget to separate a KHC::Navigator at the left from a KHC::View
at the right
That's the simple part. ;-)
## Apparently already done ;-)
KHC::Navigator
--------------
KHC::Navigator inherits QTabWidget and provides, on two tabs, a
KHC::ContentsTab object and a KHC::SearchTab object.
## KHC::Navigator shouldn't inherit from QTabWidget. This limits flexibility.
## It can create a QTabWidget instance as aggregate just as well.
# I fear premature generalization ("We could need that bit of flexibility one
# day), aggregation adds a level of indirection through a pointer variable as
# well. I would prefer not making the system more complex as long as we cannot
# predict changes which justify doing so.
1.) KHC::ContentsTab provides the following entires:
- Welcome to KDE
- KDE user's manual
- KDE FAQ
- Contact information
- Supporting KDE
# Should we create an extra item for these five and put them in there?
# Something like "General KDE" or so? OTOH that makes them less visible, and
# these are really ought to be seen. - Frerich
## The items are ok, in principle, but we should have a look at the content of
## the documents they point at. This document could benefit from some attention.
### Yes, they would. Also, there are license issues with one of them.
### I'd personally like to do an entire rewrite of the User Manual,
### without GPL encumbrance and sans the content that hasn't changed since
### KDE 1.x days. The odds of me getting this done before KDE 3.1, slim to fair.
- Application manuals
- Tutorials
- UNIX man pages
- UNIX info pages
- Glossary
# Do we really need this "Tutorials" item at all? right now it holds only two
# items, perhaps we can get rid of it. - Frerich
## Yes, please.
### There should be a "General" area, where documentation that isn't
### attached directly to an application can go. Tutorials might not be
### the best name for it I agree, but there is now some further content to
### add (the DCOP tutorial, for example, or any of the numerous tutorials
### on the websites, documenting things that aren't in the handbooks.q
# Alright, after some talk on IRC this structure evolved:
#
# - Tasks - contains short, three to four paragraph documents about how to
# solve an everyday task, examples:
# Browsing the web
# Send and receive email
# How to view images
# Playing sound files
# Installing new KDE themes
# How to configure KDE fonts
# Getting in touch with KDE contributors
# Supporting the KDE team
#
# - Guides - slightly longer, Mini-HOWTO style guides (about three to four
# pages long, perhaps) which talk about tackling jobs which don't
# occur very often, examples:
### I don't know about limiting the length. Some of these topics can stand
### a much longer document, but one of the things that differentiates them
### from the references is that they are not specific to a single application,
### nor are they complete references in the manner of the "KDE User Guide"
### Specificaly, the dcop tutorial we have is about 15 pages already, but if
### the user is interested in the topic, that isn't over much, and it's full of
### examples
# How to debug KDE programs
# Sending useful KDE bug reports
# Extending KDE's service menus
# Taking advantage of KDE's DCOP facilities
# Creating panel applets
# Phrasing questions most effectively
#
# - References - references. :-)
# KDE API reference
# KDE application manuals
# Info pages
# Man pages
# FAQ
# User's manual
#
# - Glossary - same as always.
# - By topic
# - Alphabetically
#
# My primary argument for such a structure is that it resembles a
# task-oriented interface much more closely than the simple list of
# application manuals. Imagine a user new to KDE who has a fairly precise
# description of what he's trying to do in mind (think "I want to view an
# image file") but no idea what tool to use for the job. The current list of
# application manuals requires the user to browse all the manuals which seem
# relevant, searching for the information he seeks. A task-oriented list
# solves that issue.
# This effectively enables people new to KDE in less time to become productive
# (a task-oriented list isn't so useful for peoplew ho are familiar with KDE's
# applications, of course).
# Implementation-wise, we should perhaps stop using a KListView and use a
# KOffice-style component selection widget like koshell has at the left?
The first five items are generated by KHC::Navigator itself and are direct
links to KDE documentations. The work of generating each of the last four
items is (with one exception) delegated to four helper classes, which inherit a
'KHC::TreeBuilder' class which has the following interface:
class KHC::TreeBuilder
virtual void build( KListViewItem *parent ) = 0;
## What about the trees generated as children of the contents list view?
# Oops, that's a typo, what you mean is what I originally intented: a
# TreeBuilder should take a 'KListView' as it's parent, subclasses can then
# overload that method (such as the KHC::TOCBuilder which will want to provide
# a build( KListViewItem *parent ) method).
# This concept of using a TreeBuilder baseclass might make it possible to turn
# all the classes which use that interface into plugins. That way we could
# e.g. have a ScrollKeeper plugin. - Frerich
## What exactly do you mean by plugin? A shared library loaded at run time or
## the desktop file based insertion of documents into the help center?
# The former.
The classes which inherit this interface are:
- KHC::ManualTreeBuilder: responsible for generating the tree below the
"Application manuals" item
- KHC::TOCBuilder: responsible for generating a TOC tree below each of the
manual trees items, so that you can choose Application
Manuals->Editors->KWrite->Using KWrite->Menu bar transparently. This is
the only builder which is not instantiated by KHC::ContentsTab but
instead instantiated by KHC::ManualTreeBuilder
- KHC::TutorialTreeBuilder: responsible for generating the tree below the
"Tutorials" item
- KHC::ManTreeBuilder: responsible for building the tree below the "UNIX
man pages" item
- KHC::InfoTreeBuilder: responsible for building the tree below the "UNIX
info pages" item
- KHC::GlossaryTreeBuilder: guess what
## - KHC::ScrollkeeperTreeBuilder
## It's certainly a good idea to move stuff like the info and man pages and
## scrollkeeper support to its own classes. What I consider as important is
## that the concept of representing the documentation by desktop meta files is
## used as far as possible. This makes the system very flexible and extandable.
2.) KHC::SearchTab provides a widget which lets the search through all
available help repositories, also defining some flags such as 'Search by
regexp' or 'Search case sensitive'.
# I think this means that we have to create a 'DataCollection' class which
# gets inherited by all classes which are "searchable". DataCollections should
# also be able to contains multiple child DataCollection, so that we have e.g.
# one DataCollection per application manual, and one "Manuals" collection
# which contains all the application manual collections.
# We'd probably also need a DataCollection for the info pages and man pages.
# And later, in the far future, we might extent this concept to web searches,
# so that e.g. Google represents a DataCollection which we can query.
# I'm not yet decided how to do that properly, perhaps using multiple
# inheritance, so that each TOCBuilder is a DataCollection - naw, we'd rather
# have a "TableOfContents" class which contains a TOCBuilder, and is a
# datacollection? Hm, not sure.
# In any case DataCollections should some sort of plugins, so that we can add
# e.g. new web search interfaces lateron.
# - Frerich
## What you call a DataCollection is currently represented by the DocEntry
## objects. Each DocEntry object represents a document or a collection of
## documents. It has information about the name and description of the
## document, the location and how it can be searched.
##
## Currently this information is based on URLs or file names and is optimized
## to be used by scripts, e.g. CGI scripts. A little exception from this is
## the htdig support where just a keyword "SearchMethod=htdig" is put in the
## desktop file and the help center figures out how to perform that search by
## using a special class. This could be extended to cover other search methods
## like web searches or special search methods optimized for certain kind of
## documents.
# I just thought about it - isn't that a bit overkill for the web search
# stuff? I just thought about it - all we need to do is to copy the .desktop
# files (at least some of them, like the ones for google, yahoo and excite)
# from the enhanced browsing thing and treat those as plugin .desktop files.
# We could show them in a listview on the Search tab, each found search engine
# being represented by a checkable listview item. So, we just let the user
# enter a term, replace the \{@} placeholder in the URIs specified in the
# selected .desktop files with that term, send out a request via KIO and show
# the results in our KHTMLPart (after all KHC::View is a KHTMLPart already). A
# problem with this: How to display the multiple HTML pages returned by the
# selected search engines? Using a QSplitter to split multiple KHTMLParts?
# Hmm... just wondered... perhaps we can work around that by not showing the
# returned HTML data at all but rather use a XSLT script (that is, one XSLT
# script per web search) which transforms the returned search results into a
# common format - that way, we could also filter out duplicates and then
# transform that filtered output into a nice, uniform HTML page. How about
# that?
# I like this idea very much, I just thought it and noticed you wrote this
# down already. What I thought of was having a .desktop/.xslt file pair per
# search engine: each .desktop file holds at least the name of the engine (for
# the listview) and a search URI with a placeholder, just like in your scenario.
# In additionl there could be a X-KHelpCenter-XSLT key which defines which .xslt
# stylesheet to use for that particular search engine. We then query that search
# engine by replacing the placeholder in the URI with whatever the user entered
# and hand it to KIO. All the HTML returned by the various search engines gets
# then transformed into a custom, intermediate, XML dialect, using the XSLT
# stylesheets define in the .desktop files. Using that intermediate step we
# can nicely drop duplicate hits, for example, or create a list of hits in the
# sidebar (much like http://www.copernic.com does). After that, we can use
# another XSLT stylesheet to transform that cleaned XML tree into HTML which
# we then feed to our KHTMLView. Since we then have one unified output, we don't
# need to worry about having multiple KHTMLParts, and it's also nice because
# the user doesn't see which search engine returned which hit.
# A problem with this would be that we cannot tell how a particular search
# engine treats boolean expressions (e.g. some search engines use 'foo AND bar',
# others use '+foo +bar', a third variation is '"foo bar"'). We thus cannot
# replace the placeholder in the URI but first have to translate the syntax
# entered by the user into a syntax which is appropriate for each single news
# engine. Right now I don't know how we could do this with just a .desktop/.xslt
# pair. We could always use fullblown C++ plugins which hold code which is able
# to do that translation, but I would really prefer to stick with .desktop files
# now since they're much easier to create.
# Another thing which would speak in favor of C++ plugins: different search
# engines support different features (like, google can search more than just the
# web, and you can sometimes tell a search engine to list only results in a
# certain language, or with a certain encoding), so it would be nice if we could
# let the user access those features: through a dialog which has to be tailored
# to the possibilities of the respective search engine. I wonder whether we
# could have some sort of XML tree which defines how an UI should look like, and
# then let KHelpCenter create a dialog using that XML markup, but that idea is
# very vague right now.
# Hmm, I just tried it and the XSLT idea didn't really take off: the problem
# is that many HTML pages returned by Google, Yahoo & co. don't seem to be
# valid XML, which is why tools such as meinproc or xsltproc refuse to process
# themm. :-/
KHC::View
---------
KHC::View inherits KHTMLPart and does the actual job of showing some sort of
document. Most importantly, it has a slot which passes it a KURL pointing to a
document to show. KHC::View will invoke kio_help if necessary (if the URL's
protocol == "help") by itself and otherwise use the plain URL.
# TODO: Things I didn't really think about yet: the interface between the
# navigator and the view. I think this has to be a bidirectional association
# since the navigator can change the view (e.g. by clicking on a manual which
# shows it in the view), but the view can also change the navigator (think of
# clicking on a 'See also' link in the glossary which should also scroll to
# the corresponding entry in the navigator).
## That's a very important aspect. We should have one central place where all
## document requests are processed and the necessary actions (like updating
## the navigator, loading a new page, caching the search results, etc.) are
## done.
##
## The TreeBuilder might need some interface to tell, if a certain URL exist
## in their tree, to make it possible to select content entries which aren't
## created yet, because they are only created on demand (like the application
## manuals).
# Very good idea. Perhaps I think iterating over a list of TreeBuilder
# instances and doing something like 'if ((*it)->canHandle(url))
# (*it)->selectItem(url)' which checks whether a TreeBuilder provides an item
# which corresponds to an URL (hmm, this makes me think, TreeBuilder is a bad
# name. Perhaps just 'Tree'?) and selects it (using
# QListView::ensureItemVisible() or so) if requested. This probably implies.
# that a TreeBuilder needs an internal QMap<KURL, QListViewItem *>.
# Also, the whole search engine needs more thought, that DataCollection idea
# seems promising to me but I'm not yet decided on how to do it properly.
## See above. We already have something which isn't too bad, I think.
# I just thought about this a bit, I think KHC::MainWindow should act as the
# interface between KHC::Navigator and KHC::View.
## I would prefer to have an extra class which does no GUI stuff, but passes
## URL requests around, does the needed processing and stores data, if needed
## (e.g. caching search results).
# Agreed.
## One very important aspect of the help center is that it has to be fast. It's
## not acceptable to wait several seconds after clicking on the Help menu of an
## application. We should think about that. Perhaps we can do some tricks like
## showing the main window before creating the other widgets and processing data
## or something similar. We could also think about creating more stuff only on
## demand.
# My perception is that filling the Navigator's listview takes a significant
# amount of time, just like setting up the KHTML view (loading the stylesheet,
# showing the welcome page). We could easily do taht in the background - show
# the mainwindow, then tell the TreeBuilders to start populating (using a
# QTimer with a timeout of 0, for a snappy GUI). Since they're collapsed at
# the start, the users won't even notice (and we can "fake" that they're
# already populated by calling setExpandable(true) for all of them (or letting
# them do that themselves) at the start.
## Finally a crazy idea: Wouldn't it be cool, if we would make the manuals more
## interactive. So when you read about a certain menu or a certain dialog of an
## application you can click on a link in the manual and the menu or dialog gets
## opened in the real application, or some widgets get highlghted in the real
## application. Such a feature could also be used to create interactive
## tutorials, where you have a small helpcenter window and the application next
## to each other on the screen and you can go through the tutorial step by step
## and practice with the real application while reading the instructions.
## With the help of DCOP it shouldn't be too hard to implement such an
## interactive help system. Maybe it's even possible to do it in a general way
## in the libs, so that application authors don't have to think about that
## feature.
# Hmm, that's an interesting idea. That takes KHelpCenter way beyond what it's
# currently doing. I can imagine this: we introduce a virtual "dcop" protocol,
# so that e.g. <ulink url="dcop:/kfortune/KFortuneIface/nextFortune"/>
# represents the DCOP call 'dcop kfortune KFortuneIface nextfortune'.
# KHelpCenter catches that protocol (oh dear, a lot of special cases with
# gloss, info etc. already - guess another one won't hurt). That looks like a
# good way for encapsulating DCOP calls.
# Now, the problem is - the application has to provide a dedicated
# "documentation" DCOP interface for this, with lots of calls for highlighting
# the various widgets (hm, this probably means taht we can skip the first two
# parts in our 'dcop' URL syntax, the application is known anyway, and the
# interface is hardcoded in KHelpCenter).
# So, what could happen is this: We have a piece of HTML in the documentation
# for our SuperApp application which goes like 'The
# <a href="dcop:highlightConnectButton">button labelled Connect</a> makes
# SuperApp establish a connection.' - the user clicks on that link,
# KHelpCenter catches a dcop: URL, checks whether SuperApp has already been
# started. If not, it starts a SuperApp process and does the dcop call 'dcop
# SuperApp DocIface highlightConnectButton' and SuperApp starts highlighting
# that connect button. The thing is that this requires a lot of work on the
# application side. The idea is very cool, but we'd have to think about
# outsourceing parts of that functionality, either to KHelpCenter, or to
# tdelibs.
## And another idea: The WhatsThis help texts describe all widgets of an
## application (provided that the texts are set by the developers). Currently
## they aren't accessible very easily. You have to go to a special mode and
## can then click on one widget after another to get the help, if there is one.
## There is no visual indication which widgets have help and which not. But the
## application knows about the WhatsThis helps. Perhaps it's possible to use
## the Qt object inspection stuff to extract all the texts and put them on an
## automatically generated screenshot of the corresponding dialog and put this
## graphic into the docs. Maybe it's even possible to do this at run-time and
## decorate dialogs with all WhatsThis helps at once, if the user triggers this
## mode.
# Hmm yes, that should be possible. Take the toplevel widget, use
# QObject::children() and iterate over all children, use QToolTip::textFor() to
# check whether the given qwidget has a tooltip and if so, use QToolTip::tip()
# to show the tooltip.
# One could probably add a standard dcop call to KMainWindow, like
# "showAllToolTips". KSnapShot could get a QCheckBox "Show all tooltips", and
# if that box is checked it tells the selected window to show all it's
# tooltips via that DCOP call right before it does the snapshot. The thing is
# - is it possible to map the WinID of the window the user clicked on to
# the process name we should send your DCOP call to?
## One thing we should also keep in mind is that it might be useful to provide
## the help center as a component. FOr example KDevelop has a very similar
## thing. It would be much nicer, if it could reuse the KHelpcenter code. This
## would probbaly also mean to at a DoxygenTreeBuilder or something similar.
# That probably implies that instead of a QSplitter which holds the Navigator
# and the View, we'd have a KHC::MainWidget KPart which in turn aggregates the
# splitter. The DoxygenTreeBuilder sounds like a reason to make TreeBuilders
# real plugins, with dynamically loaded libraries, so that KDevelop or other
# "IDE"-like applications (perhaps a KOffice help system?) can have their
# customized tree builders.
Font Configuration
------------------
### Many bug reports on KHelpCenter not honouring KHTML font settings,
### which is odd, because the stylesheet is intentionally loose,
### specifying only "sans-serif" as the font face.
### Ideas to fix:
### Help pages already make heavy use of the cascading feature of CSS, we
### ought to be able to leverage that by writing to perhaps the
### kde-localized.css file or a copy of it in $KDEHOME. There is already
### code in KControl to create a user CSS stylesheet, and we probably only
### need to configure the size and the face for KHC.
### Or, fix whatever is the reason KHC doesn't follow the rules. It could
### be encoding related, the help pages specify utf-8 as the encoding, and
### previous incarnations of the KHTML settings allowed fonts set on a
### per-encoding basis (at which time, this was apparently working, the bug
### reports dropped off, and only returned post KDE 3.0
# FWIW I added a simple font configuration facility a while back, which should
# IMHO be sufficient for the vast majority of users.
// vim:tw=78
|