khelpcenter: dummy port, almost useless

This commit is contained in:
Ivailo Monev 2015-02-27 09:29:54 +00:00
parent be166bbeed
commit 1b596d748c
136 changed files with 15769 additions and 0 deletions

View file

@ -0,0 +1,61 @@
add_subdirectory( plugins )
add_subdirectory( searchhandlers )
add_subdirectory( tests )
########### next target ###############
set(khc_indexbuilder_SRCS khc_indexbuilder.cpp )
kde4_add_executable(khc_indexbuilder NOGUI ${khc_indexbuilder_SRCS})
target_link_libraries(khc_indexbuilder ${KDE4_KDECORE_LIBS} )
install(TARGETS khc_indexbuilder DESTINATION ${LIBEXEC_INSTALL_DIR})
########### next target ###############
set(khelpcenter_KDEINIT_SRCS
navigator.cpp
navigatoritem.cpp
navigatorappitem.cpp
view.cpp
searchwidget.cpp
searchengine.cpp
docmetainfo.cpp
docentrytraverser.cpp
formatter.cpp
glossary.cpp
toc.cpp
mainwindow.cpp
docentry.cpp
htmlsearch.cpp
history.cpp
application.cpp
treebuilder.cpp
infotree.cpp
kcmhelpcenter.cpp
htmlsearchconfig.cpp
fontdialog.cpp
plugintraverser.cpp
scrollkeepertreebuilder.cpp
searchhandler.cpp )
qt4_add_dbus_adaptor( khelpcenter_KDEINIT_SRCS org.kde.khelpcenter.kcmhelpcenter.xml kcmhelpcenter.h KCMHelpCenter )
kde4_add_kcfg_files(khelpcenter_KDEINIT_SRCS prefs.kcfgc )
kde4_add_app_icon(khelpcenter_KDEINIT_SRCS "${KDE4_INSTALL_DIR}/share/icons/oxygen/*/apps/help-browser.png")
kde4_add_kdeinit_executable( khelpcenter ${khelpcenter_KDEINIT_SRCS})
target_link_libraries(kdeinit_khelpcenter ${KDE4_KPARTS_LIBS} ${KDE4_KDEWEBKIT_LIBS} ${QT_QTXML_LIBRARY} ${KDE4_KCMUTILS_LIBS} )
install(TARGETS kdeinit_khelpcenter ${INSTALL_TARGETS_DEFAULT_ARGS} )
install(TARGETS khelpcenter ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install( PROGRAMS Help.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
install( FILES khelpcenter.kcfg DESTINATION ${KCFG_INSTALL_DIR} )
install( FILES khelpcenter.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install( FILES khelpcenterui.rc glossary.html.in table-of-contents.xslt glossary.xslt index.html.in DESTINATION ${DATA_INSTALL_DIR}/khelpcenter )
install( FILES org.kde.khelpcenter.kcmhelpcenter.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR})

339
khelpcenter/COPYING Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

433
khelpcenter/DESIGN Normal file
View file

@ -0,0 +1,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 K3ListView 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( K3ListViewItem *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 'K3ListView' as it's parent, subclasses can then
# overload that method (such as the KHC::TOCBuilder which will want to provide
# a build( K3ListViewItem *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
# kdelibs.
## 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

104
khelpcenter/Help.desktop Executable file
View file

@ -0,0 +1,104 @@
[Desktop Entry]
Exec=khelpcenter
Icon=help-browser
X-DocPath=khelpcenter/index.html
Type=Application
Terminal=false
Name=Help
Name[af]=Hulp
Name[ar]=مساعدة
Name[as]=
Name[ast]=Ayuda
Name[be]=Дапамога
Name[be@latin]=Dapamoha
Name[bg]=Помощ
Name[bn]=
Name[bn_IN]=
Name[br]=Skoazell
Name[bs]=Pomoć
Name[ca]=Ajuda
Name[ca@valencia]=Ajuda
Name[cs]=Nápověda
Name[csb]=Pòmòc
Name[cy]=Cymorth
Name[da]=Hjælp
Name[de]=Hilfe
Name[el]=Βοήθεια
Name[en_GB]=Help
Name[eo]=Helpo
Name[es]=Ayuda
Name[et]=Abi
Name[eu]=Laguntza
Name[fa]=کمک
Name[fi]=Ohjeet
Name[fr]=Aide
Name[fy]=Help
Name[ga]=Cabhair
Name[gl]=Axuda
Name[gu]=
Name[he]=עזרה
Name[hi]=
Name[hne]=
Name[hr]=Pomoć
Name[hsb]=Pomoc
Name[hu]=Súgó
Name[ia]=Adjuta
Name[id]=Bantuan
Name[is]=Hjálp
Name[it]=Aiuto
Name[ja]=
Name[ka]=
Name[kk]=Анықтама
Name[km]=
Name[kn]=
Name[ko]=
Name[ku]=Alîkarî
Name[lt]=Pagalba
Name[lv]=Palīdzība
Name[mai]=ि
Name[mk]=Помош
Name[ml]=
Name[mr]=
Name[ms]=Bantuan
Name[nb]=Hjelp
Name[nds]=Hülp
Name[ne]=
Name[nl]=Documentatie
Name[nn]=Hjelp
Name[oc]=Ajuda
Name[or]=
Name[pa]=
Name[pl]=Pomoc
Name[pt]=Ajuda
Name[pt_BR]=Ajuda
Name[ro]=Ajutor
Name[ru]=Справка
Name[se]=Veahkki
Name[si]=
Name[sk]=Pomocník
Name[sl]=Pomoč
Name[sr]=Помоћ
Name[sr@ijekavian]=Помоћ
Name[sr@ijekavianlatin]=Pomoć
Name[sr@latin]=Pomoć
Name[sv]=Hjälp
Name[ta]=ி
Name[te]=
Name[tg]=Роҳнамо
Name[th]=
Name[tr]=Yardım
Name[ug]=ياردەم
Name[uk]=Довідка
Name[uz]=Yordam
Name[uz@cyrillic]=Ёрдам
Name[vi]=Tr giúp
Name[wa]=Aidance
Name[xh]=Uncedo
Name[x-test]=xxHelpxx
Name[zh_CN]=
Name[zh_TW]=
Categories=Qt;KDE;Core;
OnlyShowIn=KDE;

4
khelpcenter/Messages.sh Normal file
View file

@ -0,0 +1,4 @@
#! /usr/bin/env bash
$EXTRACTRC `find . -name "*.kcfg" -o -name "*.rc"` >> rc.cpp || exit 11
$XGETTEXT *.cpp -o $podir/khelpcenter.pot
rm -f rc.cpp

14
khelpcenter/README.htdig Normal file
View file

@ -0,0 +1,14 @@
To make use of the full-text search function in khelpcenter,
you need ht://dig.
ht://dig is a HTML indexing and searching tool.
You can get it from http://www.htdig.org.
NOTE: If you install htdig from source, make sure
that you put the 'htsearch' as well as the 'htdig'
and 'htmerge' binaries into your PATH.
Per default, 'htsearch' goes to some cgi-bin
directory.

128
khelpcenter/README.metadata Normal file
View file

@ -0,0 +1,128 @@
KHelpCenter documentation meta data structure
=============================================
KHelpCenter uses meta data files which describe the documentation available in
the system. Each document is represented by a meta data file and shown as an
entry in the KHelpCenter navigation tree view. The meta data contains
information about title and short description of the document, the location of
the document and some more information like how to search the document and
translations of title and description. Document hierarchy is represented as
hierarchy of the meta data files. Directories are also described by a meta data
file which contains the same information as a document meta data file.
Format of the meta data files
-----------------------------
The meta files adhere to the Desktop Entry Standard
(http://www.freedesktop.org/Standards/desktop-entry-spec). Documentation
specific extensions are covered by an own namespace using the prefix "X-DOC-".
The following table describes all keys which are currently used by
KHelpCenter:
Key Value Description
Name string Title of document
Name[xx] string Translated title for language xx
Comment string Short description of document
Comment[xx] string Translated short description for
Language xx
Icon string Name of icon for document
X-DocPath URI Location of document. In addition to the
standard URI schemes like http: and file:
all schemes which are supported through
kioslaves can be used. In particular the
following non-standard URI schemes are
supported:
help: KDE manual identified by app name
ghelp: GNOME manual identified by app name
man: man page
info: info page
cgi: output of CGI script
X-DocPath[xx] URI Language specific location for
language xx
Lang langcode Language of document
X-DOC-Identifier string Unique identifier for document, if this
entry is not present the base name of the
file is used as identifier
X-DOC-Indexer command Command used for creating a search index
for the document.
The following symbols are replaced by the
corresponding values:
%f - Filename
X-DOC-IndexTestFile filename Name of file whose existence indicates
the existence of a usable search index
X-DOC-Search command Command used for searching, the output
of the command should be HTML which is
shown in KHelpCenter.
The following symbols in the command are
replaced by the corresponding values:
%k - Words to be searched for
%n - Maximum number of results
%m - Method for combining search words,
can be 'and' or 'or'
%l - Language of documents to be searched
%s - Scope of search. This is a list of
identifiers as given by the
X-DOC-Identifier entry or the bas
name of the desktop file if not
present.
X-DOC-SearchMethod string If this entry is 'htdig' htdig is used to
index and search the document. The
Indexer, IndexTestFile and Search entries
aren't required in this case.
X-DOC-SearchEnabledDefault bool If set to 'true' the document is searched
by default, if set to 'false' it is not.
This setting is overridden by user
selected search scopes.
X-DOC-Weight int A number indicating the position of the
document within the list of siblings. A
greater weight indicates that the document
is 'heavier', thus shown below 'lighter'
documents. The default weight is 0.
X-KDE-KHelpcenter string If this entry is set to one of the
following values a set of documents
generated by other means than desktop file
meta info is inserted at the place
specified by the desktop file:
'apps' manuals of applications
from the start menu
'scrollkeeper' scrollkeeper docs
'kinfocenter' kinfocenter docs
'kcontrol' kcontrol module docs
'konqueror' konqueror plugin docs
'kioslave' kioslave docs
'info' info pages
X-DOC-DocumentType string Type of document. The type is used to look
up corresponding search handlers.
Meta File Location
------------------
A list of directories given by the config entry "MetaInfoDirs" in the "General"
group of the help center configuration file "khelpcenterrc" (at
$KDEDIRS/share/config) is scanned for desktop files. They are merged to a common
hierarchy. If the "MetaInfoDirs" entry is empty the directory at
$KDEDIRS/share/apps/khelpcenter/plugins is used.
Document Hierarchy
------------------
The hierarchy of the documents shown in the help center is reflected by the
hierarchy of the desktop files in the filesystem. Directories can have an
associated desktop file with the name ".directory". It can contain all the
keys described above.
Language handling
-----------------
In addition to translation of meta information like title and short description
of documents which is contained in the meta file, translations of whole
documents are handled. Each translation of a document has an own desktop file.
The language of the document is indicated by adding the language code as
additional suffix to the filename of the desktop file. The language suffix
is added before the ".desktop" suffix (Example: 'apache.de.desktop' would be the
file name for the german translation of the apache documentation).
KHelpCenter shows only the documents whose language is contained in the list of
used languages configured for the desktop in the control center. A document
corresponding to a desktop file without language suffix is always shown.

View file

@ -0,0 +1,89 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (c) 2002 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "application.h"
#include "mainwindow.h"
#include "version.h"
#include <KCmdLineArgs>
#include <KAboutData>
#include <KLocale>
using namespace KHC;
Application::Application() : KUniqueApplication(), mMainWindow( 0 )
{
}
int Application::newInstance()
{
if (restoringSession()) return 0;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
KUrl url;
if ( args->count() )
url = args->url( 0 );
if( !mMainWindow )
{
mMainWindow = new MainWindow;
mMainWindow->show();
}
return KUniqueApplication::newInstance();
}
extern "C" int KDE_EXPORT kdemain( int argc, char **argv )
{
KAboutData aboutData( "khelpcenter", 0, ki18n("KDE Help Center"),
HELPCENTER_VERSION,
ki18n("The KDE Help Center"),
KAboutData::License_GPL,
ki18n("(c) 1999-2011, The KHelpCenter developers") );
aboutData.addAuthor( ki18n("Cornelius Schumacher"), KLocalizedString(), "schumacher@kde.org" );
aboutData.addAuthor( ki18n("Frerich Raabe"), KLocalizedString(), "raabe@kde.org" );
aboutData.addAuthor( ki18n("Matthias Elter"), ki18n("Original Author"),
"me@kde.org" );
aboutData.addAuthor( ki18n("Wojciech Smigaj"), ki18n("Info page support"),
"achu@klub.chip.pl" );
aboutData.setProgramIconName( "help-browser" );
KCmdLineArgs::init( argc, argv, &aboutData );
KCmdLineOptions options;
options.add("+[url]", ki18n("URL to display"));
KCmdLineArgs::addCmdLineOptions( options );
KCmdLineArgs::addStdCmdLineOptions();
KHC::Application app;
if ( app.isSessionRestored() )
{
RESTORE( MainWindow );
}
return app.exec();
}
// vim:ts=2:sw=2:et

47
khelpcenter/application.h Normal file
View file

@ -0,0 +1,47 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_APPLICATION_H
#define KHC_APPLICATION_H
#include <KUniqueApplication>
namespace KHC {
class MainWindow;
class Application : public KUniqueApplication
{
public:
Application();
virtual int newInstance();
private:
MainWindow *mMainWindow;
};
}
extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); }
#endif // KHC_APPLICATION_H
// vim:ts=2:sw=2:et

359
khelpcenter/docentry.cpp Normal file
View file

@ -0,0 +1,359 @@
#include "docentry.h"
#include <QRegExp>
#include <QFileInfo>
#include <KDebug>
#include <KDesktopFile>
#include <KUrl>
#include <KStandardDirs>
#include <KApplication>
#include <KRandom>
#include "prefs.h"
using namespace KHC;
DocEntry::DocEntry()
{
init();
}
DocEntry::DocEntry( const QString &name, const QString &url,
const QString &icon )
{
init();
mName = name;
mUrl = url;
mIcon = icon;
}
void DocEntry::init()
{
mWeight = 0;
mSearchEnabled = false;
mDirectory = false;
mParent = 0;
mNextSibling = 0;
}
void DocEntry::setName( const QString &name )
{
mName = name;
}
QString DocEntry::name() const
{
return mName;
}
void DocEntry::setSearch( const QString &search )
{
mSearch = search;
}
QString DocEntry::search() const
{
return mSearch;
}
void DocEntry::setIcon( const QString &icon )
{
mIcon = icon;
}
QString DocEntry::icon() const
{
if ( !mIcon.isEmpty() ) return mIcon;
if ( !docExists() ) return QLatin1String("unknown");
if ( isDirectory() ) return QLatin1String("help-contents");
else return "text-plain";
}
void DocEntry::setUrl( const QString &url )
{
mUrl = url;
}
QString DocEntry::url() const
{
if ( !mUrl.isEmpty() ) return mUrl;
if ( identifier().isEmpty() ) return QString();
return "khelpcenter:" + identifier();
}
void DocEntry::setInfo( const QString &info )
{
mInfo = info;
}
QString DocEntry::info() const
{
return mInfo;
}
void DocEntry::setLang( const QString &lang )
{
mLang = lang;
}
QString DocEntry::lang() const
{
return mLang;
}
void DocEntry::setIdentifier( const QString &identifier )
{
mIdentifier = identifier;
}
QString DocEntry::identifier() const
{
if ( mIdentifier.isEmpty() ) mIdentifier = KRandom::randomString( 15 );
return mIdentifier;
}
void DocEntry::setIndexer( const QString &indexer )
{
mIndexer = indexer;
}
QString DocEntry::indexer() const
{
return mIndexer;
}
void DocEntry::setIndexTestFile( const QString &indexTestFile )
{
mIndexTestFile = indexTestFile;
}
QString DocEntry::indexTestFile() const
{
return mIndexTestFile;
}
void DocEntry::setWeight( int weight )
{
mWeight = weight;
}
int DocEntry::weight() const
{
return mWeight;
}
void DocEntry::setSearchMethod( const QString &method )
{
mSearchMethod = method;
}
QString DocEntry::searchMethod() const
{
return mSearchMethod;
}
void DocEntry::setDocumentType( const QString &str )
{
mDocumentType = str;
}
QString DocEntry::documentType() const
{
return mDocumentType;
}
QString DocEntry::khelpcenterSpecial() const
{
return mKhelpcenterSpecial;
}
void DocEntry::enableSearch( bool enabled )
{
mSearchEnabled = enabled;
}
bool DocEntry::searchEnabled() const
{
return mSearchEnabled;
}
void DocEntry::setSearchEnabledDefault( bool enabled )
{
mSearchEnabledDefault = enabled;
}
bool DocEntry::searchEnabledDefault() const
{
return mSearchEnabledDefault;
}
void DocEntry::setDirectory( bool dir )
{
mDirectory = dir;
}
bool DocEntry::isDirectory() const
{
return mDirectory;
}
bool DocEntry::readFromFile( const QString &fileName )
{
KDesktopFile file( fileName );
KConfigGroup desktopGroup = file.desktopGroup();
mName = file.readName();
mSearch = desktopGroup.readEntry( "X-DOC-Search" );
mIcon = file.readIcon();
mUrl = file.readDocPath();
mInfo = desktopGroup.readEntry( "Info" );
if ( mInfo.isNull() )
{
mInfo = desktopGroup.readEntry( "Comment" );
}
mLang = desktopGroup.readEntry( "Lang", "en" );
mIdentifier = desktopGroup.readEntry( "X-DOC-Identifier" );
if ( mIdentifier.isEmpty() )
{
QFileInfo fi( fileName );
mIdentifier = fi.completeBaseName();
}
mIndexer = desktopGroup.readEntry( "X-DOC-Indexer" );
mIndexer.replace( "%f", fileName );
mIndexTestFile = desktopGroup.readEntry( "X-DOC-IndexTestFile" );
mSearchEnabledDefault = desktopGroup.readEntry( "X-DOC-SearchEnabledDefault",
false );
mSearchEnabled = mSearchEnabledDefault;
mWeight = desktopGroup.readEntry( "X-DOC-Weight", 0 );
mSearchMethod = desktopGroup.readEntry( "X-DOC-SearchMethod" );
mDocumentType = desktopGroup.readEntry( "X-DOC-DocumentType" );
mKhelpcenterSpecial = desktopGroup.readEntry("X-KDE-KHelpcenter-Special");
return true;
}
bool DocEntry::indexExists( const QString &indexDir )
{
QString testFile;
if ( mIndexTestFile.isEmpty() )
{
testFile = identifier() + QLatin1String(".exists");
} else {
testFile = mIndexTestFile;
}
if ( !testFile.startsWith( QLatin1Char('/') ) ) testFile = indexDir + QLatin1Char('/') + testFile;
return QFile::exists( testFile );
}
bool DocEntry::docExists() const
{
if ( !mUrl.isEmpty() )
{
KUrl docUrl( mUrl );
if ( docUrl.isLocalFile() && !KStandardDirs::exists( docUrl.toLocalFile() ) )
{
return false;
}
}
return true;
}
void DocEntry::addChild( DocEntry *entry )
{
entry->setParent( this );
int i;
for( i = 0; i < mChildren.count(); ++i )
{
if ( i == 0 ) {
if ( entry->weight() < mChildren.first()->weight() )
{
entry->setNextSibling( mChildren.first() );
mChildren.prepend( entry );
break;
}
}
if ( i + 1 < mChildren.count() )
{
if ( entry->weight() >= mChildren[ i ]->weight() &&
entry->weight() < mChildren[ i + 1 ]->weight() )
{
entry->setNextSibling( mChildren[ i + 1 ] );
mChildren[ i ]->setNextSibling( entry );
mChildren.insert( mChildren.indexOf(mChildren.at( i + 1 )), entry );
break;
}
}
}
if ( i == mChildren.count() )
{
if ( i > 0 )
{
mChildren.last()->setNextSibling( entry );
}
mChildren.append( entry );
}
}
bool DocEntry::hasChildren()
{
return mChildren.count();
}
DocEntry *DocEntry::firstChild()
{
return mChildren.first();
}
DocEntry::List DocEntry::children()
{
return mChildren;
}
void DocEntry::setParent( DocEntry *parent )
{
mParent = parent;
}
DocEntry *DocEntry::parent()
{
return mParent;
}
void DocEntry::setNextSibling( DocEntry *next )
{
mNextSibling = next;
}
DocEntry *DocEntry::nextSibling()
{
return mNextSibling;
}
bool DocEntry::isSearchable()
{
return !search().isEmpty() && docExists() &&
indexExists( Prefs::indexDirectory() );
}
void DocEntry::dump() const
{
kDebug() << " <docentry>";
kDebug() << " <name>" << mName << "</name>";
kDebug() << " <searchmethod>" << mSearchMethod << "</searchmethod>";
kDebug() << " <search>" << mSearch << "</search>";
kDebug() << " <indexer>" << mIndexer << "</indexer>";
kDebug() << " <indextestfile>" << mIndexTestFile << "</indextestfile>";
kDebug() << " <icon>" << mIcon << "</icon>";
kDebug() << " <url>" << mUrl << "</url>";
kDebug() << " <documenttype>" << mDocumentType << "</documenttype>";
kDebug() << " </docentry>";
}
// vim:ts=2:sw=2:et

118
khelpcenter/docentry.h Normal file
View file

@ -0,0 +1,118 @@
#ifndef KHC_DOCENTRY_H
#define KHC_DOCENTRY_H
#include <QString>
#include <QList>
namespace KHC {
class DocEntry
{
public:
typedef QList<DocEntry *> List;
DocEntry();
explicit DocEntry( const QString &name, const QString &url = QString(),
const QString &icon = QString() );
void setName( const QString & );
QString name() const;
void setSearch( const QString & );
QString search() const;
void setIcon( const QString & );
QString icon() const;
void setUrl( const QString & );
QString url() const;
void setInfo( const QString & );
QString info() const;
void setLang( const QString & );
QString lang() const;
void setIdentifier( const QString & );
QString identifier() const;
void setIndexer( const QString & );
QString indexer() const;
void setIndexTestFile( const QString & );
QString indexTestFile() const;
void setWeight( int );
int weight() const;
void setSearchMethod( const QString & );
QString searchMethod() const;
void enableSearch( bool enabled );
bool searchEnabled() const;
void setSearchEnabledDefault( bool enabled );
bool searchEnabledDefault() const;
void setDocumentType( const QString & );
QString documentType() const;
void setDirectory( bool );
bool isDirectory() const;
bool readFromFile( const QString &fileName );
bool indexExists( const QString &indexDir );
bool docExists() const;
void addChild( DocEntry * );
bool hasChildren();
DocEntry *firstChild();
List children();
void setParent( DocEntry * );
DocEntry *parent();
void setNextSibling( DocEntry * );
DocEntry *nextSibling();
QString khelpcenterSpecial() const;
bool isSearchable();
void dump() const;
protected:
void init();
private:
QString mName;
QString mSearch;
QString mIcon;
QString mUrl;
QString mInfo;
QString mLang;
mutable QString mIdentifier;
QString mIndexer;
QString mIndexTestFile;
int mWeight;
QString mSearchMethod;
bool mSearchEnabled;
bool mSearchEnabledDefault;
QString mDocumentType;
bool mDirectory;
QString mKhelpcenterSpecial;
List mChildren;
DocEntry *mParent;
DocEntry *mNextSibling;
};
}
#endif //KHC_DOCENTRY_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,69 @@
/* This file is part of the KDE project
* Copyright 2002 Cornelius Schumacher <schumacher@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "docentrytraverser.h"
#include "docmetainfo.h"
using namespace KHC;
void DocEntryTraverser::setNotifyee( DocMetaInfo *n )
{
mNotifyee = n;
}
void DocEntryTraverser::startProcess( DocEntry *entry )
{
process( entry );
mNotifyee->endProcess( entry, this );
}
DocEntryTraverser *DocEntryTraverser::childTraverser( DocEntry *parentEntry )
{
DocEntryTraverser *child = createChild( parentEntry );
if (!child)
return 0;
if ( child != this )
{
child->mParent = this;
child->mNotifyee = mNotifyee;
}
return child;
}
DocEntryTraverser *DocEntryTraverser::parentTraverser()
{
return mParent;
}
void DocEntryTraverser::deleteTraverser()
{
delete this;
}
void DocEntryTraverser::setParentEntry( DocEntry *entry )
{
mParentEntry = entry;
}
DocEntry *DocEntryTraverser::parentEntry()
{
return mParentEntry;
}
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,64 @@
/* This file is part of the KDE project
Copyright 2002 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published
by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KHC_DOCENTRYTRAVERSER_H
#define KHC_DOCENTRYTRAVERSER_H
namespace KHC {
class DocEntry;
class DocMetaInfo;
class DocEntryTraverser
{
public:
DocEntryTraverser() : mNotifyee( 0 ), mParent( 0 ), mParentEntry( 0 ) {}
virtual ~DocEntryTraverser() {}
void setNotifyee( DocMetaInfo * );
virtual void process( DocEntry * ) = 0;
virtual void startProcess( DocEntry * );
virtual DocEntryTraverser *createChild( DocEntry *parentEntry ) = 0;
virtual void deleteTraverser();
virtual void finishTraversal() {}
DocEntryTraverser *childTraverser( DocEntry *parentEntry );
virtual DocEntryTraverser *parentTraverser();
void setParentEntry( DocEntry * );
DocEntry *parentEntry();
protected:
DocMetaInfo *mNotifyee;
DocEntryTraverser *mParent;
private:
DocEntry *mParentEntry;
};
}
#endif //KHC_DOCENTRYTRAVERSER_H
// vim:ts=2:sw=2:et

327
khelpcenter/docmetainfo.cpp Normal file
View file

@ -0,0 +1,327 @@
/* This file is part of the KDE project
* Copyright 2002 Cornelius Schumacher <schumacher@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "docmetainfo.h"
#include <QRegExp>
#include <KDebug>
#include <KStandardDirs>
#include <KLocale>
#include <KConfig>
#include <KConfigGroup>
#include "htmlsearch.h"
#include "docentrytraverser.h"
using namespace KHC;
bool DocMetaInfo::mLoaded = false;
DocMetaInfo *DocMetaInfo::mSelf = 0;
DocMetaInfo *DocMetaInfo::self()
{
if ( !mSelf ) mSelf = new DocMetaInfo;
return mSelf;
}
DocMetaInfo::DocMetaInfo()
{
kDebug() << "DocMetaInfo()";
mHtmlSearch = new HTMLSearch;
mRootEntry.setName( i18n("Top-Level Documentation") );
}
DocMetaInfo::~DocMetaInfo()
{
kDebug() << "~DocMetaInfo()";
DocEntry::List::ConstIterator it;
for( it = mDocEntries.constBegin(); it != mDocEntries.constEnd(); ++it )
{
delete *it;
}
delete mHtmlSearch;
mLoaded = false;
mSelf = 0;
}
DocEntry *DocMetaInfo::addDocEntry( const QString &fileName )
{
QFileInfo fi( fileName );
if ( !fi.exists() ) return 0;
QString extension = fi.completeSuffix();
QStringList extensions = extension.split( '.');
QString lang;
if ( extensions.count() >= 2 )
{
lang = extensions[ extensions.count() - 2 ];
}
if ( !lang.isEmpty() && !mLanguages.contains( lang ) )
{
return 0;
}
DocEntry *entry = new DocEntry();
if ( entry->readFromFile( fileName ) )
{
if ( !lang.isEmpty() && lang != mLanguages.first() )
{
entry->setLang( lang );
entry->setName( i18nc("doctitle (language)","%1 (%2)",
entry->name() ,
mLanguageNames[ lang ] ) );
}
if ( entry->searchMethod().toLower() == "htdig" )
{
mHtmlSearch->setupDocEntry( entry );
}
QString indexer = entry->indexer();
indexer.replace( "%f", fileName );
entry->setIndexer( indexer );
addDocEntry( entry );
return entry;
}
else
{
delete entry;
return 0;
}
}
void DocMetaInfo::addDocEntry( DocEntry *entry )
{
mDocEntries.append( entry );
if ( !entry->search().isEmpty() ) mSearchEntries.append( entry );
}
DocEntry::List DocMetaInfo::docEntries()
{
return mDocEntries;
}
DocEntry::List DocMetaInfo::searchEntries()
{
return mSearchEntries;
}
QString DocMetaInfo::languageName( const QString &langcode )
{
if ( langcode == "en" ) return i18nc("Describes documentation entries that are in English","English");
QString cfgfile = KStandardDirs::locate( "locale",
QString::fromLatin1( "%1/entry.desktop" ).arg( langcode ) );
kDebug() << "-- langcode: " << langcode << " cfgfile: " << cfgfile;
KConfig _cfg( cfgfile, KConfig::SimpleConfig );
KConfigGroup cfg(&_cfg, "KCM Locale" );
QString name = cfg.readEntry( "Name", langcode );
return name;
}
void DocMetaInfo::scanMetaInfo( bool force )
{
if ( mLoaded && !force ) return;
mLanguages = KGlobal::locale()->languageList();
kDebug( 1400 ) << "LANGS: " << mLanguages.join( QLatin1String(" ") );
QStringList::ConstIterator it;
for( it = mLanguages.constBegin(); it != mLanguages.constEnd(); ++it )
{
mLanguageNames.insert( *it, languageName( *it ) );
}
KConfig config( QLatin1String("khelpcenterrc") );
KConfigGroup cg(&config, "General");
QStringList metaInfos = cg.readEntry( "MetaInfoDirs" , QStringList() );
if ( metaInfos.isEmpty() )
{
KStandardDirs* kstd = KGlobal::dirs();
metaInfos = kstd->findDirs( "appdata", "plugins" );
}
for( it = metaInfos.constBegin(); it != metaInfos.constEnd(); ++it)
{
kDebug() << "DocMetaInfo::scanMetaInfo(): scanning " << *it;
scanMetaInfoDir( *it, &mRootEntry );
}
mLoaded = true;
}
DocEntry *DocMetaInfo::scanMetaInfoDir( const QString &dirName,
DocEntry *parent )
{
QDir dir( dirName );
if ( !dir.exists() ) return 0;
foreach( const QFileInfo &fi, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot) )
{
DocEntry *entry = 0;
if ( fi.isDir() )
{
DocEntry *dirEntry = addDirEntry( QDir( fi.absoluteFilePath() ), parent );
entry = scanMetaInfoDir( fi.absoluteFilePath(), dirEntry );
}
else if ( fi.suffix() == QLatin1String("desktop") )
{
entry = addDocEntry( fi.absoluteFilePath() );
if ( parent && entry ) parent->addChild( entry );
}
}
return 0;
}
DocEntry *DocMetaInfo::addDirEntry( const QDir &dir, DocEntry *parent )
{
DocEntry *dirEntry = addDocEntry( dir.absolutePath() + QLatin1String("/.directory") );
if ( !dirEntry )
{
dirEntry = new DocEntry;
dirEntry->setName( dir.dirName() );
addDocEntry( dirEntry );
}
dirEntry->setDirectory( true );
if ( parent ) parent->addChild( dirEntry );
return dirEntry;
}
void DocMetaInfo::traverseEntries( DocEntryTraverser *traverser )
{
traverseEntry( &mRootEntry, traverser );
}
void DocMetaInfo::traverseEntry( DocEntry *entry, DocEntryTraverser *traverser )
{
DocEntry::List children = entry->children();
DocEntry::List::ConstIterator it;
for( it = children.constBegin(); it != children.constEnd(); ++it )
{
if ( (*it)->isDirectory() && !(*it)->hasChildren() &&
(*it)->khelpcenterSpecial().isEmpty() ) continue;
traverser->process( *it );
if ( (*it)->hasChildren() )
{
DocEntryTraverser *t = traverser->childTraverser( *it );
if (t)
{
traverseEntry( *it, t );
t->deleteTraverser();
}
}
}
}
void DocMetaInfo::startTraverseEntries( DocEntryTraverser *traverser )
{
kDebug() << "DocMetaInfo::startTraverseEntries()";
traverser->setNotifyee( this );
startTraverseEntry( &mRootEntry, traverser );
}
void DocMetaInfo::startTraverseEntry( DocEntry *entry,
DocEntryTraverser *traverser )
{
if ( !traverser )
{
kDebug() << "DocMetaInfo::startTraverseEntry(): ERROR. No Traverser."
<< endl;
return;
}
if ( !entry )
{
kDebug() << "DocMetaInfo::startTraverseEntry(): no entry.";
endTraverseEntries( traverser );
return;
}
traverser->startProcess( entry );
}
void DocMetaInfo::endProcess( DocEntry *entry, DocEntryTraverser *traverser )
{
if ( !entry )
{
endTraverseEntries( traverser );
return;
}
if ( entry->hasChildren() )
{
startTraverseEntry( entry->firstChild(), traverser->childTraverser( entry ) );
} else if ( entry->nextSibling() )
{
startTraverseEntry( entry->nextSibling(), traverser );
} else
{
DocEntry *parent = entry->parent();
DocEntryTraverser *parentTraverser = 0;
while ( parent ) {
parentTraverser = traverser->parentTraverser();
traverser->deleteTraverser();
if ( parent->nextSibling() ) {
startTraverseEntry( parent->nextSibling(), parentTraverser );
break;
}
else
{
parent = parent->parent();
traverser = parentTraverser;
}
}
if ( !parent )
{
endTraverseEntries( traverser );
}
}
}
void DocMetaInfo::endTraverseEntries( DocEntryTraverser *traverser )
{
kDebug() << "DocMetaInfo::endTraverseEntries()";
if ( !traverser )
{
kDebug() << " no more traversers.";
return;
}
traverser->finishTraversal();
}
// vim:ts=2:sw=2:et

97
khelpcenter/docmetainfo.h Normal file
View file

@ -0,0 +1,97 @@
/* This file is part of the KDE project
Copyright 2002 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published
by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KHC_DOCMETAINFO_H
#define KHC_DOCMETAINFO_H
#include <QDir>
#include <QMap>
#include "docentry.h"
namespace KHC {
class HTMLSearch;
class DocEntryTraverser;
/*!
This class provides some meta information about help documents.
*/
class DocMetaInfo
{
public:
/*!
Return instance of DocMetaInfo. There can only be one instance at a time.
*/
static DocMetaInfo *self();
~DocMetaInfo();
void scanMetaInfo( bool force = false );
DocEntry *addDocEntry( const QString &fileName );
void addDocEntry( DocEntry * );
DocEntry::List docEntries();
DocEntry::List searchEntries();
void traverseEntries( DocEntryTraverser * );
void startTraverseEntries( DocEntryTraverser *traverser );
void startTraverseEntry( DocEntry *entry, DocEntryTraverser *traverser );
void endProcess( DocEntry *entry, DocEntryTraverser *traverser );
void endTraverseEntries( DocEntryTraverser * );
static QString languageName( const QString &langcode );
protected:
DocEntry *scanMetaInfoDir( const QString &filename, DocEntry *parent );
DocEntry *addDirEntry( const QDir &dir, DocEntry *parent );
void traverseEntry( DocEntry *, DocEntryTraverser * );
private:
/*!
DocMetaInfo is a singleton. Private constructor prevents direct
instantisation.
*/
DocMetaInfo();
DocEntry::List mDocEntries;
DocEntry::List mSearchEntries;
DocEntry mRootEntry;
QStringList mLanguages;
QMap<QString,QString> mLanguageNames;
HTMLSearch *mHtmlSearch;
static bool mLoaded;
static DocMetaInfo *mSelf;
};
}
#endif //KHC_DOCMETAINFO_H
// vim:ts=2:sw=2:et

226
khelpcenter/fontdialog.cpp Normal file
View file

@ -0,0 +1,226 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2003 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "fontdialog.h"
#include <KApplication>
#include <KCharsets>
#include <KComboBox>
#include <KConfig>
#include <KGlobal>
#include <KLocale>
#include <KNumInput>
#include <KVBox>
#include <KFontComboBox>
#include <KConfigGroup>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
using namespace KHC;
FontDialog::FontDialog( QWidget *parent )
: KDialog( parent )
{
setModal( true );
setCaption( i18n( "Font Configuration" ) );
setButtons( Ok | Cancel );
m_mainWidget = new KVBox( this );
setMainWidget( m_mainWidget );
setupFontSizesBox();
setupFontTypesBox();
setupFontEncodingBox();
load();
connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
}
void FontDialog::slotOk()
{
save();
accept();
}
void FontDialog::setupFontSizesBox()
{
QGroupBox *gb = new QGroupBox( i18n( "Sizes" ), m_mainWidget );
QGridLayout *layout = new QGridLayout( gb );
layout->setSpacing( KDialog::spacingHint() );
layout->setMargin( KDialog::marginHint() * 2 );
QLabel *lMinFontSize = new QLabel( i18nc( "The smallest size a will have", "M&inimum font size:" ), gb );
layout->addWidget( lMinFontSize, 0, 0 );
m_minFontSize = new KIntNumInput( gb );
layout->addWidget( m_minFontSize, 0, 1 );
m_minFontSize->setRange( 1, 20 );
lMinFontSize->setBuddy( m_minFontSize );
QLabel *lMedFontSize = new QLabel( i18nc( "The normal size a font will have", "M&edium font size:" ), gb );
layout->addWidget( lMedFontSize, 1, 0 );
m_medFontSize = new KIntNumInput( gb );
layout->addWidget( m_medFontSize, 1, 1 );
m_medFontSize->setRange( 4, 28 );
lMedFontSize->setBuddy( m_medFontSize );
}
void FontDialog::setupFontTypesBox()
{
QGroupBox *gb = new QGroupBox( i18n( "Fonts" ), m_mainWidget );
QGridLayout *layout = new QGridLayout( gb );
layout->setSpacing( KDialog::spacingHint() );
layout->setMargin( KDialog::marginHint() * 2 );
QLabel *lStandardFont = new QLabel( i18n( "S&tandard font:" ), gb );
layout->addWidget( lStandardFont, 0, 0 );
m_standardFontCombo = new KFontComboBox( gb );
layout->addWidget( m_standardFontCombo, 0, 1 );
lStandardFont->setBuddy( m_standardFontCombo );
QLabel *lFixedFont = new QLabel( i18n( "F&ixed font:" ), gb );
layout->addWidget( lFixedFont, 1, 0 );
m_fixedFontCombo = new KFontComboBox( gb );
layout->addWidget( m_fixedFontCombo, 1, 1 );
lFixedFont->setBuddy( m_fixedFontCombo );
QLabel *lSerifFont = new QLabel( i18n( "S&erif font:" ), gb );
layout->addWidget( lSerifFont, 2, 0 );
m_serifFontCombo = new KFontComboBox( gb );
layout->addWidget( m_serifFontCombo, 2, 1 );
lSerifFont->setBuddy( m_serifFontCombo );
QLabel *lSansSerifFont = new QLabel( i18n( "S&ans serif font:" ), gb );
layout->addWidget( lSansSerifFont, 3, 0 );
m_sansSerifFontCombo = new KFontComboBox( gb );
layout->addWidget( m_sansSerifFontCombo, 3, 1 );
lSansSerifFont->setBuddy( m_sansSerifFontCombo );
QLabel *lItalicFont = new QLabel( i18n( "&Italic font:" ), gb );
layout->addWidget( lItalicFont, 4, 0 );
m_italicFontCombo = new KFontComboBox( gb );
layout->addWidget( m_italicFontCombo, 4, 1 );
lItalicFont->setBuddy( m_italicFontCombo );
QLabel *lFantasyFont = new QLabel( i18n( "&Fantasy font:" ), gb );
layout->addWidget( lFantasyFont, 5, 0 );
m_fantasyFontCombo = new KFontComboBox( gb );
layout->addWidget( m_fantasyFontCombo, 5, 1 );
lFantasyFont->setBuddy( m_fantasyFontCombo );
}
void FontDialog::setupFontEncodingBox()
{
QGroupBox *gb = new QGroupBox( i18n( "Encoding" ), m_mainWidget );
QGridLayout *layout = new QGridLayout( gb );
layout->setSpacing( KDialog::spacingHint() );
layout->setMargin( KDialog::marginHint() * 2 );
QLabel *lDefaultEncoding = new QLabel( i18n( "&Default encoding:" ), gb );
layout->addWidget( lDefaultEncoding, 0, 0 );
m_defaultEncoding = new KComboBox( false, gb );
layout->addWidget( m_defaultEncoding, 0, 1 );
QStringList encodings = KGlobal::charsets()->availableEncodingNames();
encodings.prepend( i18n( "Use Language Encoding" ) );
m_defaultEncoding->addItems( encodings );
lDefaultEncoding->setBuddy( m_defaultEncoding );
QLabel *lFontSizeAdjustement = new QLabel( i18n( "&Font size adjustment:" ), gb );
layout->addWidget( lFontSizeAdjustement, 1, 0 );
m_fontSizeAdjustement = new KIntSpinBox( gb );
m_fontSizeAdjustement->setRange( -5, 5 );
m_fontSizeAdjustement->setSingleStep( 1 );
layout->addWidget( m_fontSizeAdjustement, 1, 1 );
lFontSizeAdjustement->setBuddy( m_fontSizeAdjustement );
}
void FontDialog::load()
{
KSharedConfig::Ptr cfg = KGlobal::config();
{
KConfigGroup configGroup( cfg, "HTML Settings" );
m_minFontSize->setValue( configGroup.readEntry( "MinimumFontSize", (int)HTML_DEFAULT_MIN_FONT_SIZE ) );
m_medFontSize->setValue( configGroup.readEntry( "MediumFontSize", 10 ) );
QStringList fonts = configGroup.readEntry( "Fonts" , QStringList() );
if ( fonts.isEmpty() )
fonts << KGlobalSettings::generalFont().family()
<< KGlobalSettings::fixedFont().family()
<< QLatin1String(HTML_DEFAULT_VIEW_SERIF_FONT)
<< QLatin1String(HTML_DEFAULT_VIEW_SANSSERIF_FONT)
<< QLatin1String(HTML_DEFAULT_VIEW_CURSIVE_FONT)
<< QLatin1String(HTML_DEFAULT_VIEW_FANTASY_FONT)
<< QString();
m_standardFontCombo->setCurrentFont( fonts[ 0 ] );
m_fixedFontCombo->setCurrentFont( fonts[ 1 ] );
m_serifFontCombo->setCurrentFont( fonts[ 2 ] );
m_sansSerifFontCombo->setCurrentFont( fonts[ 3 ] );
m_italicFontCombo->setCurrentFont( fonts[ 4 ] );
m_fantasyFontCombo->setCurrentFont( fonts[ 5 ] );
QString encoding = configGroup.readEntry( "DefaultEncoding" );
if (encoding.isEmpty()) m_defaultEncoding->setCurrentIndex( 0 );
else m_defaultEncoding->setCurrentItem( encoding );
m_fontSizeAdjustement->setValue( fonts[ 6 ].toInt() );
}
}
void FontDialog::save()
{
KSharedConfig::Ptr cfg = KGlobal::config();
{
KConfigGroup configGroup( cfg, "General" );
configGroup.writeEntry( "UseKonqSettings", false );
}
{
KConfigGroup configGroup( cfg, "HTML Settings" );
configGroup.writeEntry( "MinimumFontSize", m_minFontSize->value() );
configGroup.writeEntry( "MediumFontSize", m_medFontSize->value() );
QStringList fonts;
fonts << m_standardFontCombo->currentFont().family()
<< m_fixedFontCombo->currentFont().family()
<< m_serifFontCombo->currentFont().family()
<< m_sansSerifFontCombo->currentFont().family()
<< m_italicFontCombo->currentFont().family()
<< m_fantasyFontCombo->currentFont().family()
<< QString::number( m_fontSizeAdjustement->value() );
configGroup.writeEntry( "Fonts", fonts );
if ( m_defaultEncoding->currentText() == i18n( "Use Language Encoding" ) )
configGroup.writeEntry( "DefaultEncoding", QString() );
else
configGroup.writeEntry( "DefaultEncoding", m_defaultEncoding->currentText() );
}
cfg->sync();
}
#include "moc_fontdialog.cpp"
// vim:ts=4:sw=4:noet

68
khelpcenter/fontdialog.h Normal file
View file

@ -0,0 +1,68 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2003 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_FONTDIALOG_H
#define KHC_FONTDIALOG_H
#include <KDialog>
class KIntSpinBox;
class KComboBox;
class KFontComboBox;
class KIntNumInput;
class KVBox;
namespace KHC {
class FontDialog : public KDialog
{
Q_OBJECT
public:
FontDialog( QWidget *parent );
protected Q_SLOTS:
virtual void slotOk();
private:
void setupFontSizesBox();
void setupFontTypesBox();
void setupFontEncodingBox();
void load();
void save();
KIntNumInput *m_minFontSize;
KIntNumInput *m_medFontSize;
KFontComboBox *m_standardFontCombo;
KFontComboBox *m_fixedFontCombo;
KFontComboBox *m_serifFontCombo;
KFontComboBox *m_sansSerifFontCombo;
KFontComboBox *m_italicFontCombo;
KFontComboBox *m_fantasyFontCombo;
KComboBox *m_defaultEncoding;
KIntSpinBox *m_fontSizeAdjustement;
KVBox *m_mainWidget;
};
}
#endif // KHC_FONTDIALOG_H
// vim:ts=4:sw=4:noet

227
khelpcenter/formatter.cpp Normal file
View file

@ -0,0 +1,227 @@
/*
This file is part of KHelpcenter.
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "formatter.h"
#include <KLocale>
#include <KGlobal>
#include <KDebug>
#include <KConfig>
#include <KConfigGroup>
#include <KStandardDirs>
#include <QFile>
#include <QTextStream>
using namespace KHC;
Formatter::Formatter()
: mHasTemplate( false )
{
}
Formatter:: ~Formatter()
{
}
bool Formatter::readTemplates()
{
KConfigGroup cfg(KGlobal::config(), "Templates");
QString mainTemplate = cfg.readEntry( "MainTemplate" );
if ( mainTemplate.isEmpty() )
{
mainTemplate = KStandardDirs::locate( "appdata", "maintemplate" );
}
if ( mainTemplate.isEmpty() )
{
kWarning() << "Main template file name is empty." ;
return false;
}
QFile f( mainTemplate );
if ( !f.open( QIODevice::ReadOnly ) )
{
kWarning() << "Unable to open main template file '" << mainTemplate
<< "'." << endl;
return false;
}
QTextStream ts( &f );
QString line;
enum State { IDLE, SINGLELINE, MULTILINE };
State state = IDLE;
QString symbol;
QString endMarker;
QString value;
while( !( line = ts.readLine() ).isNull() ) {
switch ( state ) {
case IDLE:
if ( !line.isEmpty() && !line.startsWith( '#' ) )
{
int pos = line.indexOf( "<<" );
if ( pos >= 0 )
{
state = MULTILINE;
symbol = line.left( pos ).trimmed();
endMarker = line.mid( pos + 2 ).trimmed();
} else {
state = SINGLELINE;
symbol = line.trimmed();
}
}
break;
case SINGLELINE:
mSymbols.insert( symbol, line );
state = IDLE;
break;
case MULTILINE:
if ( line.startsWith( endMarker ) )
{
mSymbols.insert( symbol, value );
value = "";
state = IDLE;
}
else
{
value += line + '\n';
}
break;
default:
kError() << "Formatter::readTemplates(): Illegal state: "
<< static_cast<int>(state) << endl;
break;
}
}
f.close();
QStringList requiredSymbols;
requiredSymbols << "HEADER" << "FOOTER";
bool success = true;
QStringList::ConstIterator it2;
for( it2 = requiredSymbols.constBegin(); it2 != requiredSymbols.constEnd(); ++it2 )
{
if ( !mSymbols.contains( *it2 ) )
{
success = false;
kError() << "Symbol '" << *it2 << "' is missing from main template file."
<< endl;
}
}
if ( success ) mHasTemplate = true;
return success;
}
QString Formatter::header( const QString &title )
{
QString s;
if ( mHasTemplate )
{
s = mSymbols[ "HEADER" ];
s.replace( "--TITLE:--", title );
} else {
s = QLatin1String("<html><head><title>") + title + QLatin1String("</title></head>\n<body>\n");
}
return s;
}
QString Formatter::footer()
{
if ( mHasTemplate )
{
return mSymbols[ "FOOTER" ];
} else {
return QLatin1String("</body></html>");
}
}
QString Formatter::separator()
{
return "<hr>";
}
QString Formatter::docTitle( const QString &title )
{
return QLatin1String("<h3><font color=\"red\">") + title + QLatin1String("</font></h3>");
}
QString Formatter::sectionHeader( const QString &section )
{
return QLatin1String("<h2><font color=\"blue\">") + section + QLatin1String("</font></h2>");
}
QString Formatter::processResult( const QString &data )
{
QString result;
enum { Header, BodyTag, Body, Footer };
int state = Header;
for( int i = 0; i < data.length(); ++i )
{
QChar c = data[i];
switch ( state )
{
case Header:
if ( c == QLatin1Char('<') && data.mid( i, 5 ).toLower() == QLatin1String("<body") )
{
state = BodyTag;
i += 4;
}
break;
case BodyTag:
if ( c == '>' ) state = Body;
break;
case Body:
if ( c == QLatin1Char('<') && data.mid( i, 7 ).toLower() == QLatin1String("</body>") )
{
state = Footer;
} else {
result.append( c );
}
break;
case Footer:
break;
default:
result.append( c );
break;
}
}
if ( state == Header ) return data;
else return result;
}
QString Formatter::paragraph( const QString &str )
{
return QLatin1String("<p>") + str + QLatin1String("</p>");
}
QString Formatter::title( const QString &title )
{
return QLatin1String("<h2>") + title + QLatin1String("</h2>");
}
// vim:ts=2:sw=2:et

56
khelpcenter/formatter.h Normal file
View file

@ -0,0 +1,56 @@
/*
This file is part of KHelpcenter.
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_FORMATTER_H
#define KHC_FORMATTER_H
#include <QMap>
namespace KHC {
class Formatter
{
public:
Formatter();
virtual ~Formatter();
bool readTemplates();
virtual QString header( const QString &title );
virtual QString footer();
virtual QString separator();
virtual QString docTitle( const QString & );
virtual QString sectionHeader( const QString & );
virtual QString paragraph( const QString & );
virtual QString title( const QString & );
virtual QString processResult( const QString & );
private:
bool mHasTemplate;
QMap<QString,QString> mSymbols;
};
}
#endif //KHC_FORMATTER_H
// vim:ts=2:sw=2:et

356
khelpcenter/glossary.cpp Normal file
View file

@ -0,0 +1,356 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe (raabe@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "glossary.h"
#include "view.h"
#include <KApplication>
#include <KConfig>
#include <KDebug>
#include <KIconLoader>
#include <KLocale>
#include <KXmlGuiWindow>
#include <KProcess>
#include <KStandardDirs>
#include <KStatusBar>
#include <KGlobal>
#include <KConfigGroup>
#include <QTreeWidgetItemIterator>
#include <QTreeWidgetItem>
#include <QFrame>
#include <QListView>
#include <QTextStream>
#include <sys/stat.h>
using namespace KHC;
class SectionItem : public QTreeWidgetItem
{
public:
SectionItem( QTreeWidgetItem *parent, const QString &text )
: QTreeWidgetItem( parent )
{
setText(0,text);
setIcon(0,SmallIcon( "help-contents" ));
}
};
class EntryItem : public QTreeWidgetItem
{
public:
EntryItem( SectionItem *parent, const QString &term, const QString &id )
: QTreeWidgetItem( parent ), m_id( id )
{
setText(0,term);
}
QString id() const { return m_id; }
private:
QString m_id;
};
bool Glossary::m_alreadyWarned = false;
Glossary::Glossary( QWidget *parent ) : QTreeWidget( parent )
{
m_initialized = false;
setFrameStyle( QFrame::NoFrame );
connect( this, SIGNAL( itemActivated(QTreeWidgetItem *, int) ),
this, SLOT( treeItemSelected( QTreeWidgetItem * ) ) );
setHeaderHidden(true);
setAllColumnsShowFocus( true );
setRootIsDecorated( true );
m_byTopicItem = new QTreeWidgetItem( this );
m_byTopicItem->setText( 0, i18n( "By Topic" ) );
m_byTopicItem->setIcon( 0, SmallIcon( "help-contents" ) );
m_alphabItem = new QTreeWidgetItem( this );
m_alphabItem->setText( 0, i18n( "Alphabetically" ) );
m_alphabItem->setIcon( 0, SmallIcon( "character-set" ) );
m_cacheFile = KStandardDirs::locateLocal( "cache", "help/glossary.xml" );
m_sourceFile = View::langLookup( QLatin1String( "khelpcenter/glossary/index.docbook" ) );
m_config = KGlobal::config();
}
void Glossary::showEvent(QShowEvent *event)
{
if ( !m_initialized )
{
if ( cacheStatus() == NeedRebuild )
rebuildGlossaryCache();
else
buildGlossaryTree();
m_initialized = true;
}
QTreeWidget::showEvent(event);
}
Glossary::~Glossary()
{
qDeleteAll( m_glossEntries );
}
const GlossaryEntry &Glossary::entry( const QString &id ) const
{
return *m_glossEntries[ id ];
}
Glossary::CacheStatus Glossary::cacheStatus() const
{
if ( !QFile::exists( m_cacheFile ) ||
m_config->group("Glossary").readPathEntry( "CachedGlossary", QString() ) != m_sourceFile ||
m_config->group("Glossary").readEntry( "CachedGlossaryTimestamp" ).toInt() != glossaryCTime() )
return NeedRebuild;
return CacheOk;
}
int Glossary::glossaryCTime() const
{
struct stat stat_buf;
stat( QFile::encodeName( m_sourceFile ).data(), &stat_buf );
return stat_buf.st_ctime;
}
void Glossary::rebuildGlossaryCache()
{
KXmlGuiWindow *mainWindow = dynamic_cast<KXmlGuiWindow *>( kapp->activeWindow() );
if (mainWindow)
mainWindow->statusBar()->showMessage( i18n( "Rebuilding glossary cache..." ) );
KProcess *meinproc = new KProcess;
connect( meinproc, SIGNAL( finished(int,QProcess::ExitStatus) ),
this, SLOT( meinprocFinished(int,QProcess::ExitStatus) ) );
*meinproc << KStandardDirs::locate( "exe", QLatin1String( "xsltproc" ) );
*meinproc << QLatin1String( "--output" ) << m_cacheFile;
*meinproc << QLatin1String( "--stylesheet" )
<< KStandardDirs::locate( "data", QLatin1String( "khelpcenter/glossary.xslt" ) );
*meinproc << m_sourceFile;
meinproc->setOutputChannelMode(KProcess::OnlyStderrChannel);
meinproc->start();
if (!meinproc->waitForStarted())
{
kError() << "could not start process" << meinproc->program();
if (mainWindow && !m_alreadyWarned)
{
; // add warning message box with don't display again option
// http://api.kde.org/4.0-api/kdelibs-apidocs/kdeui/html/classKDialog.html
m_alreadyWarned = true;
}
delete meinproc;
}
}
void Glossary::meinprocFinished( int exitCode, QProcess::ExitStatus exitStatus )
{
KProcess *meinproc = static_cast<KProcess *>(sender());
KXmlGuiWindow *mainWindow = dynamic_cast<KXmlGuiWindow *>( kapp->activeWindow() );
if (exitStatus != QProcess::NormalExit || exitCode != 0)
{
kError() << "running" << meinproc->program() << "failed with exitCode" << exitCode;
kError() << "stderr output:" << meinproc->readAllStandardError();
if (mainWindow && !m_alreadyWarned)
{
; // add warning message box with don't display again option
// http://api.kde.org/4.0-api/kdelibs-apidocs/kdeui/html/classKDialog.html
m_alreadyWarned = true;
}
delete meinproc;
return;
}
delete meinproc;
if ( !QFile::exists( m_cacheFile ) )
return;
m_config->group("Glossary").writePathEntry( "CachedGlossary", m_sourceFile );
m_config->group("Glossary").writeEntry( "CachedGlossaryTimestamp", glossaryCTime() );
m_config->sync();
m_status = CacheOk;
if (mainWindow)
mainWindow->statusBar()->showMessage( i18n( "Rebuilding cache... done." ), 2000 );
buildGlossaryTree();
}
void Glossary::buildGlossaryTree()
{
QFile cacheFile(m_cacheFile);
if ( !cacheFile.open( QIODevice::ReadOnly ) )
return;
QDomDocument doc;
if ( !doc.setContent( &cacheFile ) )
return;
QDomNodeList sectionNodes = doc.documentElement().elementsByTagName( QLatin1String( "section" ) );
for ( int i = 0; i < sectionNodes.count(); i++ )
{
QDomElement sectionElement = sectionNodes.item( i ).toElement();
QString title = sectionElement.attribute( QLatin1String( "title" ) );
SectionItem *topicSection = new SectionItem( m_byTopicItem, title );
QDomNodeList entryNodes = sectionElement.elementsByTagName( QLatin1String( "entry" ) );
for ( int j = 0; j < entryNodes.count(); j++ )
{
QDomElement entryElement = entryNodes.item( j ).toElement();
QString entryId = entryElement.attribute( QLatin1String( "id" ) );
if ( entryId.isNull() )
continue;
QDomElement termElement = childElement( entryElement, QLatin1String( "term" ) );
QString term = termElement.text().simplified();
EntryItem *entry = new EntryItem(topicSection, term, entryId );
m_idDict.insert( entryId, entry );
SectionItem *alphabSection = 0L;
QTreeWidgetItemIterator it(m_alphabItem);
while(*it)
{
if ( (*it)->text( 0 ) == QString( term[ 0 ].toUpper() ) )
{
alphabSection = static_cast<SectionItem *>( (*it) );
break;
}
++it;
}
if ( !alphabSection )
alphabSection = new SectionItem( m_alphabItem, QString( term[ 0 ].toUpper() ) );
new EntryItem( alphabSection, term, entryId );
QDomElement definitionElement = childElement( entryElement, QLatin1String( "definition" ) );
QString definition = definitionElement.text().simplified();
GlossaryEntryXRef::List seeAlso;
QDomElement referencesElement = childElement( entryElement, QLatin1String( "references" ) );
QDomNodeList referenceNodes = referencesElement.elementsByTagName( QLatin1String( "reference" ) );
if ( referenceNodes.count() > 0 )
for ( int k = 0; k < referenceNodes.count(); k++ )
{
QDomElement referenceElement = referenceNodes.item( k ).toElement();
QString term = referenceElement.attribute( QLatin1String( "term" ) );
QString id = referenceElement.attribute( QLatin1String( "id" ) );
seeAlso += GlossaryEntryXRef( term, id );
}
m_glossEntries.insert( entryId, new GlossaryEntry( term, definition, seeAlso ) );
}
}
sortItems(0, Qt::AscendingOrder);
}
void Glossary::treeItemSelected( QTreeWidgetItem *item )
{
if ( !item )
return;
if ( EntryItem *i = dynamic_cast<EntryItem *>( item ) )
emit entrySelected( entry( i->id() ) );
item->setExpanded( !item->isExpanded() );
}
QDomElement Glossary::childElement( const QDomElement &element, const QString &name )
{
QDomElement e;
for ( e = element.firstChild().toElement(); !e.isNull(); e = e.nextSibling().toElement() )
if ( e.tagName() == name )
break;
return e;
}
QString Glossary::entryToHtml( const GlossaryEntry &entry )
{
QFile htmlFile( KStandardDirs::locate("data", "khelpcenter/glossary.html.in" ) );
if (!htmlFile.open(QIODevice::ReadOnly))
return QString( "<html><head></head><body><h3>%1</h3>%2</body></html>" )
.arg( i18n( "Error" ) )
.arg( i18n( "Unable to show selected glossary entry: unable to open "
"file 'glossary.html.in'!" ) );
QString seeAlso;
if (!entry.seeAlso().isEmpty())
{
seeAlso = i18n("See also: ");
GlossaryEntryXRef::List seeAlsos = entry.seeAlso();
GlossaryEntryXRef::List::ConstIterator it = seeAlsos.constBegin();
GlossaryEntryXRef::List::ConstIterator end = seeAlsos.constEnd();
for (; it != end; ++it)
{
seeAlso += QLatin1String("<a href=\"glossentry:");
seeAlso += (*it).id();
seeAlso += QLatin1String("\">") + (*it).term();
seeAlso += QLatin1String("</a>, ");
}
seeAlso = seeAlso.left(seeAlso.length() - 2);
}
QTextStream htmlStream(&htmlFile);
return htmlStream.readAll()
.arg( i18n( "KDE Glossary" ) )
.arg( entry.term() )
.arg( entry.definition() )
.arg( seeAlso );
}
void Glossary::slotSelectGlossEntry( const QString &id )
{
if ( !m_idDict.contains( id ) )
return;
EntryItem *newItem = m_idDict.value( id );
EntryItem *curItem = dynamic_cast<EntryItem *>( currentItem() );
if ( curItem != 0 )
{
if ( curItem->id() == id )
return;
curItem->parent()->setExpanded( false );
}
setCurrentItem( newItem );
}
#include "moc_glossary.cpp"
// vim:ts=4:sw=4:et

145
khelpcenter/glossary.h Normal file
View file

@ -0,0 +1,145 @@
/*
* glossary.h - part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe (raabe@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_GLOSSARY_H
#define KHC_GLOSSARY_H
#include <QTreeWidget>
#include <QDomElement>
#include <QList>
#include <KSharedConfig>
#include <QHash>
#include <KProcess>
class EntryItem;
namespace KHC {
class GlossaryEntryXRef
{
friend QDataStream &operator>>( QDataStream &, GlossaryEntryXRef & );
public:
typedef QList<GlossaryEntryXRef> List;
GlossaryEntryXRef() {}
GlossaryEntryXRef( const QString &term, const QString &id ) :
m_term( term ),
m_id( id )
{
}
QString term() const { return m_term; }
QString id() const { return m_id; }
private:
QString m_term;
QString m_id;
};
inline QDataStream &operator<<( QDataStream &stream, const GlossaryEntryXRef &e )
{
return stream << e.term() << e.id();
}
inline QDataStream &operator>>( QDataStream &stream, GlossaryEntryXRef &e )
{
return stream >> e.m_term >> e.m_id;
}
class GlossaryEntry
{
friend QDataStream &operator>>( QDataStream &, GlossaryEntry & );
public:
GlossaryEntry() {}
GlossaryEntry( const QString &term, const QString &definition,
const GlossaryEntryXRef::List &seeAlso ) :
m_term( term ),
m_definition( definition ),
m_seeAlso( seeAlso )
{ }
QString term() const { return m_term; }
QString definition() const { return m_definition; }
GlossaryEntryXRef::List seeAlso() const { return m_seeAlso; }
private:
QString m_term;
QString m_definition;
GlossaryEntryXRef::List m_seeAlso;
};
inline QDataStream &operator<<( QDataStream &stream, const GlossaryEntry &e )
{
return stream << e.term() << e.definition() << e.seeAlso();
}
inline QDataStream &operator>>( QDataStream &stream, GlossaryEntry &e )
{
return stream >> e.m_term >> e.m_definition >> e.m_seeAlso;
}
class Glossary : public QTreeWidget
{
Q_OBJECT
public:
Glossary( QWidget *parent );
virtual ~Glossary();
const GlossaryEntry &entry( const QString &id ) const;
static QString entryToHtml( const GlossaryEntry &entry );
public Q_SLOTS:
void slotSelectGlossEntry( const QString &id );
Q_SIGNALS:
void entrySelected( const GlossaryEntry &entry );
private Q_SLOTS:
void meinprocFinished(int exitCode, QProcess::ExitStatus exitStatus);
void treeItemSelected( QTreeWidgetItem *item );
protected:
virtual void showEvent(QShowEvent *event);
private:
enum CacheStatus { NeedRebuild, CacheOk };
CacheStatus cacheStatus() const;
int glossaryCTime() const;
void rebuildGlossaryCache();
void buildGlossaryTree();
QDomElement childElement( const QDomElement &e, const QString &name );
KSharedConfigPtr m_config;
QTreeWidgetItem *m_byTopicItem;
QTreeWidgetItem *m_alphabItem;
QString m_sourceFile;
QString m_cacheFile;
CacheStatus m_status;
QHash<QString, GlossaryEntry*> m_glossEntries;
QHash<QString, EntryItem*> m_idDict;
bool m_initialized;
static bool m_alreadyWarned;
};
}
#endif // KHC_GLOSSARY_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,47 @@
<html>
<head>
<title>%1: %2</title>
<link rel="stylesheet" href="help:/common/kde-default.css" type="text/css" />
</head>
<body>
<div style="background-image: url(help:/common/top-middle.png); width: 100%; height: 131px;">
<div style="position: absolute; right: 0px;">
<img src="help:/common/top-right.png" style="margin: 0px" alt="">
</div>
<div style="position: absolute; left: 0px;">
<img src="help:/common/top-left.png" style="margin: 0px" alt="">
</div>
<div style="position: absolute;
top: 25px;
right: 100px;
text-align: right;
font-size: xx-large;
font-weight: bold;
text-shadow: #fff 0px 0px 5px;
color: #444">
%2
</div>
</div>
<div style="margin: 100px;">
%3
<br />
<br />
%4
</div>
<div class="bannerBottom" style="background-image: url(help:/common/bottom-middle.png);
background-repeat: x-repeat;
width: 100%;
height: 100px;
bottom:0px;">
<div class="bannerBottomRight">
<img src="help:/common/bottom-right.png" style="margin: 0px" alt="">
</div>
<div class="bannerBottomLeft">
<img src="help:/common/bottom-left.png" style="margin: 0px;" alt="">
</div>
</div>
</body>
</html>

34
khelpcenter/glossary.xslt Normal file
View file

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="glossary">
<glossary>
<xsl:apply-templates select="glossdiv"/>
</glossary>
</xsl:template>
<xsl:template match="glossdiv">
<section>
<xsl:attribute name="title"><xsl:value-of select="title"/></xsl:attribute>
<xsl:apply-templates select="glossentry"/>
</section>
</xsl:template>
<xsl:template match="glossentry">
<entry>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<term><xsl:value-of select="glossterm"/></term>
<definition><xsl:value-of select="glossdef/*[not(name()='glossseealso')]"/></definition>
<references><xsl:apply-templates select="glossdef/glossseealso"/></references>
</entry>
</xsl:template>
<xsl:template match="glossseealso">
<reference>
<xsl:attribute name="term"><xsl:value-of select="."/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="@otherterm"/></xsl:attribute>
</reference>
</xsl:template>
</xsl:stylesheet>

385
khelpcenter/history.cpp Normal file
View file

@ -0,0 +1,385 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "history.h"
#include "view.h"
#include <QMenu>
#include <KAction>
#include <KActionCollection>
#include <KApplication>
#include <KDebug>
#include <KIcon>
#include <KXmlGuiWindow>
#include <KMenu>
#include <KStandardGuiItem>
#include <KStringHandler>
#include <KToolBarPopupAction>
#include <kxmlguifactory.h>
using namespace KHC;
// TODO: Needs complete redo!
// TODO: oh yeah
History *History::m_instance = 0;
History &History::self()
{
if ( !m_instance )
m_instance = new History;
return *m_instance;
}
History::History() : QObject(),
m_goBuffer( 0 )
{
m_entries_current = m_entries.end();
}
History::~History()
{
qDeleteAll(m_entries);
}
void History::setupActions( KActionCollection *coll )
{
QPair<KGuiItem, KGuiItem> backForward = KStandardGuiItem::backAndForward();
m_backAction = new KToolBarPopupAction( KIcon( backForward.first.iconName() ), backForward.first.text(), this );
coll->addAction( "back", m_backAction );
m_backAction->setShortcut(KStandardShortcut::back());
connect( m_backAction, SIGNAL( triggered() ), this, SLOT( back() ) );
connect( m_backAction->menu(), SIGNAL( triggered( QAction* ) ),
SLOT( backActivated( QAction* ) ) );
connect( m_backAction->menu(), SIGNAL( aboutToShow() ),
SLOT( fillBackMenu() ) );
m_backAction->setEnabled( false );
m_forwardAction = new KToolBarPopupAction( KIcon( backForward.second.iconName() ), backForward.second.text(), this );
coll->addAction( QLatin1String("forward"), m_forwardAction );
m_forwardAction->setShortcut(KStandardShortcut::forward());
connect( m_forwardAction, SIGNAL( triggered() ), this, SLOT( forward() ) );
connect( m_forwardAction->menu(), SIGNAL( triggered( QAction* ) ),
SLOT( forwardActivated( QAction* ) ) );
connect( m_forwardAction->menu(), SIGNAL( aboutToShow() ),
SLOT( fillForwardMenu() ) );
m_forwardAction->setEnabled( false );
}
void History::installMenuBarHook( KXmlGuiWindow *mainWindow )
{
QMenu *goMenu = dynamic_cast<QMenu *>(
mainWindow->guiFactory()->container( QLatin1String("go_web"), mainWindow ) );
if ( goMenu )
{
connect( goMenu, SIGNAL( aboutToShow() ), SLOT( fillGoMenu() ) );
connect( goMenu, SIGNAL( triggered( QAction* ) ),
SLOT( goMenuActivated( QAction* ) ) );
m_goMenuIndex = goMenu->actions().count();
}
}
void History::createEntry()
{
kDebug() << "History::createEntry()";
// First, remove any forward history
if (m_entries_current!=m_entries.end())
{
m_entries.erase(m_entries.begin(),m_entries_current);
// If current entry is empty reuse it.
if ( !(*m_entries_current)->view ) {
return;
}
}
// Append a new entry
m_entries_current = m_entries.insert(m_entries_current, new Entry ); // made current
}
void History::updateCurrentEntry( View *view )
{
if ( m_entries.isEmpty() )
return;
KUrl url = view->url();
Entry *current = *m_entries_current;
QDataStream stream( &current->buffer, QIODevice::WriteOnly );
current->view = view;
if ( url.isEmpty() ) {
kDebug() << "History::updateCurrentEntry(): internal url";
url = view->internalUrl();
}
kDebug() << "History::updateCurrentEntry(): " << view->title()
<< " (URL: " << url.url() << ")" << endl;
current->url = url;
current->title = view->title();
current->search = view->state() == View::Search;
}
void History::updateActions()
{
m_backAction->setEnabled( canGoBack() );
m_forwardAction->setEnabled( canGoForward() );
}
void History::back()
{
kDebug( 1400 ) << "History::back()";
goHistoryActivated( -1 );
}
void History::backActivated( QAction *action )
{
int id = action->data().toInt();
kDebug( 1400 ) << "History::backActivated(): id = " << id;
goHistoryActivated( -( id + 1 ) );
}
void History::forward()
{
kDebug( 1400 ) << "History::forward()";
goHistoryActivated( 1 );
}
void History::forwardActivated( QAction *action )
{
int id = action->data().toInt();
kDebug( 1400 ) << "History::forwardActivated(): id = " << id;
goHistoryActivated( id + 1 );
}
void History::goHistoryActivated( int steps )
{
kDebug( 1400 ) << "History::goHistoryActivated(): m_goBuffer = " << m_goBuffer;
if ( m_goBuffer )
return;
m_goBuffer = steps;
QTimer::singleShot( 0, this, SLOT( goHistoryDelayed() ) );
}
void History::goHistoryDelayed()
{
kDebug( 1400 ) << "History::goHistoryDelayed(): m_goBuffer = " << m_goBuffer;
if ( !m_goBuffer )
return;
int steps = m_goBuffer;
m_goBuffer = 0;
goHistory( steps );
}
void History::goHistory( int steps )
{
kDebug() << "History::goHistory(): " << steps;
// If current entry is empty remove it.
Entry *current = *m_entries_current;
if ( current && !current->view ) m_entries_current = m_entries.erase(m_entries_current);
EntryList::iterator newPos = m_entries_current - steps;
current = *newPos;
if ( !current ) {
kError() << "No History entry at position " << newPos - m_entries.begin() << endl;
return;
}
if ( !current->view ) {
kWarning() << "Empty history entry." ;
return;
}
m_entries_current = newPos;
if ( current->search ) {
kDebug() << "History::goHistory(): search";
current->view->lastSearch();
return;
}
if ( current->url.protocol() == QLatin1String("khelpcenter") ) {
kDebug() << "History::goHistory(): internal";
emit goInternalUrl( current->url );
return;
}
kDebug() << "History::goHistory(): restore state";
emit goUrl( current->url );
Entry h( *current );
h.buffer.detach();
QDataStream stream( h.buffer );
updateCurrentEntry( h.view );
updateActions();
}
void History::fillBackMenu()
{
QMenu *menu = m_backAction->menu();
menu->clear();
fillHistoryPopup( menu, true, false, false );
}
void History::fillForwardMenu()
{
QMenu *menu = m_forwardAction->menu();
menu->clear();
fillHistoryPopup( menu, false, true, false );
}
void History::fillGoMenu()
{
KXmlGuiWindow *mainWindow = static_cast<KXmlGuiWindow *>( kapp->activeWindow() );
QMenu *goMenu = dynamic_cast<QMenu *>( mainWindow->guiFactory()->container( QLatin1String( "go" ), mainWindow ) );
if ( !goMenu || m_goMenuIndex == -1 )
return;
for ( int i = goMenu->actions().count() - 1 ; i >= m_goMenuIndex; i-- )
goMenu->removeAction( goMenu->actions()[i] );
// TODO perhaps smarter algorithm (rename existing items, create new ones only if not enough) ?
// Ok, we want to show 10 items in all, among which the current url...
if ( m_entries.count() <= 9 )
{
// First case: limited history in both directions -> show it all
m_goMenuHistoryStartPos = m_entries.count() - 1; // Start right from the end
} else
// Second case: big history, in one or both directions
{
// Assume both directions first (in this case we place the current URL in the middle)
m_goMenuHistoryStartPos = (m_entries_current - m_entries.begin()) + 4;
// Forward not big enough ?
if ( m_goMenuHistoryStartPos > (int) m_entries.count() - 4 )
m_goMenuHistoryStartPos = m_entries.count() - 1;
}
Q_ASSERT( m_goMenuHistoryStartPos >= 0 && (int) m_goMenuHistoryStartPos < m_entries.count() );
m_goMenuHistoryCurrentPos = m_entries_current - m_entries.begin(); // for slotActivated
fillHistoryPopup( goMenu, false, false, true, m_goMenuHistoryStartPos );
}
void History::goMenuActivated( QAction* action )
{
KXmlGuiWindow *mainWindow = static_cast<KXmlGuiWindow *>( kapp->activeWindow() );
QMenu *goMenu = dynamic_cast<QMenu *>( mainWindow->guiFactory()->container( QLatin1String( "go" ), mainWindow ) );
if ( !goMenu )
return;
// 1 for first item in the list, etc.
int index = goMenu->actions().indexOf(action) - m_goMenuIndex + 1;
if ( index > 0 )
{
kDebug(1400) << "Item clicked has index " << index;
// -1 for one step back, 0 for don't move, +1 for one step forward, etc.
int steps = ( m_goMenuHistoryStartPos+1 ) - index - m_goMenuHistoryCurrentPos; // make a drawing to understand this :-)
kDebug(1400) << "Emit activated with steps = " << steps;
goHistory( steps );
}
}
void History::fillHistoryPopup( QMenu *popup, bool onlyBack, bool onlyForward, bool checkCurrentItem, uint startPos )
{
Q_ASSERT ( popup ); // kill me if this 0... :/
Entry * current = *m_entries_current;
QList<Entry*>::iterator it = m_entries.begin();
if (onlyBack || onlyForward)
{
it = m_entries_current; // Jump to current item
// And move off it
if ( !onlyForward ) {
if ( it != m_entries.end() ) ++it;
} else {
if ( it != m_entries.begin() ) --it;
}
} else if ( startPos )
it += startPos; // Jump to specified start pos
uint i = 0;
while ( it != m_entries.end() )
{
QString text = (*it)->title;
text = KStringHandler::csqueeze(text, 50); //CT: squeeze
text.replace( '&', "&&" );
QAction *action = popup->addAction( text );
action->setData( i );
if ( checkCurrentItem && *it == current )
{
action->setChecked( true ); // no pixmap if checked
}
if ( ++i > 10 )
break;
if ( !onlyForward ) {
++it;
} else {
if ( it == m_entries.begin() ) {
it = m_entries.end();
} else {
--it;
}
}
}
}
bool History::canGoBack() const
{
return m_entries.size()>1 && EntryList::const_iterator(m_entries_current) != (m_entries.begin()+(m_entries.size()-1));
}
bool History::canGoForward() const
{
return EntryList::const_iterator(m_entries_current) != m_entries.constBegin() && m_entries.size() > 1;
}
void History::dumpHistory() const {
for(EntryList::const_iterator it = m_entries.constBegin() ; it!=m_entries.constEnd() ; ++it) {
kDebug() << (*it)->title << (*it)->url << (it==EntryList::const_iterator(m_entries_current) ? "current" : "" ) ;
}
}
#include "moc_history.cpp"
// vim:ts=2:sw=2:et

118
khelpcenter/history.h Normal file
View file

@ -0,0 +1,118 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe <raabe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_HISTORY_H
#define KHC_HISTORY_H
#include <KUrl>
#include <QObject>
#include <QMenu>
#include <QList>
class KActionCollection;
class KXmlGuiWindow;
class KToolBarPopupAction;
class QMenu;
namespace KHC {
class View;
class History : public QObject
{
Q_OBJECT
public:
friend class foo; // to make gcc shut up
struct Entry
{
Entry() : view( 0 ), search( false ) {}
View *view;
KUrl url;
QString title;
QByteArray buffer;
bool search;
};
static History &self();
void setupActions( KActionCollection *coll );
void updateActions();
void installMenuBarHook( KXmlGuiWindow *mainWindow );
void createEntry();
void updateCurrentEntry( KHC::View *view );
Q_SIGNALS:
void goInternalUrl( const KUrl & );
void goUrl( const KUrl & );
private Q_SLOTS:
void backActivated( QAction *action );
void fillBackMenu();
void forwardActivated( QAction *action );
void fillForwardMenu();
void goMenuActivated( QAction* action );
void fillGoMenu();
void back();
void forward();
void goHistoryActivated( int steps );
void goHistory( int steps );
void goHistoryDelayed();
private:
History();
History( const History &rhs );
History &operator=( const History &rhs );
~History();
typedef QList<Entry*> EntryList;
bool canGoBack() const;
bool canGoForward() const;
void fillHistoryPopup( QMenu *, bool, bool, bool, uint = 0 );
/**
* dumps the history with a kDebug and mark wihch one is the current one
* This is a debugging function.
*/
void dumpHistory() const;
static History *m_instance;
EntryList m_entries;
EntryList::Iterator m_entries_current;
int m_goBuffer;
int m_goMenuIndex;
int m_goMenuHistoryStartPos;
int m_goMenuHistoryCurrentPos;
public:
KToolBarPopupAction *m_backAction;
KToolBarPopupAction *m_forwardAction;
};
}
#endif // KHC_HISTORY_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,62 @@
#include "htmlsearch.h"
#include <KDebug>
#include <KConfig>
#include <KConfigGroup>
#include "docentry.h"
#include "moc_htmlsearch.cpp"
using namespace KHC;
HTMLSearch::HTMLSearch()
{
mConfig = new KConfig("khelpcenterrc");
}
HTMLSearch::~HTMLSearch()
{
delete mConfig;
}
void HTMLSearch::setupDocEntry( KHC::DocEntry *entry )
{
// kDebug() << "HTMLSearch::setupDocEntry(): " << entry->name();
if ( entry->searchMethod().toLower() != QLatin1String("htdig") ) return;
if ( entry->search().isEmpty() )
entry->setSearch( defaultSearch( entry ) );
if ( entry->indexer().isEmpty() )
entry->setIndexer( defaultIndexer( entry ) );
if ( entry->indexTestFile().isEmpty() )
entry->setIndexTestFile( defaultIndexTestFile( entry ) );
// entry->dump();
}
QString HTMLSearch::defaultSearch( KHC::DocEntry *entry )
{
QString htsearch = QLatin1String("cgi:");
htsearch += mConfig->group("htdig").readPathEntry( "htsearch", QString() );
htsearch += "?words=%k&method=and&format=-desc&config=";
htsearch += entry->identifier();
return htsearch;
}
QString HTMLSearch::defaultIndexer( KHC::DocEntry * )
{
QString indexer = mConfig->group("htdig").readPathEntry( "indexer", QString() );
indexer += " --indexdir=%i %f";
return indexer;
}
QString HTMLSearch::defaultIndexTestFile( KHC::DocEntry *entry )
{
return entry->identifier() + QLatin1String(".exists");
}
// vim:ts=2:sw=2:et

51
khelpcenter/htmlsearch.h Normal file
View file

@ -0,0 +1,51 @@
/* This file is part of the KDE project
Copyright 2002 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published
by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KHC_HTMLSEARCH_H
#define KHC_HTMLSEARCH_H
#include <QObject>
class KConfig;
namespace KHC {
class DocEntry;
class HTMLSearch : public QObject
{
Q_OBJECT
public:
HTMLSearch();
~HTMLSearch();
void setupDocEntry( KHC::DocEntry * );
QString defaultSearch( KHC::DocEntry * );
QString defaultIndexer( KHC::DocEntry * );
QString defaultIndexTestFile( KHC::DocEntry * );
private:
KConfig *mConfig;
};
}
#endif //KHC_HTMLSEARCH_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,50 @@
########### next target ###############
set(htmlsearch_LIB_SRCS htmlsearch.cpp progressdialog.cpp)
kde4_add_library(htmlsearch SHARED ${htmlsearch_LIB_SRCS})
target_link_libraries(htmlsearch ${KDE4_KIO_LIBS})
set_target_properties(htmlsearch PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
install(TARGETS htmlsearch ${INSTALL_TARGETS_DEFAULT_ARGS})
########### next target ###############
set(kcm_htmlsearch_LIB_SRCS kcmhtmlsearch.cpp klangcombo.cpp ktagcombobox.cpp)
kde4_add_library(kcm_htmlsearch SHARED ${kcm_htmlsearch_LIB_SRCS})
target_link_libraries(kcm_htmlsearch ${KDE4_KIO_LIBS})
set_target_properties(kcm_htmlsearch PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
install(TARGETS kcm_htmlsearch ${INSTALL_TARGETS_DEFAULT_ARGS})
########### next target ###############
set(khtmlindex_SRCS index.cpp )
kde4_add_executable(khtmlindex ${khtmlindex_SRCS})
target_link_libraries(khtmlindex ${KDE4_KDEUI_LIBS} htmlsearch )
install(PROGRAMS khtmlindex ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install( FILES htmlsearch.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install( FILES long.html short.html wrapper.html nomatch.html syntax.html DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/en )
install( FILES star.png star_blank.png DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/pics )
install( FILES unchecked.xpm checked.xpm DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/pics )
install( PROGRAMS meinproc_wrapper DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/ )
kde4_install_icons( ${DATA_INSTALL_DIR}/khelpcenter/ )

View file

@ -0,0 +1,4 @@
#! /usr/bin/env bash
### TODO: why do we need 2 POT files for one directory?
$XGETTEXT index.cpp htmlsearch.cpp progressdialog.cpp rc.cpp -o $podir/htmlsearch.pot
$XGETTEXT kcmhtmlsearch.cpp klangcombo.cpp ktagcombobox.cpp rc.cpp -o $podir/kcmhtmlsearch.pot

View file

@ -0,0 +1,23 @@
/* XPM */
static char*unchecked[]={
"16 16 4 1",
"# c #000000",
"+ c #ffffff",
"D c #000000",
". c None",
"................",
"............++++",
"..++++++++++DDD+",
"..+########DDD+.",
"..+#++++++DDD+..",
"+DDD+...+DDD#+..",
"++DDD+++DDD+#+..",
"..+DDDDDDD++#+..",
"..+#DDDDD+.+#+..",
"..+#++DD+..+#+..",
"..+#+++++..+#+..",
"..+#++++++++#+..",
"..+##########+..",
"..++++++++++++..",
"................",
"................"};

View file

@ -0,0 +1,479 @@
#include <QRegExp>
#include <QDir>
#include <assert.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <k3process.h>
#include <klocale.h>
#include <kconfig.h>
#include "progressdialog.h"
#include <QTextStream>
#include "moc_htmlsearch.cpp"
HTMLSearch::HTMLSearch()
: QObject(), _proc(0)
{
}
QString HTMLSearch::dataPath(const QString& _lang)
{
return kapp->dirs()->saveLocation("data", QString("khelpcenter/%1").arg(_lang));
}
void HTMLSearch::scanDir(const QString& dir)
{
assert( dir.at( dir.length() - 1 ) == '/' );
QStringList::ConstIterator it;
if ( KStandardDirs::exists( dir + "index.docbook" ) ) {
_files.append(dir + "index.docbook");
progress->setFilesScanned(++_filesScanned);
} else {
QDir d(dir, "*.html", QDir::Name|QDir::IgnoreCase, QDir::Files | QDir::Readable);
QStringList const &list = d.entryList();
QString adir = d.canonicalPath () + '/';
QString file;
for (it=list.begin(); it != list.end(); ++it)
{
file = adir + *it;
if ( !_files.contains( file ) ) {
_files.append(file);
progress->setFilesScanned(++_filesScanned);
}
}
}
QDir d2(dir, QString(), QDir::Name|QDir::IgnoreCase, QDir::Dirs);
QStringList const &dlist = d2.entryList();
for (it=dlist.begin(); it != dlist.end(); ++it)
if (*it != "." && *it != "..")
{
scanDir(dir + *it + '/');
kapp->processEvents();
}
}
bool HTMLSearch::saveFilesList(const QString& _lang)
{
QStringList dirs;
// throw away old files list
_files.clear();
// open config file
KConfig config("khelpcenterrc");
KConfigGroup scopeGroup( &config, "Scope" );
// add KDE help dirs
if (scopeGroup.readEntry("KDE", true))
dirs = kapp->dirs()->findDirs("html", _lang + '/');
kDebug() << "got " << dirs.count() << " dirs\n";
// TODO: Man and Info!!
// add local urls
QStringList add = scopeGroup.readEntry("Paths", QStringList() );
QStringList::const_iterator it;
for (it = add.begin(); it != add.end(); ++it) {
if ( ( *it ).at( ( *it ).length() - 1 ) != '/' )
( *it ) += '/';
dirs.append(*it);
}
_filesScanned = 0;
for (it = dirs.begin(); it != dirs.end(); ++it)
scanDir(*it);
return true;
}
bool HTMLSearch::createConfig(const QString& _lang)
{
QString fname = dataPath(_lang) + "/htdig.conf";
// locate the common dir
QString wrapper = locate("data", QString("khelpcenter/%1/wrapper.html").arg(_lang));
if (wrapper.isEmpty())
wrapper = locate("data", QString("khelpcenter/en/wrapper.html"));
if (wrapper.isEmpty())
return false;
wrapper = wrapper.left(wrapper.length() - 12);
// locate the image dir
QString images = locate("data", "khelpcenter/pics/star.png");
if (images.isEmpty())
return false;
images = images.left(images.length() - 8);
// This is an example replacement for the default bad_words file
// distributed with ht://Dig. It was compiled by Marjolein Katsma
// <HSH@taxon.demon.nl>.
QString bad_words = i18nc( "List of words to exclude from index",
"above:about:according:across:actually:\n"
"adj:after:afterwards:again:against:all:\n"
"almost:alone:along:already:also:although:\n"
"always:among:amongst:and:another:any:\n"
"anyhow:anyone:anything:anywhere:are:aren:\n"
"arent:around:became:because:become:\n"
"becomes:becoming:been:before:beforehand:\n"
"begin:beginning:behind:being:below:beside:\n"
"besides:between:beyond:billion:both:but:\n"
"can:cant:cannot:caption:could:couldnt:\n"
"did:didnt:does:doesnt:dont:down:during:\n" //krazy:exclude=spelling
"each:eight:eighty:either:else:elsewhere:\n"
"end:ending:enough:etc:even:ever:every:\n"
"everyone:everything:everywhere:except:few:\n"
"fifty:first:five:for:former:formerly:forty:\n"
"found:four:from:further:had:has:hasnt:have:\n" //krazy:exclude=spelling
"havent:hence:her:here:hereafter:hereby:\n"
"herein:heres:hereupon:hers:herself:hes:him:\n"
"himself:his:how:however:hundred:\n"
"inc:indeed:instead:into:isnt:its:\n"
"itself:last:later:latter:latterly:least:\n"
"less:let:like:likely:ltd:made:make:makes:\n"
"many:may:maybe:meantime:meanwhile:might:\n"
"million:miss:more:moreover:most:mostly:\n"
"mrs:much:must:myself:namely:neither:\n"
"never:nevertheless:next:nine:ninety:\n"
"nobody:none:nonetheless:noone:nor:not:\n" //krazy:exclude=spelling
"nothing:now:nowhere:off:often:once:\n"
"one:only:onto:others:otherwise:our:ours:\n"
"ourselves:out:over:overall:own:page:per:\n"
"perhaps:rather:recent:recently:same:\n"
"seem:seemed:seeming:seems:seven:seventy:\n"
"several:she:shes:should:shouldnt:since:six:\n" //krazy:exclude=spelling
"sixty:some:somehow:someone:something:\n"
"sometime:sometimes:somewhere:still:stop:\n"
"such:taking:ten:than:that:the:their:them:\n"
"themselves:then:thence:there:thereafter:\n"
"thereby:therefore:therein:thereupon:these:\n"
"they:thirty:this:those:though:thousand:\n"
"three:through:throughout:thru:thus:tips:\n"
"together:too:toward:towards:trillion:\n"
"twenty:two:under:unless:unlike:unlikely:\n"
"until:update:updated:updates:upon:\n"
"used:using:very:via:want:wanted:wants:\n"
"was:wasnt:way:ways:wed:well:were:\n"
"werent:what:whats:whatever:when:whence:\n"
"whenever:where:whereafter:whereas:whereby:\n"
"wherein:whereupon:wherever:wheres:whether:\n"
"which:while:whither:who:whoever:whole:\n"
"whom:whomever:whose:why:will:with:within:\n"
"without:wont:work:worked:works:working:\n"
"would:wouldnt:yes:yet:you:youd:youll:your:\n"
"youre:yours:yourself:yourselves:youve" );
QFile f;
f.setName( dataPath(_lang) + "/bad_words" );
if (f.open(QIODevice::WriteOnly))
{
QTextStream ts( &f );
QStringList words = bad_words.split( QRegExp ( "[\n:]" ), QString::SkipEmptyParts );
for ( QStringList::ConstIterator it = words.begin();
it != words.end(); ++it )
ts << *it << endl;
f.close();
}
f.setName(fname);
if (f.open(QIODevice::WriteOnly))
{
kDebug() << "Writing config for " << _lang << " to " << fname;
QTextStream ts(&f);
ts << "database_dir:\t\t" << dataPath(_lang) << endl;
ts << "start_url:\t\t`" << dataPath(_lang) << "/files`" << endl;
ts << "local_urls:\t\tfile:/=/" << endl;
ts << "local_urls_only:\ttrue" << endl;
ts << "maximum_pages:\t\t1" << endl;
ts << "image_url_prefix:\t" << images << endl;
ts << "star_image:\t\t" << images << "star.png" << endl;
ts << "star_blank:\t\t" << images << "star_blank.png" << endl;
ts << "compression_level:\t6" << endl;
ts << "max_hop_count:\t\t0" << endl;
ts << "search_results_wrapper:\t" << wrapper << "wrapper.html" << endl;
ts << "nothing_found_file:\t" << wrapper << "nomatch.html" << endl;
ts << "syntax_error_file:\t" << wrapper << "syntax.html" << endl;
ts << "bad_word_list:\t\t" << dataPath(_lang) << "/bad_words" << endl;
ts << "external_parsers:\t" << "text/xml\t" << locate( "data", "khelpcenter/meinproc_wrapper" ) << endl;
f.close();
return true;
}
return false;
}
#define CHUNK_SIZE 15
bool HTMLSearch::generateIndex( const QString & _lang, QWidget *parent)
{
if (_lang == "C")
_lang = "en";
if (!createConfig(_lang))
return false;
// create progress dialog
progress = new ProgressDialog(parent);
progress->show();
kapp->processEvents();
// create files list ----------------------------------------------
if (!saveFilesList(_lang))
return false;
progress->setState(1);
// run htdig ------------------------------------------------------
KConfig config("khelpcenterrc", true);
KConfigGroup group(&config, "htdig");
QString exe = group.readPathEntry("htdig", KGlobal::dirs()->findExe("htdig"));
if (exe.isEmpty())
{
return false;
}
bool initial = true;
bool done = false;
int count = 0;
_filesToDig = _files.count();
progress->setFilesToDig(_filesToDig);
_filesDigged = 0;
QDir d; d.mkdir(dataPath(_lang));
while (!done)
{
// kill old process
delete _proc;
// prepare new process
_proc = new K3Process();
*_proc << exe << "-v" << "-c" << dataPath(_lang)+"/htdig.conf";
if (initial)
{
*_proc << "-i";
initial = false;
}
kDebug() << "Running htdig";
connect(_proc, SIGNAL(receivedStdout(K3Process *,char*,int)),
this, SLOT(htdigStdout(K3Process *,char*,int)));
connect(_proc, SIGNAL(processExited(K3Process *)),
this, SLOT(htdigExited(K3Process *)));
_htdigRunning = true;
// write out file
QFile f(dataPath(_lang)+"/files");
if (f.open(QIODevice::WriteOnly))
{
QTextStream ts(&f);
for (int i=0; i<CHUNK_SIZE; ++i, ++count)
if (count < _filesToDig) {
ts << "file://" + _files[count] << endl;
} else {
done = true;
break;
}
f.close();
}
else
{
kDebug() << "Could not open `files` for writing";
return false;
}
// execute htdig
_proc->start(K3Process::NotifyOnExit, K3Process::Stdout );
kapp->enter_loop();
if (!_proc->normalExit() || _proc->exitStatus() != 0)
{
delete _proc;
delete progress;
return false;
}
// _filesDigged += CHUNK_SIZE;
progress->setFilesDigged(_filesDigged);
kapp->processEvents();
}
progress->setState(2);
// run htmerge -----------------------------------------------------
exe = group.readPathEntry("htmerge", kapp->dirs()->findExe("htmerge"));
if (exe.isEmpty())
{
return false;
}
delete _proc;
_proc = new K3Process();
*_proc << exe << "-c" << dataPath(_lang)+"/htdig.conf";
kDebug() << "Running htmerge";
connect(_proc, SIGNAL(processExited(K3Process *)),
this, SLOT(htmergeExited(K3Process *)));
_htmergeRunning = true;
_proc->start(K3Process::NotifyOnExit, K3Process::Stdout);
kapp->enter_loop();
if (!_proc->normalExit() || _proc->exitStatus() != 0)
{
delete _proc;
delete progress;
return false;
}
delete _proc;
progress->setState(3);
kapp->processEvents();
delete progress;
return true;
}
void HTMLSearch::htdigStdout(K3Process *, char *buffer, int len)
{
QString line = QString(buffer).left(len);
int cnt=0, index=-1;
while ( (index = line.find("file://", index+1)) > 0)
cnt++;
_filesDigged += cnt;
cnt=0;
index=-1;
while ( (index = line.find("not changed", index+1)) > 0)
cnt++;
_filesDigged -= cnt;
progress->setFilesDigged(_filesDigged);
}
void HTMLSearch::htdigExited(K3Process *p)
{
kDebug() << "htdig terminated " << p->exitStatus();
_htdigRunning = false;
kapp->exit_loop();
}
void HTMLSearch::htmergeExited(K3Process *)
{
kDebug() << "htmerge terminated";
_htmergeRunning = false;
kapp->exit_loop();
}
void HTMLSearch::htsearchStdout(K3Process *, char *buffer, int len)
{
_searchResult += QString::fromLocal8Bit(buffer,len);
}
void HTMLSearch::htsearchExited(K3Process *)
{
kDebug() << "htsearch terminated";
_htsearchRunning = false;
kapp->exit_loop();
}
QString HTMLSearch::search( const QString & _lang, const QString & words, const QString & method, int matches,
const QString & format, const QString & sort)
{
if (_lang == "C")
_lang = "en";
createConfig(_lang);
QString result = dataPath(_lang)+"/result.html";
// run htsearch ----------------------------------------------------
KConfig *config = new KConfig("khelpcenterrc", true);
KConfigGroup group(config, "htdig");
QString exe = group.readPathEntry("htsearch", kapp->dirs()->findExe("htsearch"));
if (exe.isEmpty())
{
delete config;
return QString();
}
_proc = new K3Process();
*_proc << exe << "-c" << dataPath(_lang)+"/htdig.conf" <<
QString("words=%1;method=%2;matchesperpage=%3;format=%4;sort=%5").arg(words).arg(method).arg(matches).arg(format).arg(sort);
kDebug() << "Running htsearch";
connect(_proc, SIGNAL(receivedStdout(K3Process *,char*,int)),
this, SLOT(htsearchStdout(K3Process *,char*,int)));
connect(_proc, SIGNAL(processExited(K3Process *)),
this, SLOT(htsearchExited(K3Process *)));
_htsearchRunning = true;
_searchResult = "";
_proc->start(K3Process::NotifyOnExit, K3Process::Stdout);
kapp->enter_loop();
if (!_proc->normalExit() || _proc->exitStatus() != 0)
{
kDebug() << "Error running htsearch... returning now";
delete _proc;
delete config;
return QString();
}
delete _proc;
// modify the search result
_searchResult = _searchResult.replace("http://localhost/", "file:/");
_searchResult = _searchResult.remove("Content-type: text/html");
// dump the search result
QFile f(result);
if (f.open(QIODevice::WriteOnly))
{
QTextStream ts(&f);
ts << _searchResult << endl;
f.close();
delete config;
return result;
}
delete config;
return QString();
}

View file

@ -0,0 +1,256 @@
[Desktop Entry]
Exec=kcmshell4 htmlsearch
Icon=help_index
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/help-index.html
X-KDE-Library=kcm_htmlsearch
X-KDE-FactoryName=htmlsearch
X-KDE-ParentApp=kcontrol
Name=Index
Name[af]=Indeks
Name[ar]=الفهرس
Name[ast]=Índiz
Name[be]=Індэкс
Name[be@latin]=Źmiest
Name[bg]=Индекс
Name[bn]=ি
Name[bn_IN]=
Name[br]=Meneger
Name[bs]=Indeks
Name[ca]=Índex
Name[ca@valencia]=Índex
Name[cs]=Rejstřík
Name[csb]=Indeks
Name[cy]=Mynegai
Name[da]=Indeks
Name[de]=Stichwortverzeichnis
Name[el]=Ευρετήριο
Name[en_GB]=Index
Name[eo]=Indekso
Name[es]=Índice
Name[et]=Indeks
Name[eu]=Indizea
Name[fa]=فهرست
Name[fi]=Hakemisto
Name[fr]=Index
Name[fy]=Yndeks
Name[ga]=Innéacs
Name[gl]=Índice
Name[gu]=િ
Name[he]=אינדקס
Name[hi]=िि
Name[hne]=िि
Name[hr]=Indeks
Name[hsb]=Indeks
Name[hu]=Keresési index
Name[ia]=Indice
Name[id]=Indeks
Name[is]=Yfirlit
Name[it]=Indice
Name[ja]=
Name[ka]=
Name[kk]=Индекс
Name[km]=
Name[kn]= ()
Name[ko]=
Name[ku]=Pêrist
Name[lt]=Rodyklė
Name[lv]=Indekss
Name[mai]=
Name[mk]=Индекс
Name[ml]=ി
Name[mr]=
Name[ms]=Indeks
Name[nb]=Indeks
Name[nds]=Index
Name[ne]=ि
Name[nl]=Index
Name[nn]=Indeks
Name[oc]=Indèx
Name[or]=ି
Name[pa]=
Name[pl]=Indeks
Name[pt]=Índice
Name[pt_BR]=Índice
Name[ro]=Index
Name[ru]=Индекс
Name[se]=Indeaksa
Name[si]=
Name[sk]=Index
Name[sl]=Kazalo
Name[sr]=Индекс
Name[sr@ijekavian]=Индекс
Name[sr@ijekavianlatin]=Indeks
Name[sr@latin]=Indeks
Name[sv]=Index
Name[ta]=
Name[te]=ి
Name[tg]=Индекс
Name[th]=
Name[tr]=Dizin
Name[ug]=مۇندەرىجە
Name[uk]=Індекс
Name[uz]=Indeks
Name[uz@cyrillic]=Индекс
Name[vi]=ch mc
Name[wa]=Indecse
Name[xh]=Isalathiso
Name[x-test]=xxIndexxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Index generation
Comment[af]=Indeks genereering
Comment[ar]=توليد الفهرس
Comment[ast]=Xeneración del índiz
Comment[be]=Стварэнне індэксу
Comment[be@latin]=Stvareńnie źmiestu
Comment[bg]=Създаване на индекс
Comment[bn]=ি
Comment[bn_IN]= ি
Comment[br]=Genel ar meneger
Comment[bs]=Stvaranje indeksa
Comment[ca]=Generació de l'índex
Comment[ca@valencia]=Generació de l'índex
Comment[cs]=Vytvoření rejstříku
Comment[csb]=Generowanié indeksu
Comment[cy]=Cynhyrchu mynegai
Comment[da]=Indeksgenerering
Comment[de]=Erstellung des Stichwortverzeichnisses
Comment[el]=Δημιουργία περιεχομένων
Comment[en_GB]=Index generation
Comment[eo]=Kreado de indekso
Comment[es]=Generación del índice
Comment[et]=Indeksi loomine
Comment[eu]=Indizea sortzea
Comment[fa]=تولید فهرست
Comment[fi]=Hakemiston luonti
Comment[fr]=Génération d'index
Comment[fy]=Yndeksgeneraasje
Comment[ga]=Giniúint innéacs
Comment[gl]=Xeración do índice
Comment[gu]=િ
Comment[he]=יצירת אינדקס
Comment[hi]=
Comment[hne]=
Comment[hr]=Generiranje indeksa
Comment[hsb]=Stworjenje indeksa
Comment[hu]=Index létrehozása
Comment[ia]=Generation de indice
Comment[id]=Pembuatan indeks
Comment[is]=Yfirlitsgerð
Comment[it]=Generazione dell'indice
Comment[ja]=
Comment[ka]=
Comment[kk]=Индексті құру
Comment[km]=
Comment[kn]= () ಿ
Comment[ko]=
Comment[ku]=Afirandina pêristê
Comment[lt]=Rodyklės generavimas
Comment[lv]=Indeksa ģenerēšana
Comment[mai]=
Comment[mk]=Генерирање на индекс
Comment[ml]=ിി
Comment[mr]=
Comment[ms]=Penjanaan indeks
Comment[nb]=Lag innholdsregister
Comment[nds]=Index maken
Comment[ne]=ि ि
Comment[nl]=Indexgeneratie
Comment[nn]=Indekslaging
Comment[or]=ି ି
Comment[pa]=
Comment[pl]=Generowanie indeksu
Comment[pt]=Geração de índices
Comment[pt_BR]=Geração de índice
Comment[ro]=Generează indexul
Comment[ru]=Создание индекса
Comment[se]=Indeaksaráhkadeapmi
Comment[si]=
Comment[sk]=Generovanie indexu
Comment[sl]=Ustvarjanje kazala
Comment[sr]=Стварање индекса
Comment[sr@ijekavian]=Стварање индекса
Comment[sr@ijekavianlatin]=Stvaranje indeksa
Comment[sr@latin]=Stvaranje indeksa
Comment[sv]=Indexskapare
Comment[ta]=
Comment[te]=ి
Comment[tg]=Эҷоди индекс
Comment[th]=
Comment[tr]=Dizin oluşturma
Comment[ug]=ئىندېكس ھاسىل قىلىش
Comment[uk]=Створення індексу
Comment[uz]=Indeksni yaratish
Comment[uz@cyrillic]=Индексни яратиш
Comment[vi]=To ra ch mc
Comment[wa]=Fijhaedje d' indecse
Comment[xh]=Ulwenziwo Lwesalathiso
Comment[x-test]=xxIndex generationxx
Comment[zh_CN]=
Comment[zh_TW]=
X-KDE-Keywords=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[ar]=مساعدة,HTML,بحث,فهرس,htdig,htsearch,htmerge,نطاق,لغة
X-KDE-Keywords[bg]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,Помощ,Търсене,Индекс,Език
X-KDE-Keywords[bn]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[bs]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,pomoć,pretraga,indeks
X-KDE-Keywords[ca]=Ajuda,HTML,Cerca,Índex,htdig,htsearch,htmerge,Àmbit,Idioma
X-KDE-Keywords[ca@valencia]=Ajuda,HTML,Cerca,Índex,htdig,htsearch,htmerge,Àmbit,Idioma
X-KDE-Keywords[cs]=Nápověda,HTML,Hledání,htdig,htsearch,htmerge,Rozsah,Jazyk
X-KDE-Keywords[da]=Hjælp,HTML,Søgning,Indeks,htdig,htsearch,htmerge,Scope,sprog
X-KDE-Keywords[de]=Hilfe,HTML,Suche,Index,Stichwortverzeichnis,htdig,Sprachen
X-KDE-Keywords[el]=Βοήθεια,HTML,αναζήτηση,ευρετήριο,htdig,htsearch,htmerge,εμβέλεια,γλώσσα
X-KDE-Keywords[en_GB]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[eo]=Helpo,HTML,Serĉi,Indekso,htdig,htsearch,htmerge,Amplekso,Lingvo
X-KDE-Keywords[es]=Ayuda,HTML,Buscar,Indice,htdig,htsearch,htmerge,Ámbito,Idioma
X-KDE-Keywords[et]=abi,HTML,otsing,indeks,htdig,htsearch,htmerge,keel
X-KDE-Keywords[eu]=Laguntza,HTML,Bilaketa,Indizea,htdig,htsearch,htmerge,Esparrua,Hizkuntza
X-KDE-Keywords[fa]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[fi]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,Ohjeet,HTML,Haku,Indeksi,Hakemisto,Laajuus,Kieli
X-KDE-Keywords[fr]=Aide, HTML, recherche, index, htdig, htsearch, htmerge, étendue, langage
X-KDE-Keywords[ga]=Cabhair,HTML,Cuardach,Innéacs,htdig,htsearch,htmerge,Scóip,Teanga
X-KDE-Keywords[gl]=Axuda, buscar, índice, html, htdig, htsearch, htmerge, lingua, ámbito
X-KDE-Keywords[gu]=,HTML,,,htdig,htsearch,htmerge,,
X-KDE-Keywords[hi]=, HTML, , , htdig, htsearch, htmerge, ,
X-KDE-Keywords[hu]=Súgó,HTML,Keresés,Index,htdig,htsearch,htmerge,Tartomány,Nyelv
X-KDE-Keywords[ia]=Adjuta,HTML,Cerca,Indice,htdig,htsearch,htmerge,Scopo,Linguage
X-KDE-Keywords[id]=Bantuan,HTML,Cari,Indeks,htding,htsearch,htmerge,Cakupan,Bahasa
X-KDE-Keywords[is]=Hjálp,HTML,Leit,Yfirlit,htdig,htsearch,htmerge,Svið,Tungumál
X-KDE-Keywords[it]=aiuto,HTML,ricerca,indice,htdig,htsearch,htmerge,contesto,lingua
X-KDE-Keywords[ja]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[kk]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[km]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[ko]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,,,,
X-KDE-Keywords[lv]=Palīdzība,HTML,meklēšana,indekss,htdig,htsearch,htmerge,Scope,valoda
X-KDE-Keywords[mr]=, HTML, , ि, htdig,htsearch,htmerge, ,
X-KDE-Keywords[nb]=Hjelp,HTML,Søk,Index,htdig,htsearch,htmerge,omfang,språk
X-KDE-Keywords[nds]=Hülp.HTML,Söök,Index,htsearch,htmerge,Rebeet,Spraak
X-KDE-Keywords[nl]=Help,HTML,zoeken,index,htdig,htsearch,htmerge,scope,taal
X-KDE-Keywords[nn]=Hjelp,HTML,Søk,indeksering,htdig,htsearch,htmerge,omfang,Scope,Språk
X-KDE-Keywords[pa]=,HTML,,,,htdig,htsearch,htmerge,,,
X-KDE-Keywords[pl]=Pomoc,HTML,Znajdowanie,Wyszukiwanie,Indeks,htdig,htsearch,htmerge,Zakres,Język
X-KDE-Keywords[pt]=Ajuda,HTML,Pesquisa,Índice,htdig,htsearch,htmerge,Âmbito,Linguagem
X-KDE-Keywords[pt_BR]=Ajuda,HTML,Pesquisa,Índice,htdig,htsearch,htmerge,Âmbito,Linguagem
X-KDE-Keywords[ro]=ajutor,HTML,căutare,caută,cuprins,htdig,htsearch,htmerge,limbă
X-KDE-Keywords[ru]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,помощь,справка,поиск,индекс,язык
X-KDE-Keywords[sk]=Pomoc,HTML,Hľadať,Index,htdig,htsearch,htmerge,Scope,Jazyk
X-KDE-Keywords[sl]=pomoč,html,iskanje,kazalo,htdig,htsearch,htmerge,obseg,jezik
X-KDE-Keywords[sr]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,помоћ,ХТМЛ,претрага,тражење,индекс,језик
X-KDE-Keywords[sr@ijekavian]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,помоћ,ХТМЛ,претрага,тражење,индекс,језик
X-KDE-Keywords[sr@ijekavianlatin]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,pomoć,HTML,pretraga,traženje,indeks,jezik
X-KDE-Keywords[sr@latin]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,pomoć,HTML,pretraga,traženje,indeks,jezik
X-KDE-Keywords[sv]=Hjälp,HTML,Sök,Index,htdig,htsearch,htmerge,Omfattning,Språk
X-KDE-Keywords[tg]=Кумак,HTML,Ҷустуҷӯ,Индекс,htdig,htsearch,htmerge,Намудсоз,Забон
X-KDE-Keywords[tr]=Yardım,HTML,Arama,Dizin,htdig,htsearch,htmerge,Kapsam,Dil
X-KDE-Keywords[ug]=ياردەم، HTML، ئىزدەش، ئىندېكس، htdig، htsearch، htmerge، دائىرە، تىل
X-KDE-Keywords[uk]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,довідка,допомога,пошук,індекс,покажчик,область,мова
X-KDE-Keywords[vi]=Tr giúp,HTML,Tìm kiếm,ch mc,htdig,htsearch,htmerge,Phm vi,Ngôn ng,Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language
X-KDE-Keywords[wa]=Aidance,HTML,Cweri,Trover,Cachî,Cachî après,indecse,htdig,htsearch,htmerge,scope,fortchete,lingaedje
X-KDE-Keywords[x-test]=xxHelpxx,xxHTMLxx,xxSearchxx,xxIndexxx,xxhtdigxx,xxhtsearchxx,xxhtmergexx,xxScopexx,xxLanguagexx
X-KDE-Keywords[zh_CN]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,,,,
X-KDE-Keywords[zh_TW]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language

View file

@ -0,0 +1,62 @@
#ifndef __HTMLSEARCH_H__
#define __HTMLSEARCH_H__
class QWidget;
class K3Process;
class ProgressDialog;
class HTMLSearch : public QObject
{
Q_OBJECT
public:
HTMLSearch();
bool generateIndex(const QString & lang, QWidget *parent=0);
QString search(const QString & lang, const QString & words, const QString & method="and", int matches=10,
const QString & format="builtin-long", const QString & sort="score");
protected Q_SLOTS:
void htdigStdout(K3Process *proc, char *buffer, int buflen);
void htdigExited(K3Process *proc);
void htmergeExited(K3Process *proc);
void htsearchStdout(K3Process *proc, char *buffer, int buflen);
void htsearchExited(K3Process *proc);
protected:
QString dataPath(const QString& lang);
bool saveFilesList(const QString& lang);
void scanDir(const QString& dir);
bool createConfig(const QString& lang);
private:
QStringList _files;
K3Process *_proc;
int _filesToDig, _filesDigged, _filesScanned;
volatile bool _htdigRunning, _htmergeRunning, _htsearchRunning;
QString _searchResult;
ProgressDialog *progress;
};
#endif

View file

@ -0,0 +1,28 @@
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <kglobal.h>
#include <kapplication.h>
#include <klocale.h>
#include "htmlsearch.h"
int main(int argc, char *argv[])
{
KAboutData aboutData( "khtmlindex", "htmlsearch", ki18n("KHtmlIndex"),
"",
ki18n("KDE Index generator for help files."));
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineOptions options;
options.add("lang <lang>", ki18n("The language to index"), "en");
KCmdLineArgs::addCmdLineOptions( options );
KApplication app;
HTMLSearch search;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
search.generateIndex(args->getOption("lang"));
}

View file

@ -0,0 +1,378 @@
/**
* kcmhtmlsearch.cpp
*
* Copyright (c) 2000 Matthias Hölzer-Klüpfel <hoelzer@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <QLayout>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kurllabel.h>
#include <kapplication.h>
#include <QCheckBox>
#include <QWhatsThis>
#include <kfiledialog.h>
#include <k3process.h>
#include "klangcombo.h"
#include <kurlrequester.h>
#include <klineedit.h>
#include <ktoolinvocation.h>
#include <kpluginfactory.h>
#include "moc_kcmhtmlsearch.cpp"
K_PLUGIN_FACTORY(KHTMLSearchConfigFactory, registerPlugin<KHTMLSearchConfig>();)
K_EXPORT_PLUGIN(KHTMLSearchConfigFactory("kcmhtmlsearch"))
KHTMLSearchConfig::KHTMLSearchConfig(QWidget *parent, const QVariantList &)
: KCModule(KHTMLSearchConfigFactory::componentData(), parent), indexProc(0)
{
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setSpacing(5);
QGroupBox *gb = new QGroupBox(i18n("ht://dig"), this);
vbox->addWidget(gb);
QGridLayout *grid = new QGridLayout(gb);
grid->setSpacing(6);
grid->setMargin(6);
grid->addRowSpacing(0, gb->fontMetrics().lineSpacing());
QLabel *l = new QLabel(i18n("The fulltext search feature makes use of the "
"ht://dig HTML search engine. "
"You can get ht://dig at the"), gb);
l->setAlignment(QLabel::WordBreak);
l->setMinimumSize(l->sizeHint());
grid->addWidget(l, 1, 0, 1, 2 );
QWhatsThis::add( gb, i18n( "Information about where to get the ht://dig package." ) );
KUrlLabel *url = new KUrlLabel(gb);
url->setURL("http://www.htdig.org");
url->setText(i18n("ht://dig home page"));
url->setAlignment(QLabel::AlignHCenter);
grid->addWidget(url, 2, 0, 1, 2 );
connect(url, SIGNAL(leftClickedUrl(const QString&)),
this, SLOT(urlClicked(const QString&)));
gb = new QGroupBox(i18n("Program Locations"), this);
vbox->addWidget(gb);
grid = new QGridLayout(gb);
grid->setSpacing(6);
grid->setMargin(6);
grid->addRowSpacing(0, gb->fontMetrics().lineSpacing());
htdigBin = new KUrlRequester(gb);
l = new QLabel(i18n("ht&dig"),gb);
l->setBuddy(htdigBin);
grid->addWidget(l, 1,0);
grid->addWidget(htdigBin, 1,1);
connect(htdigBin->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(configChanged()));
QString wtstr = i18n( "Enter the path to your htdig program here, e.g. /usr/local/bin/htdig" );
QWhatsThis::add( htdigBin, wtstr );
QWhatsThis::add( l, wtstr );
htsearchBin = new KUrlRequester(gb);
l = new QLabel(i18n("ht&search"),gb);
l->setBuddy(htsearchBin);
grid->addWidget(l, 2,0);
grid->addWidget(htsearchBin, 2,1);
connect(htsearchBin->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(configChanged()));
wtstr = i18n( "Enter the path to your htsearch program here, e.g. /usr/local/bin/htsearch" );
QWhatsThis::add( htsearchBin, wtstr );
QWhatsThis::add( l, wtstr );
htmergeBin = new KUrlRequester(gb);
l = new QLabel(i18n("ht&merge"),gb);
l->setBuddy(htmergeBin);
grid->addWidget(l, 3,0);
grid->addWidget(htmergeBin, 3,1);
connect(htmergeBin->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(configChanged()));
wtstr = i18n( "Enter the path to your htmerge program here, e.g. /usr/local/bin/htmerge" );
QWhatsThis::add( htmergeBin, wtstr );
QWhatsThis::add( l, wtstr );
QHBoxLayout *hbox = new QHBoxLayout(vbox);
gb = new QGroupBox(i18n("Scope"), this);
hbox->addWidget(gb);
QWhatsThis::add( gb, i18n( "Here you can select which parts of the documentation should be included in the fulltext search index. Available options are the KDE Help pages, the installed man pages, and the installed info pages. You can select any number of these." ) );
QVBoxLayout *vvbox = new QVBoxLayout(gb);
vvbox->setSpacing(2);
vvbox->setMargin(6);
vvbox->addSpacing(gb->fontMetrics().lineSpacing());
indexKDE = new QCheckBox(i18n("&KDE help"), gb);
vvbox->addWidget(indexKDE);
connect(indexKDE, SIGNAL(clicked()), this, SLOT(configChanged()));
indexMan = new QCheckBox(i18n("&Man pages"), gb);
vvbox->addWidget(indexMan);
indexMan->setEnabled(false),
connect(indexMan, SIGNAL(clicked()), this, SLOT(configChanged()));
indexInfo = new QCheckBox(i18n("&Info pages"), gb);
vvbox->addWidget(indexInfo);
indexInfo->setEnabled(false);
connect(indexInfo, SIGNAL(clicked()), this, SLOT(configChanged()));
gb = new QGroupBox(i18n("Additional Search Paths"), this);
hbox->addWidget(gb);
QWhatsThis::add( gb, i18n( "Here you can add additional paths to search for documentation. To add a path, click on the <em>Add...</em> button and select the folder from where additional documentation should be searched. You can remove folders by clicking on the <em>Delete</em> button." ) );
grid = new QGridLayout(gb);
grid->setSpacing(2);
grid->setMargin(6);
grid->addRowSpacing(0, gb->fontMetrics().lineSpacing());
addButton = new QPushButton(i18n("Add..."), gb);
grid->addWidget(addButton, 1,0);
delButton = new QPushButton(i18n("Delete"), gb);
grid->addWidget(delButton, 2,0);
searchPaths = new KListWidget(gb);
grid->addWidget(searchPaths, 1, 1,3, 1);
grid->setRowStretch(2,2);
gb = new QGroupBox(i18n("Language Settings"), this);
vbox->addWidget(gb);
QWhatsThis::add(gb, i18n("Here you can select the language you want to create the index for."));
language = new KLanguageCombo(gb);
l = new QLabel(i18n("&Language"),gb);
l->setBuddy(language);
vvbox = new QVBoxLayout(gb);
vvbox->setSpacing(2);
vvbox->setMargin(6);
vvbox->addSpacing(gb->fontMetrics().lineSpacing());
hbox = new QHBoxLayout(vvbox);
hbox->setSpacing(6);
hbox->addWidget(l);
hbox->addWidget(language,1);
hbox->addStretch(1);
loadLanguages();
vbox->addStretch(1);
runButton = new QPushButton(i18n("Generate Index..."), this);
QWhatsThis::add( runButton, i18n( "Click this button to generate the index for the fulltext search." ) );
runButton->setFixedSize(runButton->sizeHint());
vbox->addWidget(runButton, AlignRight);
connect(runButton, SIGNAL(clicked()), this, SLOT(generateIndex()));
connect(addButton, SIGNAL(clicked()), this, SLOT(addClicked()));
connect(delButton, SIGNAL(clicked()), this, SLOT(delClicked()));
connect(searchPaths, SIGNAL(highlighted(const QString &)),
this, SLOT(pathSelected(const QString &)));
checkButtons();
load();
}
void KHTMLSearchConfig::loadLanguages()
{
// clear the list
language->clear();
// add all languages to the list
QStringList langs = KGlobal::dirs()->findAllResources("locale",
QLatin1String("*/entry.desktop"));
langs.sort();
for (QStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it)
{
KSimpleConfig entry(*it);
entry.setGroup(QLatin1String("KCM Locale"));
QString name = entry.readEntry(QLatin1String("Name"), i18n("without name"));
QString path = *it;
int index = path.lastIndexOf('/');
path = path.left(index);
index = path.lastIndexOf('/');
path = path.mid(index+1);
language->insertLanguage(path, name);
}
}
QString KHTMLSearchConfig::quickHelp() const
{
return i18n( "<h1>Help Index</h1> This configuration module lets you configure the ht://dig engine which can be used for fulltext search in the KDE documentation as well as other system documentation like man and info pages." );
}
void KHTMLSearchConfig::pathSelected(const QString &)
{
checkButtons();
}
void KHTMLSearchConfig::checkButtons()
{
delButton->setEnabled(searchPaths->currentItem() >= 0);
}
void KHTMLSearchConfig::addClicked()
{
QString dir = KFileDialog::getExistingDirectory();
if (!dir.isEmpty())
{
for (uint i=0; i<searchPaths->count(); ++i)
if (searchPaths->text(i) == dir)
return;
searchPaths->insertItem(dir);
configChanged();
}
}
void KHTMLSearchConfig::delClicked()
{
searchPaths->removeItem(searchPaths->currentItem());
checkButtons();
configChanged();
}
KHTMLSearchConfig::~KHTMLSearchConfig()
{
}
void KHTMLSearchConfig::configChanged()
{
emit changed(true);
}
void KHTMLSearchConfig::load()
{
KConfig *config = new KConfig("khelpcenterrc", true);
config->setGroup("htdig");
htdigBin->lineEdit()->setText(config->readPathEntry("htdig", kapp->dirs()->findExe("htdig")));
htsearchBin->lineEdit()->setText(config->readPathEntry("htsearch", kapp->dirs()->findExe("htsearch")));
htmergeBin->lineEdit()->setText(config->readPathEntry("htmerge", kapp->dirs()->findExe("htmerge")));
config->setGroup("Scope");
indexKDE->setChecked(config->readEntry("KDE", true));
indexMan->setChecked(config->readEntry("Man", false));
indexInfo->setChecked(config->readEntry("Info", false));
QStringList l = config->readPathEntry("Paths", QStringList());
searchPaths->clear();
QStringList::const_iterator it;
for (it=l.begin(); it != l.end(); ++it)
searchPaths->insertItem(*it);
config->setGroup("Locale");
QString lang = config->readEntry("Search Language", KGlobal::locale()->language());
language->setCurrentItem(lang);
delete config;
emit changed(false);
}
void KHTMLSearchConfig::save()
{
KConfig *config= new KConfig("khelpcenterrc", false);
config->setGroup("htdig");
config->writePathEntry("htdig", htdigBin->lineEdit()->text());
config->writePathEntry("htsearch", htsearchBin->lineEdit()->text());
config->writePathEntry("htmerge", htmergeBin->lineEdit()->text());
config->setGroup("Scope");
config->writeEntry("KDE", indexKDE->isChecked());
config->writeEntry("Man", indexMan->isChecked());
config->writeEntry("Info", indexInfo->isChecked());
QStringList l;
for (uint i=0; i<searchPaths->count(); ++i)
l.append(searchPaths->text(i));
config->writePathEntry("Paths", l);
config->setGroup("Locale");
config->writeEntry("Search Language", language->currentTag());
config->sync();
delete config;
emit changed(false);
}
void KHTMLSearchConfig::defaults()
{
htdigBin->lineEdit()->setText(kapp->dirs()->findExe("htdig"));
htsearchBin->lineEdit()->setText(kapp->dirs()->findExe("htsearch"));
htmergeBin->lineEdit()->setText(kapp->dirs()->findExe("htmerge"));
indexKDE->setChecked(true);
indexMan->setChecked(false);
indexInfo->setChecked(false);
searchPaths->clear();
language->setCurrentItem(KGlobal::locale()->language());
emit changed(true);
}
void KHTMLSearchConfig::urlClicked(const QString &url)
{
KToolInvocation::invokeBrowser(url);
}
void KHTMLSearchConfig::generateIndex()
{
save();
QString exe = kapp->dirs()->findExe("khtmlindex");
if (exe.isEmpty())
return;
delete indexProc;
indexProc = new K3Process;
*indexProc << exe << "--lang" << language->currentTag();
connect(indexProc, SIGNAL(processExited(K3Process *)),
this, SLOT(indexTerminated(K3Process *)));
runButton->setEnabled(false);
indexProc->start();
}
void KHTMLSearchConfig::indexTerminated(K3Process *)
{
runButton->setEnabled(true);
}

View file

@ -0,0 +1,84 @@
/**
* kcmhtmlsearch.h
*
* Copyright (c) 2000 Matthias Hölzer-Klüpfel <hoelzer@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __kcmhtmlsearch_h__
#define __kcmhtmlsearch_h__
#define KDE3_SUPPORT
#include <kcmodule.h>
#undef KDE3_SUPPORT
#include <QVariantList>
class QCheckBox;
class QPushButton;
class KListWidget;
class K3Process;
class KLanguageCombo;
class KUrlRequester;
class QStringList;
class KHTMLSearchConfig : public KCModule
{
Q_OBJECT
public:
KHTMLSearchConfig(QWidget *parent, const QVariantList &args);
virtual ~KHTMLSearchConfig();
void load();
void save();
void defaults();
QString quickHelp() const;
int buttons();
protected Q_SLOTS:
void configChanged();
void addClicked();
void delClicked();
void pathSelected(const QString &);
void urlClicked(const QString&);
void generateIndex();
void indexTerminated(K3Process *proc);
private:
void checkButtons();
void loadLanguages();
KUrlRequester *htdigBin, *htsearchBin, *htmergeBin;
QCheckBox *indexKDE, *indexMan, *indexInfo;
QPushButton *addButton, *delButton, *runButton;
KListWidget *searchPaths;
KLanguageCombo *language;
K3Process *indexProc;
};
#endif

View file

@ -0,0 +1,52 @@
/*
* klangcombo.cpp - Adds some methods for inserting languages.
*
* Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
*
* Requires the Qt widget libraries, available at no cost at
* http://www.troll.no/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "klangcombo.h"
#include <kstandarddirs.h>
KLanguageCombo::~KLanguageCombo ()
{
}
KLanguageCombo::KLanguageCombo (QWidget * parent, const char *name)
: KTagComboBox(parent, name)
{
}
void KLanguageCombo::insertLanguage(const QString& path, const QString& name, const QString& sub, const QString &submenu, int index)
{
QString output = name + QLatin1String(" (") + path + QString::fromLatin1(")");
QPixmap flag(locate("locale", sub + path + QLatin1String("/flag.png")));
insertItem(QIcon(flag), output, path, submenu, index);
}
void KLanguageCombo::changeLanguage(const QString& name, int i)
{
if (i < 0 || i >= count()) return;
QString output = name + QLatin1String(" (") + tag(i) + QString::fromLatin1(")");
changeItem(output, i);
}
#include "moc_klangcombo.cpp"

View file

@ -0,0 +1,47 @@
/*
* klangcombo.h - Adds some methods for inserting languages.
*
* Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
*
* Requires the Qt widget libraries, available at no cost at
* http://www.troll.no/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KLANGCOMBO_H__
#define __KLANGCOMBO_H__
#include "ktagcombobox.h"
/*
* Extends KTagCombo to support adding and changing languages.
*
* It has also support for sub menus.
*/
class KLanguageCombo : public KTagComboBox
{
Q_OBJECT
public:
explicit KLanguageCombo(QWidget *parent=0, const char *name=0);
~KLanguageCombo();
void insertLanguage(const QString& path, const QString& name, const QString& sub = QString(), const QString &submenu = QString(), int index = -1);
void changeLanguage(const QString& name, int i);
};
#endif

View file

@ -0,0 +1,250 @@
/*
* ktagcombobox.cpp - A combobox with support for submenues, icons and tags
*
* Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
*
* Requires the Qt widget libraries, available at no cost at
* http://www.troll.no/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define INCLUDE_MENUITEM_DEF 1
#include "ktagcombobox.h"
#include <QPainter>
#include <kdebug.h>
KTagComboBox::~KTagComboBox ()
{
delete popup;
}
KTagComboBox::KTagComboBox (QWidget * parent, const char *name)
: QComboBox(parent, name),
popup(0),
old_popup(0)
{
clear();
}
void KTagComboBox::popupMenu()
{
popup->popup( mapToGlobal( QPoint(0,0) ), current );
}
void KTagComboBox::keyPressEvent( QKeyEvent *e )
{
int c;
if ( ( e->key() == Key_F4 && e->state() == 0 ) ||
( e->key() == Key_Down && (e->state() & AltButton) ) ||
( e->key() == Key_Space ) ) {
if ( count() ) {
popup->setActiveItem( current );
popupMenu();
}
return;
} else {
e->ignore();
return;
}
c = currentItem();
emit highlighted( c );
emit activated( c );
}
void KTagComboBox::mousePressEvent( QMouseEvent * )
{
popupMenu();
}
void KTagComboBox::internalActivate( int index )
{
if (current == index) return;
current = index;
emit activated( index );
repaint();
}
void KTagComboBox::internalHighlight( int index )
{
emit highlighted( index );
}
void KTagComboBox::clear()
{
tags.clear();
delete old_popup;
old_popup = popup;
popup = new QPopupMenu(this);
connect( popup, SIGNAL(activated(int)),
SLOT(internalActivate(int)) );
connect( popup, SIGNAL(highlighted(int)),
SLOT(internalHighlight(int)) );
}
int KTagComboBox::count() const
{
return tags.count();
}
static inline void checkInsertPos(QPopupMenu *popup, const QString & str, int &index)
{
if (index == -2) index = popup->count();
if (index != -1) return;
int a = 0;
int b = popup->count();
while (a <= b) {
int w = (a + b) / 2;
int id = popup->idAt(w);
int j = str.compare(popup->text(id));
if (j > 0)
a = w + 1;
else
b = w - 1;
}
index = a; // it doesn't really matter ... a == b here.
}
static inline QPopupMenu *checkInsertIndex(QPopupMenu *popup, const QStringList& tags, const QString &submenu)
{
int pos = tags.findIndex(submenu);
QPopupMenu *pi = 0;
if (pos != -1)
{
QMenuItem *p = popup->findItem(pos);
pi = p?p->popup():0;
}
if (!pi) pi = popup;
return pi;
}
void KTagComboBox::insertItem(const QIcon& icon, const QString &text, const QString &tag, const QString &submenu, int index )
{
QPopupMenu *pi = checkInsertIndex(popup, tags, submenu);
checkInsertPos(pi, text, index);
pi->insertItem(icon, text, count(), index);
tags.append(tag);
}
void KTagComboBox::insertItem(const QString &text, const QString &tag, const QString &submenu, int index )
{
QPopupMenu *pi = checkInsertIndex(popup, tags, submenu);
checkInsertPos(pi, text, index);
pi->insertItem(text, count(), index);
tags.append(tag);
}
void KTagComboBox::insertSeparator(const QString &submenu, int index)
{
QPopupMenu *pi = checkInsertIndex(popup, tags, submenu);
pi->insertSeparator(index);
tags.append(QString());
}
void KTagComboBox::insertSubmenu(const QString &text, const QString &tag, const QString &submenu, int index)
{
QPopupMenu *pi = checkInsertIndex(popup, tags, submenu);
QPopupMenu *p = new QPopupMenu(pi);
checkInsertPos(pi, text, index);
pi->insertItem(text, p, count(), index);
tags.append(tag);
connect( p, SIGNAL(activated(int)),
SLOT(internalActivate(int)) );
connect( p, SIGNAL(highlighted(int)),
SLOT(internalHighlight(int)) );
}
void KTagComboBox::paintEvent( QPaintEvent * ev)
{
QComboBox::paintEvent(ev);
QPainter p (this);
// Text
QRect clip(2, 2, width() - 4, height() - 4);
#if 0
if ( hasFocus() && style().guiStyle() != MotifStyle )
p.setPen( colorGroup().highlightedText() );
#endif
p.drawText(clip, AlignCenter | SingleLine, popup->text( current ));
// Icon
QIcon *icon = popup->iconSet( this->current );
if (icon) {
QPixmap pm = icon->pixmap();
p.drawPixmap( 4, (height()-pm.height())/2, pm );
}
}
bool KTagComboBox::containsTag( const QString &str ) const
{
return tags.contains(str) > 0;
}
QString KTagComboBox::currentTag() const
{
return tags.at(currentItem());
}
QString KTagComboBox::tag(int i) const
{
if (i < 0 || i >= count())
{
kDebug() << "KTagComboBox::tag(), unknown tag " << i;
return QString();
}
return *tags.at(i);
}
int KTagComboBox::currentItem() const
{
return current;
}
void KTagComboBox::setCurrentItem(int i)
{
if (i < 0 || i >= count()) return;
current = i;
repaint();
}
void KTagComboBox::setCurrentItem(const QString &code)
{
int i = tags.findIndex(code);
if (code.isNull())
i = 0;
if (i != -1)
setCurrentItem(i);
}
void KTagComboBox::setFont( const QFont &font )
{
QComboBox::setFont( font );
popup->setFont( font );
}
#include "moc_ktagcombobox.cpp"

View file

@ -0,0 +1,92 @@
/*
* ktagcombobox.h - A combobox with support for submenues, icons and tags
*
* Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
*
* Requires the Qt widget libraries, available at no cost at
* http://www.troll.no/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KTAGCOMBOBOX_H__
#define __KTAGCOMBOBOX_H__
#include <QComboBox>
class QPopupMenu;
/*
* This class should be just like qcombobox, but it should be possible
* to have have a QIcon for each entry, and each entry should have a tag.
*
* It has also support for sub menus.
*/
class KTagComboBox : public QComboBox
{
Q_OBJECT
public:
explicit KTagComboBox(QWidget *parent=0, const char *name=0);
~KTagComboBox();
void insertItem(const QIcon& icon, const QString &text, const QString &tag, const QString &submenu = QString(), int index=-1 );
void insertItem(const QString &text, const QString &tag, const QString &submenu = QString(), int index=-1 );
void insertSeparator(const QString &submenu = QString(), int index=-1 );
void insertSubmenu(const QString &text, const QString &tag, const QString &submenu = QString(), int index=-1);
int count() const;
void clear();
/*
* Tag of the selected item
*/
QString currentTag() const;
QString tag ( int i ) const;
bool containsTag (const QString &str ) const;
/*
* Set the current item
*/
int currentItem() const;
void setCurrentItem(int i);
void setCurrentItem(const QString &code);
// widget stuff
virtual void setFont( const QFont & );
Q_SIGNALS:
void activated( int index );
void highlighted( int index );
private Q_SLOTS:
void internalActivate( int );
void internalHighlight( int );
protected:
void paintEvent( QPaintEvent * );
void mousePressEvent( QMouseEvent * );
void keyPressEvent( QKeyEvent *e );
void popupMenu();
private:
// work space for the new class
QStringList tags;
QPopupMenu *popup, *old_popup;
int current;
};
#endif

View file

@ -0,0 +1,6 @@
<dl><dt><strong><a href="$&(URL)">$&(TITLE)</a></strong>$(STARSLEFT)
</dt><dd>$(EXCERPT)<br>
<i><a href="$&(URL)">$&(URL)</a></i>
<font size="-1">$(MODIFIED), $(SIZE) bytes</font>
</dd></dl>

View file

@ -0,0 +1,4 @@
#! /bin/sh
file=`echo $3 | sed -e "s#http://localhost/#/#; s#file:/*#/#"`
meinproc --htdig $file

View file

@ -0,0 +1,21 @@
<html><head><title>No match for '$&(LOGICAL_WORDS)'</title></head>
<body bgcolor="#ffffff" text="#000000" link="#aa0000">
<h1><img src="htdig.gif">
Search results</h1>
<hr noshade size="4">
<h2>No matches were found for '$&(LOGICAL_WORDS)'</h2>
<p>
Check the spelling of the search word(s) you used.
If the spelling is correct and you only used one word,
try using one or more similar search words with "<b>Any</b>."
</p><p>
If the spelling is correct and you used more than one
word with "<b>Any</b>," try using one or more similar search
words with "<b>Any</b>."</p><p>
If the spelling is correct and you used more than one
word with "<b>All</b>," try using one or more of the same words
with "<b>Any</b>."</p>
<hr noshade size="4">
<a href="http://www.htdig.org/">
<img src="htdig.gif" border="0">ht://Dig $(VERSION)</a>
</body></html>

View file

@ -0,0 +1,81 @@
#include <QLayout>
#include <QLabel>
#include <QProgressBar>
#include <klocale.h>
#include <kstandarddirs.h>
#include "moc_progressdialog.cpp"
ProgressDialog::ProgressDialog(QWidget *parent, const char *name)
: KDialog( parent )
{
setCaption( i18n("Generating Index") );
setButtons( Cancel );
setDefaultButton( Cancel );
setObjectName( name );
setModal( false );
QGridLayout *grid = new QGridLayout(plainPage());
grid->setSpacing(spacingHint());
QLabel *l = new QLabel(i18n("Scanning for files"), plainPage());
grid->addWidget(l, 0, 1, 1,2);
filesScanned = new QLabel(plainPage());
grid->addWidget(filesScanned, 1,2);
setFilesScanned(0);
check1 = new QLabel(plainPage());
grid->addWidget(check1, 0,0);
l = new QLabel(i18n("Extracting search terms"), plainPage());
grid->addWidget(l, 2, 1, 1,2);
bar = new QProgressBar(plainPage());
grid->addWidget(bar, 3,2);
check2 = new QLabel(plainPage());
grid->addWidget(check2, 2,0);
l = new QLabel(i18n("Generating index..."), plainPage());
grid->addWidget(l, 4, 1, 1,2);
check3 = new QLabel(plainPage());
grid->addWidget(check3, 4,0);
setState(0);
setMinimumWidth(300);
}
void ProgressDialog::setFilesScanned(int n)
{
filesScanned->setText(i18n("Files processed: %1", n));
}
void ProgressDialog::setFilesToDig(int n)
{
bar->setRange(0, n);
}
void ProgressDialog::setFilesDigged(int n)
{
bar->setValue(n);
}
void ProgressDialog::setState(int n)
{
QPixmap unchecked = QPixmap(locate("data", "khelpcenter/pics/unchecked.xpm"));
QPixmap checked = QPixmap(locate("data", "khelpcenter/pics/checked.xpm"));
check1->setPixmap( n > 0 ? checked : unchecked);
check2->setPixmap( n > 1 ? checked : unchecked);
check3->setPixmap( n > 2 ? checked : unchecked);
}

View file

@ -0,0 +1,32 @@
#ifndef __PROGRESS_DIALOG_H__
#define __PROGRESS_DIALOG_H__
#include <kdialog.h>
class QLabel;
class QProgressBar;
class ProgressDialog : public KDialog
{
Q_OBJECT
public:
explicit ProgressDialog(QWidget *parent=0, const char *name=0);
void setFilesScanned(int s);
void setFilesToDig(int d);
void setFilesDigged(int d);
void setState(int n);
private:
QLabel *filesScanned, *check1, *check2, *check3;
QProgressBar *bar;
};
#endif

View file

@ -0,0 +1 @@
$(STARSRIGHT) <strong><a href="$&(URL)">$&(TITLE)</a></strong><br>

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

View file

@ -0,0 +1,19 @@
<html><head><title>Error in Boolean search for '$&(WORDS)'</title></head>
<body bgcolor="#ffffff" text="#000000" link="#aa0000">
<h1><img src="htdig.gif">
Error in Boolean search for '$&(LOGICAL_WORDS)'</h1>
<hr noshade size="4">
Boolean expressions need to be 'correct' in order for the search
system to use them.
The expression you entered has errors in it.<p>
Examples of correct expressions are: <b>cat and dog</b>, <b>cat
not dog</b>, <b>cat or (dog not nose)</b>.<br>Note that
the operator <b>not</b> has the meaning of 'without'.
<blockquote><b>
$(SYNTAXERROR)
</b></blockquote>
<hr noshade size="4">
<a href="http://www.htdig.org/">
<img src="htdig.gif" border="0">ht://Dig $(VERSION)</a>
</body></html>

View file

@ -0,0 +1,22 @@
/* XPM */
static char*unchecked[]={
"16 16 3 1",
"# c #000000",
"+ c #ffffff",
". c None",
"................",
"................",
"..++++++++++++..",
"..+##########+..",
"..+#++++++++#+..",
"..+#+......+#+..",
"..+#+......+#+..",
"..+#+......+#+..",
"..+#+......+#+..",
"..+#+......+#+..",
"..+#+......+#+..",
"..+#++++++++#+..",
"..+##########+..",
"..++++++++++++..",
"................",
"................"};

View file

@ -0,0 +1,16 @@
<html><head><title>Search results for '$&(WORDS)'</title></head>
<body bgcolor="#ffffff" text="#000000" link="#aa0000">
<h2><img src="htdig.gif">
Search results for '$&(LOGICAL_WORDS)'</h2>
<hr noshade size="4">
<b>
More <img src="reload.png" alt="*">'s indicate a better match.
</b>
<hr noshade size="1">
$(HTSEARCH_RESULTS)
$(PAGEHEADER)
$(PREVPAGE) $(PAGELIST) $(NEXTPAGE)
<hr noshade size="4">
<a href="http://www.htdig.org/">
<img src="htdig.gif" border="0">ht://Dig $(VERSION)</a>
</body></html>

View file

@ -0,0 +1,159 @@
/**
* kcmhtmlsearch.cpp
*
* Copyright (c) 2000 Matthias Hölzer-Klüpfel <hoelzer@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "htmlsearchconfig.h"
#include <QLayout>
#include <QGroupBox>
#include <QLabel>
#include <QVBoxLayout>
#include <QGridLayout>
#include <KDebug>
#include <KStandardDirs>
#include <KLocale>
#include <KUrlLabel>
#include <KApplication>
#include <KFileDialog>
#include <KUrlRequester>
#include <KLineEdit>
#include <KToolInvocation>
namespace KHC {
HtmlSearchConfig::HtmlSearchConfig(QWidget *parent, const char *name)
: QWidget(parent)
{
setObjectName( name );
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setMargin( 5 );
QGroupBox *gb = new QGroupBox(i18n("ht://dig"), this);
vbox->addWidget(gb);
QGridLayout *grid = new QGridLayout(gb);
grid->setMargin( 6 );
grid->setSpacing( 6 );
grid->addItem( new QSpacerItem( 0, gb->fontMetrics().lineSpacing() ), 0, 0 );
QLabel *l = new QLabel(i18n("The fulltext search feature makes use of the "
"ht://dig HTML search engine."), gb);
l->setMinimumSize(l->sizeHint());
grid->addWidget(l, 1, 1, 0, 1);
gb->setWhatsThis( i18n( "Information about where to get the ht://dig package." ) );
KUrlLabel *url = new KUrlLabel(gb);
url->setUrl(QLatin1String("http://www.htdig.org"));
url->setText(i18n("You can get ht://dig at the ht://dig home page"));
url->setAlignment(Qt::AlignHCenter);
grid->addWidget(url, 2,2, 0, 1);
connect(url, SIGNAL(leftClickedUrl(const QString&)),
this, SLOT(urlClicked(const QString&)));
gb = new QGroupBox(i18n("Program Locations"), this);
vbox->addWidget(gb);
grid = new QGridLayout(gb);
grid->setMargin( 6 );
grid->setSpacing( 6 );
grid->addItem( new QSpacerItem( 0, gb->fontMetrics().lineSpacing() ), 0, 0 );
mHtsearchUrl = new KUrlRequester(gb);
l = new QLabel(i18n("htsearch:"), gb);
l->setBuddy( mHtsearchUrl );
grid->addWidget(l, 1,0);
grid->addWidget(mHtsearchUrl, 1,1);
connect( mHtsearchUrl->lineEdit(), SIGNAL( textChanged( const QString & ) ),
SIGNAL( changed() ) );
QString wtstr = i18n( "Enter the URL of the htsearch CGI program." );
mHtsearchUrl->setWhatsThis( wtstr );
l->setWhatsThis( wtstr );
mIndexerBin = new KUrlRequester(gb);
l = new QLabel(i18n("Indexer:"), gb);
l->setBuddy( mIndexerBin );
grid->addWidget(l, 2,0);
grid->addWidget(mIndexerBin, 2,1);
connect( mIndexerBin->lineEdit(), SIGNAL( textChanged( const QString & ) ),
SIGNAL( changed() ) );
wtstr = i18n( "Enter the path to your htdig indexer program here." );
mIndexerBin->setWhatsThis( wtstr );
l->setWhatsThis( wtstr );
mDbDir = new KUrlRequester(gb);
mDbDir->setMode( KFile::Directory | KFile::LocalOnly );
l = new QLabel(i18n("htdig database:"), gb);
l->setBuddy( mDbDir );
grid->addWidget(l, 3,0);
grid->addWidget(mDbDir, 3,1);
connect( mDbDir->lineEdit(), SIGNAL( textChanged( const QString & ) ),
SIGNAL( changed() ) );
wtstr = i18n( "Enter the path to the htdig database folder." );
mDbDir->setWhatsThis( wtstr );
l->setWhatsThis( wtstr );
}
HtmlSearchConfig::~HtmlSearchConfig()
{
kDebug() << "~HtmlSearchConfig()";
}
void HtmlSearchConfig::makeReadOnly()
{
mHtsearchUrl->setEnabled( false );
mIndexerBin->setEnabled( false );
mDbDir->setEnabled( false );
}
void HtmlSearchConfig::load( KConfig *config )
{
mHtsearchUrl->lineEdit()->setText(config->group("htdig").readPathEntry("htsearch", KGlobal::mainComponent().dirs()->findExe("htsearch")));
mIndexerBin->lineEdit()->setText(config->group("htdig").readPathEntry("indexer", QString()));
mDbDir->lineEdit()->setText(config->group("htdig").readPathEntry("dbdir", "/opt/www/htdig/db/" ) );
}
void HtmlSearchConfig::save( KConfig *config )
{
config->group("htdig").writePathEntry("htsearch", mHtsearchUrl->lineEdit()->text());
config->group("htdig").writePathEntry("indexer", mIndexerBin->lineEdit()->text());
config->group("htdig").writePathEntry("dbdir", mDbDir->lineEdit()->text());
}
void HtmlSearchConfig::defaults()
{
mHtsearchUrl->lineEdit()->setText(KGlobal::mainComponent().dirs()->findExe("htsearch"));
mIndexerBin->lineEdit()->setText("");
mDbDir->lineEdit()->setText(QLatin1String("/opt/www/htdig/db/") );
}
void HtmlSearchConfig::urlClicked(const QString &url)
{
KToolInvocation::invokeBrowser(url);
}
} // End namespace KHC
// vim:ts=2:sw=2:et
#include "moc_htmlsearchconfig.cpp"

View file

@ -0,0 +1,58 @@
/**
* This file is part of KHelpCenter
*
* Copyright (c) 2000 Matthias Hölzer-Klüpfel <hoelzer@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_HTMLSEARCHCONFIG_H
#define KHC_HTMLSEARCHCONFIG_H
#include <QWidget>
class KUrlRequester;
class KConfig;
namespace KHC {
class HtmlSearchConfig : public QWidget
{
Q_OBJECT
public:
explicit HtmlSearchConfig(QWidget *parent = 0L, const char *name = 0L);
virtual ~HtmlSearchConfig();
void load( KConfig * );
void save( KConfig * );
void defaults();
void makeReadOnly();
Q_SIGNALS:
void changed();
protected Q_SLOTS:
void urlClicked(const QString&);
private:
KUrlRequester *mHtsearchUrl;
KUrlRequester *mIndexerBin;
KUrlRequester *mDbDir;
};
}
#endif //KHC_HTMLSEARCHCONFIG_H
// vim:ts=2:sw=2:et

42
khelpcenter/index.html.in Normal file
View file

@ -0,0 +1,42 @@
<html>
<head>
<title>%1</title>
<link rel="stylesheet" href="help:/common/kde-default.css" type="text/css" />
</head>
<body>
<div style="background-image: url(help:/common/top-middle.png); width: 100%; height: 131px;">
<div style="position: absolute; right: 0px;">
<img src="help:/common/top-right.png" style="margin: 0px" alt="">
</div>
<div style="position: absolute; left: 0px;">
<img src="help:/common/top-left.png" style="margin: 0px" alt="">
</div>
<div style="position: absolute;
top: 25px;
right: 100px;
text-align: right;
font-size: xx-large;
font-weight: bold;
text-shadow: #fff 0px 0px 5px;
color: #444">
%2
</div>
</div>
%3
<div class="bannerBottom" style="background-image: url(help:/common/bottom-middle.png);
background-repeat: x-repeat;
width: 100%;
height: 100px;
bottom:0px;">
<div class="bannerBottomRight">
<img src="help:/common/bottom-right.png" style="margin: 0px" alt="">
</div>
<div class="bannerBottomLeft">
<img src="help:/common/bottom-left.png" style="margin: 0px;" alt="">
</div>
</div>
</body>
</html>

194
khelpcenter/infotree.cpp Normal file
View file

@ -0,0 +1,194 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe (raabe@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "infotree.h"
#include "navigatoritem.h"
#include "docentry.h"
#include <KApplication>
#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KIconLoader>
#include <KGlobal>
#include <KLocale>
#include <KStandardDirs>
#include <KUrl>
#include <QFile>
#include <QTextStream>
#include <QPixmap>
#include <stdlib.h> // for getenv()
using namespace KHC;
class InfoCategoryItem : public NavigatorItem
{
public:
InfoCategoryItem( NavigatorItem *parent, const QString &text );
virtual void setExpanded( bool open );
};
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 );
// kDebug(1400) << "Got category: " << text;
}
void InfoCategoryItem::setExpanded( bool open )
{
NavigatorItem::setExpanded( open );
if ( open && childCount() > 0 ) setIcon( 0, SmallIcon( "help-contents" ) );
// TODO: was contents2 -> needs to be changed to help-contents-alternate or similar
else setIcon( 0, SmallIcon( "help-contents" ) );
}
InfoNodeItem::InfoNodeItem( InfoCategoryItem *parent, const QString &text )
: NavigatorItem( new DocEntry( text ), parent )
{
setAutoDeleteDocEntry( true );
// kDebug( 1400 ) << "Created info node item: " << text;
}
InfoTree::InfoTree( QObject *parent )
: TreeBuilder( parent ),
m_parentItem( 0 )
{
}
void InfoTree::build( NavigatorItem *parent )
{
kDebug( 1400 ) << "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 );
KConfigGroup cfg(KGlobal::config(), "Info pages");
QStringList infoDirFiles = cfg.readEntry( "Search paths" , QStringList() );
// Default paths taken fron kdebase/kioslave/info/kde-info2html.conf
if ( infoDirFiles.isEmpty() ) {
infoDirFiles << "/usr/share/info";
infoDirFiles << "/usr/info";
infoDirFiles << "/usr/lib/info";
infoDirFiles << "/usr/local/info";
infoDirFiles << "/usr/local/lib/info";
infoDirFiles << "/usr/X11R6/info";
infoDirFiles << "/usr/X11R6/lib/info";
infoDirFiles << "/usr/X11R6/lib/xemacs/info";
}
QString infoPath = ::getenv( "INFOPATH" );
if ( !infoPath.isEmpty() )
infoDirFiles += infoPath.split( ':');
QStringList::ConstIterator it = infoDirFiles.constBegin();
QStringList::ConstIterator end = infoDirFiles.constEnd();
for ( ; it != end; ++it ) {
QString infoDirFileName = *it + "/dir";
if ( QFile::exists( infoDirFileName ) )
parseInfoDirFile( infoDirFileName );
}
m_alphabItem->sortChildren( 0, Qt::AscendingOrder /* ascending */ );
}
void InfoTree::parseInfoDirFile( const QString &infoDirFileName )
{
kDebug( 1400 ) << "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:") ) ) {
;
}
while ( !stream.atEnd() ) {
QString s = stream.readLine();
if ( s.trimmed().isEmpty() )
continue;
InfoCategoryItem *catItem = new InfoCategoryItem( m_categoryItem, s );
while ( !stream.atEnd() && !s.trimmed().isEmpty() ) {
s = stream.readLine();
if ( s[ 0 ] == '*' ) {
const int colon = s.indexOf( ":" );
const int openBrace = s.indexOf( "(", colon );
const int closeBrace = s.indexOf( ")", openBrace );
const int dot = s.indexOf( ".", closeBrace );
QString appName = s.mid( 2, colon - 2 );
QString url = "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 );
InfoCategoryItem *alphabSection = 0;
QTreeWidgetItemIterator it( m_alphabItem );
while ( (*it) )
{
if ( (*it)->text( 0 ) == QString( appName[ 0 ].toUpper() ) )
{
alphabSection = static_cast<InfoCategoryItem *>( (*it) );
break;
}
++it;
}
if ( alphabSection == 0 )
alphabSection = new InfoCategoryItem( m_alphabItem, QString( appName[ 0 ].toUpper() ) );
item = new InfoNodeItem( alphabSection, appName );
item->entry()->setUrl( url );
}
}
}
infoDirFile.close();
}
#include "moc_infotree.cpp"
// vim:ts=2:sw=2:et

46
khelpcenter/infotree.h Normal file
View file

@ -0,0 +1,46 @@
/*
* infotree.h - part of the KDE Help Center
*
* Copyright (C) 2002 Frerich Raabe (raabe@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_INFOTREE_H
#define KHC_INFOTREE_H
#include "treebuilder.h"
namespace KHC
{
class NavigatorItem;
class InfoTree : public TreeBuilder
{
Q_OBJECT
public:
InfoTree( QObject *parent );
virtual void build( NavigatorItem *parentItem );
private:
void parseInfoDirFile( const QString &fileName );
NavigatorItem *m_parentItem;
NavigatorItem *m_alphabItem;
NavigatorItem *m_categoryItem;
};
}
#endif // KHC_INFOTREE_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,693 @@
/*
This file is part of KHelpcenter.
Copyright (C) 2002 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kcmhelpcenter.h"
#include "htmlsearchconfig.h"
#include "docmetainfo.h"
#include "prefs.h"
#include "searchhandler.h"
#include "searchengine.h"
#include "kcmhelpcenteradaptor.h"
#include <KConfig>
#include <KDebug>
#include <KLocale>
#include <KGlobal>
#include <KAboutData>
#include <KDialog>
#include <KStandardDirs>
#include <KProcess>
#include <KApplication>
#include <KTemporaryFile>
#include <KUrlRequester>
#include <KMessageBox>
#include <KLineEdit>
#include <QTreeWidget>
#include <QtDBus/QtDBus>
#include <QLabel>
#include <QLayout>
#include <QHeaderView>
#include <QProgressBar>
#include <QTextEdit>
#include <unistd.h>
#include <sys/types.h>
using namespace KHC;
IndexDirDialog::IndexDirDialog( QWidget *parent )
: KDialog( parent )
{
setModal( true );
setCaption( i18n("Change Index Folder") );
setButtons( Ok | Cancel );
QFrame *topFrame = new QFrame( this );
setMainWidget( topFrame );
QBoxLayout *urlLayout = new QHBoxLayout( topFrame );
QLabel *label = new QLabel( i18n("Index folder:"), topFrame );
urlLayout->addWidget( label );
mIndexUrlRequester = new KUrlRequester( topFrame );
mIndexUrlRequester->setMode( KFile::Directory | KFile::ExistingOnly |
KFile::LocalOnly );
urlLayout->addWidget( mIndexUrlRequester );
mIndexUrlRequester->setUrl( Prefs::indexDirectory() );
connect(mIndexUrlRequester->lineEdit(),SIGNAL(textChanged ( const QString & )), this, SLOT(slotUrlChanged( const QString &)));
slotUrlChanged( mIndexUrlRequester->lineEdit()->text() );
connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
}
void IndexDirDialog::slotUrlChanged( const QString &_url )
{
enableButtonOk( !_url.isEmpty() );
}
void IndexDirDialog::slotOk()
{
Prefs::setIndexDirectory( mIndexUrlRequester->url().url() );
accept();
}
IndexProgressDialog::IndexProgressDialog( QWidget *parent )
: KDialog( parent ),
mFinished( true )
{
setCaption( i18n("Build Search Indices") );
QVBoxLayout *topLayout = new QVBoxLayout( mainWidget() );
topLayout->setMargin( marginHint() );
topLayout->setSpacing( spacingHint() );
mLabel = new QLabel( mainWidget() );
mLabel->setAlignment( Qt::AlignHCenter );
topLayout->addWidget( mLabel );
mProgressBar = new QProgressBar( mainWidget() );
topLayout->addWidget( mProgressBar );
mLogLabel = new QLabel( i18n("Index creation log:"), mainWidget() );
topLayout->addWidget( mLogLabel );
mLogView = new QTextEdit( mainWidget() );
mLogView->setReadOnly( true );
mLogView->setWordWrapMode( QTextOption::NoWrap );
mLogView->setMinimumHeight( 200 );
topLayout->addWidget( mLogView );
setButtons( User1 | Close );
connect( this, SIGNAL( closeClicked() ), SLOT( slotEnd() ) );
connect( this, SIGNAL( user1Clicked() ), SLOT( toggleDetails() ) );
hideDetails();
setFinished( false );
}
IndexProgressDialog::~IndexProgressDialog()
{
if ( !mLogView->isHidden() ) {
KConfigGroup cfg(KGlobal::config(), "indexprogressdialog");
cfg.writeEntry( "size", size() );
}
}
void IndexProgressDialog::setTotalSteps( int steps )
{
mProgressBar->setRange( 0, steps );
mProgressBar->setValue( 0 );
setFinished( false );
mLogView->clear();
}
void IndexProgressDialog::advanceProgress()
{
mProgressBar->setValue( mProgressBar->value() + 1 );
}
void IndexProgressDialog::setLabelText( const QString &text )
{
mLabel->setText( text );
}
void IndexProgressDialog::setMinimumLabelWidth( int width )
{
mLabel->setMinimumWidth( width );
}
void IndexProgressDialog::setFinished( bool finished )
{
if ( finished == mFinished ) return;
mFinished = finished;
if ( mFinished ) {
setButtonText( Close, i18nc("Label for button to close search index progress dialog after successful completion", "Close") );
mLabel->setText( i18n("Index creation finished.") );
mProgressBar->setValue( mProgressBar->maximum() );
} else {
setButtonText( Close, i18nc("Label for stopping search index generation before completion", "Stop") );
}
}
void IndexProgressDialog::appendLog( const QString &text )
{
mLogView->append( text );
}
void IndexProgressDialog::slotEnd()
{
if ( mFinished ) {
emit closed();
accept();
} else {
emit cancelled();
reject();
}
}
void IndexProgressDialog::toggleDetails()
{
KConfigGroup cfg(KGlobal::config(), "indexprogressdialog");
if ( mLogView->isHidden() ) {
mLogLabel->show();
mLogView->show();
setButtonText( User1, i18n("Details &lt;&lt;") );
QSize size = cfg.readEntry( "size", QSize() );
if ( !size.isEmpty() ) resize( size );
} else {
cfg.writeEntry( "size", size() );
hideDetails();
}
}
void IndexProgressDialog::hideDetails()
{
mLogLabel->hide();
mLogView->hide();
setButtonText( User1, i18n("Details &gt;&gt;") );
// causes bug 166343
//layout()->activate();
adjustSize();
}
KCMHelpCenter::KCMHelpCenter( KHC::SearchEngine *engine, QWidget *parent,
const char *name)
: KDialog( parent ),
mEngine( engine ), mProgressDialog( 0 ), mCmdFile( 0 ),
mProcess( 0 ), mIsClosing( false ), mRunAsRoot( false )
{
new KcmhelpcenterAdaptor(this);
QDBusConnection::sessionBus().registerObject(QLatin1String("/kcmhelpcenter"), this);
setObjectName( name );
setCaption( i18n("Build Search Index") );
setButtons( Ok | Cancel );
QWidget *widget = new QWidget( this );
setMainWidget( widget );
setupMainWidget( widget );
setButtonGuiItem( KDialog::Ok, KGuiItem(i18n("Build Index")) );
mConfig = KGlobal::config();
DocMetaInfo::self()->scanMetaInfo();
load();
const QString dbusInterface = "org.kde.khelpcenter.kcmhelpcenter";
QDBusConnection dbus = QDBusConnection::sessionBus();
bool success = dbus.connect(QString(), "/kcmhelpcenter", dbusInterface, "buildIndexProgress", this, SLOT(slotIndexProgress()));
if ( !success )
kError() << "connect D-Bus signal failed" << endl;
success = dbus.connect(QString(), "/kcmhelpcenter", dbusInterface, "buildIndexError", this, SLOT(slotIndexError(const QString&)));
if ( !success )
kError() << "connect D-Bus signal failed" << endl;
KConfigGroup id( mConfig, "IndexDialog" );
restoreDialogSize( id );
}
KCMHelpCenter::~KCMHelpCenter()
{
KConfigGroup cg( KGlobal::config(), "IndexDialog" );
KDialog::saveDialogSize( cg );
}
void KCMHelpCenter::setupMainWidget( QWidget *parent )
{
QVBoxLayout *topLayout = new QVBoxLayout( parent );
topLayout->setSpacing( KDialog::spacingHint() );
QString helpText =
i18n("To be able to search a document, a search\n"
"index needs to exist. The status column of the list below shows whether an index\n"
"for a document exists.\n") +
i18n("To create an index, check the box in the list and press the\n"
"\"Build Index\" button.\n");
QLabel *label = new QLabel( helpText, parent );
topLayout->addWidget( label );
mListView = new QTreeWidget( parent );
//mListView->setFullWidth( true );
mListView->setColumnCount(2);
mListView->setHeaderLabels( QStringList() << i18n("Search Scope") << i18n("Status") );
topLayout->addWidget( mListView );
// not just itemClicked, so that Key_Space also triggers it (#123954)
connect( mListView, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
SLOT(checkSelection()) );
QBoxLayout *urlLayout = new QHBoxLayout();
topLayout->addLayout( urlLayout );
QLabel *urlLabel = new QLabel( i18n("Index folder:"), parent );
urlLayout->addWidget( urlLabel );
mIndexDirLabel = new QLabel( parent );
urlLayout->addWidget( mIndexDirLabel, 1 );
QPushButton *button = new QPushButton( i18n("Change..."), parent );
connect( button, SIGNAL( clicked() ), SLOT( showIndexDirDialog() ) );
urlLayout->addWidget( button );
QBoxLayout *buttonLayout = new QHBoxLayout();
topLayout->addLayout( buttonLayout );
buttonLayout->addStretch( 1 );
connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
}
void KCMHelpCenter::defaults()
{
}
bool KCMHelpCenter::save()
{
kDebug(1401) << "KCMHelpCenter::save()";
if ( !QFile::exists( Prefs::indexDirectory() ) ) {
KMessageBox::sorry( this,
i18n("<qt>The folder <b>%1</b> does not exist; unable to create index.</qt>",
Prefs::indexDirectory() ) );
return false;
} else {
return buildIndex();
}
return true;
}
void KCMHelpCenter::load()
{
mIndexDirLabel->setText( Prefs::indexDirectory() );
mListView->clear();
const DocEntry::List &entries = DocMetaInfo::self()->docEntries();
DocEntry::List::ConstIterator it;
for( it = entries.begin(); it != entries.end(); ++it ) {
// kDebug(1401) << "Entry: " << (*it)->name() << " Indexer: '"
// << (*it)->indexer() << "'" << endl;
if ( mEngine->needsIndex( *it ) ) {
ScopeItem *item = new ScopeItem( mListView, *it );
item->setOn( (*it)->searchEnabled() );
}
}
mListView->header()->setResizeMode( QHeaderView::ResizeToContents );
updateStatus();
}
void KCMHelpCenter::updateStatus()
{
QTreeWidgetItemIterator it( mListView );
while ( (*it) != 0 ) {
ScopeItem *item = static_cast<ScopeItem *>( (*it) );
QString status;
if ( item->entry()->indexExists( Prefs::indexDirectory() ) ) {
status = i18nc("Describes the status of a documentation index that is present", "OK");
item->setOn( false );
} else {
status = i18nc("Describes the status of a documentation index that is missing", "Missing");
}
item->setText( 1, status );
++it;
}
checkSelection();
}
bool KCMHelpCenter::buildIndex()
{
kDebug(1401) << "Build Index";
kDebug() << "IndexPath: '" << Prefs::indexDirectory() << "'";
if ( mProcess ) {
kError() << "Error: Index Process still running." << endl;
return false;
}
mIndexQueue.clear();
QFontMetrics fm( font() );
int maxWidth = 0;
mCmdFile = new KTemporaryFile;
if ( !mCmdFile->open() ) {
kError() << "Error opening command file." << endl;
deleteCmdFile();
return false;
}
QTextStream ts ( mCmdFile );
kDebug() << "Writing to file '" << mCmdFile->fileName() << "'";
bool hasError = false;
QTreeWidgetItemIterator it( mListView );
while ( (*it) != 0 ) {
ScopeItem *item = static_cast<ScopeItem *>( (*it) );
if ( item->isOn() ) {
DocEntry *entry = item->entry();
QString docText = i18nc(" Generic prefix label for error messages when creating documentation index, first arg is the document's identifier, second is the document's name", "Document '%1' (%2):\n",
entry->identifier() ,
entry->name() );
if ( entry->documentType().isEmpty() ) {
KMessageBox::sorry( this, docText +
i18n("No document type.") );
hasError = true;
} else {
QString error;
SearchHandler *handler = mEngine->handler( entry->documentType() );
if ( !handler ) {
KMessageBox::sorry( this, docText +
i18n("No search handler available for document type '%1'.",
entry->documentType() ) );
hasError = true;
} else if ( !handler->checkPaths( &error ) ) {
KMessageBox::sorry( this, docText + error );
hasError = true;
} else {
QString indexer = handler->indexCommand( entry->identifier() );
if ( indexer.isEmpty() ) {
KMessageBox::sorry( this, docText +
i18n("No indexing command specified for document type '%1'.",
entry->documentType() ) );
hasError = true;
} else {
indexer.replace( QLatin1String("%i" ), entry->identifier() );
indexer.replace( QLatin1String( "%d" ), Prefs::indexDirectory() );
indexer.replace( QLatin1String( "%p" ), entry->url() );
kDebug() << "INDEXER: " << indexer;
ts << indexer << endl;
int width = fm.width( entry->name() );
if ( width > maxWidth ) maxWidth = width;
mIndexQueue.append( entry );
}
}
}
}
++it;
}
ts.flush();
if ( mIndexQueue.isEmpty() ) {
deleteCmdFile();
return !hasError;
}
mCurrentEntry = mIndexQueue.constBegin();
QString name = (*mCurrentEntry)->name();
if ( !mProgressDialog ) {
mProgressDialog = new IndexProgressDialog( parentWidget() );
connect( mProgressDialog, SIGNAL( cancelled() ),
SLOT( cancelBuildIndex() ) );
connect( mProgressDialog, SIGNAL( closed() ),
SLOT( slotProgressClosed() ) );
}
mProgressDialog->setLabelText( name );
mProgressDialog->setTotalSteps( mIndexQueue.count() );
mProgressDialog->setMinimumLabelWidth( maxWidth );
mProgressDialog->show();
startIndexProcess();
return true;
}
void KCMHelpCenter::startIndexProcess()
{
kDebug() << "KCMHelpCenter::startIndexProcess()";
mProcess = new KProcess;
#ifndef Q_WS_WIN
if ( mRunAsRoot ) {
QString kdesu = KStandardDirs::findExe("kdesu");
if(kdesu.isEmpty()) {
kError() << "Failed to run index process as root - could not find kdesu";
} else {
*mProcess << kdesu;
if(parentWidget()) {
*mProcess << "--attach" << QString::number(parentWidget()->window()->winId());
kDebug() << "Run as root, attaching kdesu to winid " << QString::number(parentWidget()->window()->winId());
}
*mProcess << "--";
}
}
#endif
*mProcess << KStandardDirs::findExe("khc_indexbuilder");
*mProcess << mCmdFile->fileName();
*mProcess << Prefs::indexDirectory();
mProcess->setOutputChannelMode(KProcess::SeparateChannels);
connect( mProcess, SIGNAL( readyReadStandardError() ),
SLOT( slotReceivedStderr() ) );
connect( mProcess, SIGNAL( readyReadStandardOutput() ),
SLOT( slotReceivedStdout() ) );
connect( mProcess, SIGNAL( finished(int, QProcess::ExitStatus) ),
SLOT( slotIndexFinished(int, QProcess::ExitStatus) ) );
mProcess->start();
if (!mProcess->waitForStarted()) {
kError() << "KCMHelpcenter::startIndexProcess(): Failed to start process.";
deleteProcess();
deleteCmdFile();
}
}
void KCMHelpCenter::cancelBuildIndex()
{
kDebug() << "cancelBuildIndex()";
deleteProcess();
deleteCmdFile();
mIndexQueue.clear();
if ( mIsClosing ) {
mIsClosing = false;
}
}
void KCMHelpCenter::slotIndexFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
kDebug() << "KCMHelpCenter::slotIndexFinished()";
if ( exitStatus == QProcess::NormalExit && exitCode == 2 ) {
if ( mRunAsRoot ) {
kError() << "Insufficient permissions." << endl;
} else {
kDebug() << "Insufficient permissions. Trying again as root.";
mRunAsRoot = true;
deleteProcess();
startIndexProcess();
return;
}
} else if ( exitStatus != QProcess::NormalExit || exitCode != 0 ) {
kDebug() << "KProcess reported an error.";
KMessageBox::error( this, i18n("Failed to build index.") );
} else {
mConfig->group( "Search" ).writeEntry( "IndexExists", true );
emit searchIndexUpdated();
}
deleteProcess();
deleteCmdFile();
if ( mProgressDialog ) {
mProgressDialog->setFinished( true );
}
mStdOut.clear();
mStdErr.clear();
if ( mIsClosing ) {
if ( !mProgressDialog || !mProgressDialog->isVisible() ) {
mIsClosing = false;
accept();
}
}
}
void KCMHelpCenter::deleteProcess()
{
delete mProcess;
mProcess = 0;
}
void KCMHelpCenter::deleteCmdFile()
{
delete mCmdFile;
mCmdFile = 0;
}
void KCMHelpCenter::slotIndexProgress()
{
if( !mProcess )
return;
kDebug() << "KCMHelpCenter::slotIndexProgress()";
updateStatus();
advanceProgress();
}
void KCMHelpCenter::slotIndexError( const QString &str )
{
if( !mProcess )
return;
kDebug() << "KCMHelpCenter::slotIndexError()";
KMessageBox::sorry( this, i18n("Error executing indexing build command:\n%1",
str ) );
if ( mProgressDialog ) {
mProgressDialog->appendLog( "<i>" + str + "</i>" );
}
advanceProgress();
}
void KCMHelpCenter::advanceProgress()
{
if ( mProgressDialog && mProgressDialog->isVisible() ) {
mProgressDialog->advanceProgress();
mCurrentEntry++;
if ( mCurrentEntry != mIndexQueue.constEnd() ) {
QString name = (*mCurrentEntry)->name();
mProgressDialog->setLabelText( name );
}
}
}
void KCMHelpCenter::slotReceivedStdout()
{
QByteArray text= mProcess->readAllStandardOutput();
int pos = text.lastIndexOf( '\n' );
if ( pos < 0 ) {
mStdOut.append( text );
} else {
if ( mProgressDialog ) {
mProgressDialog->appendLog( mStdOut + text.left( pos ) );
mStdOut = text.mid( pos + 1 );
}
}
}
void KCMHelpCenter::slotReceivedStderr( )
{
QByteArray text = mProcess->readAllStandardError();
int pos = text.lastIndexOf( '\n' );
if ( pos < 0 ) {
mStdErr.append( text );
} else {
if ( mProgressDialog ) {
mProgressDialog->appendLog( QLatin1String("<i>") + mStdErr + text.left( pos ) +
QLatin1String("</i>"));
mStdErr = text.mid( pos + 1 );
}
}
}
void KCMHelpCenter::slotOk()
{
if ( buildIndex() ) {
if ( !mProcess ) accept();
else mIsClosing = true;
}
}
void KCMHelpCenter::slotProgressClosed()
{
kDebug() << "KCMHelpCenter::slotProgressClosed()";
if ( mIsClosing ) accept();
}
void KCMHelpCenter::showIndexDirDialog()
{
IndexDirDialog dlg( this );
if ( dlg.exec() == QDialog::Accepted ) {
load();
}
}
void KCMHelpCenter::checkSelection()
{
int count = 0;
QTreeWidgetItemIterator it( mListView );
while ( (*it) != 0 ) {
ScopeItem *item = static_cast<ScopeItem *>( (*it) );
if ( item->isOn() ) {
++count;
}
++it;
}
enableButtonOk( count != 0 );
}
#include "moc_kcmhelpcenter.cpp"
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,253 @@
[Desktop Entry]
Type=Application
Exec=kcmshell4 kcmhelpcenter
Icon=help
X-KDE-SubstituteUID=true
X-KDE-Library=helpcenter
X-KDE-RootOnly=true
X-KDE-HasReadOnlyMode=true
X-KDE-ParentApp=kcontrol
Name=Help Index
Name[af]=Hulp Indeks
Name[ar]=فهرس المساعدة
Name[ast]=Índiz d'ayuda
Name[be]=Індэкс дапамогі
Name[be@latin]=Źmiest dapamohi
Name[bg]=Помощна информация
Name[bn]= ি
Name[bn_IN]=ি
Name[br]=Meneger ar skoazell
Name[bs]=Indeks pomoći
Name[ca]=Índex d'ajuda
Name[ca@valencia]=Índex d'ajuda
Name[cs]=Rejstřík nápovědy
Name[csb]=Indeks pòmòcë
Name[cy]=Mynegai Cymorth
Name[da]=Hjælpeindeks
Name[de]=Hilfeindex
Name[el]=Ευρετήριο βοήθειας
Name[en_GB]=Help Index
Name[eo]=Helpa indekso
Name[es]=Índice de ayuda
Name[et]=Abifailide indeks
Name[eu]=Laguntza-indizea
Name[fa]=فهرست کمک
Name[fi]=Opasteen hakemisto
Name[fr]=Index d'aide
Name[fy]=Help-yndeks
Name[ga]=Innéacs na Cabhrach
Name[gl]=Índice da axuda
Name[gu]= િ
Name[he]=אינדקס עזרה
Name[hi]=
Name[hne]=
Name[hr]=Indeks pomoći
Name[hsb]=Indeks za pomoc
Name[hu]=Dokumentációkeresési index
Name[ia]=Indice de adjuta
Name[id]=Indeks Bantuan
Name[is]=Hjálparyfirlit
Name[it]=Indice della guida
Name[ja]=
Name[ka]=
Name[kk]=Анықтама индексі
Name[km]=
Name[kn]= ()
Name[ko]=
Name[ku]=Pêrista Alîkariyê
Name[lt]=Pagalbos rodyklė
Name[lv]=Palīdzības indekss
Name[mai]=ि
Name[mk]=Индекс за помош
Name[ml]=ി ി
Name[mr]=
Name[ms]=Indeks Bantuan
Name[nb]=Hjelpindeks
Name[nds]=Hülpindex
Name[ne]= ि
Name[nl]=Documentatie-index
Name[nn]=Hjelpindeks
Name[or]= ି
Name[pa]=
Name[pl]=Indeks pomocy
Name[pt]=Índice da Ajuda
Name[pt_BR]=Índice da ajuda
Name[ro]=Index ajutor
Name[ru]=Индекс справки
Name[se]=Veahkkeindeaksa
Name[si]=
Name[sk]=Index pomocníka
Name[sl]=Seznam pomoči
Name[sr]=Индекс помоћи
Name[sr@ijekavian]=Индекс помоћи
Name[sr@ijekavianlatin]=Indeks pomoći
Name[sr@latin]=Indeks pomoći
Name[sv]=Hjälpindex
Name[ta]=ி
Name[te]= ి
Name[tg]=Индекси роҳнамо
Name[th]=
Name[tr]=Yardım İçeriği
Name[ug]=ياردەم ئىندېكسى
Name[uk]=Індекс довідки
Name[uz]=Yordam indeksi
Name[uz@cyrillic]=Ёрдам индекси
Name[vi]=Ch mc Tr giúp
Name[wa]=Indecse di l' aidance
Name[xh]=Uncedo Lwesalathisi
Name[x-test]=xxHelp Indexxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Help center search index configuration and generation
Comment[af]=Hulp sentrum soektog indeks opstelling en genereering
Comment[ar]=توليد وضبط فهرس بحث مركز المساعدة
Comment[ast]=Configuración y xeneración del índiz de gueta del centru d'ayuda
Comment[be]=Настаўленне і стварэнне індэксу для пошуку ў дакументацыі
Comment[be@latin]=Naładžvańnie j stvareńnie źmiestu dla pošuku ŭ centry dapamohi
Comment[bg]=Създаване на индекс за ускоряване на търсенето в помощната информация
Comment[bn]=িি ি ি
Comment[bn_IN]=ি ি ি
Comment[bs]=Postava i stvaranje indeksa za pretragu Centra za pomoć
Comment[ca]=Configuració i generació de l'índex de cerca per al Centre d'ajuda
Comment[ca@valencia]=Configuració i generació de l'índex de cerca per al Centre d'ajuda
Comment[cs]=Generování a konfigurace rejstříku nápovědy
Comment[csb]=Kònfigùracëje ë generowanié indeksu pòmòcë
Comment[cy]=Ffurfweddu a chynhyrchu mynegai chwilio y Ganolfan Cymorth
Comment[da]=Hjælpecenterets indstilling og generering af søgeindeks
Comment[de]=Stichwortverzeichnis für das Hilfezentrum einrichten und erstellen
Comment[el]=Διαμόρφωση και δημιουργία του ευρετηρίου αναζήτησης του Κέντρου βοήθειας
Comment[en_GB]=Help centre search index configuration and generation
Comment[es]=Configuración y generación del índice de búsqueda del centro de ayuda
Comment[et]=Abifailide otsingu indeksi loomine ja seadistamine
Comment[eu]=Laguntza-zentroaren bilaketa-indizea konfiguratzea eta sortzea
Comment[fa]=تولید و پیکربندی فهرست جستجوی مرکز کمک
Comment[fi]=Opastekeskuksen hakuindeksin asetukset ja tuottaminen
Comment[fr]=Configuration et génération de l'index de recherche du centre d'aide
Comment[fy]=Sykjeyndeks fan it helpsintrum ynstellen en generearen
Comment[ga]=Cumraíocht agus giniúint an innéacs cuardaigh don lárionad cabhrach
Comment[gl]=Configuración e xeración do índice de busca do centro de axuda
Comment[gu]= િ
Comment[he]=שינוי הגדרות ויצירת אינדקס החיפוש של מרכז העזרה
Comment[hi]= ि ि
Comment[hne]= ि
Comment[hr]=Konfiguriranje i generiranje indeksa za pretraživanje pomoći
Comment[hsb]=Připrawjenje a stworjenje pytanskeho indeksa za pomhanišćo
Comment[hu]=A dokumentáció keresési indexének beállításai
Comment[ia]=Configuration e generation del indice de cerca pro le centro de adjuta
Comment[id]=Konfigurasi dan pembuatan indeks pencarian pusat bantuan
Comment[is]=Uppsettning og sköpun af leitaryfirliti fyrir hjálparmiðstöðina
Comment[it]=Configurazione e generazione dell'indice di ricerca della guida
Comment[ja]=
Comment[ka]=KDE-
Comment[kk]=Анықтамадан табу индексін баптау
Comment[km]=
Comment[kn]= () ಿ
Comment[ko]=
Comment[ku]=Hilberîn û veavakirina îndeksa lêgerînê a navenda alîkariyê
Comment[lt]=Pagalbos centro indekso konfigūravimas ir generavimas
Comment[lv]=Palīdzības centra meklēšanas indeksa konfigurācija un ģenerācija
Comment[mai]=ि ि ि
Comment[mk]=Конфигурирање и генерирање на индексот на Центарот за Помош
Comment[ml]=ി ി
Comment[mr]= ि
Comment[nb]=Tilpass søkeindeksen og legg den til i hjelpesenteret
Comment[nds]=Söökindex för't Hülpzentrum inrichten un maken laten
Comment[ne]= ि ि ि
Comment[nl]=Zoekindex van het documentatiecentrum instellen en genereren
Comment[nn]=Oppsett og generering av søkjeindeks for hjelpesenteret
Comment[or]= ି ି
Comment[pa]= ਿ
Comment[pl]=Ustawienia i tworzenie spisu treści pomocy
Comment[pt]=Configuração e geração do índice de pesquisa do centro de ajuda
Comment[pt_BR]=Configuração e geração do índice de busca do centro de ajuda
Comment[ro]=Generează și configurează indexul de căutare pentru Centrul de Ajutor
Comment[ru]=Настройка индекса справочной системы KDE
Comment[se]=Veahkkeguovddáža ohcanindeavssa heiveheapmi ja ráhkadeapmi
Comment[si]=
Comment[sk]=Nastavenie a generovanie indexu pre pomocníka
Comment[sl]=Nastavitve in ustvarjanje iskalnega kazala za Središče za pomoč
Comment[sr]=Постава и стварање индекса за претрагу Центра за помоћ
Comment[sr@ijekavian]=Постава и стварање индекса за претрагу Центра за помоћ
Comment[sr@ijekavianlatin]=Postava i stvaranje indeksa za pretragu Centra za pomoć
Comment[sr@latin]=Postava i stvaranje indeksa za pretragu Centra za pomoć
Comment[sv]=Skapa och ställ in sökindex för Hjälpcentralen
Comment[ta]=ி ி
Comment[te]= ి ి
Comment[tg]=Маркази роҳнамои ҷустуҷӯи индекси танзимот ва эҷодкорӣ
Comment[th]=
Comment[tr]=Yardım merkezi dizininin yapılandırılması ve oluşturulması
Comment[ug]=ياردەم مەركىزىنىڭ ئىزدەش ئىندېكس سەپلىمىسى ۋە ھاسىل قىلىش
Comment[uk]=Створення та налаштування індексу пошуку Центру довідки
Comment[uz]=Yordam markazining qidiruv indeksini yaratish va moslash
Comment[uz@cyrillic]=Ёрдам марказининг қидирув индексини яратиш ва мослаш
Comment[vi]=Cu hình và to ra ch mc tìm kiếm ca trung tâm tr giúp
Comment[wa]=Fijhaedje eyet apontiaedje di l' indecse di cweraedje do cinte d' aidance
Comment[xh]=Uqwalaselo lophendlo loncedo osembindi nolwenziwo
Comment[x-test]=xxHelp center search index configuration and generationxx
Comment[zh_CN]=
Comment[zh_TW]=
X-KDE-Keywords=khelpcenter,help,index,search
X-KDE-Keywords[ar]=مركز مساعدة كدي,مساعدة,فهرس,بحث
X-KDE-Keywords[bg]=khelpcenter,help,index,search,помощ,индекс,търсене
X-KDE-Keywords[bn]=khelpcenter,help,index,search
X-KDE-Keywords[bs]=khelpcenter,help,index,search,pomoć,pretraga,indeks
X-KDE-Keywords[ca]=khelpcenter,ajuda,índex,cerca
X-KDE-Keywords[ca@valencia]=khelpcenter,ajuda,índex,cerca
X-KDE-Keywords[cs]=khelpcenter,help,index,hledat
X-KDE-Keywords[da]=khelpcenter,hjælp,indeks,søg
X-KDE-Keywords[de]=Hilfezentrum,Index,Stichwortverzeichnis,Suche
X-KDE-Keywords[el]=khelpcenter,βοήθεια,ευρετήριο,αναζήτηση
X-KDE-Keywords[en_GB]=khelpcenter,help,index,search
X-KDE-Keywords[eo]=khelpcenter,helpo,indekso,serĉo
X-KDE-Keywords[es]=khelpcenter,ayuda,índice,buscar
X-KDE-Keywords[et]=khelpcenter,abi,indeks,otsing,KDE abikeskus,abikeskus
X-KDE-Keywords[eu]=khelpcenter,laguntza,indizea,bilaketa
X-KDE-Keywords[fa]=khelpcenter,help,index,search
X-KDE-Keywords[fi]=khelpcenter,ohje,opaste,indeksi,hakemisto,haku
X-KDE-Keywords[fr]=khelpcenter, aide, index, recherche
X-KDE-Keywords[ga]=khelpcenter,cabhair,innéacs,cuardach
X-KDE-Keywords[gl]=khelpcenter,axuda,índice,buscar
X-KDE-Keywords[gu]=khelpcenter,,,
X-KDE-Keywords[hi]=khelpcenter, , ,
X-KDE-Keywords[hu]=khelpcenter,súgó,index,keresés
X-KDE-Keywords[ia]=khelpcenter,adjuta,indice,cerca
X-KDE-Keywords[id]=khelpcenter,bantuan,indeks,cari
X-KDE-Keywords[is]=khelpcenter,hjálp,yfirlit,leit
X-KDE-Keywords[it]=khelpcenter,aiuto,indice,ricerca
X-KDE-Keywords[ja]=khelpcenter,help,index,search
X-KDE-Keywords[kk]=khelpcenter,help,index,search
X-KDE-Keywords[km]=khelpcenter,help,index,search
X-KDE-Keywords[ko]=khelpcenter,help,index,search,,,
X-KDE-Keywords[lv]=khelpcenter,palīdzība,indekss,meklēšana
X-KDE-Keywords[mr]=khelpcenter, , ि,
X-KDE-Keywords[nb]=khelpcenter,hjelp,index,søk
X-KDE-Keywords[nds]=khelpcenter,Hülp,Index,Söök
X-KDE-Keywords[nl]=khelpcenter,help,index,zoeken
X-KDE-Keywords[nn]=khelpcenter,hjelp,indeks,stikkord,søk
X-KDE-Keywords[pa]=khelpcenter,,,,
X-KDE-Keywords[pl]=centrum pomocy,pomoc,indeks,znajdywanie,wyszukiwanie
X-KDE-Keywords[pt]=khelpcenter,ajuda,índice,pesquisa
X-KDE-Keywords[pt_BR]=khelpcenter,ajuda,índice,pesquisa
X-KDE-Keywords[ro]=khelpcenter,centru,ajutor,cuprins,căutare
X-KDE-Keywords[ru]=khelpcenter,help,index,search,помощь,справка,индекс,поиск
X-KDE-Keywords[sk]=khelpcenter,help,index,hľadanie
X-KDE-Keywords[sl]=khelpcenter,pomoč,kazalo,iskanje
X-KDE-Keywords[sr]=khelpcenter,help,index,search,Кцентар-помоћи,помоћ,индекс,претрага,тражење
X-KDE-Keywords[sr@ijekavian]=khelpcenter,help,index,search,Кцентар-помоћи,помоћ,индекс,претрага,тражење
X-KDE-Keywords[sr@ijekavianlatin]=khelpcenter,help,index,search,Kcentar-pomoći,pomoć,indeks,pretraga,traženje
X-KDE-Keywords[sr@latin]=khelpcenter,help,index,search,Kcentar-pomoći,pomoć,indeks,pretraga,traženje
X-KDE-Keywords[sv]=Hjälpcentralen,hjälp,index,sök
X-KDE-Keywords[tg]=khelpcenter,кумак,индекс,ҷустуҷӯ
X-KDE-Keywords[tr]=khelpcenter,yardım,dizin,arama
X-KDE-Keywords[ug]=khelpcenter، ياردەم، ئىندېكس، ئىزدەش
X-KDE-Keywords[uk]=khelpcenter,help,index,search,довідка,центр,покажчик,індекс,пошук,допомога
X-KDE-Keywords[vi]=trung tâm tr giúp KDE,tr giúp,ch mc,tìm kiếm,khelpcenter,help,index,search
X-KDE-Keywords[wa]=khelpcenter,kcinte d' aidance,indecse,cweri,cweraedje,trover,cachî,cachî après
X-KDE-Keywords[x-test]=xxkhelpcenterxx,xxhelpxx,xxindexxx,xxsearchxx
X-KDE-Keywords[zh_CN]=khelpcenter,help,index,search,,
X-KDE-Keywords[zh_TW]=khelpcenter,help,index,search
Categories=Qt;KDE;X-KDE-settings-system;

168
khelpcenter/kcmhelpcenter.h Normal file
View file

@ -0,0 +1,168 @@
/*
This file is part of KHelpcenter.
Copyright (C) 2002 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KHC_KCMHELPCENTER_H
#define KHC_KCMHELPCENTER_H
#include <KDialog>
#include <KSharedConfig>
#include <KProcess>
#include "scopeitem.h"
class QPushButton;
class QProgressBar;
class QTextEdit;
class QLabel;
class KAboutData;
class KTemporaryFile;
class KUrlRequester;
class QTreeWidget;
namespace KHC {
class HtmlSearchConfig;
class DocEntry;
class SearchEngine;
}
class IndexDirDialog : public KDialog
{
Q_OBJECT
public:
IndexDirDialog( QWidget *parent );
protected Q_SLOTS:
void slotOk();
void slotUrlChanged( const QString &_url);
private:
KUrlRequester *mIndexUrlRequester;
};
class IndexProgressDialog : public KDialog
{
Q_OBJECT
public:
IndexProgressDialog( QWidget *parent );
~IndexProgressDialog();
void setTotalSteps( int );
void advanceProgress();
void setLabelText( const QString & );
void setMinimumLabelWidth( int width );
void setFinished( bool );
void appendLog( const QString &text );
Q_SIGNALS:
void closed();
void cancelled();
protected:
void hideDetails();
protected Q_SLOTS:
void slotEnd();
void toggleDetails();
private:
QLabel *mLabel;
QProgressBar *mProgressBar;
QLabel *mLogLabel;
QTextEdit *mLogView;
bool mFinished;
};
class KCMHelpCenter : public KDialog
{
Q_OBJECT
public:
explicit KCMHelpCenter( KHC::SearchEngine *, QWidget *parent = 0,
const char *name = 0 );
~KCMHelpCenter();
void load();
bool save();
void defaults();
public Q_SLOTS:
Q_SIGNALS:
void searchIndexUpdated();
public Q_SLOTS:
void slotIndexError( const QString & );
void slotIndexProgress();
protected Q_SLOTS:
bool buildIndex();
void cancelBuildIndex();
void slotIndexFinished( int exitCode, QProcess::ExitStatus exitStatus );
void slotReceivedStdout();
void slotReceivedStderr();
void slotProgressClosed();
void slotOk();
void showIndexDirDialog();
void checkSelection();
protected:
void setupMainWidget( QWidget *parent );
void updateStatus();
void startIndexProcess();
void deleteProcess();
void deleteCmdFile();
void advanceProgress();
private:
KHC::SearchEngine *mEngine;
QTreeWidget *mListView;
QLabel *mIndexDirLabel;
QPushButton *mBuildButton;
IndexProgressDialog *mProgressDialog;
QList<KHC::DocEntry *> mIndexQueue;
QList<KHC::DocEntry *>::ConstIterator mCurrentEntry;
KSharedConfigPtr mConfig;
KAboutData *mAboutData;
KHC::HtmlSearchConfig *mHtmlSearchTab;
QWidget *mScopeTab;
KTemporaryFile *mCmdFile;
KProcess *mProcess;
bool mIsClosing;
QByteArray mStdOut;
QByteArray mStdErr;
bool mRunAsRoot;
};
#endif //KHC_KCMHELPCENTER_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,203 @@
/*
This file is part of the KDE Help Center
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA
*/
#include "khc_indexbuilder.h"
#include "version.h"
#include <KAboutData>
#include <KLocale>
#include <KCmdLineArgs>
#include <KUniqueApplication>
#include <KDebug>
#include <KProcess>
#include <KConfig>
#include <KShell>
#include <QFile>
#include <QTextStream>
#include <QDBusMessage>
#include <QDBusConnection>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
using namespace KHC;
IndexBuilder::IndexBuilder(const QString& cmdFile)
{
m_cmdFile = cmdFile;
kDebug(1402) << "IndexBuilder()";
}
void IndexBuilder::buildIndices()
{
QFile f( m_cmdFile );
if ( !f.open( QIODevice::ReadOnly ) ) {
kError() << "Unable to open file '" << m_cmdFile << "'" << endl;
exit( 1 );
}
kDebug(1402) << "Opened file '" << m_cmdFile << "'";
QTextStream ts( &f );
QString line = ts.readLine();
while ( !line.isNull() ) {
kDebug(1402) << "LINE: " << line;
mCmdQueue.append( line );
line = ts.readLine();
}
processCmdQueue();
}
void IndexBuilder::processCmdQueue()
{
kDebug(1402) << "IndexBuilder::processCmdQueue()";
QStringList::Iterator it = mCmdQueue.begin();
if ( it == mCmdQueue.end() ) {
quit();
return;
}
QString cmd = *it;
kDebug(1402) << "PROCESS: " << cmd;
KProcess *proc = new KProcess;
*proc << KShell::splitArgs(cmd);
connect( proc, SIGNAL( finished( int, QProcess::ExitStatus) ),
SLOT( slotProcessExited( int, QProcess::ExitStatus) ) );
mCmdQueue.erase( it );
proc->start();
if ( !proc->waitForStarted() ) {
sendErrorSignal( i18n("Unable to start command '%1'.", cmd ) );
processCmdQueue();
delete proc;
}
}
void IndexBuilder::slotProcessExited( int exitCode, QProcess::ExitStatus exitStatus )
{
KProcess *proc = static_cast<KProcess *>(sender());
if ( exitStatus != QProcess::NormalExit ) {
kError(1402) << "Process failed" << endl;
kError(1402) << "stdout output:" << proc->readAllStandardOutput();
kError(1402) << "stderr output:" << proc->readAllStandardError();
}
else if (exitCode != 0 ) {
kError(1402) << "running" << proc->program() << "failed with exitCode" << exitCode;
kError(1402) << "stdout output:" << proc->readAllStandardOutput();
kError(1402) << "stderr output:" << proc->readAllStandardError();
}
delete proc;
sendProgressSignal();
processCmdQueue();
}
void IndexBuilder::sendErrorSignal( const QString &error )
{
kDebug(1402) << "IndexBuilder::sendErrorSignal()";
QDBusMessage message =
QDBusMessage::createSignal("/kcmhelpcenter", "org.kde.kcmhelpcenter", "buildIndexError");
message <<error;
QDBusConnection::sessionBus().send(message);
}
void IndexBuilder::sendProgressSignal()
{
kDebug(1402) << "IndexBuilder::sendProgressSignal()";
QDBusMessage message =
QDBusMessage::createSignal("/kcmhelpcenter", "org.kde.kcmhelpcenter", "buildIndexProgress");
QDBusConnection::sessionBus().send(message);
}
void IndexBuilder::quit()
{
kDebug(1402) << "IndexBuilder::quit()";
qApp->quit();
}
int main( int argc, char **argv )
{
KAboutData aboutData( "khc_indexbuilder", 0,
ki18n("KHelpCenter Index Builder"),
HELPCENTER_VERSION,
ki18n("The KDE Help Center"),
KAboutData::License_GPL,
ki18n("(c) 2003, The KHelpCenter developers") );
aboutData.addAuthor( ki18n("Cornelius Schumacher"), KLocalizedString(), "schumacher@kde.org" );
KCmdLineArgs::init( argc, argv, &aboutData );
KCmdLineOptions options;
options.add("+cmdfile", ki18n("Document to be indexed"));
options.add("+indexdir", ki18n("Index directory"));
KCmdLineArgs::addCmdLineOptions( options );
// Note: no KComponentData seems necessary
QCoreApplication app( KCmdLineArgs::qtArgc(), KCmdLineArgs::qtArgv() );
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
if ( args->count() != 2 ) {
kDebug(1402) << "Wrong number of arguments.";
return 1;
}
QString cmdFile = args->arg( 0 );
QString indexDir = args->arg( 1 );
kDebug(1402) << "cmdFile: " << cmdFile;
kDebug(1402) << "indexDir: " << indexDir;
QFile file( indexDir + "/testaccess" );
if ( !file.open( QIODevice::WriteOnly ) || !file.putChar( ' ' ) ) {
kDebug(1402) << "access denied";
return 2;
} else {
kDebug(1402) << "can access";
file.remove();
}
IndexBuilder builder(cmdFile);
QTimer::singleShot(0, &builder, SLOT(buildIndices()));
return app.exec();
}
#include "moc_khc_indexbuilder.cpp"
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,59 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_INDEXBUILDER_H
#define KHC_INDEXBUILDER_H
#include <KUniqueApplication>
#include <KProcess>
#include <QObject>
#include <QTimer>
namespace KHC {
class IndexBuilder : public QObject
{
Q_OBJECT
public:
IndexBuilder(const QString& cmdFile);
void sendProgressSignal();
void sendErrorSignal( const QString &error );
void quit();
void processCmdQueue();
protected Q_SLOTS:
void buildIndices();
void slotProcessExited( int, QProcess::ExitStatus );
private:
QString m_cmdFile;
QTimer mTimer;
QStringList mCmdQueue;
};
}
#endif //KHC_INDEXBUILDER_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,190 @@
[Desktop Entry]
Name=KHelpCenter
Name[af]=Khulpsentrum
Name[ar]=مركز مساعدة كدي
Name[ast]=KHelpcenter
Name[be]=Цэнтр дапамогі KDE
Name[be@latin]=KHelpCenter
Name[bg]=Помощен център
Name[bn]=KHelpCenter
Name[bn_IN]=KHelpCenter
Name[br]=KHelpCenter
Name[bs]=Kcentar-pomoći
Name[ca]=KHelpCenter
Name[ca@valencia]=KHelpCenter
Name[cs]=Centrum nápovědy
Name[csb]=Centróm Pòmòcë
Name[cy]=KCanolfanCymorth
Name[da]=KHjælpecenter
Name[de]=KDE-Hilfezentrum
Name[el]=KHelpCenter
Name[en_GB]=KHelpCentre
Name[eo]=KHelpCenter
Name[es]=KHelpcenter
Name[et]=KDE abikeskus
Name[eu]=KHelpCenter
Name[fa]=KHelpCenter
Name[fi]=KHelpCenter
Name[fr]=Centre d'aide de KDE
Name[fy]=KHelpCenter
Name[ga]=KHelpCenter
Name[gl]=Centro de axuda de KDE
Name[gu]=KHelpCenter
Name[he]=KHelpCenter
Name[hi]=--
Name[hne]=--
Name[hr]=KHelpCenter
Name[hsb]=KHelpCenter (pomhanišćo)
Name[hu]=KHelpCenter
Name[ia]=KHelpCenter
Name[id]=KHelpCenter
Name[is]=Hjálparkerfi KDE
Name[it]=KHelpCenter
Name[ja]=K
Name[ka]=KHelpCenter
Name[kk]=KHelpCenter
Name[km]=KHelpCenter
Name[kn]=
Name[ko]=KHelpCenter
Name[ku]=KHelpCenter
Name[lt]=KHelpCenter
Name[lv]=KHelpCenter
Name[mai]=--
Name[mk]=KHelpCenter
Name[ml]=
Name[mr]=--
Name[ms]=KHelpCenter
Name[nb]=KHelpCenter
Name[nds]=KDE-Hülpzentrum
Name[ne]=
Name[nl]=KHelpCenter
Name[nn]=KHelpCenter
Name[oc]=KHelpCenter
Name[or]=K
Name[pa]=-
Name[pl]=Centrum Pomocy
Name[pt]=KHelpCenter
Name[pt_BR]=KHelpCenter
Name[ro]=Centrul de ajutor KDE
Name[ru]=Центр справки
Name[se]=KHelpCenter
Name[si]=KHelpCenter
Name[sk]=KHelpCenter
Name[sl]=KHelpCenter
Name[sr]=Кцентар-помоћи
Name[sr@ijekavian]=Кцентар-помоћи
Name[sr@ijekavianlatin]=Kcentar-pomoći
Name[sr@latin]=Kcentar-pomoći
Name[sv]=Hjälpcentralen
Name[ta]=Kி
Name[te]=
Name[tg]=Маркази роҳнамои KDE
Name[th]=-K
Name[tr]=KHelpCenter
Name[ug]=KHelpCenter
Name[uk]=KHelpCenter
Name[uz]=Yordam markazi
Name[uz@cyrillic]=Ёрдам маркази
Name[vi]=Trung tâm Tr giúp KDE
Name[wa]=KCinte d' aidance
Name[xh]=KHelpCenter
Name[x-test]=xxKHelpCenterxx
Name[zh_CN]=KHelpcenter
Name[zh_TW]=KHelpCenter
Comment=The KDE Help Center
Comment[af]=Die Kde Hulp Sentrum
Comment[ar]=مركز كدي للمساعدة
Comment[ast]=El centru d'ayuda de KDE
Comment[be]=Цэнтр дапамогі KDE
Comment[be@latin]=Centar dapamohi KDE
Comment[bg]=Център за помощна информация
Comment[bn]=.ি..
Comment[bn_IN]=KDE
Comment[br]=Kreizenn sikour KDE
Comment[bs]=KDEov centar za pomoć
Comment[ca]=El centre d'ajuda KDE
Comment[ca@valencia]=El centre d'ajuda KDE
Comment[cs]=Centrum nápovědy prostředí KDE
Comment[csb]=Centróm Pòmòcë KDE
Comment[cy]=Canolfan Cymorth KDE
Comment[da]=KDE's hjælpecenter
Comment[de]=Das KDE-Hilfezentrum
Comment[el]=Το κέντρο βοήθειας του KDE
Comment[en_GB]=The KDE Help Centre
Comment[eo]=La helpocentro de KDE
Comment[es]=Centro de ayuda de KDE
Comment[et]=KDE abikeskus
Comment[eu]=KDEren laguntza-zentroa
Comment[fa]=مرکز کمک کیدیای
Comment[fi]=KDE:n ohjeet
Comment[fr]=Le centre d'aide de KDE
Comment[fy]=It KDE-dokumintaasjesintrum
Comment[ga]=Lárionad Cabhrach KDE
Comment[gl]=O centro de axuda de KDE
Comment[gu]=KDE
Comment[he]=מרכז העזרה של KDE
Comment[hi]=
Comment[hne]=
Comment[hr]=KDE pomoć
Comment[hsb]=KDE pomhanišćo
Comment[hu]=KDE Súgó
Comment[ia]=Le centro de adjuta de KDE
Comment[id]=Pusat Bantuan KDE
Comment[is]=Hjálparkerfi KDE
Comment[it]=Guida di KDE
Comment[ja]=KDE
Comment[ka]=KDE-
Comment[kk]=KDE анықтама орталығы
Comment[km]= KDE
Comment[kn]=ಿ
Comment[ko]=KDE
Comment[ku]=Navenda Alîkariya KDE'yê
Comment[lt]=KDE pagalbos centras
Comment[lv]=KDE palīdzības centrs
Comment[mai]= ि
Comment[mk]=KDE Центарот за Помош
Comment[ml]=ി
Comment[mr]=
Comment[ms]=Pusat Bantuan KDE
Comment[nb]=KDE Hjelpesenter
Comment[nds]=Dat KDE-Hülpzentrum
Comment[ne]=
Comment[nl]=Het KDE-documentatiecentrum
Comment[nn]=KDE-hjelpesenteret
Comment[or]=KDE
Comment[pa]=
Comment[pl]=Centrum Pomocy KDE
Comment[pt]=O Centro de Ajuda do KDE
Comment[pt_BR]=O centro de ajuda do KDE
Comment[ro]=Centrul de ajutor al KDE
Comment[ru]=Центр справки KDE
Comment[se]=KDE veahkkeguovddáš
Comment[si]=KDE
Comment[sk]=Centrum pomoci KDE
Comment[sl]=Središče za pomoč v KDE
Comment[sr]=КДЕов центар за помоћ
Comment[sr@ijekavian]=КДЕов центар за помоћ
Comment[sr@ijekavianlatin]=KDEov centar za pomoć
Comment[sr@latin]=KDEov centar za pomoć
Comment[sv]=KDE:s hjälpcentral
Comment[ta]=KDE ி
Comment[te]=ి
Comment[tg]=Маркази роҳнамои KDE
Comment[th]= KDE
Comment[tr]=KDE Yardım Merkezi
Comment[ug]=ك د ئې(KDE) ياردەم مەركىزى
Comment[uk]=Центр довідки KDE
Comment[uz]=KDE yordam markazi
Comment[uz@cyrillic]=KDE ёрдам маркази
Comment[vi]=Trung tâm Tr giúp KDE
Comment[wa]=Li cinte d' aidance di KDE
Comment[xh]=Umbindi woncedo lwe KDE
Comment[x-test]=xxThe KDE Help Centerxx
Comment[zh_CN]=KDE
Comment[zh_TW]=KDE
Icon=help-browser
X-DocPath=khelpcenter/index.html
Type=Service
Terminal=false
Exec=khelpcenter %u
X-KDE-StartupNotify=true

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<include>kstandarddirs.h</include>
<kcfgfile name="khelpcenterrc"/>
<group name="Search">
<entry type="Path" key="IndexDirectory">
<label>Path to index directory.</label>
<whatsthis>Path to directory containing search indices.</whatsthis>
<default code="true">KGlobal::dirs()->saveLocation("data", "khelpcenter/index/")</default>
</entry>
<entry type="Int" key="Method">
<default>0</default>
</entry>
<entry type="Int" key="MaxCount">
<default>0</default>
</entry>
</group>
<group name="Layout">
<entry type="Enum" key="CurrentTab">
<label>Currently visible navigator tab</label>
<choices>
<choice name="Content"/>
<choice name="Search"/>
<choice name="Glossary"/>
</choices>
<default>Content</default>
</entry>
</group>
</kcfg>

View file

@ -0,0 +1,45 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="khelpcenter" version="17">
<MenuBar>
<Menu name="edit" noMerge="1">
<text>&amp;Edit</text>
<Action name="copy_text" />
<Separator />
<Action name="selectAll" />
<Separator />
<Action name="find" />
</Menu>
<Menu name="view" noMerge="1">
<text>&amp;View</text>
<Action name="viewDocumentSource" />
<Action name="setEncoding" />
</Menu>
<Menu name="go">
<text>&amp;Go</text>
<Action name="prevPage" />
<Action name="nextPage" />
<Separator />
<Action name="back" />
<Action name="forward" />
<!--
<Separator />
<Action name="lastsearch" />
-->
</Menu>
<Menu name="settings">
<Action name="configure_fonts" append="save_merge"/>
</Menu>
</MenuBar>
<ToolBar name="mainToolBar" noMerge="1">
<text>Main Toolbar</text>
<Action name="go_home" />
<Action name="back" />
<Action name="forward" />
<Separator />
<Action name="copy_text" />
<Action name="find" />
<Separator />
<Action name="incFontSizes" />
<Action name="decFontSizes" />
</ToolBar>
</kpartgui>

440
khelpcenter/mainwindow.cpp Normal file
View file

@ -0,0 +1,440 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 1999 Matthias Elter (me@kde.org)
* 2001 Stephan Kulow (coolo@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mainwindow.h"
#include "history.h"
#include "view.h"
#include "searchengine.h"
#include "fontdialog.h"
#include "prefs.h"
#include <KAction>
#include <KActionCollection>
#include <KApplication>
#include <KConfig>
#include <KIcon>
#include <KIconLoader>
#include <KMimeType>
#include <KRun>
#include <KAboutData>
#include <KDebug>
#include <KWebView>
#include <KStatusBar>
#include <KStandardShortcut>
#include <KDialog>
#include <KLocale>
#include <KStandardAction>
#include <KXmlGuiWindow>
#include <KStartupInfo>
#include <KConfigGroup>
#include <QtDBus/QDBusConnection>
#include <QSplitter>
#include <QTextEdit>
#include <QLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QList>
#include <QBoxLayout>
#include <stdlib.h>
#include <assert.h>
#include <kglobal.h>
using namespace KHC;
class LogDialog : public KDialog
{
public:
LogDialog( QWidget *parent = 0 )
: KDialog( parent )
{
setCaption( i18n("Search Error Log") );
setButtons( Ok );
QFrame *topFrame = new QFrame( this );
setMainWidget( topFrame );
QBoxLayout *topLayout = new QVBoxLayout( topFrame );
mTextView = new QTextEdit( topFrame );
mTextView->setReadOnly ( true );
mTextView->setWordWrapMode( QTextOption::NoWrap );
topLayout->addWidget( mTextView );
KConfigGroup cg = KGlobal::config()->group( "logdialog" );
restoreDialogSize( cg );
}
~LogDialog()
{
KConfigGroup cg = KGlobal::config()->group( "logdialog" );
KDialog::saveDialogSize( cg );
}
void setLog( const QString &log )
{
mTextView->setText( log );
}
private:
QTextEdit *mTextView;
};
MainWindow::MainWindow()
: KXmlGuiWindow(0),
mLogDialog( 0 )
{
setObjectName( QLatin1String( "MainWindow" ) );
QDBusConnection::sessionBus().registerObject("/KHelpCenter", this, QDBusConnection::ExportScriptableSlots);
mSplitter = new QSplitter( this );
mDoc = new View( mSplitter, this, actionCollection() );
connect( mDoc, SIGNAL( setWindowCaption( const QString & ) ),
SLOT( setCaption( const QString & ) ) );
connect( mDoc, SIGNAL( setStatusBarText( const QString & ) ),
SLOT( statusBarMessage( const QString & ) ) );
connect( mDoc, SIGNAL( onURL( const QString & ) ),
SLOT( statusBarMessage( const QString & ) ) );
connect( mDoc, SIGNAL( started( KIO::Job * ) ),
SLOT( slotStarted( KIO::Job * ) ) );
connect( mDoc, SIGNAL( completed() ),
SLOT( documentCompleted() ) );
connect( mDoc, SIGNAL( searchResultCacheAvailable() ),
SLOT( enableLastSearchAction() ) );
connect( mDoc, SIGNAL( selectionChanged() ),
SLOT( enableCopyTextAction() ) );
statusBar()->insertItem(i18n("Preparing Index"), 0, 1);
statusBar()->setItemAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
mNavigator = new Navigator( mDoc, mSplitter, "nav" );
connect( mNavigator, SIGNAL( itemSelected( const QString & ) ),
SLOT( viewUrl( const QString & ) ) );
connect( mNavigator, SIGNAL( glossSelected( const GlossaryEntry & ) ),
SLOT( slotGlossSelected( const GlossaryEntry & ) ) );
mSplitter->insertWidget(0, mNavigator);
mSplitter->setStretchFactor(mSplitter->indexOf(mNavigator), 0);
setCentralWidget( mSplitter );
QList<int> sizes;
sizes << 220 << 580;
mSplitter->setSizes(sizes);
KSharedConfig::Ptr cfg = KGlobal::config();
{
KConfigGroup configGroup( cfg, "General" );
if ( configGroup.readEntry( "UseKonqSettings", true) ) {
KConfig konqCfg( "konquerorrc" );
}
}
setupActions();
setupGUI(QSize(800, 600), ToolBar | Keys | StatusBar | Create);
setAutoSaveSettings();
History::self().installMenuBarHook( this );
connect( &History::self(), SIGNAL( goInternalUrl( const KUrl & ) ),
mNavigator, SLOT( openInternalUrl( const KUrl & ) ) );
connect( &History::self(), SIGNAL( goUrl( const KUrl & ) ),
mNavigator, SLOT( selectItem( const KUrl & ) ) );
statusBarMessage(i18n("Ready"));
enableCopyTextAction();
readConfig();
}
MainWindow::~MainWindow()
{
writeConfig();
}
void MainWindow::enableCopyTextAction()
{
mCopyText->setEnabled( mDoc->hasSelection() );
}
void MainWindow::saveProperties( KConfigGroup &config )
{
kDebug();
}
void MainWindow::readProperties( const KConfigGroup &config )
{
kDebug();
mDoc->slotReload( KUrl( config.readPathEntry( "URL", QString() ) ) );
}
void MainWindow::readConfig()
{
KConfigGroup config(KGlobal::config(), "MainWindowState");
QList<int> sizes = config.readEntry( "Splitter", QList<int>() );
if ( sizes.count() == 2 ) {
mSplitter->setSizes( sizes );
}
mNavigator->readConfig();
}
void MainWindow::writeConfig()
{
KConfigGroup config(KGlobal::config(), "MainWindowState");
config.writeEntry( "Splitter", mSplitter->sizes() );
mNavigator->writeConfig();
Prefs::self()->writeConfig();
}
void MainWindow::setupActions()
{
actionCollection()->addAction( KStandardAction::Quit, this, SLOT( close() ) );
actionCollection()->addAction( KStandardAction::Print, this, SLOT( print() ) );
KAction *prevPage = actionCollection()->addAction( "prevPage" );
prevPage->setText( i18n( "Previous Page" ) );
prevPage->setShortcut( Qt::CTRL+Qt::Key_PageUp );
prevPage->setWhatsThis( i18n( "Moves to the previous page of the document" ) );
connect( prevPage, SIGNAL( triggered() ), mDoc, SLOT( prevPage() ) );
KAction *nextPage = actionCollection()->addAction( "nextPage" );
nextPage->setText( i18n( "Next Page" ) );
nextPage->setShortcut( Qt::CTRL + Qt::Key_PageDown );
nextPage->setWhatsThis( i18n( "Moves to the next page of the document" ) );
connect( nextPage, SIGNAL( triggered() ), mDoc, SLOT( nextPage() ) );
QAction *home = KStandardAction::home( this, SLOT( slotShowHome() ), this );
actionCollection()->addAction( home->objectName(), home );
home->setText(i18n("Table of &Contents"));
home->setToolTip(i18n("Table of contents"));
home->setWhatsThis(i18n("Go back to the table of contents"));
mCopyText = KStandardAction::copy( this, SLOT(slotCopySelectedText()), this );
actionCollection()->addAction( "copy_text", mCopyText );
mLastSearchAction = actionCollection()->addAction( QLatin1String("lastsearch") );
mLastSearchAction->setText( i18n("&Last Search Result") );
mLastSearchAction->setEnabled( false );
connect( mLastSearchAction, SIGNAL( triggered() ), this, SLOT( slotLastSearch() ) );
/*
QAction *action = actionCollection()->addAction( QLatin1String("build_index") );
action->setText( i18n("Build Search Index...") );
connect( action, SIGNAL( triggered() ), mNavigator, SLOT( showIndexDialog() ) );
KConfigGroup debugGroup( KGlobal::config(), "Debug" );
if ( debugGroup.readEntry( "SearchErrorLog", false) ) {
action = actionCollection()->addAction(QLatin1String("show_search_stderr"));
action->setText( i18n("Show Search Error Log") );
connect( action, SIGNAL( triggered() ), this, SLOT( showSearchStderr() ) );
}
*/
History::self().setupActions( actionCollection() );
QAction *action = actionCollection()->addAction(QLatin1String("configure_fonts" ));
action->setText( i18n( "Configure Fonts..." ) );
connect( action, SIGNAL( triggered() ), this, SLOT( slotConfigureFonts() ) );
action = actionCollection()->addAction(QLatin1String("incFontSizes"));
action->setText( i18n( "Increase Font Sizes" ) );
action->setIcon( KIcon( QLatin1String("zoom-in") ) );
connect( action, SIGNAL( triggered() ), this, SLOT( slotIncFontSizes() ) );
action = actionCollection()->addAction(QLatin1String("decFontSizes"));
action->setText( i18n( "Decrease Font Sizes" ) );
action->setIcon( KIcon( QLatin1String("zoom-out") ) );
connect( action, SIGNAL( triggered() ), this, SLOT( slotDecFontSizes() ) );
}
void MainWindow::slotCopySelectedText()
{
mDoc->copySelectedText();
}
void MainWindow::print()
{
}
void MainWindow::slotStarted(KIO::Job *job)
{
if (job)
connect(job, SIGNAL(infoMessage( KJob *, const QString &, const QString &)),
SLOT(slotInfoMessage(KJob *, const QString &)));
History::self().updateActions();
}
void MainWindow::viewUrl( const QString &url )
{
viewUrl( KUrl( url ) );
}
void MainWindow::viewUrl( const KUrl &url, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments &browserArgs )
{
stop();
QString proto = url.protocol().toLower();
if ( proto == "khelpcenter" ) {
History::self().createEntry();
mNavigator->openInternalUrl( url );
return;
}
bool own = false;
if ( proto == QLatin1String("help")
|| proto == QLatin1String("glossentry")
|| proto == QLatin1String("about")
|| proto == QLatin1String("man")
|| proto == QLatin1String("info")
|| proto == QLatin1String("cgi")
|| proto == QLatin1String("ghelp"))
own = true;
else if ( url.isLocalFile() ) {
KMimeType::Ptr mime = KMimeType::findByPath( url.toLocalFile() );
if ( mime->is("text/html") )
own = true;
}
if ( !own ) {
new KRun( url,this );
return;
}
History::self().createEntry();
if ( proto == QLatin1String("glossentry") ) {
QString decodedEntryId = QUrl::fromPercentEncoding( url.encodedPathAndQuery().toAscii() );
slotGlossSelected( mNavigator->glossEntry( decodedEntryId ) );
mNavigator->slotSelectGlossEntry( decodedEntryId );
} else {
mDoc->openUrl( url );
// openUrl( url );
}
}
void MainWindow::documentCompleted()
{
kDebug();
History::self().updateCurrentEntry( mDoc );
History::self().updateActions();
}
void MainWindow::slotInfoMessage(KJob *, const QString &m)
{
statusBarMessage(m);
}
void MainWindow::statusBarMessage(const QString &m)
{
statusBar()->changeItem(m, 0);
}
void MainWindow::slotGlossSelected(const GlossaryEntry &entry)
{
kDebug();
stop();
History::self().createEntry();
}
void MainWindow::stop()
{
kDebug();
History::self().updateCurrentEntry( mDoc );
}
void MainWindow::showHome()
{
slotShowHome();
}
void MainWindow::slotShowHome()
{
viewUrl( mNavigator->homeURL() );
mNavigator->clearSelection();
}
void MainWindow::lastSearch()
{
slotLastSearch();
}
void MainWindow::slotLastSearch()
{
mDoc->lastSearch();
}
void MainWindow::enableLastSearchAction()
{
mLastSearchAction->setEnabled( true );
}
void MainWindow::showSearchStderr()
{
QString log = mNavigator->searchEngine()->errorLog();
if ( !mLogDialog ) {
mLogDialog = new LogDialog( this );
}
mLogDialog->setLog( log );
mLogDialog->show();
mLogDialog->raise();
}
void MainWindow::slotIncFontSizes()
{
mDoc->slotIncFontSizes();
updateFontScaleActions();
}
void MainWindow::slotDecFontSizes()
{
mDoc->slotDecFontSizes();
updateFontScaleActions();
}
void MainWindow::updateFontScaleActions()
{
}
void MainWindow::slotConfigureFonts()
{
FontDialog dlg( this );
if ( dlg.exec() == QDialog::Accepted )
{
mDoc->slotReload();
}
}
#include "moc_mainwindow.cpp"
// vim:ts=2:sw=2:et

92
khelpcenter/mainwindow.h Normal file
View file

@ -0,0 +1,92 @@
#ifndef KHC_MAINWINDOW_H
#define KHC_MAINWINDOW_H
#include <KXmlGuiWindow>
#include <KUrl>
#include <kio/job.h>
#include <kparts/browserextension.h>
#include "navigator.h"
#include "glossary.h"
class QSplitter;
class LogDialog;
namespace KHC {
class View;
class MainWindow : public KXmlGuiWindow
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.khelpcenter.khelpcenter")
public:
MainWindow();
~MainWindow();
public Q_SLOTS:
Q_SCRIPTABLE void showHome();
Q_SCRIPTABLE void lastSearch();
public Q_SLOTS:
void print();
void statusBarMessage(const QString &m);
void slotShowHome();
void slotLastSearch();
void showSearchStderr();
/**
Show document corresponding to given URL in viewer part.
*/
void viewUrl( const QString & );
protected:
void setupActions();
/**
Show document corresponding to given URL in viewer part.
*/
void viewUrl( const KUrl &url,
const KParts::OpenUrlArguments &args = KParts::OpenUrlArguments(),
const KParts::BrowserArguments &browserArgs = KParts::BrowserArguments() );
virtual void saveProperties( KConfigGroup &config );
virtual void readProperties( const KConfigGroup &config );
void readConfig();
void writeConfig();
protected Q_SLOTS:
void enableLastSearchAction();
void enableCopyTextAction();
private:
void stop();
private Q_SLOTS:
void slotGlossSelected(const GlossaryEntry &entry);
void slotStarted(KIO::Job *job);
void slotInfoMessage(KJob *, const QString &);
void documentCompleted();
void slotIncFontSizes();
void slotDecFontSizes();
void slotConfigureFonts();
void slotCopySelectedText();
private:
void updateFontScaleActions();
QSplitter *mSplitter;
View *mDoc;
Navigator *mNavigator;
QAction *mLastSearchAction;
QAction *mCopyText;
LogDialog *mLogDialog;
};
}
#endif //KHC_MAINWINDOW_H
// vim:ts=2:sw=2:et

679
khelpcenter/navigator.cpp Normal file
View file

@ -0,0 +1,679 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 1999 Matthias Elter (me@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "navigator.h"
#include <QDir>
#include <QFile>
#include <QPixmap>
#include <QLabel>
#include <QtXml/QtXml>
#include <QTextStream>
#include <QRegExp>
#include <QLayout>
#include <QPushButton>
#include <QFrame>
#include <QHBoxLayout>
#include <QBoxLayout>
#include <QVBoxLayout>
#include <QTreeWidgetItemIterator>
#include <KAction>
#include <KApplication>
#include <KConfig>
#include <KStandardDirs>
#include <KGlobal>
#include <KLocale>
#include <KDebug>
#include <KLineEdit>
#include <KMessageBox>
#include <KIconLoader>
#include <KCharsets>
#include <KDialog>
#include <KDesktopFile>
#include <KProtocolInfo>
#include <KServiceGroup>
#include <KServiceTypeTrader>
#include <KCModuleInfo>
#include <KCModule>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "navigatoritem.h"
#include "navigatorappitem.h"
#include "searchwidget.h"
#include "searchengine.h"
#include "docmetainfo.h"
#include "docentrytraverser.h"
#include "glossary.h"
#include "toc.h"
#include "view.h"
#include "infotree.h"
#include "mainwindow.h"
#include "plugintraverser.h"
#include "scrollkeepertreebuilder.h"
#include "kcmhelpcenter.h"
#include "formatter.h"
#include "history.h"
#include "prefs.h"
using namespace KHC;
Navigator::Navigator( View *view, QWidget *parent, const char *name )
: QWidget( parent ), mIndexDialog( 0 ),
mView( view ), mSelected( false )
{
setObjectName( name );
KConfigGroup config(KGlobal::config(), "General");
mShowMissingDocs = config.readEntry("ShowMissingDocs", false);
mSearchEngine = new SearchEngine( view );
connect( mSearchEngine, SIGNAL( searchFinished() ),
SLOT( slotSearchFinished() ) );
DocMetaInfo::self()->scanMetaInfo();
QBoxLayout *topLayout = new QVBoxLayout( this );
mSearchFrame = new QFrame( this );
topLayout->addWidget( mSearchFrame );
QBoxLayout *searchLayout = new QHBoxLayout( mSearchFrame );
searchLayout->setSpacing( KDialog::spacingHint() );
searchLayout->setMargin( 6 );
mSearchEdit = new KLineEdit( mSearchFrame );
mSearchEdit->setClearButtonShown(true);
searchLayout->addWidget( mSearchEdit );
connect( mSearchEdit, SIGNAL( returnPressed() ), SLOT( slotSearch() ) );
connect( mSearchEdit, SIGNAL( textChanged( const QString & ) ),
SLOT( checkSearchButton() ) );
mSearchButton = new QPushButton( i18n("&Search"), mSearchFrame );
searchLayout->addWidget( mSearchButton );
connect( mSearchButton, SIGNAL( clicked() ), SLOT( slotSearch() ) );
mTabWidget = new QTabWidget( this );
topLayout->addWidget( mTabWidget );
setupContentsTab();
setupGlossaryTab();
setupSearchTab();
insertPlugins();
hideSearch();
/*
if ( !mSearchEngine->initSearchHandlers() ) {
hideSearch();
} else {
mSearchWidget->updateScopeList();
mSearchWidget->readConfig( KGlobal::config().data() );
}
*/
connect( mTabWidget, SIGNAL( currentChanged( QWidget * ) ),
SLOT( slotTabChanged( QWidget * ) ) );
}
Navigator::~Navigator()
{
delete mSearchEngine;
}
SearchEngine *Navigator::searchEngine() const
{
return mSearchEngine;
}
Formatter *Navigator::formatter() const
{
return mView->formatter();
}
bool Navigator::showMissingDocs() const
{
return mShowMissingDocs;
}
void Navigator::setupContentsTab()
{
mContentsTree = new QTreeWidget( mTabWidget );
mContentsTree->setFrameStyle( QFrame::NoFrame );
mContentsTree->setAllColumnsShowFocus(true);
mContentsTree->setRootIsDecorated(false);
mContentsTree->headerItem()->setHidden(true);
connect(mContentsTree, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
SLOT(slotItemSelected(QTreeWidgetItem*)));
mTabWidget->addTab(mContentsTree, i18n("&Contents"));
}
void Navigator::setupSearchTab()
{
mSearchWidget = new SearchWidget( mSearchEngine, mTabWidget );
connect( mSearchWidget, SIGNAL( searchResult( const QString & ) ),
SLOT( slotShowSearchResult( const QString & ) ) );
connect( mSearchWidget, SIGNAL( scopeCountChanged( int ) ),
SLOT( checkSearchButton() ) );
connect( mSearchWidget, SIGNAL( showIndexDialog() ),
SLOT( showIndexDialog() ) );
mTabWidget->addTab( mSearchWidget, i18n("Search Options"));
}
void Navigator::setupGlossaryTab()
{
mGlossaryTree = new Glossary( mTabWidget );
connect( mGlossaryTree, SIGNAL( entrySelected( const GlossaryEntry & ) ),
this, SIGNAL( glossSelected( const GlossaryEntry & ) ) );
mTabWidget->addTab( mGlossaryTree, i18n( "G&lossary" ) );
}
void Navigator::insertPlugins()
{
PluginTraverser t( this, mContentsTree );
DocMetaInfo::self()->traverseEntries( &t );
}
void Navigator::insertParentAppDocs( const QString &name, NavigatorItem *topItem )
{
kDebug(1400) << "Requested plugin documents for ID " << name;
KServiceGroup::Ptr grp = KServiceGroup::childGroup( name );
if ( !grp )
return;
KServiceGroup::List entries = grp->entries();
KServiceGroup::List::ConstIterator it = entries.constBegin();
KServiceGroup::List::ConstIterator end = entries.constEnd();
for ( ; it != end; ++it ) {
QString desktopFile = ( *it )->entryPath();
if ( QDir::isRelativePath( desktopFile ) )
desktopFile = KStandardDirs::locate( "apps", desktopFile );
createItemFromDesktopFile( topItem, desktopFile );
}
}
void Navigator::insertKCMDocs( const QString &name, NavigatorItem *topItem, const QString &type )
{
kDebug(1400) << "Requested KCM documents for ID" << name;
QString systemsettingskontrolconstraint = "[X-KDE-System-Settings-Parent-Category] != ''";
QString konquerorcontrolconstraint = "[X-KDE-PluginKeyword] == 'khtml_general'\
or [X-KDE-PluginKeyword] == 'performance'\
or [X-KDE-PluginKeyword] == 'bookmarks'";
QString filemanagercontrolconstraint = "[X-KDE-PluginKeyword] == 'behavior'\
or [X-KDE-PluginKeyword] == 'dolphinviewmodes'\
or [X-KDE-PluginKeyword] == 'dolphinnavigation'\
or [X-KDE-PluginKeyword] == 'dolphinservices'\
or [X-KDE-PluginKeyword] == 'dolphingeneral'\
or [X-KDE-PluginKeyword] == 'trash'";
QString browsercontrolconstraint = "[X-KDE-PluginKeyword] == 'khtml_behavior'\
or [X-KDE-PluginKeyword] == 'proxy'\
or [X-KDE-PluginKeyword] == 'khtml_appearance'\
or [X-KDE-PluginKeyword] == 'khtml_filter'\
or [X-KDE-PluginKeyword] == 'cache'\
or [X-KDE-PluginKeyword] == 'cookie'\
or [X-KDE-PluginKeyword] == 'useragent'\
or [X-KDE-PluginKeyword] == 'khtml_java_js'\
or [X-KDE-PluginKeyword] == 'khtml_plugins'";
/* missing in browsercontrolconstraint
History no X-KDE-PluginKeyword in kcmhistory.desktop
*/
QString othercontrolconstraint = "[X-KDE-PluginKeyword] == 'cgi'";
KService::List list;
if ( type == QString("kcontrol") ) {
list = KServiceTypeTrader::self()->query( "KCModule", systemsettingskontrolconstraint );
} else if ( type == QString("konquerorcontrol") ) {
list = KServiceTypeTrader::self()->query( "KCModule", konquerorcontrolconstraint );
} else if ( type == QString("browsercontrol") ) {
list = KServiceTypeTrader::self()->query( "KCModule", browsercontrolconstraint );
} else if ( type == QString("filemanagercontrol") ) {
list = KServiceTypeTrader::self()->query( "KCModule", filemanagercontrolconstraint );
} else if ( type == QString("othercontrol") ) {
list = KServiceTypeTrader::self()->query( "KCModule", othercontrolconstraint );
} else if ( type == QString("kinfocenter") ) {
list = KServiceTypeTrader::self()->query( "KCModule", "[X-KDE-ParentApp] == 'kinfocenter'" );
}
for ( KService::List::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
{
KService::Ptr s = (*it);
KCModuleInfo m = KCModuleInfo(s);
QString desktopFile = KStandardDirs::locate( "services", m.fileName() );
createItemFromDesktopFile( topItem, desktopFile );
}
topItem->sortChildren( 0, Qt::AscendingOrder /* ascending */ );
}
void Navigator::insertIOSlaveDocs( const QString &name, NavigatorItem *topItem )
{
kDebug(1400) << "Requested IOSlave documents for ID" << name;
QStringList list = KProtocolInfo::protocols();
list.sort();
NavigatorItem *prevItem = 0;
for ( QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it )
{
QString docPath = KProtocolInfo::docPath(*it);
if ( !docPath.isNull() )
{
// First parameter is ignored if second is an absolute path
KUrl url(KUrl("help:/"), docPath);
QString icon = KProtocolInfo::icon(*it);
if ( icon.isEmpty() ) icon = "text-plain";
DocEntry *entry = new DocEntry( *it, url.url(), icon );
NavigatorItem *item = new NavigatorItem( entry, topItem, prevItem );
prevItem = item;
item->setAutoDeleteDocEntry( true );
}
}
}
void Navigator::createItemFromDesktopFile( NavigatorItem *topItem,
const QString &file )
{
KDesktopFile desktopFile( file );
QString docPath = desktopFile.readDocPath();
if ( !docPath.isNull() ) {
// First parameter is ignored if second is an absolute path
KUrl url(KUrl("help:/"), docPath);
QString icon = desktopFile.readIcon();
if ( icon.isEmpty() ) icon = "text-plain";
DocEntry *entry = new DocEntry( desktopFile.readName(), url.url(), icon );
NavigatorItem *item = new NavigatorItem( entry, topItem );
item->setAutoDeleteDocEntry( true );
}
}
void Navigator::insertInfoDocs( NavigatorItem *topItem )
{
InfoTree *infoTree = new InfoTree( this );
infoTree->build( topItem );
}
NavigatorItem *Navigator::insertScrollKeeperDocs( NavigatorItem *topItem,
NavigatorItem *after )
{
ScrollKeeperTreeBuilder *builder = new ScrollKeeperTreeBuilder( this );
return builder->build( topItem, after );
}
void Navigator::selectItem( const KUrl &url )
{
kDebug() << "Navigator::selectItem(): " << url.url();
if ( url.url() == "khelpcenter:home" ) {
clearSelection();
return;
}
// help:/foo&anchor=bar gets redirected to help:/foo#bar
// Make sure that we match both the original URL as well as
// its counterpart.
KUrl alternativeURL = url;
if (url.hasRef())
{
alternativeURL.setQuery("anchor="+url.ref());
alternativeURL.setRef(QString());
}
// If the navigator already has the given URL selected, do nothing.
NavigatorItem *item;
item = static_cast<NavigatorItem *>( mContentsTree->currentItem() );
if ( item && mSelected ) {
KUrl currentURL ( item->entry()->url() );
if ( (currentURL == url) || (currentURL == alternativeURL) ) {
kDebug() << "URL already shown.";
return;
}
}
// First, populate the NavigatorAppItems if we don't want the home page
if ( url != homeURL() ) {
QTreeWidgetItemIterator it1( mContentsTree );
while( (*it1) )
{
NavigatorAppItem *appItem = dynamic_cast<NavigatorAppItem *>( (*it1) );
if ( appItem ) appItem->populate( true );
++it1;
}
}
QTreeWidgetItemIterator it( mContentsTree );
while ( (*it) ) {
NavigatorItem *item = static_cast<NavigatorItem *>( (*it) );
KUrl itemUrl( item->entry()->url() );
if ( (itemUrl == url) || (itemUrl == alternativeURL) ) {
mContentsTree->setCurrentItem( item );
// If the current item was not selected and remained unchanged it
// needs to be explicitly selected
mContentsTree->setCurrentItem(item);
item->setExpanded( true );
break;
}
++it;
}
if ( !(*it) ) {
clearSelection();
} else {
mSelected = true;
}
}
void Navigator::clearSelection()
{
mContentsTree->clearSelection();
mSelected = false;
}
void Navigator::slotItemSelected( QTreeWidgetItem *currentItem )
{
if ( !currentItem ) return;
mSelected = true;
NavigatorItem *item = static_cast<NavigatorItem *>( currentItem );
kDebug(1400) << item->entry()->name() << endl;
item->setExpanded( !item->isExpanded() );
KUrl url ( item->entry()->url() );
if ( url.protocol() == "khelpcenter" ) {
// mView->closeUrl();
History::self().updateCurrentEntry( mView );
History::self().createEntry();
showOverview( item, url );
} else {
emit itemSelected( url.url() );
}
mLastUrl = url;
}
void Navigator::openInternalUrl( const KUrl &url )
{
if ( url.url() == "khelpcenter:home" ) {
clearSelection();
showOverview( 0, url );
return;
}
selectItem( url );
if ( !mSelected ) return;
NavigatorItem *item =
static_cast<NavigatorItem *>( mContentsTree->currentItem() );
if ( item ) showOverview( item, url );
}
void Navigator::showOverview( NavigatorItem *item, const KUrl &url )
{
mView->beginInternal( url );
QString fileName = KStandardDirs::locate( "data", "khelpcenter/index.html.in" );
if ( fileName.isEmpty() )
return;
QFile file( fileName );
if ( !file.open( QIODevice::ReadOnly ) )
return;
QTextStream stream( &file );
QString res = stream.readAll();
QString title,name,content;
uint childCount;
if ( item ) {
title = item->entry()->name();
name = item->entry()->name();
QString info = item->entry()->info();
if ( !info.isEmpty() ) content = QLatin1String("<p>") + info + QLatin1String("</p>\n");
childCount = item->childCount();
} else {
title = i18n("Start Page");
name = i18n("KDE Help Center");
childCount = mContentsTree->topLevelItemCount();
}
if ( childCount > 0 ) {
QTreeWidgetItem *child;
if ( item ) child = item;
else child = mContentsTree->invisibleRootItem();
mDirLevel = 0;
content += createChildrenList( child );
}
else
content += QLatin1String("<p></p>");
res = res.arg(title).arg(name).arg(content);
// mView->write( res );
// mView->end();
}
QString Navigator::createChildrenList( QTreeWidgetItem *child )
{
++mDirLevel;
QString t;
t += QLatin1String("<ul>\n");
int cc = child->childCount();
for (int i=0;i<cc;i++)
{
NavigatorItem *childItem = static_cast<NavigatorItem *>( child->child(i) );
DocEntry *e = childItem->entry();
t += QLatin1String("<li><a href=\"") + e->url() + QLatin1String("\">");
if ( e->isDirectory() ) t += QLatin1String("<b>");
t += e->name();
if ( e->isDirectory() ) t += QLatin1String("</b>");
t += QLatin1String("</a>");
if ( !e->info().isEmpty() ) {
t += QLatin1String("<br>") + e->info();
}
t += QLatin1String("</li>\n");
if ( childItem->childCount() > 0 && mDirLevel < 2 ) {
t += createChildrenList( childItem );
}
}
t += QLatin1String("</ul>\n");
--mDirLevel;
return t;
}
void Navigator::slotSearch()
{
kDebug(1400) << "Navigator::slotSearch()";
if ( !checkSearchIndex() ) return;
if ( mSearchEngine->isRunning() ) return;
QString words = mSearchEdit->text();
QString method = mSearchWidget->method();
int pages = mSearchWidget->pages();
QString scope = mSearchWidget->scope();
kDebug(1400) << "Navigator::slotSearch() words: " << words;
kDebug(1400) << "Navigator::slotSearch() scope: " << scope;
if ( words.isEmpty() || scope.isEmpty() ) return;
// disable search Button during searches
mSearchButton->setEnabled(false);
QApplication::setOverrideCursor(Qt::WaitCursor);
if ( !mSearchEngine->search( words, method, pages, scope ) ) {
slotSearchFinished();
KMessageBox::sorry( this, i18n("Unable to run search program.") );
}
}
void Navigator::slotShowSearchResult( const QString &url )
{
QString u = url;
u.replace( "%k", mSearchEdit->text() );
emit itemSelected( u );
}
void Navigator::slotSearchFinished()
{
mSearchButton->setEnabled(true);
QApplication::restoreOverrideCursor();
kDebug( 1400 ) << "Search finished.";
}
void Navigator::checkSearchButton()
{
mSearchButton->setEnabled( !mSearchEdit->text().isEmpty() &&
mSearchWidget->scopeCount() > 0 );
mTabWidget->setCurrentIndex( mTabWidget->indexOf( mSearchWidget ) );
}
void Navigator::hideSearch()
{
mSearchFrame->hide();
mTabWidget->removeTab( mTabWidget->indexOf( mSearchWidget ) );
}
bool Navigator::checkSearchIndex()
{
KConfigGroup cfg(KGlobal::config(), "Search" );
if ( cfg.readEntry( "IndexExists", false) ) return true;
if ( mIndexDialog && !mIndexDialog->isHidden() ) return true;
QString text = i18n( "A search index does not yet exist. Do you want "
"to create the index now?" );
int result = KMessageBox::questionYesNo( this, text, QString(),
KGuiItem(i18n("Create")),
KGuiItem(i18n("Do Not Create")),
QLatin1String("indexcreation") );
if ( result == KMessageBox::Yes ) {
showIndexDialog();
return false;
}
return true;
}
void Navigator::slotTabChanged( QWidget *wid )
{
if ( wid == mSearchWidget ) checkSearchIndex();
}
void Navigator::slotSelectGlossEntry( const QString &id )
{
mGlossaryTree->slotSelectGlossEntry( id );
}
KUrl Navigator::homeURL()
{
if ( !mHomeUrl.isEmpty() ) return mHomeUrl;
KSharedConfig::Ptr cfg = KGlobal::config();
// We have to reparse the configuration here in order to get a
// language-specific StartUrl, e.g. "StartUrl[de]".
cfg->reparseConfiguration();
mHomeUrl = cfg->group("General").readPathEntry( "StartUrl", QLatin1String("khelpcenter:home") );
return mHomeUrl;
}
void Navigator::showIndexDialog()
{
if ( !mIndexDialog ) {
mIndexDialog = new KCMHelpCenter( mSearchEngine, this );
connect( mIndexDialog, SIGNAL( searchIndexUpdated() ), mSearchWidget,
SLOT( updateScopeList() ) );
}
mIndexDialog->show();
mIndexDialog->raise();
}
void Navigator::readConfig()
{
if ( Prefs::currentTab() == Prefs::Search ) {
mTabWidget->setCurrentIndex( mTabWidget->indexOf( mSearchWidget ) );
} else if ( Prefs::currentTab() == Prefs::Glossary ) {
mTabWidget->setCurrentIndex( mTabWidget->indexOf( mGlossaryTree ) );
} else {
mTabWidget->setCurrentIndex( mTabWidget->indexOf( mContentsTree ) );
}
}
void Navigator::writeConfig()
{
if ( mTabWidget->currentWidget() == mSearchWidget ) {
Prefs::setCurrentTab( Prefs::Search );
} else if ( mTabWidget->currentWidget() == mGlossaryTree ) {
Prefs::setCurrentTab( Prefs::Glossary );
} else {
Prefs::setCurrentTab( Prefs::Content );
}
}
void Navigator::clearSearch()
{
mSearchEdit->setText( QString() );
}
#include "moc_navigator.cpp"
// vim:ts=2:sw=2:et

144
khelpcenter/navigator.h Normal file
View file

@ -0,0 +1,144 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 1999 Matthias Elter (me@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_NAVIGATOR_H
#define KHC_NAVIGATOR_H
#include "glossary.h"
#include <KUrl>
#include <QFile>
#include <QTextStream>
#include <QTimer>
#include <QTabWidget>
#include <QTreeWidget>
#include <QFrame>
class QPushButton;
class KLineEdit;
class KCMHelpCenter;
namespace KHC {
class NavigatorItem;
class Navigator;
class View;
class SearchEngine;
class SearchWidget;
class Formatter;
class Navigator : public QWidget
{
Q_OBJECT
public:
explicit Navigator(View *, QWidget *parent=0, const char *name=0);
virtual ~Navigator();
KUrl homeURL();
SearchEngine *searchEngine() const;
Formatter *formatter() const;
const GlossaryEntry &glossEntry(const QString &term) const { return mGlossaryTree->entry( term ); }
void insertParentAppDocs( const QString &name, NavigatorItem *parent );
NavigatorItem *insertScrollKeeperDocs( NavigatorItem *parentItem,
NavigatorItem *after );
void insertInfoDocs( NavigatorItem *parentItem );
void insertKCMDocs(const QString &, NavigatorItem*parent, const QString &);
void insertIOSlaveDocs(const QString &, NavigatorItem*parent);
void createItemFromDesktopFile( NavigatorItem *item, const QString &name );
bool showMissingDocs() const;
void clearSelection();
void showOverview( NavigatorItem *item, const KUrl &url );
void readConfig();
void writeConfig();
public Q_SLOTS:
void openInternalUrl( const KUrl &url );
void slotItemSelected(QTreeWidgetItem* index);
void slotSearch();
void slotShowSearchResult( const QString & );
void slotSelectGlossEntry( const QString &id );
void selectItem( const KUrl &url );
void showIndexDialog();
Q_SIGNALS:
void itemSelected(const QString& itemURL);
void glossSelected(const GlossaryEntry &entry);
protected Q_SLOTS:
void slotSearchFinished();
void slotTabChanged( QWidget * );
void checkSearchButton();
bool checkSearchIndex();
void clearSearch();
protected:
QString createChildrenList( QTreeWidgetItem *child );
private:
void setupContentsTab();
void setupIndexTab();
void setupSearchTab();
void setupGlossaryTab();
void insertPlugins();
void hideSearch();
QTreeWidget *mContentsTree;
Glossary *mGlossaryTree;
SearchWidget *mSearchWidget;
KCMHelpCenter *mIndexDialog;
QTabWidget *mTabWidget;
QFrame *mSearchFrame;
KLineEdit *mSearchEdit;
QPushButton *mSearchButton;
bool mShowMissingDocs;
SearchEngine *mSearchEngine;
View *mView;
KUrl mHomeUrl;
bool mSelected;
KUrl mLastUrl;
int mDirLevel;
};
}
#endif //KHC_NAVIGATOR_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,149 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 2001 Waldo Bastian <bastian@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "navigatorappitem.h"
#include "docentry.h"
#include <KDebug>
#include <KService>
#include <KServiceGroup>
using namespace KHC;
NavigatorAppItem::NavigatorAppItem( DocEntry *entry, QTreeWidget *parent,
const QString &relPath )
: NavigatorItem( entry, parent ),
mRelpath( relPath ),
mPopulated( false )
{
populate();
}
NavigatorAppItem::NavigatorAppItem( DocEntry *entry, QTreeWidgetItem *parent,
const QString &relPath )
: NavigatorItem( entry, parent ),
mRelpath( relPath ),
mPopulated( false )
{
populate();
}
NavigatorAppItem::NavigatorAppItem( DocEntry *entry, QTreeWidget *parent,
QTreeWidgetItem *after )
: NavigatorItem( entry, parent, after ),
mPopulated( false )
{
populate();
}
NavigatorAppItem::NavigatorAppItem( DocEntry *entry, QTreeWidgetItem *parent,
QTreeWidgetItem *after )
: NavigatorItem( entry, parent, after ),
mPopulated( false )
{
populate();
}
void NavigatorAppItem::setRelpath( const QString &relpath )
{
mRelpath = relpath;
}
void NavigatorAppItem::setExpanded(bool open)
{
kDebug() << "NavigatorAppItem::setOpen()";
if ( open && (childCount() == 0) && !mPopulated )
{
kDebug() << "NavigatorAppItem::setOpen(" << this << ", "
<< mRelpath << ")" << endl;
populate();
}
QTreeWidgetItem::setExpanded(open);
}
void NavigatorAppItem::populate( bool recursive )
{
if ( mPopulated ) return;
KServiceGroup::Ptr root = KServiceGroup::group(mRelpath);
if ( !root ) {
kWarning() << "No Service groups\n";
return;
}
KServiceGroup::List list = root->entries();
for ( KServiceGroup::List::ConstIterator it = list.constBegin();
it != list.constEnd(); ++it )
{
const KSycocaEntry::Ptr e = *it;
NavigatorItem *item;
QString url;
switch ( e->sycocaType() ) {
case KST_KService:
{
const KService::Ptr s = KService::Ptr::staticCast(e);
url = documentationURL( s.data() );
if ( !url.isEmpty() ) {
DocEntry *entry = new DocEntry( s->name(), url, s->icon() );
item = new NavigatorItem( entry, this );
item->setAutoDeleteDocEntry( true );
}
break;
}
case KST_KServiceGroup:
{
KServiceGroup::Ptr g = KServiceGroup::Ptr::staticCast(e);
if ( ( g->childCount() == 0 ) || g->name().startsWith( '.' ) )
continue;
DocEntry *entry = new DocEntry( g->caption(), "", g->icon() );
NavigatorAppItem *appItem;
appItem = new NavigatorAppItem( entry, this, g->relPath() );
appItem->setAutoDeleteDocEntry( true );
if ( recursive ) appItem->populate( recursive );
break;
}
default:
break;
}
}
sortChildren( 0, Qt::AscendingOrder /* ascending */ );
mPopulated = true;
}
QString NavigatorAppItem::documentationURL( const KService *s )
{
QString docPath = s->property( QLatin1String("DocPath") ).toString();
if ( docPath.isEmpty() ) {
docPath = s->property( QLatin1String("X-DocPath") ).toString();
if ( docPath.isEmpty() ) {
return QString();
}
}
if ( docPath.startsWith( QLatin1String("file:")) || docPath.startsWith( QLatin1String("http:") ) )
return docPath;
return QLatin1String( "help:/" ) + docPath;
}
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,59 @@
/*
* navigatorappitem.h - part of the KDE Help Center
*
* Copyright (C) 2001 Waldo Bastian <bastian@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_NAVIGATORAPPITEM_H
#define KHC_NAVIGATORAPPITEM_H
#include "navigatoritem.h"
class KService;
namespace KHC {
class NavigatorAppItem : public NavigatorItem
{
public:
NavigatorAppItem( DocEntry *entry, QTreeWidget *parent,
const QString &relPath );
NavigatorAppItem( DocEntry *entry, QTreeWidgetItem *parent,
const QString &relPath );
NavigatorAppItem( DocEntry *entry, QTreeWidget *parent,
QTreeWidgetItem *after );
NavigatorAppItem( DocEntry *entry, QTreeWidgetItem *parent,
QTreeWidgetItem *after );
void setRelpath( const QString & );
virtual void setExpanded(bool);
void populate( bool recursive = false );
protected:
QString documentationURL( const KService *s );
private:
QString mRelpath;
bool mPopulated;
};
}
#endif //KHC_NAVIGATORAPPITEM_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,121 @@
/*
* This file is part of the KDE Help Center
*
* Copyright (C) 1999 Matthias Elter (me@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "navigatoritem.h"
#include "toc.h"
#include "docentry.h"
#include "view.h"
#include <KDebug>
#include <KIconLoader>
#include <QPixmap>
using namespace KHC;
NavigatorItem::NavigatorItem( DocEntry *entry, QTreeWidget *parent,
QTreeWidgetItem *after )
: QTreeWidgetItem( parent, after )
{
init( entry );
}
NavigatorItem::NavigatorItem( DocEntry *entry, QTreeWidgetItem *parent,
QTreeWidgetItem *after )
: QTreeWidgetItem( parent, after )
{
init( entry );
}
NavigatorItem::NavigatorItem( DocEntry *entry, QTreeWidget *parent )
: QTreeWidgetItem( parent )
{
init( entry );
}
NavigatorItem::NavigatorItem( DocEntry *entry, QTreeWidgetItem *parent )
: QTreeWidgetItem( parent )
{
init( entry );
}
NavigatorItem::~NavigatorItem()
{
delete mToc;
if ( mAutoDeleteDocEntry ) delete mEntry;
}
void NavigatorItem::init( DocEntry *entry )
{
mEntry = entry;
mAutoDeleteDocEntry = false;
mToc = 0;
updateItem();
}
DocEntry *NavigatorItem::entry() const
{
return mEntry;
}
void NavigatorItem::setAutoDeleteDocEntry( bool enabled )
{
mAutoDeleteDocEntry = enabled;
}
void NavigatorItem::updateItem()
{
setText( 0, entry()->name() );
setIcon( 0, SmallIcon( entry()->icon() ) );
}
void NavigatorItem::scheduleTOCBuild()
{
KUrl url ( entry()->url() );
if ( !mToc && url.protocol() == "help") {
mToc = new TOC( this );
kDebug( 1400 ) << "Trying to build TOC for " << entry()->name() << endl;
mToc->setApplication( url.directory() );
QString doc = View::langLookup( url.path() );
// Enforce the original .docbook version, in case langLookup returns a
// cached version
if ( !doc.isNull() ) {
int pos = doc.indexOf( ".html" );
if ( pos >= 0 ) {
doc.replace( pos, 5, ".docbook" );
}
kDebug( 1400 ) << "doc = " << doc;
mToc->build( doc );
}
}
}
void NavigatorItem::setExpanded( bool open )
{
scheduleTOCBuild();
QTreeWidgetItem::setExpanded( open );
}
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,68 @@
/*
* navigatoritem.h - part of the KDE Help Center
*
* Copyright (C) 1999 Matthias Elter (me@kde.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KHC_NAVIGATORITEM_H
#define KHC_NAVIGATORITEM_H
#include <QTreeWidget>
#include <QTreeWidgetItem>
namespace KHC {
class TOC;
class DocEntry;
class NavigatorItem : public QTreeWidgetItem
{
public:
NavigatorItem( DocEntry *entry, QTreeWidget *parent );
NavigatorItem( DocEntry *entry, QTreeWidgetItem *parent );
NavigatorItem( DocEntry *entry, QTreeWidget *parent,
QTreeWidgetItem *after );
NavigatorItem( DocEntry *entry, QTreeWidgetItem *parent,
QTreeWidgetItem *after );
~NavigatorItem();
DocEntry *entry() const;
void setAutoDeleteDocEntry( bool );
void updateItem();
TOC *toc() const { return mToc; }
void setExpanded( bool open );
private:
void init( DocEntry * );
void scheduleTOCBuild();
TOC *mToc;
DocEntry *mEntry;
bool mAutoDeleteDocEntry;
};
}
#endif // KHC_NAVIGATORITEM_H
// vim:ts=2:sw=2:et

View file

@ -0,0 +1,14 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.khelpcenter.kcmhelpcenter">
<method name="slotIndexProgress"/>
<method name="slotIndexError">
<arg name="error" type="s" direction="in"/>
</method>
<signal name="buildIndexProgress"/>
<signal name="buildIndexError">
<arg name="buildIndexError" type="s" direction="out"/>
</signal>
</interface>
</node>

View file

@ -0,0 +1,95 @@
[Desktop Entry]
Name=Application Manuals
Name[af]=Toepassing Handleidings
Name[ar]=دليل التطبيقات
Name[ast]=Manuales de l'aplicación
Name[be]=Даведкі аплетаў
Name[be@latin]=Padručniki pa aplikacyjach
Name[bg]=Ръководства на аплети
Name[bn]=অ্যাপলিকেশন ম্যানুয়াল
Name[bn_IN]=অ্যাপ্লিকেশনের সহায়িকা
Name[bs]=Uputstva za programe
Name[ca]=Manuals de les aplicacions
Name[ca@valencia]=Manuals de les aplicacions
Name[cs]=Příručky aplikací
Name[csb]=Pòdrãczniczi aplikacëjów
Name[da]=Programmanualer
Name[de]=Programmhandbücher
Name[el]=Εγχειρίδια εφαρμογών
Name[en_GB]=Application Manuals
Name[eo]=Manlibroj de aplikaĵoj
Name[es]=Manuales de las aplicaciones
Name[et]=Rakenduste käsiraamatud
Name[eu]=Aplikazio-eskuliburuak
Name[fa]=راهنماهای کاربرد
Name[fi]=Sovellusten oppaat
Name[fr]=Manuels des applications
Name[fy]=Applikaasje hânlieding
Name[ga]=Lámhleabhair Fheidhmchláir
Name[gl]=Manuais dos programas
Name[gu]=કાર્યક્રમ માર્ગદર્શિકાઓ
Name[he]=ספרי הדרכה של תוכניות
Name[hi]=अनुप्रयोग निर्देशिका
Name[hne]=अनुपरयोग निर्देसिका
Name[hr]=Priručnici aplikacije
Name[hsb]=Přiručki za aplikacije
Name[hu]=Alkalmazások kézikönyvei
Name[ia]=Manuales de application
Name[id]=Manual Aplikasi
Name[is]=Handbækur forrita
Name[it]=Manuali delle applicazioni
Name[ja]=アプリケーションマニュアル
Name[kk]=Қолданбаның нұсқаулары
Name[km]=សៀវភៅ​ដៃ​កម្មវិធី​
Name[kn]=ಅನ್ವಯಗಳ ಕೈಪಿಡಿಗಳು
Name[ko]=프로그램 사용 설명서
Name[ku]=Rêberên Sepanan
Name[lt]=Programų vadovai
Name[lv]=Programmu rokasgrāmatas
Name[mai]=अनुप्रयोग निर्देशिका
Name[mk]=Прирачници за апликации
Name[ml]=പ്രയോഗ സഹായകഗ്രന്ഥങ്ങള്‍
Name[mr]=अनुप्रयोग पुस्तिका
Name[nb]=Håndbøker for programmer
Name[nds]=Programmhandböker
Name[ne]=अनुप्रयोग म्यानुअल
Name[nl]=Programmahandboeken
Name[nn]=Programbruksrettleiingar
Name[or]=ପ୍ରୟୋଗ ସହାୟକ ପୁସ୍ତକ
Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਮੈਨੂਅਲ
Name[pl]=Podręczniki programów
Name[pt]=Manuais das Aplicações
Name[pt_BR]=Manuais dos aplicativos
Name[ro]=Manualele aplicațiilor
Name[ru]=Руководства приложений
Name[se]=Prográmmagiehtagirjjit
Name[si]=යෙදුම් අත්පොත්
Name[sk]=Aplikačné manuály
Name[sl]=Priročniki za programe
Name[sr]=Упутства за програме
Name[sr@ijekavian]=Упутства за програме
Name[sr@ijekavianlatin]=Uputstva za programe
Name[sr@latin]=Uputstva za programe
Name[sv]=Programhandböcker
Name[ta]=பயன்பாட்டு கையேடுகள்
Name[te]=అనువర్తనముల మాన్యువల్‍స్‌
Name[tg]=Дастуруламалҳои барнома
Name[th]=คู่มือของโปรแกรมต่าง ๆ
Name[tr]=Uygulama Kılavuzları
Name[ug]=پروگرامما قوللانمىسى
Name[uk]=Підручники з програм
Name[uz]=Dasturlar uchun qoʻllanmalar
Name[uz@cyrillic]=Дастурлар учун қўлланмалар
Name[vi]=Sổ tay ứng dụng
Name[wa]=Manuels des programes
Name[x-test]=xxApplication Manualsxx
Name[zh_CN]=应用程序手册
Name[zh_TW]=應用程式手冊
X-DOC-Weight=200
X-KDE-KHelpcenter-Special=apps
X-DOC-DocumentType=application/docbook+xml
X-DOC-Identifier=kde_application_manuals

View file

@ -0,0 +1 @@
install( FILES .directory DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Applications )

View file

@ -0,0 +1,20 @@
add_subdirectory( Applications )
if (NOT WIN32)
add_subdirectory( Manpages )
add_subdirectory( Scrollkeeper )
endif (NOT WIN32)
########### install files ###############
install( FILES fundamentals.desktop plasma.desktop
onlinehelp.desktop
info.desktop kicmodules.desktop
kcontrolmodules.desktop
konquerorcontrolmodules.desktop
browsercontrolmodules.desktop
filemanagercontrolmodules.desktop
othercontrolmodules.desktop
kioslaves.desktop DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins )

View file

@ -0,0 +1,92 @@
[Desktop Entry]
Name=UNIX manual pages
Name[af]=UNIX manual pages
Name[ar]=صفحات كتيّب يونِكس
Name[ast]=Páxines de manual d'Unix
Name[be@latin]=Padručnyja staronki UNIX („man”)
Name[bg]=Ръководство за UNIX
Name[bn]=ইউনিক্স ম্যানুয়াল পেজ
Name[bn_IN]=UNIX ম্যানুয়াল পেজ
Name[bs]=Uputne stranice naredbi
Name[ca]=Pàgines de manual del UNIX
Name[ca@valencia]=Pàgines de manual del UNIX
Name[cs]=Manuálové stránky pro UNIX
Name[csb]=Pòdrãczniczi dlô UNIXA
Name[da]=UNIX manualsider
Name[de]=UNIX-Hilfeseiten
Name[el]=Σελίδες εγχειριδίου UNIX
Name[en_GB]=UNIX manual pages
Name[eo]=Paĝoj de manlibro de UNIX
Name[es]=Páginas de manual de Unix
Name[et]=UNIX-i manuaalileheküljed
Name[eu]=UNIX eskuliburu-orriak
Name[fa]=صفحات راهنمای یونیکس
Name[fi]=UNIX man-sivut
Name[fr]=Pages de manuel UNIX
Name[fy]=UNIX hânlieding siden
Name[ga]=Leathanaigh lámhleabhair UNIX
Name[gl]=Páxinas de manual de UNIX
Name[gu]=UNIX માર્ગદર્શિકા પાનાંઓ
Name[he]=דפי הוראות של יוניקס
Name[hi]=यूनिक्स निर्देशिका पृष्ठ
Name[hne]=यूनिक्स निर्देसिका पेज
Name[hr]=UNIX stranice s uputama
Name[hsb]=UNIX manual pages
Name[hu]=UNIX man oldalak
Name[ia]=Paginas de manual UNIX
Name[id]=Halaman manual UNIX
Name[is]=UNIX handbókin
Name[it]=Pagine «man» di UNIX
Name[ja]=UNIX マニュアルページ
Name[kk]=UNIX man беттері
Name[km]=ទំព័រ​សៀវភៅ​ដៃ​របស់​យូនីក
Name[kn]=UNIX ಕೈಪಿಡಿ ಪುಟಗಳು (ಮ್ಯಾನುಯಲ್ ಪೇಜಸ್)
Name[ko]=UNIX 매뉴얼 페이지
Name[ku]=Rûpelên rêberiyê yên UNIX
Name[lt]=UNIX man (programų vadovų) puslapiai
Name[lv]=UNIX rokasgrāmatas
Name[mai]=यूनिक्स निर्देशिका पृष्ठ
Name[mk]=Страници со UNIX-прирачници
Name[ml]=യുണിക്സിലെ മാനുവല്‍ താളുകള്‍
Name[mr]=UNIX पुस्तिका पान
Name[nb]=UNIX man-sider
Name[nds]=UNIX man-Sieden
Name[ne]=युनिक्स म्यानुअल पृष्ठ
Name[nl]=UNIX-handboeken
Name[nn]=Unix-manualsider
Name[or]=UNIX ସହାୟକ ପୁସ୍ତକ ପୃଷ୍ଠାଗୁଡ଼ିକ
Name[pa]=UNIX ਮੈਨੂਅਲ ਪੇਜ਼
Name[pl]=Strony podręcznika UNIX-a
Name[pt]=Páginas de manual do UNIX
Name[pt_BR]=Páginas de manual do UNIX
Name[ro]=Pagini de manual UNIX
Name[ru]=Страницы руководств UNIX
Name[se]=Unix-giehtagirjesiiddut
Name[si]=UNIX අත්පොත් පිටු
Name[sk]=Unixové manuálové stránky
Name[sl]=Strani priročnika za UNIX
Name[sr]=Упутне странице наредби
Name[sr@ijekavian]=Упутне странице наредби
Name[sr@ijekavianlatin]=Uputne stranice naredbi
Name[sr@latin]=Uputne stranice naredbi
Name[sv]=Unix manualsidor
Name[ta]=UNIX உதவிப் பக்கங்கள்
Name[te]=UNIX మాన్యువల్ పుటలు
Name[tg]=Дастуруламалҳои UNIX
Name[th]=หน้าคู่มือ UNIX
Name[tr]=UNIX kılavuz sayfaları
Name[ug]=Unix قوللانما بەتلىرى
Name[uk]=Сторінки довідки UNIX
Name[vi]=Trang hướng dẫn UNIX
Name[wa]=Pådjes di man Unix
Name[x-test]=xxUNIX manual pagesxx
Name[zh_CN]=UNIX 手册页
Name[zh_TW]=UNIX 手冊
X-DocPath=man:/
Icon=application-x-troff-man
X-DOC-Weight=500
X-DOC-DocumentType=text/man
X-DOC-Identifier=manpages

View file

@ -0,0 +1,3 @@
install( FILES .directory man1.desktop man2.desktop man3.desktop man4.desktop man5.desktop man6.desktop man7.desktop man8.desktop DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Manpages )

View file

@ -0,0 +1,94 @@
[Desktop Entry]
Name=(1) User Commands
Name[af]=(1) Gebruikerbevele
Name[ar]=(1) أوامر المستخدم
Name[ast]=(1) Órdenes d'usuariu
Name[be]=(1) Каманды карыстальніка
Name[be@latin]=(1) Zahady karystańnika
Name[bg]=(1) Потребителски команди
Name[bn]=(1) User Commands
Name[bn_IN]=()
Name[br]=(1) Urzhiadoù arveriad
Name[bs]=(1) Korisničke naredbe
Name[ca]=(1) Ordres d'usuari
Name[ca@valencia]=(1) Ordes d'usuari
Name[cs]=(1) Uživatelské příkazy
Name[csb]=(1) Pòlét brëkòwnika
Name[cy]=(1) Gorchmynion Defnyddiwr
Name[da]=(1) Brugerkommandoer
Name[de]=(1) Benutzerbefehle
Name[el]=(1) Εντολές χρήστη
Name[en_GB]=(1) User Commands
Name[eo]=(1) Uzantkomandoj
Name[es]=(1) Órdenes de usuario
Name[et]=(1) Kasutaja käsud
Name[eu]=(1) Erabiltzaile-aginduak
Name[fa]=(۱) فرمانهای کاربر
Name[fi]=(1) Käyttäjän komennot
Name[fr]=(1) Commandes utilisateur
Name[fy]=(1) Brûkerskommando's
Name[ga]=(1) Orduithe Úsáideora
Name[gl]=(1) Ordes do usuario
Name[gu]=()
Name[he]=פקודות משתמש (1)
Name[hi]=(1)
Name[hne]=(1)
Name[hr]=(1) Korisničke naredbe
Name[hsb]=(1) Přikazy za wužiwarja
Name[hu]=(1) Felhasználói parancsok
Name[ia]=(1) Commandos de usator
Name[id]=(1) Perintah Pengguna
Name[is]=(1) Notandaskipanir
Name[it]=(1) Comandi dell'utente
Name[ja]=(1)
Name[ka]=(1)
Name[kk]=(1) Пайдаланушы командалар
Name[km]=()
Name[kn]=()
Name[ko]=(1)
Name[ku]=(1) Fermanên Bikarhêneran
Name[lt]=(1) Naudotojo komandos
Name[lv]=(1) Lietotāja komandas
Name[mai]=(1)
Name[mk]=(1) Кориснички команди
Name[ml]=(1) ി
Name[mr]=(1)
Name[ms]=(1) Arahan Pengguna
Name[nb]=(1) Brukerkommandoer
Name[nds]=(1) Brukerbefehlen
Name[ne]=()
Name[nl]=(1) Gebruikercommando's
Name[nn]=(1) Brukarkommandoar
Name[oc]=(1) Comandas personalizadas
Name[or]=(1) ିି
Name[pa]=(1)
Name[pl]=(1) Polecenia użytkownika
Name[pt]=(1) Comandos do Utilizador
Name[pt_BR]=(1) Comandos do usuário
Name[ro]=(1) Comenzi utilizator
Name[ru]=(1) Пользовательские команды
Name[se]=(1) Geavaheaddjigohččumat
Name[si]=(1)
Name[sk]=(1) Užívateľské príkazy
Name[sl]=(1) Uporabniški ukazi
Name[sr]=(1) Корисничке наредбе
Name[sr@ijekavian]=(1) Корисничке наредбе
Name[sr@ijekavianlatin]=(1) Korisničke naredbe
Name[sr@latin]=(1) Korisničke naredbe
Name[sv]=(1) Användarkommandon
Name[ta]=(1)
Name[te]=(1)
Name[tg]=(1) Фармонҳои корбар
Name[th]=(1)
Name[tr]=(1) Kullanıcı Komutları
Name[ug]=(1) ئىشلەتكۈچى بۇيرۇقلىرى
Name[uk]=(1) Команди користувача
Name[uz]=(1) Foydalanuvchi uchun buyruqlar
Name[uz@cyrillic]=(1) Фойдаланувчи учун буйруқлар
Name[vi]=(1) Lnh ca ngưi dùng
Name[wa]=(1) Comandes uzeu
Name[x-test]=xx(1) User Commandsxx
Name[zh_CN]=(1)
Name[zh_TW]=(1) 使
X-DocPath=man:/(1)

View file

@ -0,0 +1,94 @@
[Desktop Entry]
Name=(2) System Calls
Name[af]=(2) Stelselroepe
Name[ar]=(2) استدعاءات النظام
Name[ast]=(2) Llamaes del sistema
Name[be]=(2) Сістэмныя выклікі
Name[be@latin]=(2) Systemnyja vykliki
Name[bg]=(2) Системни сигнали
Name[bn]=(2) ি
Name[bn_IN]=() ি
Name[br]=(3) Galvioù reizhiad
Name[bs]=(2) Sistemski pozivi
Name[ca]=(2) Crides del sistema
Name[ca@valencia]=(2) Crides del sistema
Name[cs]=(2) Systémová volání
Name[csb]=(2) Systemòwé fùnkcëje
Name[cy]=(2) Galwadau Cysawd
Name[da]=(2) Systemkald
Name[de]=(2) Systemaufrufe
Name[el]=(2) Κλήσεις συστήματος
Name[en_GB]=(2) System Calls
Name[eo]=(2) Sistemaj vokoj
Name[es]=(2) Llamadas del sistema
Name[et]=(2) Süsteemsed väljakutsed
Name[eu]=(2) Sistema-deiak
Name[fa]=(۲) فراخوانیهای سیستم
Name[fi]=(2) Järjestelmäkutsut
Name[fr]=(2) Appels système
Name[fy]=(2) Systeemoanroppen
Name[ga]=(2) Glaonna ar an chóras
Name[gl]=(2) Chamadas do sistema
Name[gu]=() િ
Name[he]=קריאות מערכת (2)
Name[hi]=(2) ि
Name[hne]=(2) ि
Name[hr]=(2) Sistemski pozivi
Name[hsb]=(2) Systemowe přikazy
Name[hu]=(2) Rendszerhívások
Name[ia]=(2) Appellos de Systema (System Calls)
Name[id]=(2) Panggilan Sistem
Name[is]=(2) Kerfisköll
Name[it]=(2) Chiamate di sistema
Name[ja]=(2)
Name[ka]=(2)
Name[kk]=(2) Жүйелік шақырулар
Name[km]=()
Name[kn]=()
Name[ko]=(2)
Name[ku]=(2) Bangên Pergalê
Name[lt]=(2) Sisteminiai iškvietimai
Name[lv]=(2) Sistēmas izsaukumi
Name[mai]=(2) ि
Name[mk]=(2) Системски повици
Name[ml]=(2) ി
Name[mr]=(2) ि
Name[ms]=(2) Panggilan Sistem
Name[nb]=(2) Systemkall
Name[nds]=(2) Systeemoprööp
Name[ne]=()
Name[nl]=(2) Systeemaanroepen
Name[nn]=(2) Systemkall
Name[oc]=(2) Apèls sistèma
Name[or]=(2)
Name[pa]=(2) ਿ
Name[pl]=(2) Wywołania systemowe
Name[pt]=(2) Chamadas do Sistema
Name[pt_BR]=(2) Chamadas de sistema
Name[ro]=(2) Apeluri de sistem
Name[ru]=(2) Системные вызовы
Name[se]=(2) Vuogádatgohččumat
Name[si]=(2)
Name[sk]=(2) Systémové volania
Name[sl]=(2) Sistemski klici
Name[sr]=(2) Системски позиви
Name[sr@ijekavian]=(2) Системски позиви
Name[sr@ijekavianlatin]=(2) Sistemski pozivi
Name[sr@latin]=(2) Sistemski pozivi
Name[sv]=(2) Systemanrop
Name[ta]=(2) ிி
Name[te]=(2)
Name[tg]=(2) Зангҳои система
Name[th]=(2)
Name[tr]=(2) Sistem Çağrıları
Name[ug]=(2) سىستېما چاقىرىشلىرى
Name[uk]=(2) Системні виклики
Name[uz]=(2) Tizim chaqiruvlari
Name[uz@cyrillic]=(2) Тизим чақирувлари
Name[vi]=(2) Lnh gi h thng
Name[wa]=(2) Houcaedjes sistinme
Name[x-test]=xx(2) System Callsxx
Name[zh_CN]=(2)
Name[zh_TW]=(2)
X-DocPath=man:/(2)

View file

@ -0,0 +1,92 @@
[Desktop Entry]
Name=(3) Subroutines
Name[af]=(3) Subroetines
Name[ar]=(3) الوظائف الفرعية
Name[ast]=(3) Subrutines
Name[be]=(3) Падпраграмы
Name[be@latin]=(3) Padpracedury
Name[bg]=(3) Подпрограми
Name[bn]=(3) ি
Name[bn_IN]=() -ি
Name[br]=(3) Isroudennadoù
Name[bs]=(3) Potprogrami
Name[ca]=(3) Subrutines
Name[ca@valencia]=(3) Subrutines
Name[cs]=(3) Funkce
Name[csb]=(3) Pòdprogramë
Name[cy]=(3) Is-reolweithiau
Name[da]=(3) Subrutiner
Name[de]=(3) Funktionsaufrufe
Name[el]=(3) Υπορουτίνες
Name[en_GB]=(3) Subroutines
Name[eo]=(3) Proceduroj
Name[es]=(3) Subrutinas
Name[et]=(3) Alamfunktsioonid
Name[eu]=(3) Azpirrutinak
Name[fa]=(۳) زیرروالها
Name[fi]=(3) Aliohjelmat
Name[fr]=(3) Sous-programmes
Name[fy]=(3) Subroutines
Name[ga]=(3) Foghnáthaimh
Name[gl]=(3) Subrutinas
Name[gu]=() િ
Name[he]=תת־שגרות (3)
Name[hi]=(3)
Name[hne]=(3)
Name[hr]=(3) Pod-rutine
Name[hsb]=(3) Subrutiny
Name[hu]=(3) Eljárások
Name[ia]=(3) Subroutines
Name[id]=(3) Subrutin
Name[is]=(3) Stefjur
Name[it]=(3) Procedure
Name[ja]=(3)
Name[ka]=(3)
Name[kk]=(3) Процедуралар
Name[km]=()
Name[kn]=() ಿಿಿ ()
Name[ko]=(3)
Name[ku]=(3) Rûtînên Binî
Name[lt]=(3) Paprogramės
Name[lv]=(3) Subrutīnas
Name[mai]=(3)
Name[mk]=(3) Потпрограми
Name[ml]=(3)
Name[mr]=(3)
Name[ms]=(3) Subrutin
Name[nb]=(3) Delrutiner
Name[nds]=(3) Funkschonen
Name[ne]=() ि
Name[nl]=(3) Subroutines
Name[nn]=(3) Subrutinar
Name[or]=(3) Subroutines
Name[pa]=(3) -
Name[pl]=(3) Podprogramy
Name[pt]=(3) Sub-rotinas
Name[pt_BR]=(3) Sub-rotinas
Name[ro]=(3) Subrutine
Name[ru]=(3) Процедуры
Name[se]=(3) Vuollerutiinnat
Name[si]=(3)
Name[sk]=(3) Podprogramy
Name[sl]=(3) Podprogrami
Name[sr]=(3) Потпрограми
Name[sr@ijekavian]=(3) Потпрограми
Name[sr@ijekavianlatin]=(3) Potprogrami
Name[sr@latin]=(3) Potprogrami
Name[sv]=(3) Subrutiner
Name[ta]=(3)
Name[te]=(3) ి
Name[tg]=(3) Зербарномаҳо
Name[th]=(3)
Name[tr]=(3) Alt Yordamlar
Name[ug]=(3) تارماق جەريان
Name[uk]=(3) Підпрограми
Name[vi]=(3) Chương trình con
Name[wa]=(3) Fonccions di programaedje
Name[xh]=(3) Ulwenzeko rhoqo olusezantsi
Name[x-test]=xx(3) Subroutinesxx
Name[zh_CN]=(3)
Name[zh_TW]=(3)
X-DocPath=man:/(3)

View file

@ -0,0 +1,95 @@
[Desktop Entry]
Name=(4) Devices
Name[af]=(4) Toestelle
Name[ar]=(4) الأجهزة
Name[ast]=(4) Preseos
Name[be]=(4) Прылады
Name[be@latin]=(4) Pryłady
Name[bg]=(4) Устройства
Name[bn]=(4) ি
Name[bn_IN]=() ি
Name[br]=(4) Trobarzhelloù
Name[bs]=(4) Uređaji
Name[ca]=(4) Dispositius
Name[ca@valencia]=(4) Dispositius
Name[cs]=(4) Zařízení
Name[csb]=(4) Ùrządzenia
Name[cy]=(4) Dyfeisiau
Name[da]=(4) Enheder
Name[de]=(4) Geräte
Name[el]=(4) Συσκευές
Name[en_GB]=(4) Devices
Name[eo]=(4) Aparatoj
Name[es]=(4) Dispositivos
Name[et]=(4) Seadmed
Name[eu]=(4) Gailuak
Name[fa]=(۴) دستگاهها
Name[fi]=(4) Laitteet
Name[fr]=(4) Périphériques
Name[fy]=(4) Apparaten
Name[ga]=(4) Gléasra
Name[gl]=(4) Dispositivos
Name[gu]=()
Name[he]=התקנים (4)
Name[hi]=(4)
Name[hne]=(4)
Name[hr]=(4) Uređaji
Name[hsb]=(4) Graty
Name[hu]=(4) Eszközök
Name[ia]=(4) Dispositivos
Name[id]=(4) Divais
Name[is]=(4) Tæki
Name[it]=(4) Dispositivi
Name[ja]=(4)
Name[ka]=(4)
Name[kk]=(4) Құрылғылар
Name[km]=()
Name[kn]=()
Name[ko]=(4)
Name[ku]=(4) Cîhaz
Name[lt]=(4) Įrenginiai
Name[lv]=(4) Ierīces
Name[mai]=(4)
Name[mk]=(4) Уреди
Name[ml]=(4)
Name[mr]=(4)
Name[ms]=(4) Peranti
Name[nb]=(4) Enheter
Name[nds]=(4) Reedschappen
Name[ne]=()
Name[nl]=(4) Apparaten
Name[nn]=(4) Einingar
Name[oc]=(4) Periferics
Name[or]=(4) ି
Name[pa]=(4)
Name[pl]=(4) Urządzenia
Name[pt]=(4) Dispositivos
Name[pt_BR]=(4) Dispositivos
Name[ro]=(4) Dispozitive
Name[ru]=(4) Устройства
Name[se]=(4) Ovttadagat
Name[si]=(4)
Name[sk]=(4) Zariadenia
Name[sl]=(4) Naprave
Name[sr]=(4) Уређаји
Name[sr@ijekavian]=(4) Уређаји
Name[sr@ijekavianlatin]=(4) Uređaji
Name[sr@latin]=(4) Uređaji
Name[sv]=(4) Enheter
Name[ta]=(4)
Name[te]=(4) ి
Name[tg]=(4) Дастгоҳҳо
Name[th]=(4)
Name[tr]=(4) Aygıtlar
Name[ug]=(4) ئۈسكۈنە
Name[uk]=(4) Пристрої
Name[uz]=(4) Uskunalar
Name[uz@cyrillic]=(4) Ускуналар
Name[vi]=(4) Thiết b
Name[wa]=(4) Éndjins
Name[xh]=(4) Amacebo
Name[x-test]=xx(4) Devicesxx
Name[zh_CN]=(4)
Name[zh_TW]=(4)
X-DocPath=man:/(4)

View file

@ -0,0 +1,95 @@
[Desktop Entry]
Name=(5) File Formats
Name[af]=(5) Lêerformate
Name[ar]=(5) صيغ الملفات
Name[ast]=(5) Formatos de ficheros
Name[be]=(5) Фарматы файлаў
Name[be@latin]=(5) Farmaty fajłaŭ
Name[bg]=(5) Файлови формати
Name[bn]=(5)
Name[bn_IN]=() ি
Name[br]=(5) Furmadoù ar restroù
Name[bs]=(5) Formati datoteka
Name[ca]=(5) Formats de fitxers
Name[ca@valencia]=(5) Formats de fitxers
Name[cs]=(5) Datové formáty
Name[csb]=(5) Fòrmatë lopków
Name[cy]=(5) Fformatau Ffeil
Name[da]=(5) Filformater
Name[de]=(5) Dateiformate
Name[el]=(5) Μορφές αρχείων
Name[en_GB]=(5) File Formats
Name[eo]=(5) Dosieraranĝoj
Name[es]=(5) Formatos de archivos
Name[et]=(5) Failivormingud
Name[eu]=(5) Fitxategi-formatuak
Name[fa]=(۵) قالبهای پرونده
Name[fi]=(5) Tiedostomuodot
Name[fr]=(5) Formats de fichiers
Name[fy]=(5) Triemopmaak
Name[ga]=(5) Formáidí Comhaid
Name[gl]=(5) Formatos de ficheiro
Name[gu]=()
Name[he]=תבניות קבצים (5)
Name[hi]=(5)
Name[hne]=(5)
Name[hr]=(5) Oblici datoteka
Name[hsb]=(5) Datajowe formaty
Name[hu]=(5) Fájlformátumok
Name[ia]=(5) Formatos de File
Name[id]=(5) Format Berkas
Name[is]=(5) Skráasnið
Name[it]=(5) Formati di file
Name[ja]=(5)
Name[ka]=(5)
Name[kk]=(5) Файл пішімдері
Name[km]=()
Name[kn]=() ()
Name[ko]=(5)
Name[ku]=(5) Formatên Pelan
Name[lt]=(5) Failų formatai
Name[lv]=(5) Failu formāti
Name[mai]=(5)
Name[mk]=(5) Формати на датотеки
Name[ml]=(5)
Name[mr]=(5)
Name[ms]=(5) Format Fail
Name[nb]=(5) Filformat
Name[nds]=(5) Dateiformaten
Name[ne]=()
Name[nl]=(5) Bestandsformaten
Name[nn]=(5) Filformat
Name[oc]=(5) Formats de fichièrs
Name[or]=(5) ି
Name[pa]=(5)
Name[pl]=(5) Formaty plików
Name[pt]=(5) Formatos de Ficheiros
Name[pt_BR]=(5) Formatos de arquivo
Name[ro]=(5) Formate de fișiere
Name[ru]=(5) Форматы файлов
Name[se]=(5) Fiilaformáhtat
Name[si]=(5)
Name[sk]=(5) Formáty súborov
Name[sl]=(5) Vrste datotek
Name[sr]=(5) Формати фајлова
Name[sr@ijekavian]=(5) Формати фајлова
Name[sr@ijekavianlatin]=(5) Formati fajlova
Name[sr@latin]=(5) Formati fajlova
Name[sv]=(5) Filformat
Name[ta]=(5) ி
Name[te]=(5)
Name[tg]=(5) Намудҳои файл
Name[th]=(5)
Name[tr]=(5) Dosya Biçimleri
Name[ug]=(5) ھۆججەت پىچىملىرى
Name[uk]=(5) Формати файлів
Name[uz]=(5) Fayl formatlari
Name[uz@cyrillic]=(5) Файл форматлари
Name[vi]=(5) Đnh dng Tp tin
Name[wa]=(5) Sôres di fitchîs
Name[xh]=(5) Ifomati Yeefayile
Name[x-test]=xx(5) File Formatsxx
Name[zh_CN]=(5)
Name[zh_TW]=(5)
X-DocPath=man:/(5)

View file

@ -0,0 +1,95 @@
[Desktop Entry]
Name=(6) Games
Name[af]=(6) Speletjies
Name[ar]=(6) الألعاب
Name[ast]=(6) Xuegos
Name[be]=(6) Гульні
Name[be@latin]=(6) Hulni
Name[bg]=(6) Игри
Name[bn]=(6)
Name[bn_IN]=()
Name[br]=(6) C'hoarioù
Name[bs]=(6) Igre
Name[ca]=(6) Jocs
Name[ca@valencia]=(6) Jocs
Name[cs]=(6) Hry
Name[csb]=(6) Grë
Name[cy]=(6) Gemau
Name[da]=(6) Spil
Name[de]=(6) Spiele
Name[el]=(6) Παιχνίδια
Name[en_GB]=(6) Games
Name[eo]=(6) Ludoj
Name[es]=(6) Juegos
Name[et]=(6) Mängud
Name[eu]=(6) Jokoak
Name[fa]=(۶) بازیها
Name[fi]=(6) Pelit
Name[fr]=(6) Jeux
Name[fy]=(6) Spultsjes
Name[ga]=(6) Cluichí
Name[gl]=(6) Xogos
Name[gu]=()
Name[he]=משחקים (6)
Name[hi]=(6)
Name[hne]=(6)
Name[hr]=(6) Igre
Name[hsb]=(6) Hry
Name[hu]=(6) Játékok
Name[ia]=(6) Jocos
Name[id]=(6) Permainan
Name[is]=(6) Leikir
Name[it]=(6) Giochi
Name[ja]=(6)
Name[ka]=(6)
Name[kk]=(6) Ойындар
Name[km]=()
Name[kn]=()
Name[ko]=(6)
Name[ku]=(6) Lîstik
Name[lt]=(6) Žaidimai
Name[lv]=(6) Spēles
Name[mai]=(6)
Name[mk]=(6) Игри
Name[ml]=(6) ി
Name[mr]=(6)
Name[ms]=(6) Permainan
Name[nb]=(6) Spill
Name[nds]=(6) Spelen
Name[ne]=()
Name[nl]=(6) Spelletjes
Name[nn]=(6) Spel
Name[oc]=(6) Jòcs
Name[or]=(6) ି
Name[pa]=(6)
Name[pl]=(6) Gry
Name[pt]=(6) Jogos
Name[pt_BR]=(6) Jogos
Name[ro]=(6) Jocuri
Name[ru]=(6) Игры
Name[se]=(6) Spealut
Name[si]=(6)
Name[sk]=(6) Hry
Name[sl]=(6) Igre
Name[sr]=(6) Игре
Name[sr@ijekavian]=(6) Игре
Name[sr@ijekavianlatin]=(6) Igre
Name[sr@latin]=(6) Igre
Name[sv]=(6) Spel
Name[ta]=(6) ி
Name[te]=(6)
Name[tg]=(6) Бозиҳо
Name[th]=(6)
Name[tr]=(6) Oyunlar
Name[ug]=(6) ئويۇنلار
Name[uk]=(6) Ігри
Name[uz]=(6) Oʻyinlar
Name[uz@cyrillic]=(6) Ўйинлар
Name[vi]=(6) Trò chơi
Name[wa]=(6) Djeus
Name[xh]=(6) Imidlalo
Name[x-test]=xx(6) Gamesxx
Name[zh_CN]=(6)
Name[zh_TW]=(6)
X-DocPath=man:/(6)

View file

@ -0,0 +1,95 @@
[Desktop Entry]
Name=(7) Miscellaneous
Name[af]=(7) Allerlei
Name[ar]=(7) متنوع
Name[ast]=(7) Dellos
Name[be]=(7) Рознае
Name[be@latin]=(7) Roznaje
Name[bg]=(7) Разни
Name[bn]=(7) িি
Name[bn_IN]=() িি
Name[br]=(7) A bep seurt
Name[bs]=(7) Razno
Name[ca]=(7) Miscel·lània
Name[ca@valencia]=(7) Miscel·lània
Name[cs]=(7) Různé
Name[csb]=(7) Wszelejaczé
Name[cy]=(7) Amrwyiol
Name[da]=(7) Diverse
Name[de]=(7) Verschiedenes
Name[el]=(7) Διάφορα
Name[en_GB]=(7) Miscellaneous
Name[eo]=(7) Diversaĵoj
Name[es]=(7) Varios
Name[et]=(7) Muud
Name[eu]=(7) Beste zenbait
Name[fa]=(۷) متفرقه
Name[fi]=(7) Sekalaista
Name[fr]=(7) Divers
Name[fy]=(7) Ferskate
Name[ga]=(7) Rudaí éagsúla
Name[gl]=(7) Diversas
Name[gu]=()
Name[he]=שונות (7)
Name[hi]=(7) िि
Name[hne]=(7) िि
Name[hr]=(7) Razno
Name[hsb]=(7) Wšelake
Name[hu]=(7) Egyéb
Name[ia]=(7) Miscellanea
Name[id]=(7) Lain-lain
Name[is]=(7) Ýmislegt
Name[it]=(7) Varie
Name[ja]=(7)
Name[ka]=(7)
Name[kk]=(7) Әр түрлі
Name[km]=()
Name[kn]=()
Name[ko]=(7)
Name[ku]=(7) Cur be cur
Name[lt]=(7) Įvairūs dalykai
Name[lv]=(7) Dažādi
Name[mai]=(7) िि
Name[mk]=(7) Разно
Name[ml]=(7)
Name[mr]=(7) ि
Name[ms]=(7) Pelbagai
Name[nb]=(7) Diverse
Name[nds]=(7) Annerswat
Name[ne]=() िि
Name[nl]=(7) Diversen
Name[nn]=(7) Ymse
Name[oc]=(7) Divèrs
Name[or]=(7) ିି
Name[pa]=(7)
Name[pl]=(7) Różne
Name[pt]=(7) Diversos
Name[pt_BR]=(7) Diversos
Name[ro]=(7) Diverse
Name[ru]=(7) Разное
Name[se]=(7) Feará mii
Name[si]=(7)
Name[sk]=(7) Rôzne
Name[sl]=(7) Razno
Name[sr]=(7) Разно
Name[sr@ijekavian]=(7) Разно
Name[sr@ijekavianlatin]=(7) Razno
Name[sr@latin]=(7) Razno
Name[sv]=(7) Diverse
Name[ta]=(7)
Name[te]=(7)
Name[tg]=(7) Барномаҳои гуногун
Name[th]=(7)
Name[tr]=(7) Çeşitli
Name[ug]=(7) باشقىلار
Name[uk]=(7) Різне
Name[uz]=(7) Har xil
Name[uz@cyrillic]=(7) Ҳар хил
Name[vi]=(7) Khác
Name[wa]=(7) Totès sôres
Name[xh]=(7) Ezixubeneyo
Name[x-test]=xx(7) Miscellaneousxx
Name[zh_CN]=(7)
Name[zh_TW]=(7)
X-DocPath=man:/(7)

View file

@ -0,0 +1,94 @@
[Desktop Entry]
Name=(8) Sys. Administration
Name[af]=(8) Sys. Administrasie
Name[ar]=(8) إدارة النظام
Name[ast]=(8) Alministración del sistema
Name[be]=(8) Сістэмнае адміністраванне
Name[be@latin]=(8) Systemnaje administravańnie
Name[bg]=(8) Администрация
Name[bn]=(8) ি ি
Name[bn_IN]=() ি িি
Name[br]=(8) Melestradur ar reizhiad
Name[bs]=(8) Administracija sistema
Name[ca]=(8) Administració del sistema
Name[ca@valencia]=(8) Administració del sistema
Name[cs]=(8) Správa systému
Name[csb]=(8) Sprôwianié systemą
Name[cy]=(8) Gweinyddiaeth Cysawd
Name[da]=(8) Systemadministration
Name[de]=(8) Systemverwaltung
Name[el]=(8) Διαχείριση συστήματος
Name[en_GB]=(8) Sys. Administration
Name[eo]=(8) Sistemadministrado
Name[es]=(8) Administración del sistema
Name[et]=(8) Süsteemi haldamine
Name[eu]=(8) Sist.-administrazioa
Name[fa]=(۸) سرپرستی سیستم
Name[fi]=(8) Järjestelmänhallinta
Name[fr]=(8) Administration système
Name[fy]=(8) Systeembehear
Name[ga]=(8) Riarachán an Chórais
Name[gl]=(8) Administración do sistema
Name[gu]=() િ
Name[he]=ניהול המערכת (8)
Name[hi]=(8)
Name[hne]=(8)
Name[hr]=(8) Administracija sustava
Name[hsb]=(8) Zarjadowanje systema
Name[hu]=(8) Rendszeradminisztráció
Name[ia]=(8) Sys. Administration
Name[id]=(8) Administrasi Sistem
Name[is]=(8) Kerfisstjórnun
Name[it]=(8) Amministrazione di sistema
Name[ja]=(8)
Name[ka]=(8)
Name[kk]=(8) Жүйе әкімшілігі
Name[km]=()
Name[kn]=() ಿ
Name[ko]=(8)
Name[ku]=(8) Gerînendetiya Pergale
Name[lt]=(8) Sist. administravimas
Name[lv]=(8) Sistēmas administrācija
Name[mai]=(8)
Name[mk]=(8) Системска администрација
Name[ml]=(8) ിി
Name[mr]=(8)
Name[ms]=(8) Pentadbiran Sistem
Name[nb]=(8) Systemadministrasjon
Name[nds]=(8) Systeempleeg
Name[ne]=()
Name[nl]=(8) Systeembeheer
Name[nn]=(8) Systemadministrasjon
Name[or]=(8)
Name[pa]=(8) ਿ
Name[pl]=(8) Administracja systemu
Name[pt]=(8) Administração do Sistema
Name[pt_BR]=(8) Administração do sistema
Name[ro]=(8) Administrare de sistem
Name[ru]=(8) Системное администрирование
Name[se]=(8) Vuogádathálddašeapmi
Name[si]=(8)
Name[sk]=(8) Administrácia systému
Name[sl]=(8) Sistemsko skrbništvo
Name[sr]=(8) Администрација система
Name[sr@ijekavian]=(8) Администрација система
Name[sr@ijekavianlatin]=(8) Administracija sistema
Name[sr@latin]=(8) Administracija sistema
Name[sv]=(8) Systemadministration
Name[ta]=(8) ிி-ி
Name[te]=(8) ి
Name[tg]=(8) Мудирияти система
Name[th]=(8)
Name[tr]=(8) Sistem Yönetimi
Name[ug]=(8) سىستېما باشقۇرۇش
Name[uk]=(8) Сист. адміністрування
Name[uz]=(8) Tizimni boshqarish
Name[uz@cyrillic]=(8) Тизимни бошқариш
Name[vi]=(8) Qun tr H thng
Name[wa]=(8) Manaedjmint do sistinme
Name[xh]=(8) Sys. Administration
Name[x-test]=xx(8) Sys. Administrationxx
Name[zh_CN]=(8)
Name[zh_TW]=(8)
X-DocPath=man:/(8)

View file

@ -0,0 +1,94 @@
[Desktop Entry]
Name=(9) Kernel
Name[af]=(9) Kern
Name[ar]=(9) النواة
Name[ast]=(9) Nucleu
Name[be]=(9) Ядро
Name[be@latin]=(9) Jadro
Name[bg]=(9) Ядро
Name[bn]=(9)
Name[bn_IN]=() (Kernel)
Name[br]=(9) Kalon
Name[bs]=(9) Kernel
Name[ca]=(9) Nucli
Name[ca@valencia]=(9) Nucli
Name[cs]=(9) Jádro
Name[csb]=(9) Jądro systemë
Name[cy]=(9) Cnewyllen
Name[da]=(9) Kerne
Name[de]=(9) Kernel
Name[el]=(9) Πυρήνας
Name[en_GB]=(9) Kernel
Name[eo]=(9) Kerno
Name[es]=(9) Núcleo
Name[et]=(9) Kernel
Name[eu]=(9) Nukleoa
Name[fa]=(۹) هسته
Name[fi]=(9) Ydin
Name[fr]=(9) Noyau (Kernel)
Name[fy]=(9) Kernel
Name[ga]=(9) Eithne
Name[gl]=(9) Núcleo
Name[gu]=()
Name[he]=גרעין (9)
Name[hi]=(9)
Name[hne]=(9)
Name[hr]=(9) Kernel
Name[hsb]=(9) Kernel
Name[hu]=(9) Kernel
Name[ia]=(9) Kernel
Name[id]=(9) Kernel
Name[is]=(9) Kjarni
Name[it]=(9) Kernel
Name[ja]=(9)
Name[ka]=(9)
Name[kk]=(9) Өзегі
Name[km]=()
Name[kn]=() ಿ ()
Name[ko]=(9)
Name[ku]=(9) Kernel (Kakîl)
Name[lt]=(9) Branduolys
Name[lv]=(9) Kodols
Name[mai]=(9)
Name[mk]=(9) Кернел
Name[ml]=(9)
Name[mr]=(9)
Name[ms]=(9) Kernel
Name[nb]=(9) Kjerne
Name[nds]=(9) Kernel (Karn vun't Bedriefsysteem)
Name[ne]=()
Name[nl]=(9) Kernel
Name[nn]=(9) Kjerne
Name[or]=(9)
Name[pa]=(9)
Name[pl]=(9) Jądro systemu
Name[pt]=(9) 'Kernel'
Name[pt_BR]=(9) Kernel
Name[ro]=(9) Nucleu
Name[ru]=(9) Ядро
Name[se]=(9) Čoahkku
Name[si]=(9)
Name[sk]=(9) Kernel
Name[sl]=(9) Jedro
Name[sr]=(9) Кернел
Name[sr@ijekavian]=(9) Кернел
Name[sr@ijekavianlatin]=(9) Kernel
Name[sr@latin]=(9) Kernel
Name[sv]=(9) Kärna
Name[ta]=(9)
Name[te]=(9)
Name[tg]=(9) Мағзи система
Name[th]=(9)
Name[tr]=(9) Çekirdek
Name[ug]=(9) يادروسى
Name[uk]=(9) Ядро
Name[uz]=(9) Kernel
Name[uz@cyrillic]=(9) Кернел
Name[vi]=(9) Ht nhân
Name[wa]=(9) Fonccions do nawea linux
Name[xh]=(9) Kernel
Name[x-test]=xx(9) Kernelxx
Name[zh_CN]=(9)
Name[zh_TW]=(9)
X-DocPath=man:/(9)

View file

@ -0,0 +1,94 @@
[Desktop Entry]
Name=(n) New
Name[af]=(n) Nuwe
Name[ar]=(n) جديد
Name[ast]=(n) Nuevu
Name[be]=(n) Новыя
Name[be@latin]=(n) Novaje
Name[bg]=(n) Нови
Name[bn]=(n)
Name[bn_IN]=(n)
Name[br]=(n) Nevez
Name[bs]=(n) Novo
Name[ca]=(n) Nou
Name[ca@valencia]=(n) Nou
Name[cs]=(n) Nové
Name[csb]=(n) Nowé
Name[cy]=(n) Newydd
Name[da]=(n) Ny
Name[de]=(n) Neu
Name[el]=(n) Νέο
Name[en_GB]=(n) New
Name[eo]=(n) Nova
Name[es]=(n) Nuevo
Name[et]=(n) Uus
Name[eu]=(n) Berria
Name[fa]=(n) جدید
Name[fi]=(n) Uudet
Name[fr]=(n) Nouveautés
Name[fy]=(n) Nij
Name[ga]=(n) Nua
Name[gl]=(n) Novo
Name[gu]=(n)
Name[he]=חדש (n)
Name[hi]=(n)
Name[hne]=(n)
Name[hr]=(n) Novo
Name[hsb]=(n) Nowe
Name[hu]=(n) Új
Name[ia]=(n) Nove
Name[id]=(n) Baru
Name[is]=(n) Nýtt
Name[it]=(n) Nuovi
Name[ja]=(n)
Name[ka]=(n)
Name[kk]=(n) Жаңа
Name[km]=(n)
Name[kn]=(n)
Name[ko]=(n)
Name[ku]=(n) Nû
Name[lt]=(n) Nauji dalykai
Name[lv]=(n) Jauns
Name[mai]=(n)
Name[mk]=(n) Нови
Name[ml]=(n) ി
Name[mr]=(n)
Name[ms]=(n) Baru
Name[nb]=(n) Ny
Name[nds]=(n) Nieg
Name[ne]=(n)
Name[nl]=(n) Nieuw
Name[nn]=(n) Ny
Name[or]=(n)
Name[pa]=(n)
Name[pl]=(n) nowe
Name[pt]=(n) Novos
Name[pt_BR]=(n) Novos
Name[ro]=(n) Nou
Name[ru]=(n) Новые
Name[se]=(n) Ođđa
Name[si]=(n)
Name[sk]=(n) Nové
Name[sl]=(n) Novo
Name[sr]=(n) Ново
Name[sr@ijekavian]=(n) Ново
Name[sr@ijekavianlatin]=(n) Novo
Name[sr@latin]=(n) Novo
Name[sv]=(n) Ny
Name[ta]=(n) ி
Name[te]=(n)
Name[tg]=(н) Нав
Name[th]=(n)
Name[tr]=(n) Yeni
Name[ug]=(n) يېڭى
Name[uk]=(n) Нові
Name[uz]=(n) Yangi
Name[uz@cyrillic]=(n) Янги
Name[vi]=(n) Mi
Name[wa]=(n) Noveas
Name[xh]=(n) Entsha
Name[x-test]=xx(n) Newxx
Name[zh_CN]=(n)
Name[zh_TW]=(n)
X-DocPath=man:/(n)

View file

@ -0,0 +1,88 @@
[Desktop Entry]
Name=Scrollkeeper
Name[af]=Scrollkeeper
Name[ar]=حافظ التمرير
Name[ast]=Scrollkeeper
Name[be]=Scrollkeeper
Name[be@latin]=Scrollkeeper
Name[bg]=Scrollkeeper
Name[bn]=স্ক্রোলকীপার
Name[bn_IN]=স্ক্রোল-কিপার
Name[bs]=Čuvar svitaka
Name[ca]=Scrollkeeper
Name[ca@valencia]=Scrollkeeper
Name[cs]=Scrollkeeper
Name[csb]=Scrollkeeper
Name[da]=Scrollkeeper
Name[de]=Scrollkeeper
Name[el]=Scrollkeeper
Name[en_GB]=Scrollkeeper
Name[es]=Scrollkeeper
Name[et]=Scrollkeeper
Name[eu]=Scrollkeeper
Name[fa]=Scrollkeeper
Name[fi]=Scrollkeeper
Name[fr]=Scrollkeeper
Name[fy]=Skowhâlder
Name[ga]=Scrollkeeper
Name[gl]=Scrollkeeper
Name[gu]=સ્ક્રોલકિપર
Name[he]=Scrollkeeper
Name[hi]=स्क्रॉलकीपर
Name[hne]=स्क्रालकीपर
Name[hr]=Scrollkeeper
Name[hsb]=Scrollkeeper
Name[hu]=Scrollkeeper
Name[ia]=Scrollkeeper (mantenitor de rolo)
Name[id]=Scrollkeeper
Name[is]=Scrollkeeper
Name[it]=Scrollkeeper
Name[ja]=Scrollkeeper
Name[kk]=Scrollkeeper
Name[km]=ឧបករណ៍​រក្សា​រមូរ​
Name[kn]=ಸುರುಳು ಪಾಲಕ (ಸ್ಕ್ರಾಲ್ ಕೀಪರ್)
Name[ko]=읽을 거리
Name[ku]=Scrollkeeper
Name[lt]=Scrollkeeper
Name[lv]=Scrollkeeper
Name[mai]=स्क्रालकीपर
Name[mk]=Scrollkeeper
Name[ml]=സ്ക്രോള്‍കീപ്പര്‍
Name[mr]=स्क्रोलकीपर
Name[nb]=Scrollkeeper
Name[nds]=Scrollkeeper
Name[ne]=स्क्रोलकिपर
Name[nl]=Scrollkeeper
Name[nn]=Scrollkeeper
Name[or]=Scrollkeeper
Name[pa]=ਸਕਰੋਲਕੀਪਰ
Name[pl]=Scrollkeeper
Name[pt]=Scrollkeeper
Name[pt_BR]=Scrollkeeper
Name[ro]=Scrollkeeper
Name[ru]=Scrollkeeper
Name[se]=Scrollkeeper
Name[si]=Scrollkeeper
Name[sk]=Scrollkeeper
Name[sl]=Scrollkeeper
Name[sr]=Чувар свитака
Name[sr@ijekavian]=Чувар свитака
Name[sr@ijekavianlatin]=Čuvar svitaka
Name[sr@latin]=Čuvar svitaka
Name[sv]=Scrollkeeper
Name[ta]=மாற்றுவைப்பு
Name[te]=స్క్రాల్‌కీపర్
Name[tg]=Дорандаи паймоиш
Name[th]=Scrollkeeper
Name[tr]=Scrollkeeper
Name[ug]=Scrollkeeper
Name[uk]=Scrollkeeper
Name[uz]=Scrollkeeper
Name[uz@cyrillic]=Scrollkeeper
Name[vi]=Scrollkeeper
Name[wa]=Scrollkeeper
Name[x-test]=xxScrollkeeperxx
Name[zh_CN]=Scrollkeeper
Name[zh_TW]=捲軸固定
Icon=help-contents
X-DOC-Weight=550

View file

@ -0,0 +1,2 @@
install( FILES .directory scrollkeeper.desktop DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Scrollkeeper )

View file

@ -0,0 +1,2 @@
[Desktop Entry]
X-KDE-KHelpcenter-Special=scrollkeeper

View file

@ -0,0 +1,49 @@
[Desktop Entry]
Name=Browser Settings Modules
Name[ar]=مستعرض دليل الإعدادات
Name[ca]=Mòduls de configuració del navegador
Name[ca@valencia]=Mòduls de configuració del navegador
Name[cs]=Moduly nastavení prohlížeče
Name[da]=Moduler til browserindstillinger
Name[de]=Browser-Einstellungsmodule
Name[el]=Αρθρώματα ρυθμίσεων του περιηγητή
Name[en_GB]=Browser Settings Modules
Name[es]=Módulos de preferencias del navegador
Name[et]=Brauseriseadistuste moodulid
Name[eu]=Arakatzaile-ezarpenen moduluak
Name[fa]=مرور پیمانههای تنظیمات
Name[fi]=Selaimen asetusosiot
Name[fr]=Modules des paramètres du navigateur
Name[gl]=Módulos de configuración do navegador
Name[hu]=Böngésző beállítási modulok
Name[ia]=Modulos pro navigar inter preferentias
Name[id]=Modul Pengaturan Peramban
Name[is]=Stillingaeiningar vafra
Name[it]=Moduli delle impostazioni del browser
Name[ko]=
Name[nb]=Moduler for nettleser-innstillinger
Name[nds]=Nettkieker-Instellenmodulen
Name[nl]=Modules voor instellingen van de browser
Name[pa]= ਿ
Name[pl]=Moduły ustawień przeglądarki
Name[pt]=Módulos de Configuração do Navegador
Name[pt_BR]=Módulos de configuração do Navegador
Name[ru]=Модули настроек браузера
Name[sk]=Moduly nastavení prehliadača
Name[sl]=Moduli nastavitev brskalnika
Name[sr]=Модули поставки прегледача
Name[sr@ijekavian]=Модули поставки прегледача
Name[sr@ijekavianlatin]=Moduli postavki pregledača
Name[sr@latin]=Moduli postavki pregledača
Name[sv]=Inställningsmoduler för webbläsare
Name[tr]=Tarayıcı Ayar Modülleri
Name[uk]=Модулі параметрів перегляду інтернету
Name[x-test]=xxBrowser Settings Modulesxx
Name[zh_CN]=
Name[zh_TW]=
Icon=preferences-system
X-DOC-Weight=370
X-KDE-KHelpcenter-Special=browsercontrol

View file

@ -0,0 +1,49 @@
[Desktop Entry]
Name=Filemanager Settings Modules
Name[ar]=نماذج إعدادات مدير الملفات
Name[ca]=Mòduls de configuració del gestor de fitxers
Name[ca@valencia]=Mòduls de configuració del gestor de fitxers
Name[cs]=Moduly nastavení správce souborů
Name[da]=Moduler til filhåndteringindstillinger
Name[de]=Dateiverwaltungs-Einstellungsmodule
Name[el]=Αρθρώματα ρυθμίσεων του διαχειριστή αρχείων
Name[en_GB]=Filemanager Settings Modules
Name[es]=Módulos de preferencias del gestor de archivos
Name[et]=Failihalduri seadistuste moodulid
Name[eu]=Fitxategi-kudeatzaile-ezarpenen moduluak
Name[fa]=پیمانههای تنظیمات مدیر پرونده
Name[fi]=Tiedostonhallinnan asetusosiot
Name[fr]=Modules des paramètres du gestionnaire de fichiers
Name[gl]=Módulos de configuración do xestor de ficheiros
Name[hu]=Fájlkezelő beállítási modulok
Name[ia]=Modulos de Preferentias de gerente de file
Name[id]=Modul Pengaturan Manajer Berkas
Name[is]=Stillingaeiningar skráastjóra
Name[it]=Moduli delle impostazioni del gestore dei file
Name[ko]=
Name[nb]=Moduler for filbehandler-innstillinger
Name[nds]=Dateipleger-Instellenmodulen
Name[nl]=Modules voor instellingen van de bestandsbeheerder
Name[pa]=- ਿ
Name[pl]=Moduły ustawień przeglądarki plików
Name[pt]=Módulos de Configuração do Gestor de Ficheiros
Name[pt_BR]=Módulos de configuração do Gerenciador de Arquivos
Name[ru]=Модули настроек диспетчера файлов
Name[sk]=Moduly nastavení správcu súborov
Name[sl]=Moduli nastavitev upravljalnika datotek
Name[sr]=Модули поставки менаџера фајлова
Name[sr@ijekavian]=Модули поставки менаџера фајлова
Name[sr@ijekavianlatin]=Moduli postavki menadžera fajlova
Name[sr@latin]=Moduli postavki menadžera fajlova
Name[sv]=Inställningsmoduler för filhanterare
Name[tr]=Dosya Yönetici Ayar Modülleri
Name[uk]=Модулі параметрів керування файлами
Name[x-test]=xxFilemanager Settings Modulesxx
Name[zh_CN]=
Name[zh_TW]=
Icon=preferences-system
X-DOC-Weight=350
X-KDE-KHelpcenter-Special=filemanagercontrol

View file

@ -0,0 +1,61 @@
[Desktop Entry]
X-DocPath=help:/fundamentals/index.html
Icon=system-help
Name=KDE Fundamentals
Name[ar]=أساسيات كدي
Name[bg]=Основи на KDE
Name[bn]=.ি..
Name[bs]=KDE osnove
Name[ca]=Fonaments del KDE
Name[ca@valencia]=Fonaments del KDE
Name[cs]=Základy KDE
Name[da]=KDE Fundamentals
Name[de]=KDE-Grundlagen
Name[el]=Βασικές αρχές του KDE
Name[en_GB]=KDE Fundamentals
Name[eo]=Bazoj de KDE
Name[es]=Fundamentos de KDE
Name[et]=KDE põhialused
Name[eu]=KDEren oinarriak
Name[fa]=اصول کیدیای
Name[fi]=KDE:n perusasiat
Name[fr]=Fondamentaux de KDE
Name[ga]=Uraiceacht KDE
Name[gl]=Esenciais de KDE
Name[gu]=KDE
Name[he]=יסודות של KDE
Name[hi]=
Name[hu]=KDE Fundamentals
Name[ia]=Fundamentales de KDE
Name[id]=Fundamental KDE
Name[is]=Grunnatriði KDE
Name[it]=Fondamentali di KDE
Name[kk]=KDE негіздері
Name[km]= KDE
Name[ko]=KDE
Name[lt]=KDE pagrindai
Name[mr]=
Name[nb]=Grunnleggende KDE
Name[nds]=KDE-Grundlagen
Name[nl]=KDE-fundamentals
Name[nn]=Grunnleggjande KDE
Name[pa]=KDE
Name[pl]=Fundamenty KDE
Name[pt]=Fundamentos do KDE
Name[pt_BR]=Fundamentos do KDE
Name[ro]=Noțiuni de bază KDE
Name[ru]=Основы KDE
Name[sk]=KDE princípy
Name[sl]=Osnove KDE-ja
Name[sr]=Основе КДЕа
Name[sr@ijekavian]=Основе КДЕа
Name[sr@ijekavianlatin]=Osnove KDEa
Name[sr@latin]=Osnove KDEa
Name[sv]=KDE:s grunder
Name[tr]=Temel KDE Bilgileri
Name[ug]=ك د ئې(KDE) ئاساسلىرى
Name[uk]=Основи KDE
Name[wa]=Soûmints di KDE
Name[x-test]=xxKDE Fundamentalsxx
Name[zh_CN]=KDE
Name[zh_TW]=KDE

View file

@ -0,0 +1,98 @@
[Desktop Entry]
Name=Browse Info Pages
Name[af]=Blaai deur inligting bladsye (Info pages)
Name[ar]=تصفح صفحات المعلومات
Name[ast]=Restolar pente páxines d'info
Name[be]=Праглядзець старонкі info
Name[be@latin]=Hartańnie infarmacyjnych staronak (info)
Name[bg]=Преглед на страниците с информация
Name[bn]=
Name[bn_IN]=Info ি
Name[br]=Furchal ar pajennoù titouroù
Name[bs]=Pregledanje info stranica
Name[ca]=Navega per les pàgines Info
Name[ca@valencia]=Navega per les pàgines Info
Name[cs]=Prohlížeč info stránek
Name[csb]=Przezéranié wëdowiédnëch starnów
Name[cy]=Pori Tudalennau Info
Name[da]=Gennemse infosider
Name[de]=Infoseiten durchsehen
Name[el]=Περιήγηση στις σελίδες info
Name[en_GB]=Browse Info Pages
Name[eo]=Foliumi informopaĝojn
Name[es]=Examinar páginas info
Name[et]=Infolehekülgede lehitsemine
Name[eu]=Arakatu informazio-orriak
Name[fa]=مرور صفحات اطلاعات
Name[fi]=Selaa info-sivuja
Name[fr]=Naviguer dans les pages d'informations
Name[fy]=ynfo-siden trochblêdzje
Name[ga]=Brabhsáil Leathanaigh Eolais
Name[gl]=Navegar polas páxinas info
Name[gu]=િ
Name[he]=עיון בדפי מידע
Name[hi]=
Name[hne]=
Name[hr]=Pretraživanje info stranica
Name[hsb]=Informaciske strony přelistować
Name[hu]=Info oldalak
Name[ia]=Naviga in le paginas de info
Name[id]=Ramban Halaman Info
Name[is]=Flakka um upplýsingasíður
Name[it]=Sfoglia le pagine «info»
Name[ja]=Info
Name[ka]=
Name[kk]=Info парақтары
Name[km]=
Name[kn]=ಿಿ ಿ
Name[ko]=Info
Name[ku]=Rûpelên Agahiyan Veke
Name[lt]=Naršyti info puslapius
Name[lv]=Pārlūkot info lapas
Name[mai]=
Name[mk]=Прелистај ги info страниците
Name[ml]=
Name[mr]=
Name[ms]=Layar Halaman Maklumat
Name[nb]=Les info-sider
Name[nds]=Info-Sieden dörkieken
Name[ne]=
Name[nl]=Info-pagina's doorbladeren
Name[nn]=Les info-sider
Name[or]= ି
Name[pa]=
Name[pl]=Przeglądanie stron informacyjnych
Name[pt]=Navegar nas Páginas do Info
Name[pt_BR]=Páginas de navegação no Info
Name[ro]=Pagini info
Name[ru]=Страницы Info
Name[se]=Loga info-siidduid
Name[si]=
Name[sk]=Prehliadanie info stránok
Name[sl]=Brskanje po straneh info
Name[sr]=Прегледање инфо страница
Name[sr@ijekavian]=Прегледање инфо страница
Name[sr@ijekavianlatin]=Pregledanje info stranica
Name[sr@latin]=Pregledanje info stranica
Name[sv]=Bläddra i info-sidor
Name[ta]= ி
Name[te]=info ి
Name[tg]=Намоиши саҳифаҳои маълумот
Name[th]= (info)
Name[tr]=Bilgi Sayfalarını Tara
Name[ug]=ئۇچۇر بېتىنى كۆرۈش
Name[uk]=Перегляд сторінок info
Name[uz]=Info varaqlarni koʻrish
Name[uz@cyrillic]=Info варақларни кўриш
Name[vi]=Duyt Trang Thông tin
Name[wa]=Foyter les pådjes info
Name[x-test]=xxBrowse Info Pagesxx
Name[zh_CN]=
Name[zh_TW]=
Icon=help-contents
X-KDE-KHelpcenter-Special=info
X-DocPath=info:/dir
X-DOC-Weight=700

View file

@ -0,0 +1,49 @@
[Desktop Entry]
Name=System Settings Modules
Name[ar]=نماذج إعدادات النظام
Name[ca]=Mòduls de configuració del sistema
Name[ca@valencia]=Mòduls de configuració del sistema
Name[cs]=Moduly nastavení systému
Name[da]=Moduler til Systemindstillinger
Name[de]=Systemeinstellungen-Module
Name[el]=Αρθρώματα ρυθμίσεων του συστήματος
Name[en_GB]=System Settings Modules
Name[es]=Módulos de preferencias del sistema
Name[et]=Süsteemi seadistuste moodulid
Name[eu]=Sistema-ezarpenen moduluak
Name[fa]=پیمانههای تنظیمات سیستم
Name[fi]=Järjestelmäasetusosiot
Name[fr]=Modules des paramètres du système
Name[gl]=Módulos de configuración do sistema
Name[hu]=Rendszerbeállítások modulok
Name[ia]=Modulosde Preferentias de Systema
Name[id]=Modul Pengaturan Sistem
Name[is]=Stillingaeiningar kerfis
Name[it]=Moduli delle impostazioni di sistema
Name[ko]=
Name[nb]=Moduler for systeminnstillinger
Name[nds]=Systeem-Instellenmodulen
Name[nl]=Modules voor systeeminstellingen
Name[pa]=ਿ ਿ
Name[pl]=Moduły ustawień systemu
Name[pt]=Módulos de Configuração do Sistema
Name[pt_BR]=Módulos das Configurações do Sistema
Name[ru]=Модули «Параметров системы»
Name[sk]=Moduly nastavení systému
Name[sl]=Moduli sistemskih nastavitev
Name[sr]=Модули системских поставки
Name[sr@ijekavian]=Модули системских поставки
Name[sr@ijekavianlatin]=Moduli sistemskih postavki
Name[sr@latin]=Moduli sistemskih postavki
Name[sv]=Inställningsmoduler för system
Name[tr]=Sistem Ayar Modülleri
Name[uk]=Модулі системних параметрів
Name[x-test]=xxSystem Settings Modulesxx
Name[zh_CN]=
Name[zh_TW]=
Icon=preferences-system
X-DOC-Weight=300
X-KDE-KHelpcenter-Special=kcontrol

View file

@ -0,0 +1,98 @@
[Desktop Entry]
Name=KInfoCenter Modules
Name[af]=K-Inligtingsentrum Modules
Name[ar]=نماذج مركز معلومات كدي
Name[ast]=Módulos del KInfoCenter
Name[be]=Модулі інфармацыйнага цэнтра
Name[be@latin]=Moduli KInfoCenter
Name[bg]=Информационен център
Name[bn]=KInfoCenter ি
Name[bn_IN]=KInfoCenter ি
Name[br]=Molladoù KInfoCenter
Name[bs]=Moduli Kinfocentra
Name[ca]=Mòduls del KInfoCenter
Name[ca@valencia]=Mòduls del KInfoCenter
Name[cs]=Moduly Informačního centra
Name[csb]=Wëdowiédné mòdułë centróm kòntrolë
Name[cy]=Modiwlau KInfoCenter
Name[da]=KInfoCenter-moduler
Name[de]=Infozentrum-Module
Name[el]=Αρθρώματα KInfoCenter
Name[en_GB]=KInfoCentre Modules
Name[eo]=Moduloj de KInfoCenter
Name[es]=Módulos de KInfoCenter
Name[et]=Infokeskuse moodulid
Name[eu]=KInfoCenter moduluak
Name[fa]=پیمانههای KInfoCenter
Name[fi]=KInfoCenter-moduulit
Name[fr]=Modules du centre d'informations
Name[fy]=Ynformaasjesintrummodules
Name[ga]=Modúil KInfoCenter
Name[gl]=Módulos de KInfoCenter
Name[gu]=KInfoCenter
Name[he]=מודולי מרכז המידע
Name[hi]=--
Name[hne]=--
Name[hr]=KInfoCenter moduli
Name[hsb]=Module za KInfoCenter
Name[hu]=KInfoCenter-modulok
Name[ia]=Modulos de KInfoCenter
Name[id]=Modul KInfoCenter
Name[is]=Upplýsingaborðseiningar
Name[it]=Moduli del centro d'informazione
Name[ja]=KInfoCenter
Name[ka]=
Name[kk]=KInfoCenter модульдері
Name[km]= KInfoCenter
Name[kn]=
Name[ko]=KInfoCenter
Name[ku]=Modulên Navenda KInfo
Name[lt]=KInfoCenter moduliai
Name[lv]=KInfoCenter moduļi
Name[mai]=--
Name[mk]=KInfoCenter модули
Name[ml]=
Name[mr]=ि ि
Name[ms]=Modul KInfoCenter
Name[nb]=Infosentermoduler
Name[nds]=Modulen för dat KDE-Infozentrum
Name[ne]=
Name[nl]=Informatiecentrummodules
Name[nn]=Infosentermodular
Name[or]=KInfoCenter ି
Name[pa]=-
Name[pl]=Moduły informacyjne Centrum sterowania
Name[pt]=Módulos do KInfoCenter
Name[pt_BR]=Módulos do centro de informações
Name[ro]=Module Centru de Informații
Name[ru]=Модули «Информации о системе»
Name[se]=Diehtoguovddášmoduvllat
Name[si]=KInfoCenter
Name[sk]=Moduly pre Informačné centrum
Name[sl]=Moduli Informacijskega središča
Name[sr]=Модули Кинфоцентра
Name[sr@ijekavian]=Модули Кинфоцентра
Name[sr@ijekavianlatin]=Moduli Kinfocentra
Name[sr@latin]=Moduli Kinfocentra
Name[sv]=Moduler i Informationscentralen
Name[ta]= ி
Name[te]=
Name[tg]=Модулҳои маркази иттилоотӣ
Name[th]=
Name[tr]=KInfoCenter Modülleri
Name[ug]=KInfoCenter بۆلەكلىرى
Name[uk]=Модулі KInfoCenter
Name[uz]=KInfoCenter modullari
Name[uz@cyrillic]=KInfoCenter модуллари
Name[vi]=Mô-đun Trung tâm Thông tin ca KDE
Name[wa]=Modules do cinte d' infôrmåcions di KDE
Name[xh]=Izicatshulwa ze KInfoCenter
Name[x-test]=xxKInfoCenter Modulesxx
Name[zh_CN]=KInfoCenter
Name[zh_TW]=KInfoCenter
Icon=help-contents
X-DOC-Weight=400
X-KDE-KHelpcenter-Special=kinfocenter

View file

@ -0,0 +1,97 @@
[Desktop Entry]
Name=Kioslaves
Name[af]=Kioslaves
Name[ar]=Kioslaves
Name[ast]=Kioslaves
Name[be]=Kioslaves
Name[be@latin]=Słužby kioslave
Name[bg]=Система за вход-изход
Name[bn]=Kioslaves
Name[bn_IN]=Kioslaves
Name[br]=Kioslaves
Name[bs]=U/I zahvati
Name[ca]=Kioslaves
Name[ca@valencia]=Kioslaves
Name[cs]=Pomocné protokoly KDE
Name[csb]=wtëkôczë wéńdzeniô/wińdzeniô
Name[cy]=Kioslaves
Name[da]=Kioslaver
Name[de]=Ein-/Ausgabemodule
Name[el]=Kioslaves
Name[en_GB]=Kioslaves
Name[eo]=Kioslaves
Name[es]=Kioslaves
Name[et]=KIO-moodulid
Name[eu]=Kioslaves
Name[fa]=Kioslaves
Name[fi]=KIO-palvelut
Name[fr]=Modules d'entrées / sorties
Name[fy]=Kioslaves
Name[ga]=Sclábhaithe KIO
Name[gl]=Kioslaves
Name[gu]=Kioslaves
Name[he]=פרוטוקולים
Name[hi]=-
Name[hne]=-
Name[hr]=Kioslaves
Name[hsb]=Kioslaves
Name[hu]=KDE-protokollok
Name[ia]=Kioslaves
Name[id]=Kioslaves
Name[is]=Kioslaves
Name[it]=Kioslave
Name[ja]=Kioslave
Name[ka]=Kioslaves
Name[kk]=Kioslaves
Name[km]=Kioslaves
Name[kn]=
Name[ko]=KIO
Name[ku]=Kioslaves
Name[lt]=Kioprotokolai
Name[lv]=KIO vergi
Name[mai]=-
Name[mk]=Kioslaves
Name[ml]=ി
Name[mr]=Kioslaves
Name[ms]=Kioslaves
Name[nb]=Kioslaver
Name[nds]=In-/Utgaavmodulen
Name[ne]=ि
Name[nl]=Kioslaves
Name[nn]=Kioslavar
Name[oc]=Kioslaves
Name[or]=Kioslaves
Name[pa]=Kioslaves
Name[pl]=Wtyczki wejścia/wyjścia
Name[pt]=Kioslaves
Name[pt_BR]=Kioslaves
Name[ro]=Dispozitive KIO
Name[ru]=Поддержка протоколов
Name[se]=KIO-šlávat
Name[si]=Kioslaves
Name[sk]=Kioslaves
Name[sl]=Kioslaves
Name[sr]=У/И захвати
Name[sr@ijekavian]=У/И захвати
Name[sr@ijekavianlatin]=U/I zahvati
Name[sr@latin]=U/I zahvati
Name[sv]=I/O-slavar
Name[ta]=Kioslaves
Name[te]= ి
Name[tg]=Kioslaves
Name[th]=Kioslaves
Name[tr]=Kioslaves
Name[ug]=Kioslaves
Name[uk]=Підлеглі В/В
Name[uz]=Kioslaves
Name[uz@cyrillic]=Kioslaves
Name[vi]=Kioslaves
Name[wa]=Vårlets d' I/R (kioslaves)
Name[x-test]=xxKioslavesxx
Name[zh_CN]=Kioslaves
Name[zh_TW]=Kioslaves
Icon=help-contents
X-DOC-Weight=500
X-KDE-KHelpcenter-Special=kioslave

View file

@ -0,0 +1,50 @@
[Desktop Entry]
Name=Konqueror Settings Modules
Name[ar]=نماذج إعدادات كونكيورر
Name[ca]=Mòduls de configuració del Konqueror
Name[ca@valencia]=Mòduls de configuració del Konqueror
Name[cs]=Moduly nastavení Konqueroru
Name[da]=Moduler til Konqueror-indstillinger
Name[de]=Konqueror-Einstellungsmodule
Name[el]=Αρθρώματα ρυθμίσεων του Konqueror
Name[en_GB]=Konqueror Settings Modules
Name[es]=Módulos de preferencias de Konqueror
Name[et]=Konquerori seadistuste moodulid
Name[eu]=Konqueror-ezarpenen moduluak
Name[fa]=پیمانههای تنظیمات کانکرر
Name[fi]=Konquerorin asetusosiot
Name[fr]=Modules des paramètres de Konqueror
Name[gl]=Módulos de configuración do Konqueror
Name[hu]=Konqueror beállítási modulok
Name[ia]=Modulos de preferentias de Konqueror
Name[id]=Modul Pengaturan Konqueror
Name[is]=Stillingaeiningar Konqueror
Name[it]=Moduli delle impostazioni di Konqueror
Name[ja]=Konqueror
Name[ko]=Konqueror
Name[nb]=Modulen for Konqueror-innstillinger
Name[nds]=Konqueror-Instellenmodulen
Name[nl]=Modules voor instellingen van Konqueror
Name[pa]=ਿ ਿ
Name[pl]=Moduły ustawień Konquerora
Name[pt]=Módulos de Configuração do Konqueror
Name[pt_BR]=Módulos de configuração do Konqueror
Name[ru]=Модули настроек Konqueror
Name[sk]=Moduly nastavení Konquerora
Name[sl]=Moduli nastavitev Konquerorja
Name[sr]=Модули Косвајачевих поставки
Name[sr@ijekavian]=Модули Косвајачевих поставки
Name[sr@ijekavianlatin]=Moduli Kosvajačevih postavki
Name[sr@latin]=Moduli Kosvajačevih postavki
Name[sv]=Inställningsmoduler för Konqueror
Name[tr]=Konqueror Ayar Modülleri
Name[uk]=Модулі параметрів Konqueror
Name[x-test]=xxKonqueror Settings Modulesxx
Name[zh_CN]=Konqueror
Name[zh_TW]=Konqueror
Icon=preferences-system
X-DOC-Weight=330
X-KDE-KHelpcenter-Special=konquerorcontrol

View file

@ -0,0 +1,72 @@
[Desktop Entry]
Name=Online Help
Name[ar]=مساعدة عبر الإنترنت
Name[ast]=Ayuda en llinia
Name[bg]=Помощ в мрежата
Name[bn]=
Name[bs]=Pomoć na vezi
Name[ca]=Ajuda en línia
Name[ca@valencia]=Ajuda en línia
Name[cs]=Nápověda online
Name[da]=Online hjælp
Name[de]=Online-Hilfe
Name[el]=Βοήθεια στο διαδίκτυο
Name[en_GB]=Online Help
Name[eo]=Reta helpo
Name[es]=Ayuda en línea
Name[et]=Abi
Name[eu]=Lineako laguntza
Name[fa]=کمک برخط
Name[fi]=Online-ohje
Name[fr]=Aide en ligne
Name[ga]=Cabhair Ar Líne
Name[gl]=Axuda con conexión
Name[gu]=
Name[he]=עזרה מקוונת
Name[hi]=
Name[hr]=Online Pomoć
Name[hu]=Online súgó
Name[ia]=Adjuta in linea
Name[id]=Bantuan Daring
Name[is]=Hjálp á netinu
Name[it]=Aiuto in rete
Name[ja]=
Name[kk]=Интернет анықтамасы
Name[km]=
Name[kn]=
Name[ko]=
Name[lt]=Pagalba internete
Name[lv]=Tiešsaistes palīdzība
Name[mai]= ि
Name[mr]=
Name[nb]=Hjelp på nettverket
Name[nds]=Online-Hülp
Name[nl]=Online-hulp
Name[nn]=Hjelp på nettet
Name[pa]=
Name[pl]=Pomoc w sieci
Name[pt]=Ajuda 'Online'
Name[pt_BR]=Ajuda on-line
Name[ro]=Ajutor online
Name[ru]=Справка в Интернете
Name[si]=
Name[sk]=Online pomocník
Name[sl]=Pomoč na spletu
Name[sr]=Помоћ на вези
Name[sr@ijekavian]=Помоћ на вези
Name[sr@ijekavianlatin]=Pomoć na vezi
Name[sr@latin]=Pomoć na vezi
Name[sv]=Direkthjälp
Name[tg]=Кӯмаки онлайн
Name[th]=
Name[tr]=Çevrimiçi Yardım
Name[ug]=توردىكى ياردەم
Name[uk]=Довідка у інтернеті
Name[vi]=Tr giúp trc tuyến
Name[wa]=Aidance so fyis
Name[x-test]=xxOnline Helpxx
Name[zh_CN]=线
Name[zh_TW]=
Icon=help-contents
X-DocPath=help:/onlinehelp/index.html
X-DOC-Weight=100

Some files were not shown because too many files have changed in this diff Show more