You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
22 KiB
434 lines
22 KiB
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 $TDEHOME. 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
|