diff options
Diffstat (limited to 'khelpcenter')
158 files changed, 16489 insertions, 0 deletions
diff --git a/khelpcenter/CMakeLists.txt b/khelpcenter/CMakeLists.txt new file mode 100644 index 000000000..279ecd389 --- /dev/null +++ b/khelpcenter/CMakeLists.txt @@ -0,0 +1,63 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( plugins ) +add_subdirectory( pics ) +add_subdirectory( searchhandlers ) + + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES Help.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install( FILES khelpcenter.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES khelpcenter.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) + +install( FILES + khelpcenterui.rc intro.html.in glossary.html.in + table-of-contents.xslt glossary.xslt index.html.in + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter ) + + +##### khelpcenter (tdeinit) ##################### + +tde_add_tdeinit_executable( khelpcenter AUTOMOC + SOURCES + 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 searchwidget.skel + treebuilder.cpp infotree.cpp mainwindow.skel + kcmhelpcenter.cpp htmlsearchconfig.cpp kcmhelpcenter.skel + fontdialog.cpp plugintraverser.cpp scrollkeepertreebuilder.cpp + prefs.kcfgc searchhandler.cpp + LINK tdehtml-shared +) + + +##### khc_indexbuilder (executable) ############# + +tde_add_executable( khc_indexbuilder AUTOMOC + SOURCES khc_indexbuilder.cpp + LINK tdecore-shared + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/khelpcenter/COPYING b/khelpcenter/COPYING new file mode 100644 index 000000000..0b84a43fd --- /dev/null +++ b/khelpcenter/COPYING @@ -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. diff --git a/khelpcenter/DESIGN b/khelpcenter/DESIGN new file mode 100644 index 000000000..68d762a53 --- /dev/null +++ b/khelpcenter/DESIGN @@ -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 TDE + - 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 TDEListView 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( TDEListViewItem *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 'TDEListView' as it's parent, subclasses can then +# overload that method (such as the KHC::TOCBuilder which will want to provide +# a build( TDEListViewItem *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 TDEIO and show +# the results in our TDEHTMLPart (after all KHC::View is a TDEHTMLPart already). A +# problem with this: How to display the multiple HTML pages returned by the +# selected search engines? Using a QSplitter to split multiple TDEHTMLParts? +# 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 TDEIO. 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 TDEHTMLView. Since we then have one unified output, we don't +# need to worry about having multiple TDEHTMLParts, 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 TDEHTMLPart 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 tdeio_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 TDEHTML view (loading the stylesheet, +# showing the welcome page). We could easily do taht in the background - show +# the mainwindow, then tell the TreeBuilders to start populating (using a +# QTimer with a timeout of 0, for a snappy GUI). Since they're collapsed at +# the start, the users won't even notice (and we can "fake" that they're +# already populated by calling setExpandable(true) for all of them (or letting +# them do that themselves) at the start. + +## Finally a crazy idea: Wouldn't it be cool, if we would make the manuals more +## interactive. So when you read about a certain menu or a certain dialog of an +## application you can click on a link in the manual and the menu or dialog gets +## opened in the real application, or some widgets get highlghted in the real +## application. Such a feature could also be used to create interactive +## tutorials, where you have a small helpcenter window and the application next +## to each other on the screen and you can go through the tutorial step by step +## and practice with the real application while reading the instructions. +## With the help of DCOP it shouldn't be too hard to implement such an +## interactive help system. Maybe it's even possible to do it in a general way +## in the libs, so that application authors don't have to think about that +## feature. + +# Hmm, that's an interesting idea. That takes KHelpCenter way beyond what it's +# currently doing. I can imagine this: we introduce a virtual "dcop" protocol, +# so that e.g. <ulink url="dcop:/kfortune/KFortuneIface/nextFortune"/> +# represents the DCOP call 'dcop kfortune KFortuneIface nextfortune'. +# KHelpCenter catches that protocol (oh dear, a lot of special cases with +# gloss, info etc. already - guess another one won't hurt). That looks like a +# good way for encapsulating DCOP calls. +# Now, the problem is - the application has to provide a dedicated +# "documentation" DCOP interface for this, with lots of calls for highlighting +# the various widgets (hm, this probably means taht we can skip the first two +# parts in our 'dcop' URL syntax, the application is known anyway, and the +# interface is hardcoded in KHelpCenter). +# So, what could happen is this: We have a piece of HTML in the documentation +# for our SuperApp application which goes like 'The +# <a href="dcop:highlightConnectButton">button labelled Connect</a> makes +# SuperApp establish a connection.' - the user clicks on that link, +# KHelpCenter catches a dcop: URL, checks whether SuperApp has already been +# started. If not, it starts a SuperApp process and does the dcop call 'dcop +# SuperApp DocIface highlightConnectButton' and SuperApp starts highlighting +# that connect button. The thing is that this requires a lot of work on the +# application side. The idea is very cool, but we'd have to think about +# outsourceing parts of that functionality, either to KHelpCenter, or to +# tdelibs. + +## And another idea: The WhatsThis help texts describe all widgets of an +## application (provided that the texts are set by the developers). Currently +## they aren't accessible very easily. You have to go to a special mode and +## can then click on one widget after another to get the help, if there is one. +## There is no visual indication which widgets have help and which not. But the +## application knows about the WhatsThis helps. Perhaps it's possible to use +## the Qt object inspection stuff to extract all the texts and put them on an +## automatically generated screenshot of the corresponding dialog and put this +## graphic into the docs. Maybe it's even possible to do this at run-time and +## decorate dialogs with all WhatsThis helps at once, if the user triggers this +## mode. + +# Hmm yes, that should be possible. Take the toplevel widget, use +# QObject::children() and iterate over all children, use QToolTip::textFor() to +# check whether the given qwidget has a tooltip and if so, use QToolTip::tip() +# to show the tooltip. +# One could probably add a standard dcop call to TDEMainWindow, 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 TDEHTML font settings, +### which is odd, because the stylesheet is intentionally loose, +### specifying only "sans-serif" as the font face. + +### Ideas to fix: + +### Help pages already make heavy use of the cascading feature of CSS, we +### ought to be able to leverage that by writing to perhaps the +### kde-localized.css file or a copy of it in $TDEHOME. There is already +### code in KControl to create a user CSS stylesheet, and we probably only +### need to configure the size and the face for KHC. + +### Or, fix whatever is the reason KHC doesn't follow the rules. It could +### be encoding related, the help pages specify utf-8 as the encoding, and +### previous incarnations of the TDEHTML 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 diff --git a/khelpcenter/Help.desktop b/khelpcenter/Help.desktop new file mode 100644 index 000000000..9f423cff7 --- /dev/null +++ b/khelpcenter/Help.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Exec=khelpcenter +Icon=khelpcenter +DocPath=khelpcenter/index.html +Type=Application +Terminal=false +Name=Help +Name[af]=Hulp +Name[ar]=مساعدة +Name[be]=Дапамога +Name[bg]=Помощ +Name[bn]=সাহায্য +Name[br]=Skoazell +Name[bs]=Pomoć +Name[ca]=Ajuda +Name[cs]=Nápověda +Name[csb]=Pòmòc +Name[cy]=Cymorth +Name[da]=Hjælp +Name[de]=Hilfe +Name[el]=Βοήθεια +Name[eo]=Helpo +Name[es]=Ayuda +Name[et]=Abi +Name[eu]=Laguntza +Name[fa]=کمک +Name[fi]=Ohje +Name[fr]=Aide +Name[ga]=Cabhair +Name[gl]=Axuda +Name[he]=עזרה +Name[hr]=Pomoć +Name[hu]=Segítség +Name[id]=Keterangan bantu +Name[is]=Hjálp +Name[it]=Aiuto +Name[ja]=ヘルプ +Name[ka]=დახმარება +Name[kk]=Анықтама +Name[km]=ជំនួយ +Name[ko]=도움말 +Name[lo]=ລະບົບຊ່ວຍເຫືລອ +Name[lt]=Pagalba +Name[lv]=Palīdzība +Name[mk]=Помош +Name[mn]=Тусламж +Name[ms]=Bantuan +Name[nb]=Hjelp +Name[nds]=Hülp +Name[ne]=मद्दत +Name[nl]=Documentatie +Name[nn]=Hjelp +Name[nso]=Thuso +Name[oc]=Ajuda +Name[pa]=ਸਹਾਇਤਾ +Name[pl]=Pomoc +Name[pt]=Ajuda +Name[pt_BR]=Ajuda +Name[ro]=Ajutor +Name[ru]=Справка +Name[rw]=Ifashayobora +Name[se]=Veahkki +Name[sk]=Pomocník +Name[sl]=Pomoč +Name[sr]=Помоћ +Name[sr@Latn]=Pomoć +Name[ss]=Sita +Name[sv]=Hjälp +Name[ta]=உதவி +Name[te]=సహాయం +Name[tg]=Роҳнамо +Name[th]=ระบบช่วยเหลือ +Name[tr]=Yardım +Name[tt]=Yärdäm +Name[uk]=Довідка +Name[uz]=Yordam +Name[uz@cyrillic]=Ёрдам +Name[ven]=Thuso +Name[vi]=Trợ giúp +Name[wa]=Aidance +Name[xh]=Uncedo +Name[zh_CN]=帮助 +Name[zh_TW]=求助 +Name[zu]=Usizo +Categories=Qt;TDE;Core; +OnlyShowIn=TDE; diff --git a/khelpcenter/Makefile.am b/khelpcenter/Makefile.am new file mode 100644 index 000000000..e9e3ac015 --- /dev/null +++ b/khelpcenter/Makefile.am @@ -0,0 +1,57 @@ +SUBDIRS = plugins pics searchhandlers + +INCLUDES = $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = khc_indexbuilder +lib_LTLIBRARIES = + +khc_indexbuilder_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor +khc_indexbuilder_LDADD = $(LIB_TDECORE) +khc_indexbuilder_SOURCES = khc_indexbuilder.cpp + +tdeinit_LTLIBRARIES = khelpcenter.la + +khelpcenter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +khelpcenter_la_LIBADD = $(LIB_TDEHTML) +khelpcenter_la_SOURCES = 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 searchwidget.skel treebuilder.cpp \ + infotree.cpp mainwindow.skel \ + kcmhelpcenter.cpp htmlsearchconfig.cpp kcmhelpcenter.skel \ + fontdialog.cpp plugintraverser.cpp scrollkeepertreebuilder.cpp \ + prefs.kcfgc searchhandler.cpp + +#kcm_helpcenter_la_LDFLAGS = $(KDE_RPATH) -module -avoid-version \ +# $(all_libraries) -no-undefined +#kcm_helpcenter_la_LIBADD = $(LIB_TDEIO) +#kcm_helpcenter_la_SOURCES = kcmhelpcenter.cpp docmetainfo.cpp \ +# docentrytraverser.cpp docentry.cpp htmlsearch.cpp \ +# htmlsearchconfig.cpp + +EXTRA_PROGRAMS = testmetainfo + +testmetainfo_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor +testmetainfo_LDADD = $(LIB_TDECORE) docentry.lo docmetainfo.lo \ + docentrytraverser.lo htmlsearch.lo +testmetainfo_SOURCES = testmetainfo.cpp + +service_DATA = khelpcenter.desktop +servicedir = $(kde_servicesdir) + +xdg_apps_DATA = Help.desktop + +#xdg_apps_DATA = kcmhelpcenter.desktop + +rc_DATA = khelpcenterui.rc intro.html.in glossary.html.in table-of-contents.xslt \ + glossary.xslt index.html.in +rcdir = $(kde_datadir)/khelpcenter + +kde_kcfg_DATA = khelpcenter.kcfg + +messages: rc.cpp + $(EXTRACTRC) `find . -name "*.kcfg"` >> rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/khelpcenter.pot diff --git a/khelpcenter/README.htdig b/khelpcenter/README.htdig new file mode 100644 index 000000000..c4981035f --- /dev/null +++ b/khelpcenter/README.htdig @@ -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. + diff --git a/khelpcenter/README.metadata b/khelpcenter/README.metadata new file mode 100644 index 000000000..adbddc106 --- /dev/null +++ b/khelpcenter/README.metadata @@ -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 +DocPath URI Location of document. In addition to the + standard URI schemes like http: and file: + all schemes which are supported through + tdeioslaves 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 +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-TDE-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 + 'applets' panel applet docs + 'kcontrol' kcontrol module docs + 'konqueror' konqueror plugin docs + 'tdeioslave' tdeioslave 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 +$TDEDIRS/share/config) is scanned for desktop files. They are merged to a common +hierarchy. If the "MetaInfoDirs" entry is empty the directory at +$TDEDIRS/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 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. diff --git a/khelpcenter/application.cpp b/khelpcenter/application.cpp new file mode 100644 index 000000000..7adafeb04 --- /dev/null +++ b/khelpcenter/application.cpp @@ -0,0 +1,90 @@ + /* + * This file is part of the Trinity Help Center + * + * Copyright (c) 2002 Frerich Raabe <[email protected]> + * + * 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 <tdecmdlineargs.h> +#include <tdeaboutdata.h> + +using namespace KHC; + +Application::Application() : KUniqueApplication(), mMainWindow( 0 ) +{ +} + +int Application::newInstance() +{ + if (restoringSession()) return 0; + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + KURL url; + if ( args->count() ) + url = args->url( 0 ); + + if( !mMainWindow ) { + mMainWindow = new MainWindow; + setMainWidget( mMainWindow ); + mMainWindow->show(); + } + + mMainWindow->openUrl( url ); + + return KUniqueApplication::newInstance(); +} + +static TDECmdLineOptions options[] = +{ + { "+[url]", I18N_NOOP("URL to display"), "" }, + TDECmdLineLastOption +}; + +extern "C" int KDE_EXPORT kdemain( int argc, char **argv ) +{ + TDEAboutData aboutData( "khelpcenter", I18N_NOOP("Trinity Help Center"), + HELPCENTER_VERSION, + I18N_NOOP("The Trinity Help Center"), + TDEAboutData::License_GPL, + I18N_NOOP("(c) 1999-2003, The KHelpCenter developers") ); + + aboutData.addAuthor( "Timothy Pearson", 0, "[email protected]" ); + aboutData.addAuthor( "Cornelius Schumacher", 0, "[email protected]" ); + aboutData.addAuthor( "Frerich Raabe", 0, "[email protected]" ); + aboutData.addAuthor( "Matthias Elter", I18N_NOOP("Original Author"), + "[email protected]" ); + aboutData.addAuthor( "Wojciech Smigaj", I18N_NOOP("Info page support"), + "[email protected]" ); + + TDECmdLineArgs::init( argc, argv, &aboutData ); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication::addCmdLineOptions(); + + KHC::Application app; + + if ( app.isRestored() ) { + RESTORE( MainWindow ); + } + + return app.exec(); +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/application.h b/khelpcenter/application.h new file mode 100644 index 000000000..642f4dfda --- /dev/null +++ b/khelpcenter/application.h @@ -0,0 +1,45 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe <[email protected]> + * + * 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 APPLICATION_H +#define APPLICATION_H + +#include <kuniqueapplication.h> + +namespace KHC { + +class MainWindow; + +class Application : public KUniqueApplication +{ + public: + Application(); + + virtual int newInstance(); + + private: + MainWindow *mMainWindow; +}; + +} + +extern "C" { int kdemain(int argc, char **argv); } + +#endif // APPLICATION_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/configure.in.in b/khelpcenter/configure.in.in new file mode 100644 index 000000000..88801ab8a --- /dev/null +++ b/khelpcenter/configure.in.in @@ -0,0 +1,2 @@ +dnl AC_OUTPUT(khelpcenter/searchhandlers/khc_docbookdig.pl) +dnl AC_OUTPUT(khelpcenter/searchhandlers/khc_htdig.pl) diff --git a/khelpcenter/docentry.cpp b/khelpcenter/docentry.cpp new file mode 100644 index 000000000..05f3ffac0 --- /dev/null +++ b/khelpcenter/docentry.cpp @@ -0,0 +1,348 @@ +#include <tqregexp.h> +#include <tqfileinfo.h> + +#include <kdebug.h> +#include <kdesktopfile.h> +#include <kurl.h> +#include <kstandarddirs.h> +#include <tdeapplication.h> + +#include "prefs.h" + +#include "docentry.h" + +using namespace KHC; + +DocEntry::DocEntry() +{ + init(); +} + +DocEntry::DocEntry( const TQString &name, const TQString &url, + const TQString &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 TQString &name ) +{ + mName = name; +} + +TQString DocEntry::name() const +{ + return mName; +} + +void DocEntry::setSearch( const TQString &search ) +{ + mSearch = search; +} + +TQString DocEntry::search() const +{ + return mSearch; +} + +void DocEntry::setIcon( const TQString &icon ) +{ + mIcon = icon; +} + +TQString DocEntry::icon() const +{ + if ( !mIcon.isEmpty() ) return mIcon; + + if ( !docExists() ) return "unknown"; + + if ( isDirectory() ) return "contents2"; + else return "document2"; +} + +void DocEntry::setUrl( const TQString &url ) +{ + mUrl = url; +} + +TQString DocEntry::url() const +{ + if ( !mUrl.isEmpty() ) return mUrl; + + if ( identifier().isEmpty() ) return TQString::null; + + return "khelpcenter:" + identifier(); +} + +void DocEntry::setInfo( const TQString &info ) +{ + mInfo = info; +} + +TQString DocEntry::info() const +{ + return mInfo; +} + +void DocEntry::setLang( const TQString &lang ) +{ + mLang = lang; +} + +TQString DocEntry::lang() const +{ + return mLang; +} + +void DocEntry::setIdentifier( const TQString &identifier ) +{ + mIdentifier = identifier; +} + +TQString DocEntry::identifier() const +{ + if ( mIdentifier.isEmpty() ) mIdentifier = TDEApplication::randomString( 15 ); + return mIdentifier; +} + +void DocEntry::setIndexer( const TQString &indexer ) +{ + mIndexer = indexer; +} + +TQString DocEntry::indexer() const +{ + return mIndexer; +} + +void DocEntry::setIndexTestFile( const TQString &indexTestFile ) +{ + mIndexTestFile = indexTestFile; +} + +TQString DocEntry::indexTestFile() const +{ + return mIndexTestFile; +} + +void DocEntry::setWeight( int weight ) +{ + mWeight = weight; +} + +int DocEntry::weight() const +{ + return mWeight; +} + +void DocEntry::setSearchMethod( const TQString &method ) +{ + mSearchMethod = method; +} + +TQString DocEntry::searchMethod() const +{ + return mSearchMethod; +} + +void DocEntry::setDocumentType( const TQString &str ) +{ + mDocumentType = str; +} + +TQString DocEntry::documentType() const +{ + return mDocumentType; +} + +TQString 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 TQString &fileName ) +{ + KDesktopFile file( fileName ); + + mName = file.readName(); + mSearch = file.readEntry( "X-DOC-Search" ); + mIcon = file.readIcon(); + mUrl = file.readPathEntry( "DocPath" ); + mInfo = file.readEntry( "Info" ); + if ( mInfo.isNull() ) mInfo = file.readEntry( "Comment" ); + mLang = file.readEntry( "Lang", "en" ); + mIdentifier = file.readEntry( "X-DOC-Identifier" ); + if ( mIdentifier.isEmpty() ) { + TQFileInfo fi( fileName ); + mIdentifier = fi.baseName( true ); + } + mIndexer = file.readEntry( "X-DOC-Indexer" ); + mIndexer.replace( "%f", fileName ); + mIndexTestFile = file.readEntry( "X-DOC-IndexTestFile" ); + mSearchEnabledDefault = file.readBoolEntry( "X-DOC-SearchEnabledDefault", + false ); + mSearchEnabled = mSearchEnabledDefault; + mWeight = file.readNumEntry( "X-DOC-Weight", 0 ); + mSearchMethod = file.readEntry( "X-DOC-SearchMethod" ); + mDocumentType = file.readEntry( "X-DOC-DocumentType" ); + + mKhelpcenterSpecial = file.readEntry("X-TDE-KHelpcenter-Special"); + + return true; +} + +bool DocEntry::indexExists( const TQString &indexDir ) +{ + TQString testFile; + if ( mIndexTestFile.isEmpty() ) { + testFile = identifier() + ".exists"; + } else { + testFile = mIndexTestFile; + } + + if ( !testFile.startsWith( "/" ) ) testFile = indexDir + "/" + testFile; + + return TQFile::exists( testFile ); +} + +bool DocEntry::docExists() const +{ + if ( !mUrl.isEmpty() ) { + KURL docUrl( mUrl ); + if ( docUrl.isLocalFile() && !TDEStandardDirs::exists( docUrl.path() ) ) { +// kdDebug(1400) << "URL not found: " << docUrl.url() << endl; + return false; + } + } + + return true; +} + +void DocEntry::addChild( DocEntry *entry ) +{ + entry->setParent( this ); + + uint 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.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 +{ + kdDebug() << " <docentry>" << endl; + kdDebug() << " <name>" << mName << "</name>" << endl; + kdDebug() << " <searchmethod>" << mSearchMethod << "</searchmethod>" << endl; + kdDebug() << " <search>" << mSearch << "</search>" << endl; + kdDebug() << " <indexer>" << mIndexer << "</indexer>" << endl; + kdDebug() << " <indextestfile>" << mIndexTestFile << "</indextestfile>" << endl; + kdDebug() << " <icon>" << mIcon << "</icon>" << endl; + kdDebug() << " <url>" << mUrl << "</url>" << endl; + kdDebug() << " <documenttype>" << mDocumentType << "</documenttype>" << endl; + kdDebug() << " </docentry>" << endl; +} +// vim:ts=2:sw=2:et diff --git a/khelpcenter/docentry.h b/khelpcenter/docentry.h new file mode 100644 index 000000000..d86cde9d2 --- /dev/null +++ b/khelpcenter/docentry.h @@ -0,0 +1,117 @@ +#ifndef DOCENTRY_H +#define DOCENTRY_H + +#include <tqstring.h> +#include <tqvaluelist.h> + +namespace KHC { + +class DocEntry +{ + public: + typedef TQValueList<DocEntry *> List; + + DocEntry(); + + DocEntry( const TQString &name, const TQString &url = TQString::null, + const TQString &icon = TQString::null ); + + void setName( const TQString & ); + TQString name() const; + + void setSearch( const TQString & ); + TQString search() const; + + void setIcon( const TQString & ); + TQString icon() const; + + void setUrl( const TQString & ); + TQString url() const; + + void setInfo( const TQString & ); + TQString info() const; + + void setLang( const TQString & ); + TQString lang() const; + + void setIdentifier( const TQString & ); + TQString identifier() const; + + void setIndexer( const TQString & ); + TQString indexer() const; + + void setIndexTestFile( const TQString & ); + TQString indexTestFile() const; + + void setWeight( int ); + int weight() const; + + void setSearchMethod( const TQString & ); + TQString searchMethod() const; + + void enableSearch( bool enabled ); + bool searchEnabled() const; + + void setSearchEnabledDefault( bool enabled ); + bool searchEnabledDefault() const; + + void setDocumentType( const TQString & ); + TQString documentType() const; + + void setDirectory( bool ); + bool isDirectory() const; + + bool readFromFile( const TQString &fileName ); + + bool indexExists( const TQString &indexDir ); + + bool docExists() const; + + void addChild( DocEntry * ); + bool hasChildren(); + DocEntry *firstChild(); + List children(); + + void setParent( DocEntry * ); + DocEntry *parent(); + + void setNextSibling( DocEntry * ); + DocEntry *nextSibling(); + + TQString khelpcenterSpecial() const; + + bool isSearchable(); + + void dump() const; + + protected: + void init(); + + private: + TQString mName; + TQString mSearch; + TQString mIcon; + TQString mUrl; + TQString mInfo; + TQString mLang; + mutable TQString mIdentifier; + TQString mIndexer; + TQString mIndexTestFile; + int mWeight; + TQString mSearchMethod; + bool mSearchEnabled; + bool mSearchEnabledDefault; + TQString mDocumentType; + bool mDirectory; + + TQString mKhelpcenterSpecial; + + List mChildren; + DocEntry *mParent; + DocEntry *mNextSibling; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/docentrytraverser.cpp b/khelpcenter/docentrytraverser.cpp new file mode 100644 index 000000000..d6335d232 --- /dev/null +++ b/khelpcenter/docentrytraverser.cpp @@ -0,0 +1,49 @@ +#include "docmetainfo.h" + +#include "docentrytraverser.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 diff --git a/khelpcenter/docentrytraverser.h b/khelpcenter/docentrytraverser.h new file mode 100644 index 000000000..d8c8cb15e --- /dev/null +++ b/khelpcenter/docentrytraverser.h @@ -0,0 +1,44 @@ +#ifndef DOCENTRYTRAVERSER_H +#define 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 +// vim:ts=2:sw=2:et diff --git a/khelpcenter/docmetainfo.cpp b/khelpcenter/docmetainfo.cpp new file mode 100644 index 000000000..8e254d909 --- /dev/null +++ b/khelpcenter/docmetainfo.cpp @@ -0,0 +1,287 @@ +#include <tqregexp.h> + +#include <kdebug.h> +#include <kstandarddirs.h> +#include <tdelocale.h> +#include <ksimpleconfig.h> + +#include "htmlsearch.h" + +#include "docentrytraverser.h" + +#include "docmetainfo.h" + +using namespace KHC; + +bool DocMetaInfo::mLoaded = false; + +DocMetaInfo *DocMetaInfo::mSelf = 0; + +DocMetaInfo *DocMetaInfo::self() +{ + if ( !mSelf ) mSelf = new DocMetaInfo; + return mSelf; +} + +DocMetaInfo::DocMetaInfo() +{ + kdDebug() << "DocMetaInfo()" << endl; + + mHtmlSearch = new HTMLSearch; + + mRootEntry.setName( i18n("Top-Level Documentation") ); +} + +DocMetaInfo::~DocMetaInfo() +{ + kdDebug() << "~DocMetaInfo()" << endl; + + DocEntry::List::ConstIterator it; + for( it = mDocEntries.begin(); it != mDocEntries.end(); ++it ) { + delete *it; + } + + delete mHtmlSearch; + + mLoaded = false; + + mSelf = 0; +} + +DocEntry *DocMetaInfo::addDocEntry( const TQString &fileName ) +{ + TQFileInfo fi( fileName ); + if ( !fi.exists() ) return 0; + + TQString extension = fi.extension(); + TQStringList extensions = TQStringList::split( '.', extension ); + TQString lang; + if ( extensions.count() >= 2 ) { + lang = extensions[ extensions.count() - 2 ]; + } + + if ( !lang.isEmpty() && mLanguages.find( lang ) == mLanguages.end() ) { + return 0; + } + + DocEntry *entry = new DocEntry(); + + if ( entry->readFromFile( fileName ) ) { + if ( !lang.isEmpty() && lang != mLanguages.first() ) { + entry->setLang( lang ); + entry->setName( i18n("doctitle (language)","%1 (%2)") + .arg( entry->name() ) + .arg( mLanguageNames[ lang ] ) ); + } + if ( entry->searchMethod().lower() == "htdig" ) { + mHtmlSearch->setupDocEntry( entry ); + } + TQString 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; +} + +TQString DocMetaInfo::languageName( const TQString &langcode ) +{ + if ( langcode == "en" ) return i18n("English"); + + TQString cfgfile = locate( "locale", + TQString::fromLatin1( "%1/entry.desktop" ).arg( langcode ) ); + + kdDebug() << "-- langcode: " << langcode << " cfgfile: " << cfgfile << endl; + + KSimpleConfig cfg( cfgfile ); + cfg.setGroup( "KCM Locale" ); + TQString name = cfg.readEntry( "Name", langcode ); + + return name; +} + +void DocMetaInfo::scanMetaInfo( bool force ) +{ + if ( mLoaded && !force ) return; + + mLanguages = TDEGlobal::locale()->languagesTwoAlpha(); + + kdDebug( 1400 ) << "LANGS: " << mLanguages.join( " " ) << endl; + + TQStringList::ConstIterator it; + for( it = mLanguages.begin(); it != mLanguages.end(); ++it ) { + mLanguageNames.insert( *it, languageName( *it ) ); + } + + TDEConfig config( "khelpcenterrc" ); + config.setGroup( "General" ); + TQStringList metaInfos = config.readListEntry( "MetaInfoDirs" ); + + if ( metaInfos.isEmpty() ) { + TDEStandardDirs* kstd = TDEGlobal::dirs(); + kstd->addResourceType( "data", "share/apps/khelpcenter" ); + metaInfos = kstd->findDirs( "data", "plugins" ); + } + for( it = metaInfos.begin(); it != metaInfos.end(); it++) { + kdDebug() << "DocMetaInfo::scanMetaInfo(): scanning " << *it << endl; + scanMetaInfoDir( *it, &mRootEntry ); + } + + mLoaded = true; +} + +DocEntry *DocMetaInfo::scanMetaInfoDir( const TQString &dirName, + DocEntry *parent ) +{ + TQDir dir( dirName ); + if ( !dir.exists() ) return 0; + + const TQFileInfoList *entryList = dir.entryInfoList(); + TQFileInfoListIterator it( *entryList ); + TQFileInfo *fi; + for( ; ( fi = it.current() ); ++it ) { + DocEntry *entry = 0; + if ( fi->isDir() && fi->fileName() != "." && fi->fileName() != ".." ) { + DocEntry *dirEntry = addDirEntry( TQDir( fi->absFilePath() ), parent ); + entry = scanMetaInfoDir( fi->absFilePath(), dirEntry ); + } else if ( fi->extension( false ) == "desktop" ) { + entry = addDocEntry( fi->absFilePath() ); + if ( parent && entry ) parent->addChild( entry ); + } + } + + return 0; +} + +DocEntry *DocMetaInfo::addDirEntry( const TQDir &dir, DocEntry *parent ) +{ + DocEntry *dirEntry = addDocEntry( dir.absPath() + "/.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.begin(); it != children.end(); ++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 ) +{ + kdDebug() << "DocMetaInfo::startTraverseEntries()" << endl; + traverser->setNotifyee( this ); + startTraverseEntry( &mRootEntry, traverser ); +} + +void DocMetaInfo::startTraverseEntry( DocEntry *entry, + DocEntryTraverser *traverser ) +{ +// kdDebug() << "DocMetaInfo::startTraverseEntry() " << entry->name() << endl; + + if ( !traverser ) { + kdDebug() << "DocMetaInfo::startTraverseEntry(): ERROR. No Traverser." + << endl; + return; + } + + if ( !entry ) { + kdDebug() << "DocMetaInfo::startTraverseEntry(): no entry." << endl; + endTraverseEntries( traverser ); + return; + } + + traverser->startProcess( entry ); +} + +void DocMetaInfo::endProcess( DocEntry *entry, DocEntryTraverser *traverser ) +{ +// kdDebug() << "DocMetaInfo::endProcess() " << entry->name() << endl; + + 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 ) +{ + kdDebug() << "DocMetaInfo::endTraverseEntries()" << endl; + + if ( !traverser ) { + kdDebug() << " no more traversers." << endl; + return; + } + + traverser->finishTraversal(); +} +// vim:ts=2:sw=2:et diff --git a/khelpcenter/docmetainfo.h b/khelpcenter/docmetainfo.h new file mode 100644 index 000000000..9b6871fa7 --- /dev/null +++ b/khelpcenter/docmetainfo.h @@ -0,0 +1,80 @@ +#ifndef DOCMETAINFO_H +#define DOCMETAINFO_H + +#include <tqstring.h> +#include <tqstringlist.h> +#include <tqvaluelist.h> +#include <tqdir.h> +#include <tqmap.h> + +#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 TQString &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 TQString languageName( const TQString &langcode ); + + protected: + DocEntry *scanMetaInfoDir( const TQString &filename, DocEntry *parent ); + DocEntry *addDirEntry( const TQDir &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; + + TQStringList mLanguages; + + TQMap<TQString,TQString> mLanguageNames; + + HTMLSearch *mHtmlSearch; + + static bool mLoaded; + + static DocMetaInfo *mSelf; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/fontdialog.cpp b/khelpcenter/fontdialog.cpp new file mode 100644 index 000000000..1f0cc8f68 --- /dev/null +++ b/khelpcenter/fontdialog.cpp @@ -0,0 +1,212 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2003 Frerich Raabe <[email protected]> + * + * 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 <tdeapplication.h> +#include <kcharsets.h> +#include <kcombobox.h> +#include <tdeconfig.h> +#include <tdefontcombo.h> +#include <tdehtmldefaults.h> +#include <tdelocale.h> +#include <knuminput.h> + +#include <tqgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqspinbox.h> + +using namespace KHC; + +FontDialog::FontDialog( TQWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n( "Font Configuration" ), + Ok | Cancel ) +{ + makeVBoxMainWidget(); + + setupFontSizesBox(); + setupFontTypesBox(); + setupFontEncodingBox(); + + load(); +} + +void FontDialog::slotOk() +{ + save(); + accept(); +} + +void FontDialog::setupFontSizesBox() +{ + TQGroupBox *gb = new TQGroupBox( i18n( "Sizes" ), mainWidget() ); + + TQGridLayout *layout = new TQGridLayout( gb ); + layout->setSpacing( KDialog::spacingHint() ); + layout->setMargin( KDialog::marginHint() * 2 ); + + TQLabel *lMinFontSize = new TQLabel( i18n( "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 ); + + TQLabel *lMedFontSize = new TQLabel( i18n( "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() +{ + TQGroupBox *gb = new TQGroupBox( i18n( "Fonts" ), mainWidget() ); + + TQGridLayout *layout = new TQGridLayout( gb ); + layout->setSpacing( KDialog::spacingHint() ); + layout->setMargin( KDialog::marginHint() * 2 ); + + TQLabel *lStandardFont = new TQLabel( i18n( "S&tandard font:" ), gb ); + layout->addWidget( lStandardFont, 0, 0 ); + m_standardFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_standardFontCombo, 0, 1 ); + lStandardFont->setBuddy( m_standardFontCombo ); + + TQLabel *lFixedFont = new TQLabel( i18n( "F&ixed font:" ), gb ); + layout->addWidget( lFixedFont, 1, 0 ); + m_fixedFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_fixedFontCombo, 1, 1 ); + lFixedFont->setBuddy( m_fixedFontCombo ); + + TQLabel *lSerifFont = new TQLabel( i18n( "S&erif font:" ), gb ); + layout->addWidget( lSerifFont, 2, 0 ); + m_serifFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_serifFontCombo, 2, 1 ); + lSerifFont->setBuddy( m_serifFontCombo ); + + TQLabel *lSansSerifFont = new TQLabel( i18n( "S&ans serif font:" ), gb ); + layout->addWidget( lSansSerifFont, 3, 0 ); + m_sansSerifFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_sansSerifFontCombo, 3, 1 ); + lSansSerifFont->setBuddy( m_sansSerifFontCombo ); + + TQLabel *lItalicFont = new TQLabel( i18n( "&Italic font:" ), gb ); + layout->addWidget( lItalicFont, 4, 0 ); + m_italicFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_italicFontCombo, 4, 1 ); + lItalicFont->setBuddy( m_italicFontCombo ); + + TQLabel *lFantasyFont = new TQLabel( i18n( "&Fantasy font:" ), gb ); + layout->addWidget( lFantasyFont, 5, 0 ); + m_fantasyFontCombo = new TDEFontCombo( gb ); + layout->addWidget( m_fantasyFontCombo, 5, 1 ); + lFantasyFont->setBuddy( m_fantasyFontCombo ); +} + +void FontDialog::setupFontEncodingBox() +{ + TQGroupBox *gb = new TQGroupBox( i18n( "Encoding" ), mainWidget() ); + + TQGridLayout *layout = new TQGridLayout( gb ); + layout->setSpacing( KDialog::spacingHint() ); + layout->setMargin( KDialog::marginHint() * 2 ); + + TQLabel *lDefaultEncoding = new TQLabel( i18n( "&Default encoding:" ), gb ); + layout->addWidget( lDefaultEncoding, 0, 0 ); + m_defaultEncoding = new KComboBox( false, gb ); + layout->addWidget( m_defaultEncoding, 0, 1 ); + TQStringList encodings = TDEGlobal::charsets()->availableEncodingNames(); + encodings.prepend( i18n( "Use Language Encoding" ) ); + m_defaultEncoding->insertStringList( encodings ); + lDefaultEncoding->setBuddy( m_defaultEncoding ); + + TQLabel *lFontSizeAdjustement = new TQLabel( i18n( "&Font size adjustment:" ), gb ); + layout->addWidget( lFontSizeAdjustement, 1, 0 ); + m_fontSizeAdjustement = new TQSpinBox( -5, 5, 1, gb ); + layout->addWidget( m_fontSizeAdjustement, 1, 1 ); + lFontSizeAdjustement->setBuddy( m_fontSizeAdjustement ); +} + +void FontDialog::load() +{ + TDEConfig *cfg = kapp->config(); + { + TDEConfigGroupSaver groupSaver( cfg, "HTML Settings" ); + + m_minFontSize->setValue( cfg->readNumEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE ) ); + m_medFontSize->setValue( cfg->readNumEntry( "MediumFontSize", 10 ) ); + + TQStringList fonts = cfg->readListEntry( "Fonts" ); + if ( fonts.isEmpty() ) + fonts << TDEGlobalSettings::generalFont().family() + << TDEGlobalSettings::fixedFont().family() + << HTML_DEFAULT_VIEW_SERIF_FONT + << HTML_DEFAULT_VIEW_SANSSERIF_FONT + << HTML_DEFAULT_VIEW_CURSIVE_FONT + << HTML_DEFAULT_VIEW_FANTASY_FONT; + + 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 ] ); + + m_defaultEncoding->setCurrentItem( cfg->readEntry( "DefaultEncoding" ) ); + m_fontSizeAdjustement->setValue( fonts[ 6 ].toInt() ); + } +} + +void FontDialog::save() +{ + TDEConfig *cfg = kapp->config(); + { + TDEConfigGroupSaver groupSaver( cfg, "General" ); + cfg->writeEntry( "UseKonqSettings", false ); + } + { + TDEConfigGroupSaver groupSaver( cfg, "HTML Settings" ); + + cfg->writeEntry( "MinimumFontSize", m_minFontSize->value() ); + cfg->writeEntry( "MediumFontSize", m_medFontSize->value() ); + + TQStringList fonts; + fonts << m_standardFontCombo->currentText() + << m_fixedFontCombo->currentText() + << m_serifFontCombo->currentText() + << m_sansSerifFontCombo->currentText() + << m_italicFontCombo->currentText() + << m_fantasyFontCombo->currentText() + << TQString::number( m_fontSizeAdjustement->value() ); + + cfg->writeEntry( "Fonts", fonts ); + + if ( m_defaultEncoding->currentText() == i18n( "Use Language Encoding" ) ) + cfg->writeEntry( "DefaultEncoding", TQString::null ); + else + cfg->writeEntry( "DefaultEncoding", m_defaultEncoding->currentText() ); + } + cfg->sync(); +} + +#include "fontdialog.moc" +// vim:ts=4:sw=4:noet diff --git a/khelpcenter/fontdialog.h b/khelpcenter/fontdialog.h new file mode 100644 index 000000000..ef06f2b84 --- /dev/null +++ b/khelpcenter/fontdialog.h @@ -0,0 +1,66 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2003 Frerich Raabe <[email protected]> + * + * 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 FONTDIALOG_H +#define FONTDIALOG_H + +#include <kdialogbase.h> + +class TQBoxLayout; +class TQSpinBox; + +class KComboBox; +class TDEFontCombo; +class KIntNumInput; + +namespace KHC { + +class FontDialog : public KDialogBase +{ + Q_OBJECT + public: + FontDialog( TQWidget *parent, const char *name = 0 ); + + protected slots: + virtual void slotOk(); + + private: + void setupFontSizesBox(); + void setupFontTypesBox(); + void setupFontEncodingBox(); + + void load(); + void save(); + + KIntNumInput *m_minFontSize; + KIntNumInput *m_medFontSize; + TDEFontCombo *m_standardFontCombo; + TDEFontCombo *m_fixedFontCombo; + TDEFontCombo *m_serifFontCombo; + TDEFontCombo *m_sansSerifFontCombo; + TDEFontCombo *m_italicFontCombo; + TDEFontCombo *m_fantasyFontCombo; + KComboBox *m_defaultEncoding; + TQSpinBox *m_fontSizeAdjustement; +}; + +} + +#endif // FONTDIALOG_H +// vim:ts=4:sw=4:noet diff --git a/khelpcenter/formatter.cpp b/khelpcenter/formatter.cpp new file mode 100644 index 000000000..7188ec214 --- /dev/null +++ b/khelpcenter/formatter.cpp @@ -0,0 +1,222 @@ +/* + This file is part of KHelpcenter. + + Copyright (c) 2003 Cornelius Schumacher <[email protected]> + + 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 <tdelocale.h> +#include <tdeglobal.h> +#include <kdebug.h> +#include <tdeconfig.h> +#include <kstandarddirs.h> + +#include <tqfile.h> +#include <tqtextstream.h> + +using namespace KHC; + +Formatter::Formatter() + : mHasTemplate( false ) +{ +} + +Formatter:: ~Formatter() +{ +} + +bool Formatter::readTemplates() +{ + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "Templates" ); + TQString mainTemplate = cfg->readEntry( "MainTemplate" ); + + if ( mainTemplate.isEmpty() ) { + mainTemplate = locate( "appdata", "maintemplate" ); + } + + if ( mainTemplate.isEmpty() ) { + kdWarning() << "Main template file name is empty." << endl; + return false; + } + + TQFile f( mainTemplate ); + if ( !f.open( IO_ReadOnly ) ) { + kdWarning() << "Unable to open main template file '" << mainTemplate + << "'." << endl; + return false; + } + + TQTextStream ts( &f ); + TQString line; + enum State { IDLE, SINGLELINE, MULTILINE }; + State state = IDLE; + TQString symbol; + TQString endMarker; + TQString value; + while( !( line = ts.readLine() ).isNull() ) { + switch ( state ) { + case IDLE: + if ( !line.isEmpty() && !line.startsWith( "#" ) ) { + int pos = line.find( "<<" ); + if ( pos >= 0 ) { + state = MULTILINE; + symbol = line.left( pos ).stripWhiteSpace(); + endMarker = line.mid( pos + 2 ).stripWhiteSpace(); + } else { + state = SINGLELINE; + symbol = line.stripWhiteSpace(); + } + } + 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: + kdError() << "Formatter::readTemplates(): Illegal state: " + << state << endl; + break; + } + } + + f.close(); + +#if 0 + TQMap<TQString,TQString>::ConstIterator it; + for( it = mSymbols.begin(); it != mSymbols.end(); ++it ) { + kdDebug() << "KEY: " << it.key() << endl; + kdDebug() << "VALUE: " << it.data() << endl; + } +#endif + + TQStringList requiredSymbols; + requiredSymbols << "HEADER" << "FOOTER"; + + bool success = true; + TQStringList::ConstIterator it2; + for( it2 = requiredSymbols.begin(); it2 != requiredSymbols.end(); ++it2 ) { + if ( !mSymbols.contains( *it2 ) ) { + success = false; + kdError() << "Symbol '" << *it2 << "' is missing from main template file." + << endl; + } + } + + if ( success ) mHasTemplate = true; + + return success; +} + +TQString Formatter::header( const TQString &title ) +{ + TQString s; + if ( mHasTemplate ) { + s = mSymbols[ "HEADER" ]; + s.replace( "--TITLE:--", title ); + } else { + s = "<html><head><title>" + title + "</title></head>\n<body>\n"; + } + return s; +} + +TQString Formatter::footer() +{ + if ( mHasTemplate ) { + return mSymbols[ "FOOTER" ]; + } else { + return "</body></html>"; + } +} + +TQString Formatter::separator() +{ +// return "<table width=100%><tr><td bgcolor=\"#7B8962\"> " +// "</td></tr></table>"; + return "<hr>"; +} + +TQString Formatter::docTitle( const TQString &title ) +{ + return "<h3><font color=\"red\">" + title + "</font></h3>"; +} + +TQString Formatter::sectionHeader( const TQString §ion ) +{ + return "<h2><font color=\"blue\">" + section + "</font></h2>"; +} + +TQString Formatter::processResult( const TQString &data ) +{ + TQString result; + + enum { Header, BodyTag, Body, Footer }; + + int state = Header; + + for( uint i = 0; i < data.length(); ++i ) { + TQChar c = data[i]; + switch ( state ) { + case Header: + if ( c == '<' && data.mid( i, 5 ).lower() == "<body" ) { + state = BodyTag; + i += 4; + } + break; + case BodyTag: + if ( c == '>' ) state = Body; + break; + case Body: + if ( c == '<' && data.mid( i, 7 ).lower() == "</body>" ) { + state = Footer; + } else { + result.append( c ); + } + break; + case Footer: + break; + default: + result.append( c ); + break; + } + } + + if ( state == Header ) return data; + else return result; +} + +TQString Formatter::paragraph( const TQString &str ) +{ + return "<p>" + str + "</p>"; +} + +TQString Formatter::title( const TQString &title ) +{ + return "<h2>" + title + "</h2>"; +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/formatter.h b/khelpcenter/formatter.h new file mode 100644 index 000000000..9710a0dca --- /dev/null +++ b/khelpcenter/formatter.h @@ -0,0 +1,55 @@ +/* + This file is part of KHelpcenter. + + Copyright (c) 2003 Cornelius Schumacher <[email protected]> + + 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 <tqstring.h> +#include <tqmap.h> + +namespace KHC { + +class Formatter +{ + public: + Formatter(); + virtual ~Formatter(); + + bool readTemplates(); + + virtual TQString header( const TQString &title ); + virtual TQString footer(); + virtual TQString separator(); + virtual TQString docTitle( const TQString & ); + virtual TQString sectionHeader( const TQString & ); + virtual TQString paragraph( const TQString & ); + virtual TQString title( const TQString & ); + + virtual TQString processResult( const TQString & ); + + private: + bool mHasTemplate; + TQMap<TQString,TQString> mSymbols; +}; + +} + +#endif + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/glossary.cpp b/khelpcenter/glossary.cpp new file mode 100644 index 000000000..0d25dbf79 --- /dev/null +++ b/khelpcenter/glossary.cpp @@ -0,0 +1,322 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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 <tdeapplication.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdemainwindow.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kstatusbar.h> + +#include <tqheader.h> + +#include <sys/stat.h> + +using namespace KHC; + +class SectionItem : public TDEListViewItem +{ + public: + SectionItem( TQListViewItem *parent, const TQString &text ) + : TDEListViewItem( parent, text ) + { + setOpen( false ); + } + + virtual void setOpen( bool open ) + { + TDEListViewItem::setOpen(open); + + setPixmap( 0, SmallIcon( TQString::fromLatin1( open ? "contents" : "contents2" ) ) ); + + } +}; + +class EntryItem : public TDEListViewItem +{ + public: + EntryItem( SectionItem *parent, const TQString &term, const TQString &id ) + : TDEListViewItem( parent, term ), + m_id( id ) + { + } + + TQString id() const { return m_id; } + + private: + TQString m_id; +}; + +Glossary::Glossary( TQWidget *parent ) : TDEListView( parent ) +{ + m_initialized = false; + + connect( this, TQT_SIGNAL( clicked( TQListViewItem * ) ), + this, TQT_SLOT( treeItemSelected( TQListViewItem * ) ) ); + connect( this, TQT_SIGNAL( returnPressed( TQListViewItem * ) ), + this, TQT_SLOT( treeItemSelected( TQListViewItem * ) ) ); + + setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + addColumn( TQString::null ); + header()->hide(); + setAllColumnsShowFocus( true ); + setRootIsDecorated( true ); + + m_byTopicItem = new TDEListViewItem( this, i18n( "By Topic" ) ); + m_byTopicItem->setPixmap( 0, SmallIcon( "help" ) ); + + m_alphabItem = new TDEListViewItem( this, i18n( "Alphabetically" ) ); + m_alphabItem->setPixmap( 0, SmallIcon( "charset" ) ); + + m_cacheFile = locateLocal( "cache", "help/glossary.xml" ); + + m_sourceFile = View::View::langLookup( TQString::fromLatin1( "khelpcenter/glossary/index.docbook" ) ); + + m_config = kapp->config(); + m_config->setGroup( "Glossary" ); + +} + +void Glossary::show() +{ + if ( !m_initialized ) { + if ( cacheStatus() == NeedRebuild ) + rebuildGlossaryCache(); + else + buildGlossaryTree(); + m_initialized = true; + } + TDEListView::show(); +} + +Glossary::~Glossary() +{ + m_glossEntries.setAutoDelete( true ); + m_glossEntries.clear(); +} + +const GlossaryEntry &Glossary::entry( const TQString &id ) const +{ + return *m_glossEntries[ id ]; +} + +Glossary::CacheStatus Glossary::cacheStatus() const +{ + if ( !TQFile::exists( m_cacheFile ) || + m_config->readPathEntry( "CachedGlossary" ) != m_sourceFile || + m_config->readNumEntry( "CachedGlossaryTimestamp" ) != glossaryCTime() ) + return NeedRebuild; + + return CacheOk; +} + +int Glossary::glossaryCTime() const +{ + struct stat stat_buf; + stat( TQFile::encodeName( m_sourceFile ).data(), &stat_buf ); + + return stat_buf.st_ctime; +} + +void Glossary::rebuildGlossaryCache() +{ + TDEMainWindow *mainWindow = dynamic_cast<TDEMainWindow *>( kapp->mainWidget() ); + Q_ASSERT( mainWindow ); + mainWindow->statusBar()->message( i18n( "Rebuilding cache..." ) ); + + TDEProcess *meinproc = new TDEProcess; + connect( meinproc, TQT_SIGNAL( processExited( TDEProcess * ) ), + this, TQT_SLOT( meinprocExited( TDEProcess * ) ) ); + + *meinproc << locate( "exe", TQString::fromLatin1( "meinproc" ) ); + *meinproc << TQString::fromLatin1( "--output" ) << m_cacheFile; + *meinproc << TQString::fromLatin1( "--stylesheet" ) + << locate( "data", TQString::fromLatin1( "khelpcenter/glossary.xslt" ) ); + *meinproc << m_sourceFile; + + meinproc->start( TDEProcess::NotifyOnExit ); +} + +void Glossary::meinprocExited( TDEProcess *meinproc ) +{ + delete meinproc; + + if ( !TQFile::exists( m_cacheFile ) ) + return; + + m_config->writePathEntry( "CachedGlossary", m_sourceFile ); + m_config->writeEntry( "CachedGlossaryTimestamp", glossaryCTime() ); + m_config->sync(); + + m_status = CacheOk; + + TDEMainWindow *mainWindow = dynamic_cast<TDEMainWindow *>( kapp->mainWidget() ); + Q_ASSERT( mainWindow ); + mainWindow->statusBar()->message( i18n( "Rebuilding cache... done." ), 2000 ); + + buildGlossaryTree(); +} + +void Glossary::buildGlossaryTree() +{ + TQFile cacheFile(m_cacheFile); + if ( !cacheFile.open( IO_ReadOnly ) ) + return; + + TQDomDocument doc; + if ( !doc.setContent( &cacheFile ) ) + return; + + TQDomNodeList sectionNodes = doc.documentElement().elementsByTagName( TQString::fromLatin1( "section" ) ); + for ( unsigned int i = 0; i < sectionNodes.count(); i++ ) { + TQDomElement sectionElement = sectionNodes.item( i ).toElement(); + TQString title = sectionElement.attribute( TQString::fromLatin1( "title" ) ); + SectionItem *topicSection = new SectionItem( m_byTopicItem, title ); + + TQDomNodeList entryNodes = sectionElement.elementsByTagName( TQString::fromLatin1( "entry" ) ); + for ( unsigned int j = 0; j < entryNodes.count(); j++ ) { + TQDomElement entryElement = entryNodes.item( j ).toElement(); + + TQString entryId = entryElement.attribute( TQString::fromLatin1( "id" ) ); + if ( entryId.isNull() ) + continue; + + TQDomElement termElement = childElement( entryElement, TQString::fromLatin1( "term" ) ); + TQString term = termElement.text().simplifyWhiteSpace(); + + EntryItem *entry = new EntryItem(topicSection, term, entryId ); + m_idDict.insert( entryId, entry ); + + SectionItem *alphabSection = 0L; + for ( TQListViewItemIterator it( m_alphabItem ); it.current(); it++ ) + if ( it.current()->text( 0 ) == term[ 0 ].upper() ) { + alphabSection = static_cast<SectionItem *>( it.current() ); + break; + } + + if ( !alphabSection ) + alphabSection = new SectionItem( m_alphabItem, term[ 0 ].upper() ); + + new EntryItem( alphabSection, term, entryId ); + + TQDomElement definitionElement = childElement( entryElement, TQString::fromLatin1( "definition" ) ); + TQString definition = definitionElement.text().simplifyWhiteSpace(); + + GlossaryEntryXRef::List seeAlso; + + TQDomElement referencesElement = childElement( entryElement, TQString::fromLatin1( "references" ) ); + TQDomNodeList referenceNodes = referencesElement.elementsByTagName( TQString::fromLatin1( "reference" ) ); + if ( referenceNodes.count() > 0 ) + for ( unsigned int k = 0; k < referenceNodes.count(); k++ ) { + TQDomElement referenceElement = referenceNodes.item( k ).toElement(); + + TQString term = referenceElement.attribute( TQString::fromLatin1( "term" ) ); + TQString id = referenceElement.attribute( TQString::fromLatin1( "id" ) ); + + seeAlso += GlossaryEntryXRef( term, id ); + } + + m_glossEntries.insert( entryId, new GlossaryEntry( term, definition, seeAlso ) ); + } + } +} + +void Glossary::treeItemSelected( TQListViewItem *item ) +{ + if ( !item ) + return; + + if ( EntryItem *i = dynamic_cast<EntryItem *>( item ) ) + emit entrySelected( entry( i->id() ) ); + + item->setOpen( !item->isOpen() ); +} + +TQDomElement Glossary::childElement( const TQDomElement &element, const TQString &name ) +{ + TQDomElement e; + for ( e = element.firstChild().toElement(); !e.isNull(); e = e.nextSibling().toElement() ) + if ( e.tagName() == name ) + break; + return e; +} + +TQString Glossary::entryToHtml( const GlossaryEntry &entry ) +{ + TQFile htmlFile( locate("data", "khelpcenter/glossary.html.in" ) ); + if (!htmlFile.open(IO_ReadOnly)) + return TQString( "<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'!" ) ); + + TQString seeAlso; + if (!entry.seeAlso().isEmpty()) { + seeAlso = i18n("See also: "); + GlossaryEntryXRef::List seeAlsos = entry.seeAlso(); + GlossaryEntryXRef::List::ConstIterator it = seeAlsos.begin(); + GlossaryEntryXRef::List::ConstIterator end = seeAlsos.end(); + for (; it != end; ++it) { + seeAlso += TQString::fromLatin1("<a href=\"glossentry:"); + seeAlso += (*it).id(); + seeAlso += TQString::fromLatin1("\">") + (*it).term(); + seeAlso += TQString::fromLatin1("</a>, "); + } + seeAlso = seeAlso.left(seeAlso.length() - 2); + } + + TQTextStream htmlStream(&htmlFile); + return htmlStream.read() + .arg( i18n( "KDE Glossary" ) ) + .arg( entry.term() ) + .arg( View::langLookup( "khelpcenter/konq.css" ) ) + .arg( View::langLookup( "khelpcenter/pointers.png" ) ) + .arg( View::langLookup( "khelpcenter/khelpcenter.png" ) ) + .arg( View::langLookup( "khelpcenter/lines.png" ) ) + .arg( entry.term() ) + .arg( entry.definition() ) + .arg( seeAlso) + .arg( View::langLookup( "khelpcenter/kdelogo2.png" ) ); +} + +void Glossary::slotSelectGlossEntry( const TQString &id ) +{ + EntryItem *newItem = m_idDict.find( id ); + if ( newItem == 0 ) + return; + + EntryItem *curItem = dynamic_cast<EntryItem *>( currentItem() ); + if ( curItem != 0 ) { + if ( curItem->id() == id ) + return; + curItem->parent()->setOpen( false ); + } + + setCurrentItem( newItem ); + ensureItemVisible( newItem ); +} + +#include "glossary.moc" +// vim:ts=4:sw=4:et diff --git a/khelpcenter/glossary.h b/khelpcenter/glossary.h new file mode 100644 index 000000000..616c51b86 --- /dev/null +++ b/khelpcenter/glossary.h @@ -0,0 +1,146 @@ +/* + * glossary.h - part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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 <tdelistview.h> + +#include <tqdict.h> +#include <tqdom.h> +#include <tqstringlist.h> + +class TDEConfig; +class TDEProcess; + +class EntryItem; + +namespace KHC { + +class GlossaryEntryXRef +{ + friend TQDataStream &operator>>( TQDataStream &, GlossaryEntryXRef & ); + public: + typedef TQValueList<GlossaryEntryXRef> List; + + GlossaryEntryXRef() {} + GlossaryEntryXRef( const TQString &term, const TQString &id ) : + m_term( term ), + m_id( id ) + { + } + + TQString term() const { return m_term; } + TQString id() const { return m_id; } + + private: + TQString m_term; + TQString m_id; +}; + +inline TQDataStream &operator<<( TQDataStream &stream, const GlossaryEntryXRef &e ) +{ + return stream << e.term() << e.id(); +} + +inline TQDataStream &operator>>( TQDataStream &stream, GlossaryEntryXRef &e ) +{ + return stream >> e.m_term >> e.m_id; +} + +class GlossaryEntry +{ + friend TQDataStream &operator>>( TQDataStream &, GlossaryEntry & ); + public: + GlossaryEntry() {} + GlossaryEntry( const TQString &term, const TQString &definition, + const GlossaryEntryXRef::List &seeAlso ) : + m_term( term ), + m_definition( definition ), + m_seeAlso( seeAlso ) + { + } + + TQString term() const { return m_term; } + TQString definition() const { return m_definition; } + GlossaryEntryXRef::List seeAlso() const { return m_seeAlso; } + + private: + TQString m_term; + TQString m_definition; + GlossaryEntryXRef::List m_seeAlso; +}; + +inline TQDataStream &operator<<( TQDataStream &stream, const GlossaryEntry &e ) +{ + return stream << e.term() << e.definition() << e.seeAlso(); +} + +inline TQDataStream &operator>>( TQDataStream &stream, GlossaryEntry &e ) +{ + return stream >> e.m_term >> e.m_definition >> e.m_seeAlso; +} + +class Glossary : public TDEListView +{ + Q_OBJECT + public: + Glossary( TQWidget *parent ); + virtual ~Glossary(); + + const GlossaryEntry &entry( const TQString &id ) const; + + static TQString entryToHtml( const GlossaryEntry &entry ); + + virtual void show(); + + public slots: + void slotSelectGlossEntry( const TQString &id ); + + signals: + void entrySelected( const GlossaryEntry &entry ); + + private slots: + void meinprocExited( TDEProcess *meinproc ); + void treeItemSelected( TQListViewItem *item ); + + private: + enum CacheStatus { NeedRebuild, CacheOk }; + + CacheStatus cacheStatus() const; + int glossaryCTime() const; + void rebuildGlossaryCache(); + void buildGlossaryTree(); + TQDomElement childElement( const TQDomElement &e, const TQString &name ); + + TDEConfig *m_config; + TQListViewItem *m_byTopicItem; + TQListViewItem *m_alphabItem; + TQString m_sourceFile; + TQString m_cacheFile; + CacheStatus m_status; + TQDict<GlossaryEntry> m_glossEntries; + TQDict<EntryItem> m_idDict; + bool m_initialized; +}; + +} + +#endif // KHC_GLOSSARY_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/glossary.html.in b/khelpcenter/glossary.html.in new file mode 100644 index 000000000..343d844c8 --- /dev/null +++ b/khelpcenter/glossary.html.in @@ -0,0 +1,95 @@ +<HTML> + +<HEAD> + <title>%1: %1</title> <!-- KDE Glossary: <Term> --> + <link rel="stylesheet" href="file:%1" type="text/css" /> <!-- konq.css --> +</HEAD> + +<BODY BGCOLOR=#3679AD LEFTMARGIN=0 TOPMARGIN=5> +<div style="position:absolute; left: 0px; top: 5px; right: 0px; bottom: 500px;"> +<TABLE BORDER=0 WIDTH=100% CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <COLGROUP> + <COL WIDTH=156> + <COL WIDTH=20> + <COL WIDTH=282> + <COL WIDTH=*> + </COLGROUP> + <TR HEIGHT=24> + <TD BGCOLOR=#505050 ALIGN=RIGHT><IMG WIDTH=70 HEIGHT=22 SRC="file:%1"></TD> <!-- pointers.png --> + <TD BGCOLOR=#505050 COLSPAN=3></TD> + </TR> + <TR> + <TD WIDTH=176 COLSPAN=2 ROWSPAN=2> </TD> + <TD BGCOLOR=#DDDDDD><IMG WIDTH=282 HEIGHT=77 SRC="file:%1"></TD> <!-- khelpcenter.png --> + <TD BGCOLOR=#DDDDDD BACKGROUND="file:%1"> </TD> <!-- lines.png --> + </TR> + + <TR> + + <TD COLSPAN=2 BGCOLOR=#505050 ALIGN=LEFT HEIGHT=22> + +<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <TR> + <TD HEIGHT=20 class="menu"> </TD> + </TR> +</TABLE> + </TD> + </TR> + + <TR> + <TD COLSPAN=2 WIDTH=176></TD> + <TD COLSPAN=2 class="shadow1" HEIGHT=9 COLSPAN=4></TD> + </TR> + <TR> + <TD COLSPAN=2 WIDTH=176></TD> + <TD COLSPAN=2 HEIGHT=46 COLSPAN=4></TD> + </TR> +</TABLE> + +<!-- end of header --> + + +<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> +<TR> + <TD WIDTH=114></TD> + <TD class="trans" BGCOLOR=#D0DFEC> + + <TABLE WIDTH= 100% BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <TR> + <TD HEIGHT=20 WIDTH=20> </TD> + <TD> </TD> + </TR> + <TR> + <TD WIDTH=20> </TD> + <TD VALIGN=TOP><H2>%1</H2>%1<P>%1</TD> + <TD WIDTH=20> </TD> + </TR> + <TR> + <TD HEIGHT=20 WIDTH=20> </TD> + <TD> </TD> + </TR> + +</TABLE> + + </TD> + <TD WIDTH=20> </TD> + </TR> + <TR> + <TD HEIGHT=44 COLSPAN=3> </TD> + </TR> +</TR> +</TABLE> +<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=0> +<TR> +<TD class="end" WIDTH=*> </TD> +<TD WIDTH=204><A HREF="http://www.kde.org"> <IMG WIDTH=204 BORDER=0 +HEIGHT=57 +SRC="file:%1"></A></TD> +</TR> +<TR> + <TD HEIGHT=50 COLSPAN=2> </TD> +</TR> +</TABLE> +</div> +</BODY> +</HTML> diff --git a/khelpcenter/glossary.xslt b/khelpcenter/glossary.xslt new file mode 100644 index 000000000..4be123a82 --- /dev/null +++ b/khelpcenter/glossary.xslt @@ -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> diff --git a/khelpcenter/history.cpp b/khelpcenter/history.cpp new file mode 100644 index 000000000..0f0085a02 --- /dev/null +++ b/khelpcenter/history.cpp @@ -0,0 +1,351 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe <[email protected]> + * + * 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 <tdeaction.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <tdemainwindow.h> +#include <tdepopupmenu.h> +#include <kstdguiitem.h> +#include <kstringhandler.h> + + + +using namespace KHC; + +History *History::m_instance = 0; + +History &History::self() +{ + if ( !m_instance ) + m_instance = new History; + return *m_instance; +} + +History::History() : TQObject(), + m_goBuffer( 0 ) +{ + m_entries.setAutoDelete( true ); +} + +History::~History() +{ +} + +void History::setupActions( TDEActionCollection *coll ) +{ + TQPair<KGuiItem, KGuiItem> backForward = KStdGuiItem::backAndForward(); + + m_backAction = new TDEToolBarPopupAction( backForward.first, ALT+Key_Left, + this, TQT_SLOT( back() ), coll, "back" ); + connect( m_backAction->popupMenu(), TQT_SIGNAL( activated( int ) ), + TQT_SLOT( backActivated( int ) ) ); + connect( m_backAction->popupMenu(), TQT_SIGNAL( aboutToShow() ), + TQT_SLOT( fillBackMenu() ) ); + m_backAction->setEnabled( false ); + + m_forwardAction = new TDEToolBarPopupAction( backForward.second, ALT+Key_Right, + this, TQT_SLOT( forward() ), coll, + "forward" ); + connect( m_forwardAction->popupMenu(), TQT_SIGNAL( activated( int ) ), + TQT_SLOT( forwardActivated( int ) ) ); + connect( m_forwardAction->popupMenu(), TQT_SIGNAL( aboutToShow() ), + TQT_SLOT( fillForwardMenu() ) ); + m_forwardAction->setEnabled( false ); +} + +void History::installMenuBarHook( TDEMainWindow *mainWindow ) +{ + TQPopupMenu *goMenu = dynamic_cast<TQPopupMenu *>( + mainWindow->guiFactory()->container( "go_web", mainWindow ) ); + if ( goMenu ) { + connect( goMenu, TQT_SIGNAL( aboutToShow() ), TQT_SLOT( fillGoMenu() ) ); + connect( goMenu, TQT_SIGNAL( activated( int ) ), + TQT_SLOT( goMenuActivated( int ) ) ); + m_goMenuIndex = goMenu->count(); + } +} + +void History::createEntry() +{ + kdDebug() << "History::createEntry()" << endl; + + // First, remove any forward history + Entry * current = m_entries.current(); + if (current) + { + m_entries.at( m_entries.count() - 1 ); // go to last one + for ( ; m_entries.current() != current ; ) + { + if ( !m_entries.removeLast() ) { // and remove from the end (faster and easier) + Q_ASSERT(0); + return; + } + else + m_entries.at( m_entries.count() - 1 ); + } + // Now current is the current again. + + // If current entry is empty reuse it. + if ( !current->view ) return; + } + + // Append a new entry + m_entries.append( new Entry ); // made current + Q_ASSERT( m_entries.at() == (int) m_entries.count() - 1 ); +} + +void History::updateCurrentEntry( View *view ) +{ + if ( m_entries.isEmpty() ) + return; + + KURL url = view->url(); + + Entry *current = m_entries.current(); + + TQDataStream stream( current->buffer, IO_WriteOnly ); + view->browserExtension()->saveState( stream ); + + current->view = view; + + if ( url.isEmpty() ) { + kdDebug() << "History::updateCurrentEntry(): internal url" << endl; + url = view->internalUrl(); + } + + kdDebug() << "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() +{ + kdDebug( 1400 ) << "History::back()" << endl; + goHistoryActivated( -1 ); +} + +void History::backActivated( int id ) +{ + kdDebug( 1400 ) << "History::backActivated(): id = " << id << endl; + goHistoryActivated( -( m_backAction->popupMenu()->indexOf( id ) + 1 ) ); +} + +void History::forward() +{ + kdDebug( 1400 ) << "History::forward()" << endl; + goHistoryActivated( 1 ); +} + +void History::forwardActivated( int id ) +{ + kdDebug( 1400 ) << "History::forwardActivated(): id = " << id << endl; + goHistoryActivated( m_forwardAction->popupMenu()->indexOf( id ) + 1 ); +} + +void History::goHistoryActivated( int steps ) +{ + kdDebug( 1400 ) << "History::goHistoryActivated(): m_goBuffer = " << m_goBuffer << endl; + if ( m_goBuffer ) + return; + m_goBuffer = steps; + TQTimer::singleShot( 0, this, TQT_SLOT( goHistoryDelayed() ) ); +} + +void History::goHistoryDelayed() +{ + kdDebug( 1400 ) << "History::goHistoryDelayed(): m_goBuffer = " << m_goBuffer << endl; + if ( !m_goBuffer ) + return; + int steps = m_goBuffer; + m_goBuffer = 0; + goHistory( steps ); +} + +void History::goHistory( int steps ) +{ + kdDebug() << "History::goHistory(): " << steps << endl; + + // If current entry is empty remove it. + Entry *current = m_entries.current(); + if ( current && !current->view ) m_entries.remove(); + + int newPos = m_entries.at() + steps; + + current = m_entries.at( newPos ); + if ( !current ) { + kdError() << "No History entry at position " << newPos << endl; + return; + } + + if ( !current->view ) { + kdWarning() << "Empty history entry." << endl; + return; + } + + if ( current->search ) { + kdDebug() << "History::goHistory(): search" << endl; + current->view->lastSearch(); + return; + } + + if ( current->url.protocol() == "khelpcenter" ) { + kdDebug() << "History::goHistory(): internal" << endl; + emit goInternalUrl( current->url ); + return; + } + + kdDebug() << "History::goHistory(): restore state" << endl; + + emit goUrl( current->url ); + + Entry h( *current ); + h.buffer.detach(); + + TQDataStream stream( h.buffer, IO_ReadOnly ); + + h.view->closeURL(); + updateCurrentEntry( h.view ); + h.view->browserExtension()->restoreState( stream ); + + updateActions(); +} + +void History::fillBackMenu() +{ + TQPopupMenu *menu = m_backAction->popupMenu(); + menu->clear(); + fillHistoryPopup( menu, true, false, false ); +} + +void History::fillForwardMenu() +{ + TQPopupMenu *menu = m_forwardAction->popupMenu(); + menu->clear(); + fillHistoryPopup( menu, false, true, false ); +} + +void History::fillGoMenu() +{ + TDEMainWindow *mainWindow = static_cast<TDEMainWindow *>( kapp->mainWidget() ); + TQPopupMenu *goMenu = dynamic_cast<TQPopupMenu *>( mainWindow->guiFactory()->container( TQString::fromLatin1( "go" ), mainWindow ) ); + if ( !goMenu || m_goMenuIndex == -1 ) + return; + + for ( int i = goMenu->count() - 1 ; i >= m_goMenuIndex; i-- ) + goMenu->removeItemAt( 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.at() + 4; + + // Forward not big enough ? + if ( m_entries.at() > (int)m_entries.count() - 4 ) + m_goMenuHistoryStartPos = m_entries.count() - 1; + } + Q_ASSERT( m_goMenuHistoryStartPos >= 0 && (uint)m_goMenuHistoryStartPos < m_entries.count() ); + m_goMenuHistoryCurrentPos = m_entries.at(); // for slotActivated + fillHistoryPopup( goMenu, false, false, true, m_goMenuHistoryStartPos ); +} + +void History::goMenuActivated( int id ) +{ + TDEMainWindow *mainWindow = static_cast<TDEMainWindow *>( kapp->mainWidget() ); + TQPopupMenu *goMenu = dynamic_cast<TQPopupMenu *>( mainWindow->guiFactory()->container( TQString::fromLatin1( "go" ), mainWindow ) ); + if ( !goMenu ) + return; + + // 1 for first item in the list, etc. + int index = goMenu->indexOf(id) - m_goMenuIndex + 1; + if ( index > 0 ) + { + kdDebug(1400) << "Item clicked has index " << index << endl; + // -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 :-) + kdDebug(1400) << "Emit activated with steps = " << steps << endl; + goHistory( steps ); + } +} + +void History::fillHistoryPopup( TQPopupMenu *popup, bool onlyBack, bool onlyForward, bool checkCurrentItem, uint startPos ) +{ + Q_ASSERT ( popup ); // kill me if this 0... :/ + + Entry * current = m_entries.current(); + TQPtrListIterator<Entry> it( m_entries ); + if (onlyBack || onlyForward) + { + it += m_entries.at(); // Jump to current item + if ( !onlyForward ) --it; else ++it; // And move off it + } else if ( startPos ) + it += startPos; // Jump to specified start pos + + uint i = 0; + while ( it.current() ) + { + TQString text = it.current()->title; + text = KStringHandler::csqueeze(text, 50); //CT: squeeze + text.replace( "&", "&&" ); + if ( checkCurrentItem && it.current() == current ) + { + int id = popup->insertItem( text ); // no pixmap if checked + popup->setItemChecked( id, true ); + } else + popup->insertItem( text ); + if ( ++i > 10 ) + break; + if ( !onlyForward ) --it; else ++it; + } +} + +bool History::canGoBack() const +{ + return m_entries.at() > 0; +} + +bool History::canGoForward() const +{ + return m_entries.at() != static_cast<int>( m_entries.count() ) - 1; +} + +#include "history.moc" +// vim:ts=2:sw=2:et diff --git a/khelpcenter/history.h b/khelpcenter/history.h new file mode 100644 index 000000000..c7c4c9532 --- /dev/null +++ b/khelpcenter/history.h @@ -0,0 +1,107 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe <[email protected]> + * + * 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 HISTORY_H +#define HISTORY_H + +#include <kurl.h> + +#include <tqobject.h> +#include <tqptrlist.h> + +class TDEActionCollection; +class TDEMainWindow; +class TDEToolBarPopupAction; +class TQPopupMenu; + +namespace KHC { + +class View; + +class History : public TQObject +{ + Q_OBJECT + public: + friend class foo; // to make gcc shut up + struct Entry + { + Entry() : view( 0 ), search( false ) {} + + View *view; + KURL url; + TQString title; + TQByteArray buffer; + bool search; + }; + + static History &self(); + + void setupActions( TDEActionCollection *coll ); + void updateActions(); + + void installMenuBarHook( TDEMainWindow *mainWindow ); + + void createEntry(); + void updateCurrentEntry( KHC::View *view ); + + signals: + void goInternalUrl( const KURL & ); + void goUrl( const KURL & ); + + private slots: + void backActivated( int id ); + void fillBackMenu(); + void forwardActivated( int id ); + void fillForwardMenu(); + void goMenuActivated( int id ); + 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(); + + bool canGoBack() const; + bool canGoForward() const; + void fillHistoryPopup( TQPopupMenu *, bool, bool, bool, uint = 0 ); + + static History *m_instance; + + TQPtrList<Entry> m_entries; + + + int m_goBuffer; + int m_goMenuIndex; + int m_goMenuHistoryStartPos; + int m_goMenuHistoryCurrentPos; + public: + TDEToolBarPopupAction *m_backAction; + TDEToolBarPopupAction *m_forwardAction; +}; + +} + +#endif // HISTORY_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/htmlsearch.cpp b/khelpcenter/htmlsearch.cpp new file mode 100644 index 000000000..72eaa432d --- /dev/null +++ b/khelpcenter/htmlsearch.cpp @@ -0,0 +1,61 @@ +#include <kdebug.h> +#include <tdeconfig.h> + +#include "docentry.h" + +#include "htmlsearch.h" +#include "htmlsearch.moc" + +using namespace KHC; + +HTMLSearch::HTMLSearch() +{ + mConfig = new TDEConfig("khelpcenterrc", true); + mConfig->setGroup( "htdig" ); +} + +HTMLSearch::~HTMLSearch() +{ + delete mConfig; +} + +void HTMLSearch::setupDocEntry( KHC::DocEntry *entry ) +{ +// kdDebug() << "HTMLSearch::setupDocEntry(): " << entry->name() << endl; + + if ( entry->searchMethod().lower() != "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(); +} + +TQString HTMLSearch::defaultSearch( KHC::DocEntry *entry ) +{ + TQString htsearch = "cgi:"; + htsearch += mConfig->readPathEntry( "htsearch" ); + htsearch += "?words=%k&method=and&format=-desc&config="; + htsearch += entry->identifier(); + + return htsearch; +} + +TQString HTMLSearch::defaultIndexer( KHC::DocEntry * ) +{ + TQString indexer = mConfig->readPathEntry( "indexer" ); + indexer += " --indexdir=%i %f"; + + return indexer; +} + +TQString HTMLSearch::defaultIndexTestFile( KHC::DocEntry *entry ) +{ + return entry->identifier() + ".exists"; +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/htmlsearch.h b/khelpcenter/htmlsearch.h new file mode 100644 index 000000000..1ca97488f --- /dev/null +++ b/khelpcenter/htmlsearch.h @@ -0,0 +1,33 @@ +#ifndef KHC_HTMLSEARCH_H +#define KHC_HTMLSEARCH_H + +#include <tqobject.h> +#include <tqstring.h> + +class TDEConfig; + +namespace KHC { + +class DocEntry; + +class HTMLSearch : public QObject +{ + Q_OBJECT + public: + HTMLSearch(); + ~HTMLSearch(); + + void setupDocEntry( KHC::DocEntry * ); + + TQString defaultSearch( KHC::DocEntry * ); + TQString defaultIndexer( KHC::DocEntry * ); + TQString defaultIndexTestFile( KHC::DocEntry * ); + + private: + TDEConfig *mConfig; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/htmlsearch/Makefile.am b/khelpcenter/htmlsearch/Makefile.am new file mode 100644 index 000000000..d4d00fb5f --- /dev/null +++ b/khelpcenter/htmlsearch/Makefile.am @@ -0,0 +1,39 @@ +khelpcenter_en_data_DATA = long.html short.html wrapper.html nomatch.html syntax.html +khelpcenter_en_datadir = $(kde_datadir)/khelpcenter/en + +star_DATA = star.png star_blank.png +stardir = $(kde_datadir)/khelpcenter/pics + +INCLUDES = $(all_includes) +METASOURCES = AUTO + +lib_LTLIBRARIES = libhtmlsearch.la libkcm_htmlsearch.la + +libhtmlsearch_la_SOURCES = htmlsearch.cpp progressdialog.cpp +libhtmlsearch_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libhtmlsearch_la_LIBADD = $(LIB_TDEIO) + +libkcm_htmlsearch_la_SOURCES = kcmhtmlsearch.cpp klangcombo.cpp ktagcombobox.cpp +libkcm_htmlsearch_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkcm_htmlsearch_la_LIBADD = $(LIB_TDEIO) + +noinst_HEADERS = kcmhtmlsearch.h htmlsearch.h + +xdg_apps_DATA = htmlsearch.desktop + +bin_PROGRAMS = tdehtmlindex + +wrapperdir = $(kde_datadir)/khelpcenter/ +wrapper_SCRIPTS = meinproc_wrapper + +tdehtmlindex_SOURCES = index.cpp +tdehtmlindex_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor +tdehtmlindex_LDADD = libhtmlsearch.la $(LIB_TDEUI) + +xpm_DATA = unchecked.xpm checked.xpm +xpmdir = $(kde_datadir)/khelpcenter/pics + +messages: + $(XGETTEXT) index.cpp $(libhtmlsearch_la_SOURCES) -o $(podir)/htmlsearch.pot + $(XGETTEXT) $(libkcm_htmlsearch_la_SOURCES) -o $(podir)/kcmhtmlsearch.pot + diff --git a/khelpcenter/htmlsearch/checked.xpm b/khelpcenter/htmlsearch/checked.xpm new file mode 100644 index 000000000..1ed190249 --- /dev/null +++ b/khelpcenter/htmlsearch/checked.xpm @@ -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+..+#+..", +"..+#+++++..+#+..", +"..+#++++++++#+..", +"..+##########+..", +"..++++++++++++..", +"................", +"................"}; diff --git a/khelpcenter/htmlsearch/htmlsearch.cpp b/khelpcenter/htmlsearch/htmlsearch.cpp new file mode 100644 index 000000000..5fd0f4640 --- /dev/null +++ b/khelpcenter/htmlsearch/htmlsearch.cpp @@ -0,0 +1,487 @@ +#include <tqregexp.h> +#include <tqdir.h> +#include <assert.h> + +#include <tdeapplication.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kprocess.h> +#include <tdelocale.h> +#include <tdeconfig.h> + + +#include "progressdialog.h" +#include "htmlsearch.moc" + + +HTMLSearch::HTMLSearch() + : TQObject(), _proc(0) +{ +} + + +TQString HTMLSearch::dataPath(const TQString& _lang) +{ + return kapp->dirs()->saveLocation("data", TQString("khelpcenter/%1").arg(_lang)); +} + + +void HTMLSearch::scanDir(const TQString& dir) +{ + assert( dir.at( dir.length() - 1 ) == '/' ); + + TQStringList::ConstIterator it; + + if ( TDEStandardDirs::exists( dir + "index.docbook" ) ) { + _files.append(dir + "index.docbook"); + progress->setFilesScanned(++_filesScanned); + } else { + TQDir d(dir, "*.html", TQDir::Name|TQDir::IgnoreCase, TQDir::Files | TQDir::Readable); + TQStringList const &list = d.entryList(); + TQString adir = d.canonicalPath () + "/"; + TQString file; + for (it=list.begin(); it != list.end(); ++it) + { + file = adir + *it; + if ( !_files.contains( file ) ) { + _files.append(file); + progress->setFilesScanned(++_filesScanned); + } + } + } + + TQDir d2(dir, TQString::null, TQDir::Name|TQDir::IgnoreCase, TQDir::Dirs); + TQStringList const &dlist = d2.entryList(); + for (it=dlist.begin(); it != dlist.end(); ++it) + if (*it != "." && *it != "..") + { + scanDir(dir + *it + "/"); + kapp->processEvents(); + } +} + + +bool HTMLSearch::saveFilesList(const TQString& _lang) +{ + TQStringList dirs; + + // throw away old files list + _files.clear(); + + // open config file + TDEConfig *config = new TDEConfig("khelpcenterrc"); + config->setGroup("Scope"); + + // add KDE help dirs + if (config->readBoolEntry("KDE", true)) + dirs = kapp->dirs()->findDirs("html", _lang + "/"); + kdDebug() << "got " << dirs.count() << " dirs\n"; + + // TODO: Man and Info!! + + // add local urls + TQStringList add = config->readListEntry("Paths"); + TQStringList::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); + + delete config; + + return true; +} + + +bool HTMLSearch::createConfig(const TQString& _lang) +{ + TQString fname = dataPath(_lang) + "/htdig.conf"; + + // locate the common dir + TQString wrapper = locate("data", TQString("khelpcenter/%1/wrapper.html").arg(_lang)); + if (wrapper.isEmpty()) + wrapper = locate("data", TQString("khelpcenter/en/wrapper.html")); + if (wrapper.isEmpty()) + return false; + wrapper = wrapper.left(wrapper.length() - 12); + + // locate the image dir + TQString 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 + // <[email protected]>. + TQString bad_words = i18n( "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" + "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" + "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" + "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" + "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" ); + + TQFile f; + f.setName( dataPath(_lang) + "/bad_words" ); + if (f.open(IO_WriteOnly)) + { + TQTextStream ts( &f ); + TQStringList words = TQStringList::split ( TQRegExp ( "[\n:]" ), + bad_words, false); + for ( TQStringList::ConstIterator it = words.begin(); + it != words.end(); ++it ) + ts << *it << endl; + f.close(); + } + + f.setName(fname); + if (f.open(IO_WriteOnly)) + { + kdDebug() << "Writing config for " << _lang << " to " << fname << endl; + + TQTextStream 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(TQString _lang, TQWidget *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 ------------------------------------------------------ + TDEConfig *config = new TDEConfig("khelpcenterrc", true); + TDEConfigGroupSaver saver(config, "htdig"); + TQString exe = config->readPathEntry("htdig", kapp->dirs()->findExe("htdig")); + + if (exe.isEmpty()) + { + delete config; + return false; + } + bool initial = true; + bool done = false; + int count = 0; + + _filesToDig = _files.count(); + progress->setFilesToDig(_filesToDig); + _filesDigged = 0; + + TQDir d; d.mkdir(dataPath(_lang)); + + while (!done) + { + // kill old process + delete _proc; + + // prepare new process + _proc = new TDEProcess(); + *_proc << exe << "-v" << "-c" << dataPath(_lang)+"/htdig.conf"; + if (initial) + { + *_proc << "-i"; + initial = false; + } + + kdDebug() << "Running htdig" << endl; + + connect(_proc, TQT_SIGNAL(receivedStdout(TDEProcess *,char*,int)), + this, TQT_SLOT(htdigStdout(TDEProcess *,char*,int))); + + connect(_proc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(htdigExited(TDEProcess *))); + + _htdigRunning = true; + + // write out file + TQFile f(dataPath(_lang)+"/files"); + if (f.open(IO_WriteOnly)) + { + TQTextStream 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 + { + kdDebug() << "Could not open `files` for writing" << endl; + delete config; + return false; + } + + + // execute htdig + _proc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout ); + + kapp->enter_loop(); + + if (!_proc->normalExit() || _proc->exitStatus() != 0) + { + delete _proc; + delete progress; + delete config; + return false; + } + + // _filesDigged += CHUNK_SIZE; + progress->setFilesDigged(_filesDigged); + kapp->processEvents(); + } + + progress->setState(2); + + // run htmerge ----------------------------------------------------- + exe = config->readPathEntry("htmerge", kapp->dirs()->findExe("htmerge")); + if (exe.isEmpty()) + { + delete config; + return false; + } + delete _proc; + _proc = new TDEProcess(); + *_proc << exe << "-c" << dataPath(_lang)+"/htdig.conf"; + + kdDebug() << "Running htmerge" << endl; + + connect(_proc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(htmergeExited(TDEProcess *))); + + _htmergeRunning = true; + + _proc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout); + + kapp->enter_loop(); + + if (!_proc->normalExit() || _proc->exitStatus() != 0) + { + delete _proc; + delete progress; + delete config; + return false; + } + + delete _proc; + + progress->setState(3); + kapp->processEvents(); + + delete progress; + delete config; + + return true; +} + + + +void HTMLSearch::htdigStdout(TDEProcess *, char *buffer, int len) +{ + TQString line = TQString(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(TDEProcess *p) +{ + kdDebug() << "htdig terminated " << p->exitStatus() << endl; + _htdigRunning = false; + kapp->exit_loop(); +} + + +void HTMLSearch::htmergeExited(TDEProcess *) +{ + kdDebug() << "htmerge terminated" << endl; + _htmergeRunning = false; + kapp->exit_loop(); +} + + +void HTMLSearch::htsearchStdout(TDEProcess *, char *buffer, int len) +{ + _searchResult += TQString::fromLocal8Bit(buffer,len); +} + + +void HTMLSearch::htsearchExited(TDEProcess *) +{ + kdDebug() << "htsearch terminated" << endl; + _htsearchRunning = false; + kapp->exit_loop(); +} + + +TQString HTMLSearch::search(TQString _lang, TQString words, TQString method, int matches, + TQString format, TQString sort) +{ + if (_lang == "C") + _lang = "en"; + + createConfig(_lang); + + TQString result = dataPath(_lang)+"/result.html"; + + // run htsearch ---------------------------------------------------- + TDEConfig *config = new TDEConfig("khelpcenterrc", true); + TDEConfigGroupSaver saver(config, "htdig"); + TQString exe = config->readPathEntry("htsearch", kapp->dirs()->findExe("htsearch")); + if (exe.isEmpty()) + { + delete config; + return TQString::null; + } + _proc = new TDEProcess(); + *_proc << exe << "-c" << dataPath(_lang)+"/htdig.conf" << + TQString("words=%1;method=%2;matchesperpage=%3;format=%4;sort=%5").arg(words).arg(method).arg(matches).arg(format).arg(sort); + + kdDebug() << "Running htsearch" << endl; + + connect(_proc, TQT_SIGNAL(receivedStdout(TDEProcess *,char*,int)), + this, TQT_SLOT(htsearchStdout(TDEProcess *,char*,int))); + connect(_proc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(htsearchExited(TDEProcess *))); + + _htsearchRunning = true; + _searchResult = ""; + + _proc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout); + + kapp->enter_loop(); + + if (!_proc->normalExit() || _proc->exitStatus() != 0) + { + kdDebug() << "Error running htsearch... returning now" << endl; + delete _proc; + delete config; + return TQString::null; + } + + delete _proc; + + // modify the search result + _searchResult = _searchResult.replace("http://localhost/", "file:/"); + _searchResult = _searchResult.replace("Content-type: text/html", TQString::null); + + // dump the search result + TQFile f(result); + if (f.open(IO_WriteOnly)) + { + TQTextStream ts(&f); + + ts << _searchResult << endl; + + f.close(); + delete config; + return result; + } + delete config; + return TQString::null; +} diff --git a/khelpcenter/htmlsearch/htmlsearch.desktop b/khelpcenter/htmlsearch/htmlsearch.desktop new file mode 100644 index 000000000..e70b40a96 --- /dev/null +++ b/khelpcenter/htmlsearch/htmlsearch.desktop @@ -0,0 +1,239 @@ +[Desktop Entry] +Exec=tdecmshell htmlsearch +Icon=help_index +Type=Application +DocPath=kcontrol/help-index.html + +X-TDE-ModuleType=Library +X-TDE-Library=htmlsearch +X-TDE-FactoryName=htmlsearch +X-TDE-ControlModuleType=User + +Name=Index +Name[af]=Indeks +Name[ar]=الفهرس +Name[az]=İndeks +Name[be]=Індэкс +Name[bg]=Индекс +Name[bn]=সূচি +Name[br]=Meneger +Name[bs]=Indeks +Name[ca]=Índex +Name[cs]=Rejstřík +Name[csb]=Indeks +Name[cy]=Mynegai +Name[da]=Indeks +Name[de]=Stichwortverzeichnis +Name[el]=Ευρετήριο +Name[eo]=Indekso +Name[es]=Índice +Name[et]=Indeks +Name[eu]=Indizea +Name[fa]=نمایه +Name[fi]=Hakemisto +Name[fy]=Yndeks +Name[ga]=Innéacs +Name[gl]=Índice +Name[he]=אינדקס +Name[hi]=सूची +Name[hr]=Indeks +Name[hu]=Keresési index +Name[id]=Indeks +Name[is]=Yfirlit +Name[it]=Indice +Name[ja]=インデックス +Name[ka]=ინდექსი +Name[kk]=Индекс +Name[km]=លិបិក្រម +Name[ko]=찾아보기 +Name[lo]=ດັດສະນີ +Name[lt]=Rodyklė +Name[lv]=Indekss +Name[mk]=Индекс +Name[mn]=Товчоон +Name[ms]=Indeks +Name[mt]=Indiċi +Name[nb]=Indeks +Name[ne]=अनुक्रमणिका +Name[nn]=Indeks +Name[nso]=Palo ya Bangwadi +Name[pa]=ਤਤਕਰਾ +Name[pl]=Indeks +Name[pt]=Índice +Name[pt_BR]=Índice +Name[ru]=Индекс +Name[rw]=Umubarendanga +Name[se]=Indeaksa +Name[sk]=Katalóg +Name[sl]=Indeks +Name[sr]=Индекс +Name[sr@Latn]=Indeks +Name[ss]=Indzikimba +Name[ta]=பொருளடக்கம் +Name[te]=సూచిక +Name[tg]=Феҳрист +Name[th]=ดัชนี +Name[tr]=İndeks +Name[tt]=İsemlek +Name[uk]=Індекс +Name[uz]=Indeks +Name[uz@cyrillic]=Индекс +Name[ven]=Mafhelelo a bugu +Name[vi]=Danh mục +Name[wa]=Indecse +Name[xh]=Isalathiso +Name[zh_CN]=索引 +Name[zh_TW]=索引 +Name[zu]=Uhlelo lokuqukethwe + +Comment=Index generation +Comment[af]=Indeks genereering +Comment[ar]=توليد الفهارس +Comment[az]=İndeks yaratma +Comment[be]=Стварэнне індэксу +Comment[bg]=Създаване на индекс +Comment[bn]=সূচি উত্পাদন +Comment[br]=Genel ar meneger +Comment[bs]=Pravljenje indeksa +Comment[ca]=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[eo]=Indekskreado +Comment[es]=Generación del índice +Comment[et]=Indeksi tekitamine +Comment[eu]=Indizea sortu +Comment[fa]=تولید نمایه +Comment[fi]=Hakemiston luonti +Comment[fr]=Génération d'index +Comment[fy]=Yndeksgeneraasje +Comment[gl]=Xeración de Índices +Comment[he]=יצירת אינדקס +Comment[hi]=सूची बनाएँ +Comment[hr]=Generiranje indeksa +Comment[hu]=Index létrehozása +Comment[id]=Pembuatan Index +Comment[is]=Yfirlitsgerð +Comment[it]=Generazione dell'indice +Comment[ja]=インデックスを生成 +Comment[ka]=ინდექსის შექმნა +Comment[kk]=Индексті құру +Comment[km]=ការបង្កើតលិបិក្រម +Comment[ko]=찾아보기 생성 +Comment[lo]=ສ້າງດັດສະນີ +Comment[lt]=Rodyklės generavimas +Comment[lv]=Indeksa ģenerēšana +Comment[mk]=Генерирање на индекс +Comment[mn]=Товчоон үүсгэх +Comment[ms]=Penjanaan indeks +Comment[mt]=Ġenerazzjoni tal-Indiċi +Comment[nb]=Indekslaging +Comment[nds]=Index maken +Comment[ne]=अनुक्रमणिका उत्पादन +Comment[nl]=Indexgeneratie +Comment[nn]=Indekslaging +Comment[nso]=Thlagiso ya Palo ya Bangwadi +Comment[oc]=Generacion de l'index +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[rw]=Irema ry'Umubarendanga +Comment[se]=Indeaksaráhkadeapmi +Comment[sk]=Generovanie katalógu +Comment[sl]=Ustvarjanje indeksa +Comment[sr]=Генерисање индекса +Comment[sr@Latn]=Generisanje indeksa +Comment[sv]=Indexskapare +Comment[ta]=பொருளடக்க இயக்கம் +Comment[te]=సూచిక ను తయారుచెయుట +Comment[tg]=Эҷоди феҳрист +Comment[th]=สร้างดัชนี +Comment[tr]=İndeks oluşturma +Comment[tt]=İsemlek ürçetü +Comment[uk]=Утворення індексу +Comment[uz]=Indeksni yaratish +Comment[uz@cyrillic]=Индексни яратиш +Comment[ven]=Murafho wa Index +Comment[vi]=Tạo danh mục +Comment[wa]=Ahiver l' indecse +Comment[xh]=Ulwenziwo Lwesalathiso +Comment[zh_CN]=索引生成 +Comment[zh_TW]=產生索引 +Comment[zu]=Ukugaywa kohlelo lokuqukethwe + +Keywords=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language +Keywords[ar]=مساعدة,HTML,بحث,فهرس,htdig,htsearch,htmerge,Scope,اللغة +Keywords[az]=Yardım,HTML,Axtar,İndeks,htdig,htmerge,Dil +Keywords[be]=Дапамога,Даведка,Пошук,Індэкс,Мова,Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language +Keywords[bg]=помощ, индекс, търсене, обхват, език, Help, HTML, Search, Index, htdig, htsearch, htmerge, Scope, Language +Keywords[ca]=Ajuda,HTML,Cerca,Índex,htdig,htsearch,htmerge,Scope,Llengua +Keywords[cs]=Nápověda,HTML,Hledat,Index,htdig,htsearch,htmerge,Rejstřík,Jazyk,Rozsah +Keywords[csb]=pòmòc,HTML,szëkôj,szëkba,indeks,htdig,htsearch,htmerge,òbjim,jãzëk +Keywords[cy]=Cymorth,HTML,Chwilio,Mynegai,htdig,htsearch,htmerge,Amrediad,Iaith +Keywords[da]=Hjælp,HTML,Søg,Indeks,htdig,htsearch,htmerge,Scope,Sprog +Keywords[de]=Hilfe,HTML,Suche,Index,Stichwortverzeichnis,htdig,Sprachen +Keywords[el]=Βοήθεια,HTML,Αναζήτηση,Ευρετήριο,htdig,htsearch,htmerge,Scope,Γλώσσα +Keywords[eo]=helpo,HTML,serĉo,indekso,htdig,htsearch,htmerge,areo,lingvo +Keywords[es]=Ayuda,HTML,Búsqueda,Índice,htdig,htsearch,htmerge,Ámbito,Idioma +Keywords[et]=abi,HTML,otsing,indeks,htdig,htsearch,htmerge,skoop,keel +Keywords[eu]=Laguntza,HTML,Bilatu,Indizea,htdig,htsearch,htmerge,Scope,Hizkuntza +Keywords[fa]=کمک، زنگام، جستجو، نمایه، htdig، htsearch، htmerge، دامنه، زبان +Keywords[fi]=Ohje,HTML,Etsi,Indeksi,htdig,htsearch,htmerge,Kieli +Keywords[fr]=aide,HTML,recherche,index,htdig,htsearch,htmerge,pays,langue +Keywords[fy]=help,html,zoeken,sykje,yndeks,htdig,htsearch,htmerge,scope,taal +Keywords[ga]=Cabhair,HTML,Cuardach,Innéacs,htdig,htsearch,htmerge,Scóip,Teanga +Keywords[gl]=Axuda,HTML,Procura,Índice,htdig,htsearch,htmerge,Scope,Lingua +Keywords[he]=עזרה,HTML,חיפוש,אינדקס,htdig,htsearch,htmerge,טווח,שפה,Help,Search,Index,htdig,htsearch,htmerge,Scope,Language +Keywords[hi]=मदद,एचटीएमएल,खोज,तालिका,एचटीडिक,एचटीसर्च,एचटीमर्ज,स्कोप,भाषा +Keywords[hr]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,Pomoć,Pretraživanje,Traži,Pretraga,Indeks,Opseg,Raspon,Jezik +Keywords[hu]=segítség,HTML,keresés,index,htdig,htsearch,htmerge,érvényességi kör,nyelv +Keywords[id]=Bantuan,HTML,Cari,Indeks,htdig,htsearch,htmerge,Scope,Language +Keywords[is]=Hjálp,HTML,leit,yfirlit,htdig,svæði,tungumál +Keywords[it]=aiuto,HTML,cerca,indice,htdig,htsearch,htmerge,scope,lingua +Keywords[ja]=ヘルプ,HTML,検索,インデックス,htdig,htsearch,htmerge,スコープ,言語 +Keywords[km]=ជំនួយ,HTML,ស្វែងរក,លិបិក្រម,htdig,htsearch,htmerge,វិសាលភាព,ភាសា +Keywords[lo]=ຊ່ວຍເຫລືອ,HTML,ຄົ້ນຫາດັດສະນີ,htdig,htsearch,htmerge,Scope,ພາສາ +Keywords[lt]=Pagalba,HTML,Paieška,Sąrašas,htdig,htsearch,htmerge,Sritis,Kalba +Keywords[lv]=Palīdzība,HTML,Meklēt,Indekss,htdig,htsearch,htmerge,Mērķis,Valoda +Keywords[mk]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language, Помош,Пребарувај,Индекс,Опфат,Јазик +Keywords[mn]=Тусламж,HTML,Хайх,Товчоо,Товчоон,htdig,Хэлүүд +Keywords[mt]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,Għajnuna,Fittex,Indiċi +Keywords[nb]=Hjelp,HTML,Søk,Indeks,htdig,htsearch,htmerge,språk +Keywords[nds]=Hülp,HTML,Söken,Index,htdig,htsearch,htmerge,Scope,Spraak +Keywords[ne]=मद्दत,HTML, खोजी, अनुक्रमणिका,htdig,htsearch,htmerge, क्षेत्र, भाषा +Keywords[nl]=help,html,zoeken,index,htdig,htsearch,htmerge,scope,taal +Keywords[nn]=hjelp,HTML,søk,indeks,htdig,htmerge,område,språk +Keywords[nso]=Thuso,HTML,Nyako,Palo ya Bangwadi,htdig,htnyako,htmerge,Scope,Leleme +Keywords[pa]=ਸਹਾਇਤਾ,HTML,Index,htdig,htsearch,htmerge,Scope,ਭਾਸ਼ਾ,ਖੋਜ +Keywords[pl]=pomoc,HTML,szukaj,indeks,htdig,htsearch,htmerge,zakres,język +Keywords[pt]=ajuda,html,procura,índice,htdig,htsearch,htmerge,âmbito,língua +Keywords[pt_BR]=Ajuda,HTML,Procurar,Índice,htdig,htsearch,htmerge,escopo,idioma +Keywords[ro]=ajutor,HTML,căutare,index,htdig,htsearch,htmerge,domeniu,limbaj +Keywords[rw]=Ifashayobora,HTML,Ishakisha,htgucukura,htgushakisha,htgukomatanya,Igishushanyombonera,Ururimi +Keywords[se]=veahkki,HTML,ohcan,indeaksa,indeksa,htdig,htmerge,gaska,giella +Keywords[sk]=Pomoc,HTML,Hľadať,Katalóg,Index,htdig,htsearch,htmerge,rozsah,jazyk,Pomocník +Keywords[sl]=Pomoč,HTML,iskanje,indeks,htdig,htsearch,htmerge,doseg,jezik +Keywords[sr]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,помоћ,претрага,индекс,језик,опсег +Keywords[sr@Latn]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,pomoć,pretraga,indeks,jezik,opseg +Keywords[sv]=Hjälp,HTML,Sök,Index,htdig,htsearch,htmerge,Omfång,Språk +Keywords[ta]=உதவி,HTML,தேடு,பொருளடக்கம்,htdig,htதேடு,htகல,வரையெல்லை,மொழி +Keywords[te]=సహాయం,హెచ్ టి ఎంఎల్,అన్వెషణ, సూచిక, హెచ్ టి డిగ్,హెచ్ టి అన్వెషణ,హెచ్ టి కలుపు, లక్ష్యము, భాష. +Keywords[th]=ช่วยเหลือ,HTML,ค้นหา,ดัชนี,htdig,htsearch,htmerge,Scope,ภาษา +Keywords[tr]=Yardım,HTML,Ara,İndeks,htdig,htmerge,Dil +Keywords[uk]=довідка,HTML,пошук,індекс,htdig,контекст,мова,htsearch,htmerge +Keywords[uz]=Yordam,HTML,Qidirish,Indeks,htdig,htsearch,htmerge,Til +Keywords[uz@cyrillic]=Ёрдам,HTML,Қидириш,Индекс,htdig,htsearch,htmerge,Тил +Keywords[ven]=Thuso,HTML,Toda,Mafhelelo,bwa ha ht,toda ha ht,thanganyo ya ht,zwaphanda,luambo +Keywords[vi]=Trợ giúp,HTML,Tìm kiếm,danh sách,htdig,htsearch,htmerge,Phạm vi,Ngôn ngữ +Keywords[wa]=Aide,Aidance,HTML,Trover,Indecse,htdig,htsearch,htmerge,Scope,Lingaedje +Keywords[xh]=Uncedo,HTML,Phendla,Isalathiso,htdig,htsearch,htmerge,Scope,Ulwimi +Keywords[zh_CN]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,帮助,查找,索引,范围,语言 +Keywords[zh_TW]=Help,HTML,Search,Index,htdig,htsearch,htmerge,Scope,Language,求助,搜尋,索引,語言 +Keywords[zu]=Usizo,HTML,Usesho,Uhlelo lokuqukethwe,htdig,htsearch,htmerge, Indawo elinganiselwe,Ulimi +Categories=Qt;TDE;X-TDE-settings-system; diff --git a/khelpcenter/htmlsearch/htmlsearch.h b/khelpcenter/htmlsearch/htmlsearch.h new file mode 100644 index 000000000..37d9bf39f --- /dev/null +++ b/khelpcenter/htmlsearch/htmlsearch.h @@ -0,0 +1,64 @@ +#ifndef __HTMLSEARCH_H__ +#define __HTMLSEARCH_H__ + + +#include <tqstring.h> +#include <tqstringlist.h> + + +class TQWidget; +class TQProgressDialog; + + +class TDEProcess; + + +class ProgressDialog; + + +class HTMLSearch : public QObject +{ + Q_OBJECT + +public: + + HTMLSearch(); + + bool generateIndex(TQString lang, TQWidget *parent=0); + + TQString search(TQString lang, TQString words, TQString method="and", int matches=10, + TQString format="builtin-long", TQString sort="score"); + + +protected slots: + + void htdigStdout(TDEProcess *proc, char *buffer, int buflen); + void htdigExited(TDEProcess *proc); + void htmergeExited(TDEProcess *proc); + void htsearchStdout(TDEProcess *proc, char *buffer, int buflen); + void htsearchExited(TDEProcess *proc); + + +protected: + + TQString dataPath(const TQString& lang); + + bool saveFilesList(const TQString& lang); + void scanDir(const TQString& dir); + + bool createConfig(const TQString& lang); + + +private: + + TQStringList _files; + TDEProcess *_proc; + int _filesToDig, _filesDigged, _filesScanned; + volatile bool _htdigRunning, _htmergeRunning, _htsearchRunning; + TQString _searchResult; + ProgressDialog *progress; + +}; + + +#endif diff --git a/khelpcenter/htmlsearch/index.cpp b/khelpcenter/htmlsearch/index.cpp new file mode 100644 index 000000000..680f9f4ab --- /dev/null +++ b/khelpcenter/htmlsearch/index.cpp @@ -0,0 +1,31 @@ + +#include <tdecmdlineargs.h> +#include <tdeaboutdata.h> +#include <tdeglobal.h> +#include <tdeapplication.h> + +#include "htmlsearch.h" + +static TDECmdLineOptions options[] = +{ + { "lang <lang>", I18N_NOOP("The language to index"), "en" }, + TDECmdLineLastOption // End of options. +}; + + +int main(int argc, char *argv[]) +{ + TDEAboutData aboutData( "tdehtmlindex", I18N_NOOP("KHtmlIndex"), + "", + I18N_NOOP("TDE Index generator for help files.")); + + TDECmdLineArgs::init(argc, argv, &aboutData); + TDECmdLineArgs::addCmdLineOptions( options ); + + TDEGlobal::locale()->setMainCatalogue("htmlsearch"); + TDEApplication app; + HTMLSearch search; + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + search.generateIndex(args->getOption("lang")); +} diff --git a/khelpcenter/htmlsearch/kcmhtmlsearch.cpp b/khelpcenter/htmlsearch/kcmhtmlsearch.cpp new file mode 100644 index 000000000..3db9c9895 --- /dev/null +++ b/khelpcenter/htmlsearch/kcmhtmlsearch.cpp @@ -0,0 +1,370 @@ +/** + * kcmhtmlsearch.cpp + * + * Copyright (c) 2000 Matthias H�lzer-Kl�pfel <[email protected]> + * + * 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 <tqlayout.h> +#include <kstandarddirs.h> +#include <tdelocale.h> +#include <kurllabel.h> +#include <tdeapplication.h> +#include <tqcheckbox.h> +#include <tqwhatsthis.h> +#include <tdefiledialog.h> +#include <kprocess.h> +#include "klangcombo.h" +#include <kurlrequester.h> +#include <klineedit.h> + +#include "kcmhtmlsearch.moc" + + +TDEHTMLSearchConfig::TDEHTMLSearchConfig(TQWidget *parent, const char *name) + : TDECModule(parent, name), indexProc(0) +{ + TQVBoxLayout *vbox = new TQVBoxLayout(this, 5); + + + TQGroupBox *gb = new TQGroupBox(i18n("ht://dig"), this); + vbox->addWidget(gb); + + TQGridLayout *grid = new TQGridLayout(gb, 3,2, 6,6); + + grid->addRowSpacing(0, gb->fontMetrics().lineSpacing()); + + TQLabel *l = new TQLabel(i18n("The fulltext search feature makes use of the " + "ht://dig HTML search engine. " + "You can get ht://dig at the"), gb); + l->setAlignment(TQLabel::WordBreak); + l->setMinimumSize(l->sizeHint()); + grid->addMultiCellWidget(l, 1, 1, 0, 1); + TQWhatsThis::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(TQLabel::AlignHCenter); + grid->addMultiCellWidget(url, 2,2, 0, 1); + connect(url, TQT_SIGNAL(leftClickedURL(const TQString&)), + this, TQT_SLOT(urlClicked(const TQString&))); + + gb = new TQGroupBox(i18n("Program Locations"), this); + + vbox->addWidget(gb); + grid = new TQGridLayout(gb, 4,2, 6,6); + grid->addRowSpacing(0, gb->fontMetrics().lineSpacing()); + + htdigBin = new KURLRequester(gb); + l = new TQLabel(htdigBin, i18n("ht&dig"), gb); + l->setBuddy( htdigBin ); + grid->addWidget(l, 1,0); + grid->addWidget(htdigBin, 1,1); + connect(htdigBin->lineEdit(), TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(configChanged())); + TQString wtstr = i18n( "Enter the path to your htdig program here, e.g. /usr/local/bin/htdig" ); + TQWhatsThis::add( htdigBin, wtstr ); + TQWhatsThis::add( l, wtstr ); + + htsearchBin = new KURLRequester(gb); + l = new TQLabel(htsearchBin, i18n("ht&search"), gb); + l->setBuddy( htsearchBin ); + grid->addWidget(l, 2,0); + grid->addWidget(htsearchBin, 2,1); + connect(htsearchBin->lineEdit(), TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(configChanged())); + wtstr = i18n( "Enter the path to your htsearch program here, e.g. /usr/local/bin/htsearch" ); + TQWhatsThis::add( htsearchBin, wtstr ); + TQWhatsThis::add( l, wtstr ); + + htmergeBin = new KURLRequester(gb); + l = new TQLabel(htmergeBin, i18n("ht&merge"), gb); + l->setBuddy( htmergeBin ); + grid->addWidget(l, 3,0); + grid->addWidget(htmergeBin, 3,1); + connect(htmergeBin->lineEdit(), TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(configChanged())); + wtstr = i18n( "Enter the path to your htmerge program here, e.g. /usr/local/bin/htmerge" ); + TQWhatsThis::add( htmergeBin, wtstr ); + TQWhatsThis::add( l, wtstr ); + + TQHBoxLayout *hbox = new TQHBoxLayout(vbox); + + gb = new TQGroupBox(i18n("Scope"), this); + hbox->addWidget(gb); + TQWhatsThis::add( gb, i18n( "Here you can select which parts of the documentation should be included in the fulltext search index. Available options are the TDE Help pages, the installed man pages, and the installed info pages. You can select any number of these." ) ); + + TQVBoxLayout *vvbox = new TQVBoxLayout(gb, 6,2); + vvbox->addSpacing(gb->fontMetrics().lineSpacing()); + + indexKDE = new TQCheckBox(i18n("&TDE help"), gb); + vvbox->addWidget(indexKDE); + connect(indexKDE, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); + + indexMan = new TQCheckBox(i18n("&Man pages"), gb); + vvbox->addWidget(indexMan); + indexMan->setEnabled(false), + connect(indexMan, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); + + indexInfo = new TQCheckBox(i18n("&Info pages"), gb); + vvbox->addWidget(indexInfo); + indexInfo->setEnabled(false); + connect(indexInfo, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); + + gb = new TQGroupBox(i18n("Additional Search Paths"), this); + hbox->addWidget(gb); + TQWhatsThis::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 TQGridLayout(gb, 4,3, 6,2); + grid->addRowSpacing(0, gb->fontMetrics().lineSpacing()); + + addButton = new TQPushButton(i18n("Add..."), gb); + grid->addWidget(addButton, 1,0); + + delButton = new TQPushButton(i18n("Delete"), gb); + grid->addWidget(delButton, 2,0); + + searchPaths = new TDEListBox(gb); + grid->addMultiCellWidget(searchPaths, 1,3, 1,1); + grid->setRowStretch(2,2); + + gb = new TQGroupBox(i18n("Language Settings"), this); + vbox->addWidget(gb); + TQWhatsThis::add(gb, i18n("Here you can select the language you want to create the index for.")); + language = new KLanguageCombo(gb); + l = new TQLabel(language, i18n("&Language"), gb); + vvbox = new TQVBoxLayout(gb, 6,2); + vvbox->addSpacing(gb->fontMetrics().lineSpacing()); + hbox = new TQHBoxLayout(vvbox, 6); + hbox->addWidget(l); + hbox->addWidget(language,1); + hbox->addStretch(1); + + loadLanguages(); + + vbox->addStretch(1); + + runButton = new TQPushButton(i18n("Generate Index..."), this); + TQWhatsThis::add( runButton, i18n( "Click this button to generate the index for the fulltext search." ) ); + runButton->setFixedSize(runButton->sizeHint()); + vbox->addWidget(runButton, AlignRight); + connect(runButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(generateIndex())); + + connect(addButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(addClicked())); + connect(delButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(delClicked())); + connect(searchPaths, TQT_SIGNAL(highlighted(const TQString &)), + this, TQT_SLOT(pathSelected(const TQString &))); + + checkButtons(); + + load(); +} + + +void TDEHTMLSearchConfig::loadLanguages() +{ + // clear the list + language->clear(); + + // add all languages to the list + TQStringList langs = TDEGlobal::dirs()->findAllResources("locale", + TQString::fromLatin1("*/entry.desktop")); + langs.sort(); + + for (TQStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it) + { + KSimpleConfig entry(*it); + entry.setGroup(TQString::fromLatin1("KCM Locale")); + TQString name = entry.readEntry(TQString::fromLatin1("Name"), TDEGlobal::locale()->translate("without name")); + + TQString path = *it; + int index = path.findRev('/'); + path = path.left(index); + index = path.findRev('/'); + path = path.mid(index+1); + language->insertLanguage(path, name); + } +} + + +TQString TDEHTMLSearchConfig::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 TDE documentation as well as other system documentation like man and info pages." ); +} + + +void TDEHTMLSearchConfig::pathSelected(const TQString &) +{ + checkButtons(); +} + + +void TDEHTMLSearchConfig::checkButtons() +{ + + delButton->setEnabled(searchPaths->currentItem() >= 0); +} + + +void TDEHTMLSearchConfig::addClicked() +{ + TQString 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 TDEHTMLSearchConfig::delClicked() +{ + searchPaths->removeItem(searchPaths->currentItem()); + checkButtons(); + configChanged(); +} + + +TDEHTMLSearchConfig::~TDEHTMLSearchConfig() +{ +} + + +void TDEHTMLSearchConfig::configChanged() +{ + emit changed(true); +} + + +void TDEHTMLSearchConfig::load() +{ + TDEConfig *config = new TDEConfig("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->readBoolEntry("KDE", true)); + indexMan->setChecked(config->readBoolEntry("Man", false)); + indexInfo->setChecked(config->readBoolEntry("Info", false)); + + TQStringList l = config->readPathListEntry("Paths"); + searchPaths->clear(); + TQStringList::Iterator it; + for (it=l.begin(); it != l.end(); ++it) + searchPaths->insertItem(*it); + + config->setGroup("Locale"); + TQString lang = config->readEntry("Search Language", TDEGlobal::locale()->language()); + language->setCurrentItem(lang); + + emit changed(false); +} + + +void TDEHTMLSearchConfig::save() +{ + TDEConfig *config= new TDEConfig("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()); + + TQStringList 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 TDEHTMLSearchConfig::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(TDEGlobal::locale()->language()); + + emit changed(true); +} + + +void TDEHTMLSearchConfig::urlClicked(const TQString &url) +{ + kapp->invokeBrowser(url); +} + + +void TDEHTMLSearchConfig::generateIndex() +{ + save(); + + TQString exe = kapp->dirs()->findExe("tdehtmlindex"); + if (exe.isEmpty()) + return; + + delete indexProc; + + indexProc = new TDEProcess; + *indexProc << exe << "--lang" << language->currentTag(); + + connect(indexProc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(indexTerminated(TDEProcess *))); + + runButton->setEnabled(false); + + indexProc->start(); +} + + +void TDEHTMLSearchConfig::indexTerminated(TDEProcess *) +{ + runButton->setEnabled(true); +} + + +extern "C" +{ + KDE_EXPORT TDECModule *create_htmlsearch(TQWidget *parent, const char *name) + { + TDEGlobal::locale()->insertCatalogue("kcmhtmlsearch"); + return new TDEHTMLSearchConfig(parent, name); + }; +} diff --git a/khelpcenter/htmlsearch/kcmhtmlsearch.h b/khelpcenter/htmlsearch/kcmhtmlsearch.h new file mode 100644 index 000000000..28445437a --- /dev/null +++ b/khelpcenter/htmlsearch/kcmhtmlsearch.h @@ -0,0 +1,81 @@ +/** + * kcmhtmlsearch.h + * + * Copyright (c) 2000 Matthias H�lzer-Kl�pfel <[email protected]> + * + * 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__ + + +#include <tdecmodule.h> + + +class TQLineEdit; +class TQCheckBox; +class TQPushButton; +class TDEListBox; +class TDEProcess; +class KLanguageCombo; +class KURLRequester; + +class TDEHTMLSearchConfig : public TDECModule +{ + Q_OBJECT + +public: + + TDEHTMLSearchConfig(TQWidget *parent = 0L, const char *name = 0L); + virtual ~TDEHTMLSearchConfig(); + + void load(); + void save(); + void defaults(); + + TQString quickHelp() const; + + int buttons(); + + +protected slots: + + void configChanged(); + void addClicked(); + void delClicked(); + void pathSelected(const TQString &); + void urlClicked(const TQString&); + void generateIndex(); + + void indexTerminated(TDEProcess *proc); + + +private: + + void checkButtons(); + void loadLanguages(); + + KURLRequester *htdigBin, *htsearchBin, *htmergeBin; + TQCheckBox *indexKDE, *indexMan, *indexInfo; + TQPushButton *addButton, *delButton, *runButton; + TDEListBox *searchPaths; + KLanguageCombo *language; + + TDEProcess *indexProc; + +}; + +#endif diff --git a/khelpcenter/htmlsearch/klangcombo.cpp b/khelpcenter/htmlsearch/klangcombo.cpp new file mode 100644 index 000000000..308109d12 --- /dev/null +++ b/khelpcenter/htmlsearch/klangcombo.cpp @@ -0,0 +1,52 @@ +/* + * klangcombo.cpp - Adds some methods for inserting languages. + * + * Copyright (c) 1999-2000 Hans Petter Bieker <[email protected]> + * + * 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 <tqiconset.h> + +#include <kstandarddirs.h> + +#include "klangcombo.h" +#include "klangcombo.moc" + +KLanguageCombo::~KLanguageCombo () +{ +} + +KLanguageCombo::KLanguageCombo (TQWidget * parent, const char *name) + : KTagComboBox(parent, name) +{ +} + +void KLanguageCombo::insertLanguage(const TQString& path, const TQString& name, const TQString& sub, const TQString &submenu, int index) +{ + TQString output = name + TQString::fromLatin1(" (") + path + TQString::fromLatin1(")"); + TQPixmap flag(locate("locale", sub + path + TQString::fromLatin1("/flag.png"))); + insertItem(TQIconSet(flag), output, path, submenu, index); +} + +void KLanguageCombo::changeLanguage(const TQString& name, int i) +{ + if (i < 0 || i >= count()) return; + TQString output = name + TQString::fromLatin1(" (") + tag(i) + TQString::fromLatin1(")"); + changeItem(output, i); +} diff --git a/khelpcenter/htmlsearch/klangcombo.h b/khelpcenter/htmlsearch/klangcombo.h new file mode 100644 index 000000000..4ca6e2f3b --- /dev/null +++ b/khelpcenter/htmlsearch/klangcombo.h @@ -0,0 +1,47 @@ +/* + * klangcombo.h - Adds some methods for inserting languages. + * + * Copyright (c) 1999-2000 Hans Petter Bieker <[email protected]> + * + * 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 menues. + */ +class KLanguageCombo : public KTagComboBox +{ + Q_OBJECT + +public: + KLanguageCombo(TQWidget *parent=0, const char *name=0); + ~KLanguageCombo(); + + void insertLanguage(const TQString& path, const TQString& name, const TQString& sub = TQString::null, const TQString &submenu = TQString::null, int index = -1); + void changeLanguage(const TQString& name, int i); +}; + +#endif diff --git a/khelpcenter/htmlsearch/ktagcombobox.cpp b/khelpcenter/htmlsearch/ktagcombobox.cpp new file mode 100644 index 000000000..b3c70915c --- /dev/null +++ b/khelpcenter/htmlsearch/ktagcombobox.cpp @@ -0,0 +1,252 @@ +/* + * ktagcombobox.cpp - A combobox with support for submenues, icons and tags + * + * Copyright (c) 1999-2000 Hans Petter Bieker <[email protected]> + * + * 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 <tqpainter.h> +#include <tqpopupmenu.h> + +#include <kdebug.h> + +#include "ktagcombobox.h" +#include "ktagcombobox.moc" + +KTagComboBox::~KTagComboBox () +{ + delete popup; + delete tags; +} + +KTagComboBox::KTagComboBox (TQWidget * parent, const char *name) + : TQComboBox(parent, name), + popup(0), + old_popup(0) +{ + tags = new TQStringList; + + clear(); +} + +void KTagComboBox::popupMenu() +{ + popup->popup( mapToGlobal( TQPoint(0,0) ), current ); +} + +void KTagComboBox::keyPressEvent( TQKeyEvent *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( TQMouseEvent * ) +{ + 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 TQPopupMenu(this); + connect( popup, TQT_SIGNAL(activated(int)), + TQT_SLOT(internalActivate(int)) ); + connect( popup, TQT_SIGNAL(highlighted(int)), + TQT_SLOT(internalHighlight(int)) ); +} + +int KTagComboBox::count() const +{ + return tags->count(); +} + +static inline void checkInsertPos(TQPopupMenu *popup, const TQString & 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 TQPopupMenu *checkInsertIndex(TQPopupMenu *popup, const TQStringList *tags, const TQString &submenu) +{ + int pos = tags->findIndex(submenu); + + TQPopupMenu *pi = 0; + if (pos != -1) + { + TQMenuItem *p = popup->findItem(pos); + pi = p?p->popup():0; + } + if (!pi) pi = popup; + + return pi; +} + +void KTagComboBox::insertItem(const TQIconSet& icon, const TQString &text, const TQString &tag, const TQString &submenu, int index ) +{ + TQPopupMenu *pi = checkInsertIndex(popup, tags, submenu); + checkInsertPos(pi, text, index); + pi->insertItem(icon, text, count(), index); + tags->append(tag); +} + +void KTagComboBox::insertItem(const TQString &text, const TQString &tag, const TQString &submenu, int index ) +{ + TQPopupMenu *pi = checkInsertIndex(popup, tags, submenu); + checkInsertPos(pi, text, index); + pi->insertItem(text, count(), index); + tags->append(tag); +} + +void KTagComboBox::insertSeparator(const TQString &submenu, int index) +{ + TQPopupMenu *pi = checkInsertIndex(popup, tags, submenu); + pi->insertSeparator(index); + tags->append(TQString::null); +} + +void KTagComboBox::insertSubmenu(const TQString &text, const TQString &tag, const TQString &submenu, int index) +{ + TQPopupMenu *pi = checkInsertIndex(popup, tags, submenu); + TQPopupMenu *p = new TQPopupMenu(pi); + checkInsertPos(pi, text, index); + pi->insertItem(text, p, count(), index); + tags->append(tag); + connect( p, TQT_SIGNAL(activated(int)), + TQT_SLOT(internalActivate(int)) ); + connect( p, TQT_SIGNAL(highlighted(int)), + TQT_SLOT(internalHighlight(int)) ); +} + +void KTagComboBox::paintEvent( TQPaintEvent * ev) +{ + TQComboBox::paintEvent(ev); + + TQPainter p (this); + + // Text + TQRect 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 + TQIconSet *icon = popup->iconSet( this->current ); + if (icon) { + TQPixmap pm = icon->pixmap(); + p.drawPixmap( 4, (height()-pm.height())/2, pm ); + } +} + +bool KTagComboBox::containsTag( const TQString &str ) const +{ + return tags-.contains(str) > 0; +} + +TQString KTagComboBox::currentTag() const +{ + return *tags->at(currentItem()); +} + +TQString KTagComboBox::tag(int i) const +{ + if (i < 0 || i >= count()) + { + kdDebug() << "KTagComboBox::tag(), unknown tag " << i << endl; + return TQString::null; + } + 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 TQString &code) +{ + int i = tags->findIndex(code); + if (code.isNull()) + i = 0; + if (i != -1) + setCurrentItem(i); +} + +void KTagComboBox::setFont( const TQFont &font ) +{ + TQComboBox::setFont( font ); + popup->setFont( font ); +} diff --git a/khelpcenter/htmlsearch/ktagcombobox.h b/khelpcenter/htmlsearch/ktagcombobox.h new file mode 100644 index 000000000..df58120ce --- /dev/null +++ b/khelpcenter/htmlsearch/ktagcombobox.h @@ -0,0 +1,92 @@ +/* + * ktagcombobox.h - A combobox with support for submenues, icons and tags + * + * Copyright (c) 1999-2000 Hans Petter Bieker <[email protected]> + * + * 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 <tqcombobox.h> + +class TQPopupMenu; + +/* + * This class should be just like qcombobox, but it should be possible + * to have have a TQIconSet for each entry, and each entry should have a tag. + * + * It has also support for sub menues. + */ +class KTagComboBox : public QComboBox +{ + Q_OBJECT + +public: + KTagComboBox(TQWidget *parent=0, const char *name=0); + ~KTagComboBox(); + + void insertItem(const TQIconSet& icon, const TQString &text, const TQString &tag, const TQString &submenu = TQString::null, int index=-1 ); + void insertItem(const TQString &text, const TQString &tag, const TQString &submenu = TQString::null, int index=-1 ); + void insertSeparator(const TQString &submenu = TQString::null, int index=-1 ); + void insertSubmenu(const TQString &text, const TQString &tag, const TQString &submenu = TQString::null, int index=-1); + + int count() const; + void clear(); + + /* + * Tag of the selected item + */ + TQString currentTag() const; + TQString tag ( int i ) const; + bool containsTag (const TQString &str ) const; + + /* + * Set the current item + */ + int currentItem() const; + void setCurrentItem(int i); + void setCurrentItem(const TQString &code); + + // widget stuff + virtual void setFont( const TQFont & ); + +signals: + void activated( int index ); + void highlighted( int index ); + +private slots: + void internalActivate( int ); + void internalHighlight( int ); + +protected: + void paintEvent( TQPaintEvent * ); + void mousePressEvent( TQMouseEvent * ); + void keyPressEvent( TQKeyEvent *e ); + void popupMenu(); + +private: + // work space for the new class + TQStringList *tags; + TQPopupMenu *popup, *old_popup; + int current; +}; + +#endif diff --git a/khelpcenter/htmlsearch/long.html b/khelpcenter/htmlsearch/long.html new file mode 100644 index 000000000..1d0fa4cec --- /dev/null +++ b/khelpcenter/htmlsearch/long.html @@ -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> + diff --git a/khelpcenter/htmlsearch/meinproc_wrapper b/khelpcenter/htmlsearch/meinproc_wrapper new file mode 100644 index 000000000..239cf7462 --- /dev/null +++ b/khelpcenter/htmlsearch/meinproc_wrapper @@ -0,0 +1,4 @@ +#! /bin/sh + +file=`echo $3 | sed -e "s#http://localhost/#/#; s#file:/*#/#"` +meinproc --htdig $file diff --git a/khelpcenter/htmlsearch/nomatch.html b/khelpcenter/htmlsearch/nomatch.html new file mode 100644 index 000000000..305927030 --- /dev/null +++ b/khelpcenter/htmlsearch/nomatch.html @@ -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> diff --git a/khelpcenter/htmlsearch/progressdialog.cpp b/khelpcenter/htmlsearch/progressdialog.cpp new file mode 100644 index 000000000..33a783127 --- /dev/null +++ b/khelpcenter/htmlsearch/progressdialog.cpp @@ -0,0 +1,76 @@ +#include <tqlayout.h> +#include <tqlabel.h> + + +#include <tdelocale.h> +#include <kprogress.h> +#include <kstandarddirs.h> + + +#include "progressdialog.moc" + + +ProgressDialog::ProgressDialog(TQWidget *parent, const char *name) + : KDialogBase(KDialogBase::Plain, i18n("Generating Index"), Cancel, Cancel, + parent, name, false) +{ + TQGridLayout *grid = new TQGridLayout(plainPage(), 5,3, spacingHint()); + + TQLabel *l = new TQLabel(i18n("Scanning for files"), plainPage()); + grid->addMultiCellWidget(l, 0,0, 1,2); + + filesScanned = new TQLabel(plainPage()); + grid->addWidget(filesScanned, 1,2); + setFilesScanned(0); + + check1 = new TQLabel(plainPage()); + grid->addWidget(check1, 0,0); + + l = new TQLabel(i18n("Extracting search terms"), plainPage()); + grid->addMultiCellWidget(l, 2,2, 1,2); + + bar = new KProgress(plainPage()); + grid->addWidget(bar, 3,2); + + check2 = new TQLabel(plainPage()); + grid->addWidget(check2, 2,0); + + l = new TQLabel(i18n("Generating index..."), plainPage()); + grid->addMultiCellWidget(l, 4,4, 1,2); + + check3 = new TQLabel(plainPage()); + grid->addWidget(check3, 4,0); + + setState(0); + + setMinimumWidth(300); +} + + +void ProgressDialog::setFilesScanned(int n) +{ + filesScanned->setText(i18n("Files processed: %1").arg(n)); +} + + +void ProgressDialog::setFilesToDig(int n) +{ + bar->setTotalSteps(n); +} + + +void ProgressDialog::setFilesDigged(int n) +{ + bar->setProgress(n); +} + + +void ProgressDialog::setState(int n) +{ + TQPixmap unchecked = TQPixmap(locate("data", "khelpcenter/pics/unchecked.xpm")); + TQPixmap checked = TQPixmap(locate("data", "khelpcenter/pics/checked.xpm")); + + check1->setPixmap( n > 0 ? checked : unchecked); + check2->setPixmap( n > 1 ? checked : unchecked); + check3->setPixmap( n > 2 ? checked : unchecked); +} diff --git a/khelpcenter/htmlsearch/progressdialog.h b/khelpcenter/htmlsearch/progressdialog.h new file mode 100644 index 000000000..9ab5660d9 --- /dev/null +++ b/khelpcenter/htmlsearch/progressdialog.h @@ -0,0 +1,35 @@ +#ifndef __PROGRESS_DIALOG_H__ +#define __PROGRESS_DIALOG_H__ + + +#include <kdialogbase.h> + + +class TQLabel; +class KProgress; + + +class ProgressDialog : public KDialogBase +{ + + Q_OBJECT + +public: + + ProgressDialog(TQWidget *parent=0, const char *name=0); + + void setFilesScanned(int s); + void setFilesToDig(int d); + void setFilesDigged(int d); + + void setState(int n); + +private: + + TQLabel *filesScanned, *check1, *check2, *check3; + KProgress *bar; + +}; + + +#endif diff --git a/khelpcenter/htmlsearch/short.html b/khelpcenter/htmlsearch/short.html new file mode 100644 index 000000000..e3e5e447f --- /dev/null +++ b/khelpcenter/htmlsearch/short.html @@ -0,0 +1 @@ +$(STARSRIGHT) <strong><a href="$&(URL)">$&(TITLE)</a></strong><br> diff --git a/khelpcenter/htmlsearch/star.png b/khelpcenter/htmlsearch/star.png Binary files differnew file mode 100644 index 000000000..5e7615871 --- /dev/null +++ b/khelpcenter/htmlsearch/star.png diff --git a/khelpcenter/htmlsearch/star_blank.png b/khelpcenter/htmlsearch/star_blank.png Binary files differnew file mode 100644 index 000000000..2689281af --- /dev/null +++ b/khelpcenter/htmlsearch/star_blank.png diff --git a/khelpcenter/htmlsearch/syntax.html b/khelpcenter/htmlsearch/syntax.html new file mode 100644 index 000000000..e724fd90c --- /dev/null +++ b/khelpcenter/htmlsearch/syntax.html @@ -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> + diff --git a/khelpcenter/htmlsearch/unchecked.xpm b/khelpcenter/htmlsearch/unchecked.xpm new file mode 100644 index 000000000..e447281a9 --- /dev/null +++ b/khelpcenter/htmlsearch/unchecked.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char*unchecked[]={ +"16 16 3 1", +"# c #000000", +"+ c #ffffff", +". c None", +"................", +"................", +"..++++++++++++..", +"..+##########+..", +"..+#++++++++#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#++++++++#+..", +"..+##########+..", +"..++++++++++++..", +"................", +"................"}; diff --git a/khelpcenter/htmlsearch/wrapper.html b/khelpcenter/htmlsearch/wrapper.html new file mode 100644 index 000000000..251266ded --- /dev/null +++ b/khelpcenter/htmlsearch/wrapper.html @@ -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> diff --git a/khelpcenter/htmlsearchconfig.cpp b/khelpcenter/htmlsearchconfig.cpp new file mode 100644 index 000000000..a9eef3b41 --- /dev/null +++ b/khelpcenter/htmlsearchconfig.cpp @@ -0,0 +1,151 @@ +/** + * kcmhtmlsearch.cpp + * + * Copyright (c) 2000 Matthias H�lzer-Kl�pfel <[email protected]> + * + * 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 <tqlayout.h> +#include <tqwhatsthis.h> + +#include <kdebug.h> +#include <kstandarddirs.h> +#include <tdelocale.h> +#include <kurllabel.h> +#include <tdeapplication.h> +#include <tdefiledialog.h> +#include <kurlrequester.h> +#include <klineedit.h> + +#include "htmlsearchconfig.h" +#include "htmlsearchconfig.moc" + +namespace KHC { + +HtmlSearchConfig::HtmlSearchConfig(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQVBoxLayout *vbox = new TQVBoxLayout(this, 5); + + + TQGroupBox *gb = new TQGroupBox(i18n("ht://dig"), this); + vbox->addWidget(gb); + + TQGridLayout *grid = new TQGridLayout(gb, 3,2, 6,6); + + grid->addRowSpacing(0, gb->fontMetrics().lineSpacing()); + + TQLabel *l = new TQLabel(i18n("The fulltext search feature makes use of the " + "ht://dig HTML search engine. " + "You can get ht://dig at the"), gb); + l->setAlignment(TQLabel::WordBreak); + l->setMinimumSize(l->sizeHint()); + grid->addMultiCellWidget(l, 1, 1, 0, 1); + TQWhatsThis::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(TQLabel::AlignHCenter); + grid->addMultiCellWidget(url, 2,2, 0, 1); + connect(url, TQT_SIGNAL(leftClickedURL(const TQString&)), + this, TQT_SLOT(urlClicked(const TQString&))); + + gb = new TQGroupBox(i18n("Program Locations"), this); + + vbox->addWidget(gb); + grid = new TQGridLayout(gb, 4,2, 6,6); + grid->addRowSpacing(0, gb->fontMetrics().lineSpacing()); + + mHtsearchUrl = new KURLRequester(gb); + l = new TQLabel(mHtsearchUrl, i18n("htsearch:"), gb); + l->setBuddy( mHtsearchUrl ); + grid->addWidget(l, 1,0); + grid->addWidget(mHtsearchUrl, 1,1); + connect( mHtsearchUrl->lineEdit(), TQT_SIGNAL( textChanged( const TQString & ) ), + TQT_SIGNAL( changed() ) ); + TQString wtstr = i18n( "Enter the URL of the htsearch CGI program." ); + TQWhatsThis::add( mHtsearchUrl, wtstr ); + TQWhatsThis::add( l, wtstr ); + + mIndexerBin = new KURLRequester(gb); + l = new TQLabel(mIndexerBin, i18n("Indexer:"), gb); + l->setBuddy( mIndexerBin ); + grid->addWidget(l, 2,0); + grid->addWidget(mIndexerBin, 2,1); + connect( mIndexerBin->lineEdit(), TQT_SIGNAL( textChanged( const TQString & ) ), + TQT_SIGNAL( changed() ) ); + wtstr = i18n( "Enter the path to your htdig indexer program here." ); + TQWhatsThis::add( mIndexerBin, wtstr ); + TQWhatsThis::add( l, wtstr ); + + mDbDir = new KURLRequester(gb); + mDbDir->setMode( KFile::Directory | KFile::LocalOnly ); + l = new TQLabel(mDbDir, i18n("htdig database:"), gb); + l->setBuddy( mDbDir ); + grid->addWidget(l, 3,0); + grid->addWidget(mDbDir, 3,1); + connect( mDbDir->lineEdit(), TQT_SIGNAL( textChanged( const TQString & ) ), + TQT_SIGNAL( changed() ) ); + wtstr = i18n( "Enter the path to the htdig database folder." ); + TQWhatsThis::add( mDbDir, wtstr ); + TQWhatsThis::add( l, wtstr ); +} + +HtmlSearchConfig::~HtmlSearchConfig() +{ + kdDebug() << "~HtmlSearchConfig()" << endl; +} + +void HtmlSearchConfig::makeReadOnly() +{ + mHtsearchUrl->setEnabled( false ); + mIndexerBin->setEnabled( false ); + mDbDir->setEnabled( false ); +} + +void HtmlSearchConfig::load( TDEConfig *config ) +{ + config->setGroup("htdig"); + + mHtsearchUrl->lineEdit()->setText(config->readPathEntry("htsearch", kapp->dirs()->findExe("htsearch"))); + mIndexerBin->lineEdit()->setText(config->readPathEntry("indexer")); + mDbDir->lineEdit()->setText(config->readPathEntry("dbdir", "/opt/www/htdig/db/" ) ); +} + +void HtmlSearchConfig::save( TDEConfig *config ) +{ + config->setGroup("htdig"); + + config->writePathEntry("htsearch", mHtsearchUrl->lineEdit()->text()); + config->writePathEntry("indexer", mIndexerBin->lineEdit()->text()); + config->writePathEntry("dbdir", mDbDir->lineEdit()->text()); +} + +void HtmlSearchConfig::defaults() +{ + mHtsearchUrl->lineEdit()->setText(kapp->dirs()->findExe("htsearch")); + mIndexerBin->lineEdit()->setText(""); + mDbDir->lineEdit()->setText("/opt/www/htdig/db/" ); +} + +void HtmlSearchConfig::urlClicked(const TQString &url) +{ + kapp->invokeBrowser(url); +} + +} // End namespace KHC +// vim:ts=2:sw=2:et diff --git a/khelpcenter/htmlsearchconfig.h b/khelpcenter/htmlsearchconfig.h new file mode 100644 index 000000000..7f5742b1e --- /dev/null +++ b/khelpcenter/htmlsearchconfig.h @@ -0,0 +1,58 @@ +/** + * This file is part of KHelpCenter + * + * Copyright (c) 2000 Matthias H�lzer-Kl�pfel <[email protected]> + * + * 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 <tqwidget.h> + +class KURLRequester; +class TDEConfig; + +namespace KHC { + +class HtmlSearchConfig : public TQWidget +{ + Q_OBJECT + public: + HtmlSearchConfig(TQWidget *parent = 0L, const char *name = 0L); + virtual ~HtmlSearchConfig(); + + void load( TDEConfig * ); + void save( TDEConfig * ); + void defaults(); + void makeReadOnly(); + + signals: + void changed(); + + protected slots: + void urlClicked(const TQString&); + + private: + KURLRequester *mHtsearchUrl; + KURLRequester *mIndexerBin; + KURLRequester *mDbDir; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/index.html.in b/khelpcenter/index.html.in new file mode 100644 index 000000000..45cbd3dc7 --- /dev/null +++ b/khelpcenter/index.html.in @@ -0,0 +1,42 @@ +<html> + + <head> + <title>%1</title> + <link rel="stylesheet" href="help:/common/tde-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-konqueror.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> diff --git a/khelpcenter/infotree.cpp b/khelpcenter/infotree.cpp new file mode 100644 index 000000000..c0c5a9d9e --- /dev/null +++ b/khelpcenter/infotree.cpp @@ -0,0 +1,184 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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 <tdeapplication.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <tdelistview.h> +#include <tdelocale.h> +#include <kstandarddirs.h> +#include <kurl.h> + +#include <tqfile.h> +#include <tqtextstream.h> + +#include <stdlib.h> // for getenv() + +using namespace KHC; + +class InfoCategoryItem : public NavigatorItem +{ + public: + InfoCategoryItem( NavigatorItem *parent, const TQString &text ); + + virtual void setOpen( bool open ); +}; + +class InfoNodeItem : public NavigatorItem +{ + public: + InfoNodeItem( InfoCategoryItem *parent, const TQString &text ); +}; + +InfoCategoryItem::InfoCategoryItem( NavigatorItem *parent, const TQString &text ) + : NavigatorItem( new DocEntry( text ), parent ) +{ + setAutoDeleteDocEntry( true ); + setOpen( false ); +// kdDebug(1400) << "Got category: " << text << endl; +} + +void InfoCategoryItem::setOpen( bool open ) +{ + NavigatorItem::setOpen( open ); + + if ( open && childCount() > 0 ) setPixmap( 0, SmallIcon( "contents" ) ); + else setPixmap( 0, SmallIcon( "contents2" ) ); +} + +InfoNodeItem::InfoNodeItem( InfoCategoryItem *parent, const TQString &text ) + : NavigatorItem( new DocEntry( text ), parent ) +{ + setAutoDeleteDocEntry( true ); +// kdDebug( 1400 ) << "Created info node item: " << text << endl; +} + +InfoTree::InfoTree( TQObject *parent, const char *name ) + : TreeBuilder( parent, name ), + m_parentItem( 0 ) +{ +} + +void InfoTree::build( NavigatorItem *parent ) +{ + kdDebug( 1400 ) << "Populating info tree." << endl; + + 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 ); + + TDEConfig *cfg = kapp->config(); + cfg->setGroup( "Info pages" ); + TQStringList infoDirFiles = cfg->readListEntry( "Search paths" ); + // Default paths taken fron tdebase/tdeioslave/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"; + } + + TQString infoPath = ::getenv( "INFOPATH" ); + if ( !infoPath.isEmpty() ) + infoDirFiles += TQStringList::split( ':', infoPath ); + + TQStringList::ConstIterator it = infoDirFiles.begin(); + TQStringList::ConstIterator end = infoDirFiles.end(); + for ( ; it != end; ++it ) { + TQString infoDirFileName = *it + "/dir"; + if ( TQFile::exists( infoDirFileName ) ) + parseInfoDirFile( infoDirFileName ); + } + + m_alphabItem->sortChildItems( 0, true /* ascending */ ); +} + +void InfoTree::parseInfoDirFile( const TQString &infoDirFileName ) +{ + kdDebug( 1400 ) << "Parsing info dir file " << infoDirFileName << endl; + + TQFile infoDirFile( infoDirFileName ); + if ( !infoDirFile.open( IO_ReadOnly ) ) + return; + + TQTextStream stream( &infoDirFile ); + // Skip introduction blurb. + while ( !stream.eof() && !stream.readLine().startsWith( "* Menu:" ) ); + + while ( !stream.eof() ) { + TQString s = stream.readLine(); + if ( s.stripWhiteSpace().isEmpty() ) + continue; + + InfoCategoryItem *catItem = new InfoCategoryItem( m_categoryItem, s ); + while ( !stream.eof() && !s.stripWhiteSpace().isEmpty() ) { + s = stream.readLine(); + if ( s[ 0 ] == '*' ) { + const int colon = s.find( ":" ); + const int openBrace = s.find( "(", colon ); + const int closeBrace = s.find( ")", openBrace ); + const int dot = s.find( ".", closeBrace ); + + TQString appName = s.mid( 2, colon - 2 ); + TQString url = "info:/" + s.mid( openBrace + 1, closeBrace - openBrace - 1 ); + if ( dot - closeBrace > 1 ) + url += "/" + s.mid( closeBrace + 1, dot - closeBrace - 1 ); + else + url += "/Top"; + + InfoNodeItem *item = new InfoNodeItem( catItem, appName ); + item->entry()->setUrl( url ); + + InfoCategoryItem *alphabSection = 0; + for ( TQListViewItem* it=m_alphabItem->firstChild(); it; it=it->nextSibling() ) { + if ( it->text( 0 ) == appName[ 0 ].upper() ) { + alphabSection = static_cast<InfoCategoryItem *>( it ); + break; + } + } + + if ( alphabSection == 0 ) + alphabSection = new InfoCategoryItem( m_alphabItem, appName[ 0 ].upper() ); + + item = new InfoNodeItem( alphabSection, appName ); + item->entry()->setUrl( url ); + } + } + } + infoDirFile.close(); +} + +#include "infotree.moc" +// vim:ts=2:sw=2:et diff --git a/khelpcenter/infotree.h b/khelpcenter/infotree.h new file mode 100644 index 000000000..ab1911818 --- /dev/null +++ b/khelpcenter/infotree.h @@ -0,0 +1,48 @@ +/* + * infotree.h - part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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" + +class TQListViewItem; + +namespace KHC +{ + class NavigatorItem; + class InfoTree : public TreeBuilder + { + Q_OBJECT + public: + InfoTree( TQObject *parent, const char *name = 0 ); + + virtual void build( NavigatorItem *parentItem ); + + private: + void parseInfoDirFile( const TQString &fileName ); + + NavigatorItem *m_parentItem; + NavigatorItem *m_alphabItem; + NavigatorItem *m_categoryItem; + }; +} + +#endif // KHC_INFOTREE_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/intro.html.in b/khelpcenter/intro.html.in new file mode 100644 index 000000000..64528084a --- /dev/null +++ b/khelpcenter/intro.html.in @@ -0,0 +1,141 @@ +<HTML> + +<HEAD> + <title>%1</title> + <link rel="stylesheet" href="file:%1" type="text/css" /> +</HEAD> + +<BODY BGCOLOR=#3679AD LEFTMARGIN=0 TOPMARGIN=5> +<div style="position:absolute; left: 0px; top: 5px; right: 0px; bottom: 500px;"> +<TABLE BORDER=0 WIDTH=100% CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <COLGROUP> + <COL WIDTH=156> + <COL WIDTH=20> + <COL WIDTH=282> + <COL WIDTH=*> + </COLGROUP> + <TR HEIGHT=24> + <TD BGCOLOR=#505050 ALIGN=RIGHT><IMG WIDTH=70 HEIGHT=22 SRC="file:%1"></TD> + <TD BGCOLOR=#505050 COLSPAN=3></TD> + </TR> + <TR> + <TD WIDTH=176 COLSPAN=2 ROWSPAN=2> </TD> + <TD CLASS="caption" ALIGN="center" WIDTH=282 HEIGHT=77 BACKGROUND="file:%1">%1</TD> + <TD BGCOLOR=#DDDDDD BACKGROUND="file:%1"> </TD> + </TR> + + <TR> + + <TD COLSPAN=2 BGCOLOR=#505050 ALIGN=RIGHT HEIGHT=22> + +<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <TR> + <TD HEIGHT=20 class="menu"> </TD> + </TR> +</TABLE> + </TD> + </TR> + + <TR> + <TD COLSPAN=2 WIDTH=176></TD> + <TD COLSPAN=2 class="shadow1" HEIGHT=9 COLSPAN=4></TD> + </TR> + <TR> + <TD COLSPAN=2 WIDTH=176></TD> + <TD COLSPAN=2 HEIGHT=46 COLSPAN=4></TD> + </TR> +</TABLE> + +<!-- end of header --> + + +<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> +<TR> + <TD WIDTH=114></TD> + <TD class="trans" BGCOLOR=#D0DFEC> + + <TABLE WIDTH= 100% BORDER=0 CELLPADDING=0 CELLSPACING=0 CELLPADDING=0> + <TR> + <TD HEIGHT=20 WIDTH=20> </TD> + <TD> </TD> + </TR> + <TR> + <TD WIDTH=20> </TD> + <TD VALIGN=TOP> + +<!-- here comes the content --> + + +<h1>%1</h1> <!-- Welcome to the Trinity Desktop Environment --> + +<p><i>%1</i></p> <!-- The TDE team welcomes you to user-friendly Unix-like computing --> + +<p>%1</p><!-- TDE is a graphical desktop environment for UNIX workstations. The +Trinity Desktop Environment combines ease of use, contemporary functionality, and +professional graphical design along with the technical advantages of +the Unix-like operating systems. --> + +<ul> +<li><p><a href="help:/khelpcenter/index.html?anchor=whatistde">%1</a></p></li> +<li><p><a href="help:/khelpcenter/index.html?anchor=contact">%1</a></p></li> <!-- Contacting the TDE Project --> +<li><p><a href="help:/khelpcenter/index.html?anchor=support">%1</a></p></li> <!-- Supporting the TDE Project --> +<li><p><a href="help:/khelpcenter/index.html?anchor=links">%1</a></p></li> <!-- Useful links --> +</ul> + +<h2>%1</h2> <!-- Getting the most out of TDE --> + +<h3>%1</h3> <!-- General Documentation --> + +<ul> +<li><p><a href="help:/khelpcenter/quickstart/index.html" target="_top">%1</a></p></li> +<li><p><a href="help:/khelpcenter/userguide/index.html" target="_top">%1</a></p></li> +<li><p><a href="help:/khelpcenter/faq/index.html" target="_top">%1</a></p></li> +</ul> + +<h3>%1</h3> + +<ul> +<li><p><a href="help:/kicker/index.html" target="_top">%1</a></p></li> +<li><p><a href="help:/kcontrol/index.html" target="_top">%1</a></p></li> +<li><p><a href="help:/konqueror/index.html" target="_top">%1</a></p></li> +</ul> + + + + + +<!-- End of text --> + + + </TD> + <TD WIDTH=20> </TD> + </TR> + <TR> + <TD HEIGHT=20 WIDTH=20> </TD> + <TD> </TD> + </TR> + +</TABLE> + + </TD> + <TD WIDTH=20> </TD> + </TR> + <TR> + <TD HEIGHT=44 COLSPAN=3> </TD> + </TR> +</TR> +</TABLE> +<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=0> +<TR> +<TD class="end" WIDTH=*> </TD> +<TD WIDTH=204><A HREF="http://www.kde.org"> <IMG WIDTH=204 BORDER=0 +HEIGHT=57 +SRC="file:%1"></A></TD> +</TR> +<TR> + <TD HEIGHT=50 COLSPAN=2> </TD> +</TR> +</TABLE> +</div> +</BODY> +</HTML> diff --git a/khelpcenter/kcmhelpcenter.cpp b/khelpcenter/kcmhelpcenter.cpp new file mode 100644 index 000000000..df8f1b36e --- /dev/null +++ b/khelpcenter/kcmhelpcenter.cpp @@ -0,0 +1,687 @@ +/* + This file is part of KHelpcenter. + + Copyright (C) 2002 Cornelius Schumacher <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 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 "kcmhelpcenter.h" + +#include "htmlsearchconfig.h" +#include "docmetainfo.h" +#include "prefs.h" +#include "searchhandler.h" +#include "searchengine.h" + +#include <tdeconfig.h> +#include <kdebug.h> +#include <tdelocale.h> +#include <tdeglobal.h> +#include <tdeaboutdata.h> +#include <kdialog.h> +#include <kstandarddirs.h> +#include <kprocess.h> +#include <tdeapplication.h> +#include <dcopclient.h> +#include <tdetempfile.h> +#include <kurlrequester.h> +#include <tdemessagebox.h> +#include <tdelistview.h> +#include <klineedit.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqdir.h> +#include <tqtabwidget.h> +#include <tqprogressbar.h> +#include <tqfile.h> +#include <tqlabel.h> +#include <tqvbox.h> +#include <tqtextedit.h> +#include <tqregexp.h> + +#include <unistd.h> +#include <sys/types.h> + +using namespace KHC; + +IndexDirDialog::IndexDirDialog( TQWidget *parent ) + : KDialogBase( parent, 0, true, i18n("Change Index Folder"), Ok | Cancel ) +{ + TQFrame *topFrame = makeMainWidget(); + + TQBoxLayout *urlLayout = new TQHBoxLayout( topFrame ); + + TQLabel *label = new TQLabel( 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(),TQT_SIGNAL(textChanged ( const TQString & )), this, TQT_SLOT(slotUrlChanged( const TQString &))); + slotUrlChanged( mIndexUrlRequester->lineEdit()->text() ); +} + +void IndexDirDialog::slotUrlChanged( const TQString &_url ) +{ + enableButtonOK( !_url.isEmpty() ); +} + + +void IndexDirDialog::slotOk() +{ + Prefs::setIndexDirectory( mIndexUrlRequester->url() ); + accept(); +} + + +IndexProgressDialog::IndexProgressDialog( TQWidget *parent ) + : KDialog( parent, "IndexProgressDialog", true ), + mFinished( true ) +{ + setCaption( i18n("Build Search Indices") ); + + TQBoxLayout *topLayout = new TQVBoxLayout( this ); + topLayout->setMargin( marginHint() ); + topLayout->setSpacing( spacingHint() ); + + mLabel = new TQLabel( this ); + mLabel->setAlignment( AlignHCenter ); + topLayout->addWidget( mLabel ); + + mProgressBar = new TQProgressBar( this ); + topLayout->addWidget( mProgressBar ); + + mLogLabel = new TQLabel( i18n("Index creation log:"), this ); + topLayout->addWidget( mLogLabel ); + + mLogView = new TQTextEdit( this ); + mLogView->setTextFormat( LogText ); + mLogView->setMinimumHeight( 200 ); + topLayout->addWidget( mLogView, 1 ); + + TQBoxLayout *buttonLayout = new TQHBoxLayout( topLayout ); + + buttonLayout->addStretch( 1 ); + + mDetailsButton = new TQPushButton( this ); + connect( mDetailsButton, TQT_SIGNAL( clicked() ), TQT_SLOT( toggleDetails() ) ); + buttonLayout->addWidget( mDetailsButton ); + + hideDetails(); + + mEndButton = new TQPushButton( this ); + connect( mEndButton, TQT_SIGNAL( clicked() ), TQT_SLOT( slotEnd() ) ); + buttonLayout->addWidget( mEndButton ); + + setFinished( false ); +} + +IndexProgressDialog::~IndexProgressDialog() +{ + if ( !mLogView->isHidden() ) { + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "indexprogressdialog" ); + cfg->writeEntry( "size", size() ); + } +} + +void IndexProgressDialog::setTotalSteps( int steps ) +{ + mProgressBar->setTotalSteps( steps ); + mProgressBar->setProgress( 0 ); + setFinished( false ); + mLogView->clear(); +} + +void IndexProgressDialog::advanceProgress() +{ + mProgressBar->setProgress( mProgressBar->progress() + 1 ); +} + +void IndexProgressDialog::setLabelText( const TQString &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 ) { + mEndButton->setText( i18n("Close") ); + mLabel->setText( i18n("Index creation finished.") ); + } else { + mEndButton->setText( i18n("Stop") ); + } +} + +void IndexProgressDialog::appendLog( const TQString &text ) +{ + mLogView->append( text ); +} + +void IndexProgressDialog::slotEnd() +{ + if ( mFinished ) { + emit closed(); + accept(); + } else { + emit cancelled(); + reject(); + } +} + +void IndexProgressDialog::toggleDetails() +{ + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "indexprogressdialog" ); + if ( mLogView->isHidden() ) { + mLogLabel->show(); + mLogView->show(); + mDetailsButton->setText( i18n("Details <<") ); + TQSize size = cfg->readSizeEntry( "size" ); + if ( !size.isEmpty() ) resize( size ); + } else { + cfg->writeEntry( "size", size() ); + hideDetails(); + } +} + +void IndexProgressDialog::hideDetails() +{ + mLogLabel->hide(); + mLogView->hide(); + mDetailsButton->setText( i18n("Details >>") ); + layout()->activate(); + adjustSize(); +} + + +KCMHelpCenter::KCMHelpCenter( KHC::SearchEngine *engine, TQWidget *parent, + const char *name) + : DCOPObject( "kcmhelpcenter" ), + KDialogBase( parent, name, false, i18n("Build Search Index"), + Ok | Cancel, Ok, true ), + mEngine( engine ), mProgressDialog( 0 ), mCurrentEntry( 0 ), mCmdFile( 0 ), + mProcess( 0 ), mIsClosing( false ), mRunAsRoot( false ) +{ + TQWidget *widget = makeMainWidget(); + + setupMainWidget( widget ); + + setButtonOK( i18n("Build Index") ); + + mConfig = TDEGlobal::config(); + + DocMetaInfo::self()->scanMetaInfo(); + + load(); + + bool success = kapp->dcopClient()->connectDCOPSignal( "khc_indexbuilder", + 0, "buildIndexProgress()", "kcmhelpcenter", + "slotIndexProgress()", false ); + if ( !success ) kdError() << "connect DCOP signal failed" << endl; + + success = kapp->dcopClient()->connectDCOPSignal( "khc_indexbuilder", + 0, "buildIndexError(TQString)", "kcmhelpcenter", + "slotIndexError(TQString)", false ); + if ( !success ) kdError() << "connect DCOP signal failed" << endl; + + resize( configDialogSize( "IndexDialog" ) ); +} + +KCMHelpCenter::~KCMHelpCenter() +{ + saveDialogSize( "IndexDialog" ); +} + +void KCMHelpCenter::setupMainWidget( TQWidget *parent ) +{ + TQVBoxLayout *topLayout = new TQVBoxLayout( parent ); + topLayout->setSpacing( KDialog::spacingHint() ); + + TQString helpText = + i18n("To be able to search a document, there needs to exist a search\n" + "index. The status column of the list below shows, if 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"); + + TQLabel *label = new TQLabel( helpText, parent ); + topLayout->addWidget( label ); + + mListView = new TDEListView( parent ); + mListView->setFullWidth( true ); + mListView->addColumn( i18n("Search Scope") ); + mListView->addColumn( i18n("Status") ); + mListView->setColumnAlignment( 1, AlignCenter ); + topLayout->addWidget( mListView ); + connect( mListView, TQT_SIGNAL( clicked( TQListViewItem * ) ), + TQT_SLOT( checkSelection() ) ); + + TQBoxLayout *urlLayout = new TQHBoxLayout( topLayout ); + + TQLabel *urlLabel = new TQLabel( i18n("Index folder:"), parent ); + urlLayout->addWidget( urlLabel ); + + mIndexDirLabel = new TQLabel( parent ); + urlLayout->addWidget( mIndexDirLabel, 1 ); + + TQPushButton *button = new TQPushButton( i18n("Change..."), parent ); + connect( button, TQT_SIGNAL( clicked() ), TQT_SLOT( showIndexDirDialog() ) ); + urlLayout->addWidget( button ); + + TQBoxLayout *buttonLayout = new TQHBoxLayout( topLayout ); + + buttonLayout->addStretch( 1 ); +} + +void KCMHelpCenter::defaults() +{ +} + +bool KCMHelpCenter::save() +{ + kdDebug(1401) << "KCMHelpCenter::save()" << endl; + + if ( !TQFile::exists( Prefs::indexDirectory() ) ) { + KMessageBox::sorry( this, + i18n("<qt>The folder <b>%1</b> does not exist; unable to create index.</qt>") + .arg( Prefs::indexDirectory() ) ); + return false; + } else { + return buildIndex(); + } + + return true; +} + +void KCMHelpCenter::load() +{ + findWriteableIndexDir(); + mIndexDirLabel->setText( Prefs::indexDirectory() ); + + mListView->clear(); + + DocEntry::List entries = DocMetaInfo::self()->docEntries(); + DocEntry::List::ConstIterator it; + for( it = entries.begin(); it != entries.end(); ++it ) { +// kdDebug(1401) << "Entry: " << (*it)->name() << " Indexer: '" +// << (*it)->indexer() << "'" << endl; + if ( mEngine->canSearch( *it ) && mEngine->needsIndex( *it ) ) { + ScopeItem *item = new ScopeItem( mListView, *it ); + item->setOn( (*it)->searchEnabled() ); + } + } + + updateStatus(); +} + +void KCMHelpCenter::updateStatus() +{ + TQListViewItemIterator it( mListView ); + while ( it.current() != 0 ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + TQString status; + if ( item->entry()->indexExists( Prefs::indexDirectory() ) ) { + status = i18n("OK"); + item->setOn( false ); + } else { + status = i18n("Missing"); + } + item->setText( 1, status ); + + ++it; + } + + checkSelection(); +} + +bool KCMHelpCenter::buildIndex() +{ + kdDebug(1401) << "Build Index" << endl; + + kdDebug() << "IndexPath: '" << Prefs::indexDirectory() << "'" << endl; + + if ( mProcess ) { + kdError() << "Error: Index Process still running." << endl; + return false; + } + + mIndexQueue.clear(); + + TQFontMetrics fm( font() ); + int maxWidth = 0; + + mCmdFile = new KTempFile; + mCmdFile->setAutoDelete( true ); + TQTextStream *ts = mCmdFile->textStream(); + if ( !ts ) { + kdError() << "Error opening command file." << endl; + deleteCmdFile(); + return false; + } else { + kdDebug() << "Writing to file '" << mCmdFile->name() << "'" << endl; + } + + bool hasError = false; + + TQListViewItemIterator it( mListView ); + while ( it.current() != 0 ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + if ( item->isOn() ) { + DocEntry *entry = item->entry(); + + TQString docText = i18n("Document '%1' (%2):\n") + .arg( entry->identifier() ) + .arg( entry->name() ); + if ( entry->documentType().isEmpty() ) { + KMessageBox::sorry( this, docText + + i18n("No document type.") ); + hasError = true; + } else { + SearchHandler *handler = mEngine->handler( entry->documentType() ); + if ( !handler ) { + KMessageBox::sorry( this, docText + + i18n("No search handler available for document type '%1'.") + .arg( entry->documentType() ) ); + hasError = true; + } else { + TQString indexer = handler->indexCommand( entry->identifier() ); + if ( indexer.isEmpty() ) { + KMessageBox::sorry( this, docText + + i18n("No indexing command specified for document type '%1'.") + .arg( entry->documentType() ) ); + hasError = true; + } else { + indexer.replace( TQRegExp( "%i" ), entry->identifier() ); + indexer.replace( TQRegExp( "%d" ), Prefs::indexDirectory() ); + indexer.replace( TQRegExp( "%p" ), entry->url() ); + kdDebug() << "INDEXER: " << indexer << endl; + *ts << indexer << endl; + + int width = fm.width( entry->name() ); + if ( width > maxWidth ) maxWidth = width; + + mIndexQueue.append( entry ); + } + } + } + } + ++it; + } + + mCmdFile->close(); + + if ( mIndexQueue.isEmpty() ) { + deleteCmdFile(); + return !hasError; + } + + mCurrentEntry = mIndexQueue.begin(); + TQString name = (*mCurrentEntry)->name(); + + if ( !mProgressDialog ) { + mProgressDialog = new IndexProgressDialog( this ); + connect( mProgressDialog, TQT_SIGNAL( cancelled() ), + TQT_SLOT( cancelBuildIndex() ) ); + connect( mProgressDialog, TQT_SIGNAL( closed() ), + TQT_SLOT( slotProgressClosed() ) ); + } + mProgressDialog->setLabelText( name ); + mProgressDialog->setTotalSteps( mIndexQueue.count() ); + mProgressDialog->setMinimumLabelWidth( maxWidth ); + mProgressDialog->show(); + + startIndexProcess(); + + return true; +} + +void KCMHelpCenter::startIndexProcess() +{ + kdDebug() << "KCMHelpCenter::startIndexProcess()" << endl; + + mProcess = new TDEProcess; + + if ( mRunAsRoot ) { + *mProcess << "tdesu" << "--nonewdcop"; + kdDebug() << "Run as root" << endl; + } + + *mProcess << locate("exe", "khc_indexbuilder"); + *mProcess << mCmdFile->name(); + *mProcess << Prefs::indexDirectory(); + + connect( mProcess, TQT_SIGNAL( processExited( TDEProcess * ) ), + TQT_SLOT( slotIndexFinished( TDEProcess * ) ) ); + connect( mProcess, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ), + TQT_SLOT( slotReceivedStdout(TDEProcess *, char *, int ) ) ); + connect( mProcess, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ), + TQT_SLOT( slotReceivedStderr( TDEProcess *, char *, int ) ) ); + + if ( !mProcess->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput ) ) { + kdError() << "KCMHelpcenter::startIndexProcess(): Failed to start process." + << endl; + } +} + +void KCMHelpCenter::cancelBuildIndex() +{ + kdDebug() << "cancelBuildIndex()" << endl; + + deleteProcess(); + deleteCmdFile(); + mIndexQueue.clear(); + + if ( mIsClosing ) { + mIsClosing = false; + } +} + +void KCMHelpCenter::slotIndexFinished( TDEProcess *proc ) +{ + kdDebug() << "KCMHelpCenter::slotIndexFinished()" << endl; + + if ( proc == 0 ) { + kdWarning() << "Process null." << endl; + return; + } + + if ( proc != mProcess ) { + kdError() << "Unexpected Process finished." << endl; + return; + } + + if ( mProcess->normalExit() && mProcess->exitStatus() == 2 ) { + if ( mRunAsRoot ) { + kdError() << "Insufficient permissions." << endl; + } else { + kdDebug() << "Insufficient permissions. Trying again as root." << endl; + mRunAsRoot = true; + deleteProcess(); + startIndexProcess(); + return; + } + } else if ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) { + kdDebug() << "TDEProcess reported an error." << endl; + KMessageBox::error( this, i18n("Failed to build index.") ); + } else { + mConfig->setGroup( "Search" ); + mConfig->writeEntry( "IndexExists", true ); + emit searchIndexUpdated(); + } + + deleteProcess(); + deleteCmdFile(); + + mCurrentEntry = 0; + + if ( mProgressDialog ) { + mProgressDialog->setFinished( true ); + } + + mStdOut = TQString(); + mStdErr = TQString(); + + if ( mIsClosing ) { + if ( !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; + + kdDebug() << "KCMHelpCenter::slotIndexProgress()" << endl; + + updateStatus(); + + advanceProgress(); +} + +void KCMHelpCenter::slotIndexError( const TQString &str ) +{ + if( !mProcess ) + return; + + kdDebug() << "KCMHelpCenter::slotIndexError()" << endl; + + KMessageBox::sorry( this, i18n("Error executing indexing build command:\n%1") + .arg( str ) ); + + if ( mProgressDialog ) { + mProgressDialog->appendLog( "<i>" + str + "</i>" ); + } + + advanceProgress(); +} + +void KCMHelpCenter::advanceProgress() +{ + if ( mProgressDialog && mProgressDialog->isVisible() ) { + mProgressDialog->advanceProgress(); + mCurrentEntry++; + if ( mCurrentEntry != mIndexQueue.end() ) { + TQString name = (*mCurrentEntry)->name(); + mProgressDialog->setLabelText( name ); + } + } +} + +void KCMHelpCenter::slotReceivedStdout( TDEProcess *, char *buffer, int buflen ) +{ + TQString text = TQString::fromLocal8Bit( buffer, buflen ); + int pos = text.findRev( '\n' ); + if ( pos < 0 ) { + mStdOut.append( text ); + } else { + if ( mProgressDialog ) { + mProgressDialog->appendLog( mStdOut + text.left( pos ) ); + mStdOut = text.mid( pos + 1 ); + } + } +} + +void KCMHelpCenter::slotReceivedStderr( TDEProcess *, char *buffer, int buflen ) +{ + TQString text = TQString::fromLocal8Bit( buffer, buflen ); + int pos = text.findRev( '\n' ); + if ( pos < 0 ) { + mStdErr.append( text ); + } else { + if ( mProgressDialog ) { + mProgressDialog->appendLog( "<i>" + mStdErr + text.left( pos ) + + "</i>"); + mStdErr = text.mid( pos + 1 ); + } + } +} + +void KCMHelpCenter::slotOk() +{ + if ( buildIndex() ) { + if ( !mProcess ) accept(); + else mIsClosing = true; + } +} + +void KCMHelpCenter::slotProgressClosed() +{ + kdDebug() << "KCMHelpCenter::slotProgressClosed()" << endl; + + if ( mIsClosing ) accept(); +} + +void KCMHelpCenter::showIndexDirDialog() +{ + IndexDirDialog dlg( this ); + if ( dlg.exec() == TQDialog::Accepted ) { + load(); + } +} + +void KCMHelpCenter::checkSelection() +{ + int count = 0; + + TQListViewItemIterator it( mListView ); + while ( it.current() != 0 ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + if ( item->isOn() ) { + ++count; + } + ++it; + } + + enableButtonOK( count != 0 ); +} + +void KCMHelpCenter::findWriteableIndexDir() +{ + TQFileInfo currentDir( Prefs::indexDirectory() ); + if ( !currentDir.isWritable() ) + Prefs::setIndexDirectory( TDEGlobal::dirs()->saveLocation("data", "khelpcenter/index/") ); +} +#include "kcmhelpcenter.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/kcmhelpcenter.desktop b/khelpcenter/kcmhelpcenter.desktop new file mode 100644 index 000000000..1b8baac49 --- /dev/null +++ b/khelpcenter/kcmhelpcenter.desktop @@ -0,0 +1,236 @@ +[Desktop Entry] +Type=Application +Exec=tdecmshell kcmhelpcenter +Icon=help + +X-TDE-SubstituteUID=true +X-TDE-ModuleType=Library +X-TDE-Library=helpcenter +X-TDE-RootOnly=true +X-TDE-HasReadOnlyMode=true +X-TDE-ParentApp=kcontrol + +Name=Help Index +Name[af]=Hulp Indeks +Name[ar]=فهرس المساعدة +Name[be]=Індэкс дапамогі +Name[bg]=Помощна информация +Name[bn]=সাহায্য সূচি +Name[br]=Meneger ar skoazell +Name[bs]=Indeks pomoći +Name[ca]=Í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[eo]=Helpindekso +Name[es]=Índice de ayuda +Name[et]=Abifailide indeks +Name[eu]=Laguntza indizea +Name[fa]=نمایۀ کمک +Name[fi]=Ohjeen hakemisto +Name[fr]=Index d'aide +Name[fy]=Help-yndeks +Name[ga]=Innéacs na Cabhrach +Name[gl]=Índice de Axuda +Name[he]=אינדקס עזרה +Name[hi]=मदद सूची +Name[hr]=Indeks pomoći +Name[hu]=Dokumentációkeresési index +Name[is]=Hjálparyfirlit +Name[it]=Indice della guida +Name[ja]=ヘルプインデックス +Name[ka]=დახმარების ინდექსი +Name[kk]=Анықтама индексі +Name[km]=លិបិក្រមជំនួយ +Name[ko]=도움말 찾아보기 +Name[lo]=ດັດສະນີ +Name[lt]=Pagalbos rodyklė +Name[lv]=Palīdzības indekss +Name[mk]=Индекс за помош +Name[mn]=Тусламж товчоо +Name[ms]=Indeks Bantuan +Name[mt]=Indiċi tal-għajnuna +Name[nb]=Hjelpindeks +Name[nds]=Hülpindex +Name[ne]=मद्दत अनुक्रमणिका +Name[nl]=Documentatie-index +Name[nn]=Hjelpindeks +Name[nso]=Palo ya Thuso +Name[pa]=ਸਹਾਇਤਾ ਤਤਕਰਾ +Name[pl]=Indeks pomocy +Name[pt]=Índice da Ajuda +Name[pt_BR]=Índice de Ajuda +Name[ro]=Index ajutor +Name[ru]=Индекс справки +Name[rw]=Umubarendanga w'Ifashayobora +Name[se]=Veahkkeindeaksa +Name[sk]=Index pomocníka +Name[sl]=Seznam pomoči +Name[sr]=Индекс помоћи +Name[sr@Latn]=Indeks pomoći +Name[sv]=Hjälpindex +Name[ta]=உதவி பொருளடக்கம் +Name[te]=సహాయ సూచిక +Name[tg]=Феҳрасти роҳнамо +Name[th]=ดัชนีความช่วยเหลือ +Name[tr]=Yardım İçeriği +Name[tt]=Yärdäm İsemlege +Name[uk]=Індекс довідки +Name[uz]=Yordam indeksi +Name[uz@cyrillic]=Ёрдам индекси +Name[ven]=Thusani Index +Name[vi]=Danh mục Trợ giúp +Name[wa]=Indecse di l' aidance +Name[xh]=Uncedo Lwesalathisi +Name[zh_CN]=帮助索引 +Name[zh_TW]=說明索引 +Name[zu]=Uhlelo lokuqukethwe losizo + +Comment=Help center search index configuration and generation +Comment[af]=Hulp sentrum soektog indeks opstelling en genereering +Comment[ar]=توليد و تهيئة فهرس البحث لمركز المساعدة +Comment[be]=Настаўленне і стварэнне індэксу для пошуку ў дакументацыі +Comment[bg]=Създаване на индекс за ускоряване на търсенето в помощната информация +Comment[bn]=সহায়িকাসন্ধানসূচি কনফিগারেশন এবং সৃষ্টি +Comment[bs]=Podešavanje i pravljenje indeksa za pretragu centra za pomoć +Comment[ca]=Configuració i generació de l'índex de recerca per al Centre d'ajuda +Comment[cs]=Generování a konfigurace rejstříku nápovědy +Comment[csb]=Kònfigùracëjë ë 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[eo]=Agordo kaj fabriko de KHelpcentra serĉindekso +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 guneko bilaketa indizearen konfigurazio eta sorkuntza +Comment[fa]=تولید و پیکربندی نمایۀ جستجوی مرکز کمک +Comment[fi]=Ohjeen hakuindeksin asetukset ja luonti +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[gl]=Configuración e xeración do índice de procura do centro de axuda +Comment[he]=שינוי הגדרות ויצירת אינדקס החיפוש של מרכז העזרה +Comment[hi]=मदद केंद्र खोज तालिका कॉन्फ़िगरेशन तथा ज़ेनरेशन +Comment[hr]=Konfiguriranje i generiranje indeksa za pretraživanje pomoći +Comment[hu]=A dokumentáció keresési indexének beállításai +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]=TDE-ს დახმარების სისტემაში ინდექსების კონფიგურაცია +Comment[kk]=Анықтамадан табу индексін баптау +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធ និងការបង្កើតលិបិក្រមស្វែងរក សម្រាប់មជ្ឈមណ្ឌលជំនួយ +Comment[ko]=도움말 찾아보기 설정 및 생성 +Comment[lt]=Pagalbos centro indekso konfigūravimas ir generavimas +Comment[lv]=Palīdzības centra meklēšanas indeksa konfigurācija un ģenerācija +Comment[mk]=Конфигурирање и генерирање на индексот на Центарот за Помош +Comment[mn]=Товчоон тохируулах +Comment[mt]=Konfigurazzjoni u ġenerazzjoni tal-indiċi ta' tfittxija taċ-ċentru ta' għajnuna +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[nso]=Thlagiso le peakanyo ya palo ya bangwadi le ya nyako ya bogare bja thuso +Comment[pa]=ਸਹਾਇਤਾ ਕੇਂਦਰ ਖੋਜ ਤਤਕਰਾ ਸੰਰਚਨਾ ਅਤੇ ਨਿਰਮਾਣ +Comment[pl]=Konfiguracja i generowanie indeksu 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]=Настройка индексов справочной системы TDE +Comment[rw]=Iboneza n'irema umubarendanga w'ishakisha ifashayobora hagati +Comment[se]=Veahkkeguovddáža ohcanindeavssa heiveheapmi ja ráhkadeapmi +Comment[sk]=Nastavenie a generovanie indexu pre pomocníka +Comment[sl]=Nastavitve in ustvarjanje iskalnega indeksa za Središče za pomoč +Comment[sr]=Подешавање и генерисање индекса за претрагу Центра за помоћ +Comment[sr@Latn]=Podešavanje i generisanje 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 indeks yapılandırması +Comment[tt]=Yärdäm üzägeneñ ezläw isemleklären caylaw/ürçetü +Comment[uk]=Створення та налаштування індексу пошуку центру довідки +Comment[uz]=Yordam markazining qidiruv indeksini yaratish va moslash +Comment[uz@cyrillic]=Ёрдам марказининг қидирув индексини яратиш ва мослаш +Comment[ven]=Nzudzanyo ya index yau setsha senthara ya thuso na murafho +Comment[vi]=Cấu hình và tạo danh mục tìm kiếm của trung tâm trợ giúp +Comment[wa]=Apontiaedje et ahivaedje di l' indecse di cweraedje do cinte d' aidance +Comment[xh]=Uqwalaselo lophendlo loncedo osembindi nolwenziwo +Comment[zh_CN]=帮助中心搜索索引配置和生成 +Comment[zh_TW]=求助中心搜尋索引的組態與產生 +Comment[zu]=ukuhlanganiselwa kanye nokugaywa kohlelo lokuqukethwe lokusesha indawo yosizo + +Keywords=khelpcenter,help,index,search +Keywords[ar]=khelpcenter,help,index,search,مساعدة,فهرس,بحث +Keywords[be]=Цэнтр дапамогі,Дапамога,Даведка,Індэкс,Пошук,khelpcenter,help,index,search +Keywords[bg]=индекс, търсене, помощ, информация, khelpcenter, help, index, search +Keywords[br]=khelpcenter,skoazell,meneger,klask +Keywords[bs]=khelpcenter,help,index,search,pretraga,indeks +Keywords[ca]=khelpcenter,ajuda,índex,cerca +Keywords[cs]=khelpcenter,nápověda,rejstřík,index,hledání +Keywords[csb]=centróm pòmòcë,pòmòc,indeks,szëkba +Keywords[cy]=khelpcenter,kcanolfancymorth,cymorth,mynegai,chwilio +Keywords[da]=khelpcenter,hjælp,indeks,søg +Keywords[de]=Hilfezentrum,Index,Stichwortverzeichnis,Suche +Keywords[el]=khelpcenter,βοήθεια,ευρετήριο,αναζήτηση +Keywords[eo]=KHelpcentro,helpo,indekso,serĉo,serĉi +Keywords[es]=khelpcenter,ayuda,índice,búsqueda +Keywords[et]=abifailid,indeks,otsing +Keywords[eu]=khelpcenter,laguntza,indizea,bilaketa +Keywords[fa]=khelpcenter، کمک، نمایه، جستجو +Keywords[fi]=khelpcenter,ohje,indeksi,haku +Keywords[fr]=khelpcenter,aide,index,recherche +Keywords[fy]=khelpcenter,help,index,yndeks,sykje,fine,search,hulp,zoeken +Keywords[ga]=khelpcenter,cabhair,innéacs,cuardach +Keywords[gl]=khelpcenter,axuda,índice,procura +Keywords[he]=khelpcenter,עזרה,אינדקס,חיפוש,help,index,search +Keywords[hi]=के-हेल्पसेंटर,मदद,तालिका,खोज +Keywords[hr]=khelpcenter,help,index,search,pomoć,indeks,pretraživanje +Keywords[hu]=khelpcenter,segítség,index,keresés +Keywords[is]=khelpcenter,hjálparmiðstöð,hjálp,index,yfirlit,leit +Keywords[it]=khelpcenter,guida,indice,ricerca +Keywords[ja]=khelpcenter,ヘルプ,インデックス,検索 +Keywords[km]=khelpcenter,ជំនួយ,លិបិក្រម,ស្វែងរក +Keywords[lt]=khelpcenter,help,index,search, pagalbos centras, pagalba, indeksas, paieška +Keywords[lv]=kpalīdzības centrs,palīdzība,indekss,meklēt +Keywords[mk]=khelpcenter,help,index,search,помош,индекс,пребарувај +Keywords[mn]=Тусламжийн төв,Товчоо,Товчоон,Хайх +Keywords[mt]=khelpcenter,help,index,search,għajnuna,indiċi,fittex +Keywords[nb]=khelpcenter,help,index,search, hjelpesenter,hjelp,indeks,søk +Keywords[nds]=khelpcenter,Help,Hülp,Hölp,Index,Söken +Keywords[ne]=केडीई मद्दत केन्द्र, मद्दत, अनुक्रमणिका, खोजी +Keywords[nl]=khelpcenter,help,index,search,hulp,zoeken,documentatie,handboek +Keywords[nn]=KHelpCenter,hjelp,indeks,søk +Keywords[nso]=kbogare bja thuso,thuso,palo ya bangwadi,nyako +Keywords[pa]=ਸਹਾਇਤਾ ਕੇਂਦਰ,ਸਹਾਇਤਾ,ਤਤਕਰਾ,ਖੋਜ +Keywords[pl]=centrum pomocy,pomoc,indeks,szukanie +Keywords[pt]=khelpcenter,ajuda,índice,procura +Keywords[pt_BR]=centro de ajuda,ajuda,índice,busca +Keywords[ro]=centrul de ajutor,khelpcenter,ajutor,index,căutare +Keywords[rw]=k-ifashayoborahagati,ifashayobora,umubarendanga,ishakisha +Keywords[se]=KHelpCenter,veahkki,indeaksa,indeksa,ohcan +Keywords[sk]=khelpcenter,help,index,pomocník,hľadanie +Keywords[sl]=khelpcenter,pomoč,indeks,iskanje +Keywords[sr]=khelpcenter,помоћ,садржај,претрага +Keywords[sr@Latn]=khelpcenter,pomoć,sadržaj,pretraga +Keywords[sv]=khelpcenter,hjälp,index,sök +Keywords[ta]=kஉதவி மையம், உதவி, சுட்டு இணைப்பு முறை, தேடுதல், தேடு +Keywords[te]=కెసహాయకేంద్రం,సహాయం,సూచిక, అన్వెషణ +Keywords[th]=ศูนย์ช่วยเหลือ,ช่วยเหลือ,ดัชนี,ค้นหา +Keywords[tr]=khelpcenter,yardım,ara,tarama,indeks +Keywords[uk]=khelpcenter,довідка,індекс,пошук +Keywords[uz]=khelpcenter,yordam,indeks,qidirish +Keywords[uz@cyrillic]=khelpcenter,ёрдам,индекс,қидириш +Keywords[ven]=senthara ya thuso k,thuso,index,toda +Keywords[vi]=trung tâm trợ giúp TDE,trợ giúp,danh mục,tìm kiếm +Keywords[wa]=khelpcenter,aide,aidance,indecse,trover,cwerî +Keywords[xh]=khelpcenter,uncedo,isalathisi,uphendlo +Keywords[zh_CN]=khelpcenter,help,index,search,帮助中心,帮助,索引,搜索 +Keywords[zh_TW]=khelpcenter,help,index,search,求助,索引,搜尋 +Keywords[zu]=khelpcenter,usizo,uhlelo lokuqukethwe,usesho +Categories=Qt;TDE;X-TDE-settings-system; diff --git a/khelpcenter/kcmhelpcenter.h b/khelpcenter/kcmhelpcenter.h new file mode 100644 index 000000000..0212a22c5 --- /dev/null +++ b/khelpcenter/kcmhelpcenter.h @@ -0,0 +1,185 @@ +/* + This file is part of KHelpcenter. + + Copyright (C) 2002 Cornelius Schumacher <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 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 KCMHELPCENTER_H +#define KCMHELPCENTER_H + +#include <kdialog.h> +#include <kdialogbase.h> + +#include <dcopobject.h> + +#include "scopeitem.h" + +class TQPushButton; +class TQProgressBar; +class TQTextEdit; +class TQLabel; + +class TDEProcess; +class TDEConfig; +class TDEAboutData; +class KTempFile; +class KURLRequester; +class TDEListView; + +namespace KHC { +class HtmlSearchConfig; +class DocEntry; +class SearchEngine; +} + +class IndexDirDialog : public KDialogBase +{ + Q_OBJECT + public: + IndexDirDialog( TQWidget *parent ); + + protected slots: + void slotOk(); + void slotUrlChanged( const TQString &_url); + private: + KURLRequester *mIndexUrlRequester; +}; + +class IndexProgressDialog : public KDialog +{ + Q_OBJECT + public: + IndexProgressDialog( TQWidget *parent ); + ~IndexProgressDialog(); + + void setTotalSteps( int ); + void advanceProgress(); + void setLabelText( const TQString & ); + void setMinimumLabelWidth( int width ); + void setFinished( bool ); + + void appendLog( const TQString &text ); + + signals: + void closed(); + void cancelled(); + + protected: + void hideDetails(); + + protected slots: + void slotEnd(); + void toggleDetails(); + + private: + TQLabel *mLabel; + TQProgressBar *mProgressBar; + TQLabel *mLogLabel; + TQTextEdit *mLogView; + TQPushButton *mDetailsButton; + TQPushButton *mEndButton; + + bool mFinished; +}; + +class KCMHelpCenterIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual void slotIndexProgress() = 0; + virtual void slotIndexError( const TQString & ) = 0; +}; + +class KCMHelpCenter : public KDialogBase, virtual public KCMHelpCenterIface +{ + Q_OBJECT + public: + KCMHelpCenter( KHC::SearchEngine *, TQWidget *parent = 0, + const char *name = 0 ); + ~KCMHelpCenter(); + + void load(); + bool save(); + void defaults(); + + public slots: + + signals: + void searchIndexUpdated(); + + protected slots: + bool buildIndex(); + void cancelBuildIndex(); + void slotIndexFinished( TDEProcess * ); + void slotIndexProgress(); + void slotIndexError( const TQString & ); + void slotReceivedStdout(TDEProcess *proc, char *buffer, int buflen); + void slotReceivedStderr(TDEProcess *proc, char *buffer, int buflen); + void slotProgressClosed(); + + void slotOk(); + + void showIndexDirDialog(); + + void checkSelection(); + + protected: + void setupMainWidget( TQWidget *parent ); + void updateStatus(); + void startIndexProcess(); + + void deleteProcess(); + void deleteCmdFile(); + + void advanceProgress(); + + /** + * Find a user-writeable location for the indices, if the current location + * is not. + */ + void findWriteableIndexDir(); + private: + KHC::SearchEngine *mEngine; + + TDEListView *mListView; + TQLabel *mIndexDirLabel; + TQPushButton *mBuildButton; + IndexProgressDialog *mProgressDialog; + + TQValueList<KHC::DocEntry *> mIndexQueue; + TQValueList<KHC::DocEntry *>::ConstIterator mCurrentEntry; + + TDEConfig *mConfig; + + TDEAboutData *mAboutData; + + KHC::HtmlSearchConfig *mHtmlSearchTab; + TQWidget *mScopeTab; + + KTempFile *mCmdFile; + + TDEProcess *mProcess; + + bool mIsClosing; + + TQString mStdOut; + TQString mStdErr; + + bool mRunAsRoot; +}; + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/khc_indexbuilder.cpp b/khelpcenter/khc_indexbuilder.cpp new file mode 100644 index 000000000..9c605687b --- /dev/null +++ b/khelpcenter/khc_indexbuilder.cpp @@ -0,0 +1,221 @@ +/* + This file is part of the TDE Help Center + + Copyright (c) 2003 Cornelius Schumacher <[email protected]> + + 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 <tdeaboutdata.h> +#include <tdelocale.h> +#include <tdecmdlineargs.h> +#include <kuniqueapplication.h> +#include <kdebug.h> +#include <dcopclient.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <tdeconfig.h> + +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqdir.h> +#include <tqtextstream.h> + +#include <unistd.h> +#include <stdlib.h> +#include <iostream> + +using namespace KHC; + +IndexBuilder::IndexBuilder(const TQString& cmdFile) +{ + m_cmdFile = cmdFile; + kdDebug(1402) << "IndexBuilder()" << endl; +} + +void IndexBuilder::buildIndices() +{ + TQFile f( m_cmdFile ); + if ( !f.open( IO_ReadOnly ) ) { + kdError() << "Unable to open file '" << m_cmdFile << "'" << endl; + exit( 1 ); + } + kdDebug(1402) << "Opened file '" << m_cmdFile << "'" << endl; + TQTextStream ts( &f ); + TQString line = ts.readLine(); + while ( !line.isNull() ) { + kdDebug(1402) << "LINE: " << line << endl; + mCmdQueue.append( line ); + line = ts.readLine(); + } + + processCmdQueue(); +} + +void IndexBuilder::processCmdQueue() +{ + kdDebug(1402) << "IndexBuilder::processCmdQueue()" << endl; + + TQStringList::Iterator it = mCmdQueue.begin(); + + if ( it == mCmdQueue.end() ) { + quit(); + return; + } + + TQString cmd = *it; + + kdDebug(1402) << "PROCESS: " << cmd << endl; + + TDEProcess *proc = new TDEProcess; + proc->setRunPrivileged( true ); + + TQStringList args = TQStringList::split( " ", cmd ); + *proc << args; + + + connect( proc, TQT_SIGNAL( processExited( TDEProcess * ) ), + TQT_SLOT( slotProcessExited( TDEProcess * ) ) ); + connect( proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int ) ), + TQT_SLOT( slotReceivedStdout(TDEProcess *, char *, int ) ) ); + connect( proc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int ) ), + TQT_SLOT( slotReceivedStderr(TDEProcess *, char *, int ) ) ); + + mCmdQueue.remove( it ); + + if ( !proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput ) ) { + sendErrorSignal( i18n("Unable to start command '%1'.").arg( cmd ) ); + processCmdQueue(); + } +} + +void IndexBuilder::slotProcessExited( TDEProcess *proc ) +{ + kdDebug(1402) << "IndexBuilder::slotIndexFinished()" << endl; + + if ( !proc->normalExit() ) { + kdError(1402) << "Process failed" << endl; + } else { + int status = proc->exitStatus(); + kdDebug(1402) << "Exit status: " << status << endl; + } + + delete proc; + + sendProgressSignal(); + + processCmdQueue(); +} + +void IndexBuilder::slotReceivedStdout( TDEProcess *, char *buffer, int buflen ) +{ + TQString text = TQString::fromLocal8Bit( buffer, buflen ); + std::cout << text.local8Bit().data() << std::flush; +} + +void IndexBuilder::slotReceivedStderr( TDEProcess *, char *buffer, int buflen ) +{ + TQString text = TQString::fromLocal8Bit( buffer, buflen ); + std::cerr << text.local8Bit().data() << std::flush; +} + +void IndexBuilder::sendErrorSignal( const TQString &error ) +{ + kdDebug(1402) << "IndexBuilder::sendErrorSignal()" << endl; + + TQByteArray params; + TQDataStream stream( params, IO_WriteOnly ); + stream << error; + kapp->dcopClient()->emitDCOPSignal("buildIndexError(TQString)", params ); +} + +void IndexBuilder::sendProgressSignal() +{ + kdDebug(1402) << "IndexBuilder::sendProgressSignal()" << endl; + + kapp->dcopClient()->emitDCOPSignal("buildIndexProgress()", TQByteArray() ); +} + +void IndexBuilder::quit() +{ + kdDebug(1402) << "IndexBuilder::quit()" << endl; + + kapp->quit(); +} + + +static TDECmdLineOptions options[] = +{ + { "+cmdfile", I18N_NOOP("Document to be indexed"), 0 }, + { "+indexdir", I18N_NOOP("Index directory"), 0 }, + TDECmdLineLastOption +}; + +int main( int argc, char **argv ) +{ + TDEAboutData aboutData( "khc_indexbuilder", + I18N_NOOP("KHelpCenter Index Builder"), + HELPCENTER_VERSION, + I18N_NOOP("The TDE Help Center"), + TDEAboutData::License_GPL, + I18N_NOOP("(c) 2003, The KHelpCenter developers") ); + + aboutData.addAuthor( "Cornelius Schumacher", 0, "[email protected]" ); + + TDECmdLineArgs::init( argc, argv, &aboutData ); + TDECmdLineArgs::addCmdLineOptions( options ); + KUniqueApplication::addCmdLineOptions(); + + TDEApplication app; + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + if ( args->count() != 2 ) { + kdDebug(1402) << "Wrong number of arguments." << endl; + return 1; + } + + TQString cmdFile = args->arg( 0 ); + TQString indexDir = args->arg( 1 ); + + kdDebug(1402) << "cmdFile: " << cmdFile << endl; + kdDebug(1402) << "indexDir: " << indexDir << endl; + + TQFile file( indexDir + "/testaccess" ); + if ( !file.open( IO_WriteOnly ) || file.putch( ' ' ) < 0 ) { + kdDebug(1402) << "access denied" << endl; + return 2; + } else { + kdDebug(1402) << "can access" << endl; + file.remove(); + } + + app.dcopClient()->registerAs( "khc_indexbuilder", false ); + + IndexBuilder builder(cmdFile); + + TQTimer::singleShot(0, &builder, TQT_SLOT(buildIndices())); + + return app.exec(); +} + +#include "khc_indexbuilder.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/khc_indexbuilder.h b/khelpcenter/khc_indexbuilder.h new file mode 100644 index 000000000..5eb849419 --- /dev/null +++ b/khelpcenter/khc_indexbuilder.h @@ -0,0 +1,61 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2003 Cornelius Schumacher <[email protected]> + * + * 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.h> + +#include <tqobject.h> +#include <tqtimer.h> + +class TDEProcess; + +namespace KHC { + +class IndexBuilder : public QObject +{ + Q_OBJECT + public: + IndexBuilder(const TQString& cmdFile); + + void sendProgressSignal(); + void sendErrorSignal( const TQString &error ); + void quit(); + + void processCmdQueue(); + + protected slots: + void buildIndices(); + void slotProcessExited( TDEProcess * ); + void slotReceivedStdout( TDEProcess *, char *buffer, int buflen ); + void slotReceivedStderr( TDEProcess *, char *buffer, int buflen ); + + private: + TQString m_cmdFile; + TQTimer mTimer; + TQStringList mCmdQueue; +}; + +} + +#endif + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/khelpcenter.desktop b/khelpcenter/khelpcenter.desktop new file mode 100644 index 000000000..8fba4bb2f --- /dev/null +++ b/khelpcenter/khelpcenter.desktop @@ -0,0 +1,133 @@ +[Desktop Entry] +Name=KHelpCenter +Name[af]=Khulpsentrum +Name[be]=Цэнтр дапамогі Trinity +Name[bg]=Помощен център +Name[cs]=Centrum nápovědy +Name[csb]=Centróm Pòmòcë +Name[cy]=KCanolfanCymorth +Name[da]=KHjælpecenter +Name[de]=Trinity-Hilfezentrum +Name[en_GB]=KHelpCentre +Name[eo]=KHelpCentro +Name[es]=KHelpcenter +Name[et]=Trinity abikeskus +Name[fr]=Centre d'aide de Trinity +Name[gl]=Centro de Axuda de Trinity +Name[hi]=के-हेल्प-सेंटर +Name[is]=Hjálparkerfi Trinity +Name[ja]=K ヘルプセンター +Name[lo]=ສູນຊ່ວຍເຫລືອ - K +Name[lv]=KPalīdzībasCentrs +Name[mn]=КДЭ-Тусламжийн төв +Name[nds]=Trinity-Hülpzentrum +Name[ne]=केडीई मद्दत केन्द्र +Name[nso]=KBogare bja Thuso +Name[pa]=ਕੇਸਹਾਇਤਾਕੇਂਦਰ +Name[pl]=Centrum Pomocy +Name[pt_BR]=Centro de Ajuda +Name[ro]=Centrul de ajutor Trinity +Name[ru]=Центр справки +Name[rw]=K-UmwanyaGufasha +Name[sv]=Hjälpcentralen +Name[ta]=Kஉதவிமையம் +Name[te]=కెసహాయ కేంద్రం +Name[tg]=Маркази роҳнамо +Name[th]=ศูนย์ช่วยเหลือ K +Name[tr]=Trinity Yardım Merkezi +Name[uz]=Yordam markazi +Name[uz@cyrillic]=Ёрдам маркази +Name[ven]=Senthara ya thuso ya K +Name[vi]=Trung tâm Trợ giúp Trinity +Name[wa]=KCinteDAidance +Name[zh_CN]=KHelpcenter +Comment=The Trinity Help Center +Comment[af]=Die Kde Hulp Sentrum +Comment[ar]=مركز Trinity للمساعدة +Comment[az]=Trinity Yardım Mərkəzi +Comment[be]=Цэнтр дапамогі Trinity +Comment[bg]=Център за помощна информация +Comment[bn]=কে.ডি.ই. সাহায্য কেন্দ্র +Comment[br]=Kreizenn sikour Trinity +Comment[bs]=Trinity centar za pomoć +Comment[ca]=El centre d'ajuda Trinity +Comment[cs]=Centrum nápovědy prostředí Trinity +Comment[csb]=Centróm Pòmòcë Trinity +Comment[cy]=Canolfan Cymorth Trinity +Comment[da]=Trinity's hjælpecenter +Comment[de]=Das Trinity-Hilfezentrum +Comment[el]=Το κέντρο βοήθειας του Trinity +Comment[en_GB]=The Trinity Help Centre +Comment[eo]=La Trinity-helpocentro +Comment[es]=El centro de ayuda de Trinity +Comment[et]=Trinity abikeskus +Comment[eu]=Trinity laguntza gunea +Comment[fa]=مرکز کمک Trinity +Comment[fi]=Trinity:n Ohje +Comment[fr]=Le centre de documentation de Trinity +Comment[fy]=It Trinity-dokumintaasjesintrum +Comment[ga]=Lárionad Cabhrach Trinity +Comment[gl]=O Centro de Axuda de Trinity +Comment[he]=מרכז העזרה של Trinity +Comment[hi]=केडीई मदद केंद्र +Comment[hr]=Trinity pomoć +Comment[hu]=Trinity Segítség +Comment[id]=Pusat Bantuan Trinity +Comment[is]=Hjálparkerfi Trinity +Comment[it]=La guida di Trinity +Comment[ja]=Trinity ヘルプセンター +Comment[ka]=Trinity-ს დახმარების ცენტრი +Comment[kk]=Trinity анықтама орталығы +Comment[km]=មជ្ឈមណ្ឌលជំនួយរបស់ Trinity +Comment[ko]=Trinity 도움말 센터 +Comment[lo]=ສູນຊ່ວຍເຫລືອຂອງ Trinity +Comment[lt]=Trinity pagalbos centras +Comment[lv]=Trinity Palīdzības Centrs +Comment[mk]=Trinity Центарот за Помош +Comment[mn]=КДЭ-Тусламжийн төв +Comment[ms]=Pusat Bantuan Trinity +Comment[mt]=Ċentru tal-Għajnuna Trinity +Comment[nb]=Trinity Hjelpesenter +Comment[nds]=Dat Trinity-Hülpzentrum +Comment[ne]=केडीई मद्दत केन्द्र +Comment[nl]=Het Trinity-documentatiecentrum +Comment[nn]=Trinity Hjelpesenter +Comment[nso]=Bogare bja Thuso ya Trinity +Comment[oc]=Lo centre d'ajuda Trinity +Comment[pa]=ਕੇਡੀਈ ਸਹਾਇਤਾ ਕੇਂਦਰ +Comment[pl]=Centrum Pomocy Trinity +Comment[pt]=O Centro de Ajuda do Trinity +Comment[pt_BR]=Centro de Ajuda do Trinity +Comment[ro]=Centrul de ajutor al Trinity +Comment[ru]=Центр справки Trinity +Comment[rw]=Trinity Ifashayobora Hagati +Comment[se]=Trinity veahkkeguovddáš +Comment[sk]=Trinity Centrum pomoci +Comment[sl]=Središče pomoči za Trinity +Comment[sr]=Trinity центар за помоћ +Comment[sr@Latn]=Trinity centar za pomoć +Comment[sv]=Trinity:s hjälpcentral +Comment[ta]=Trinity உதவி மையம் +Comment[te]=కెడిఈ సహాయ కేంద్రం +Comment[tg]=Маркази роҳнамои Trinity +Comment[th]=ศูนย์ช่วยเหลือของ Trinity +Comment[tr]=Trinity Yardım Merkezi +Comment[tt]=Trinity Yärdäm Üzäge +Comment[uk]=Центр довідок Trinity +Comment[uz]=Trinity yordam markazi +Comment[uz@cyrillic]=Trinity ёрдам маркази +Comment[ven]=Senthara ya thuso ya Trinity +Comment[vi]=Trung tâm Trợ giúp Trinity +Comment[wa]=Li Cinte d' aidance Trinity +Comment[xh]=Umbindi woncedo lwe Trinity +Comment[zh_CN]=Trinity 帮助中心 +Comment[zh_TW]=Trinity 求助中心 +Comment[zu]=Indawo Yosizi ye-Trinity +Icon=khelpcenter +DocPath=khelpcenter/index.html +Type=Service +Terminal=false +Exec=khelpcenter %u +SwallowExec= +SwallowTitle= +X-TDE-StartupNotify=true diff --git a/khelpcenter/khelpcenter.kcfg b/khelpcenter/khelpcenter.kcfg new file mode 100644 index 000000000..836bb9f45 --- /dev/null +++ b/khelpcenter/khelpcenter.kcfg @@ -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">TDEGlobal::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> diff --git a/khelpcenter/khelpcenterui.rc b/khelpcenter/khelpcenterui.rc new file mode 100644 index 000000000..7dfcb2f20 --- /dev/null +++ b/khelpcenter/khelpcenterui.rc @@ -0,0 +1,53 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="khelpcenter" version="14"> +<MenuBar> + <Menu name="file" noMerge="1"> + <text>&File</text> + <Action name="printFrame" group="print" /> + <Action name="show_search_stderr" /> + <Separator /> + <Action name="file_quit"/> + </Menu> + <Menu name="edit" noMerge="1"> + <text>&Edit</text> + <Action name="copy_text" /> + <Separator /> + <Action name="selectAll" /> + <Separator /> + <Action name="find" /> + </Menu> + <Menu name="view" noMerge="1"> + <text>&View</text> + <Action name="viewDocumentSource" /> + <Action name="setEncoding" /> + </Menu> + <Menu name="go_web"> + <text>&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"/> + <Action name="build_index" 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="printFrame" /> + <Separator /> + <Action name="copy_text" /> + <Action name="find" /> + <Separator /> + <Action name="incFontSizes" /> + <Action name="decFontSizes" /> +</ToolBar> +</kpartgui> diff --git a/khelpcenter/mainwindow.cpp b/khelpcenter/mainwindow.cpp new file mode 100644 index 000000000..ab75d29a7 --- /dev/null +++ b/khelpcenter/mainwindow.cpp @@ -0,0 +1,467 @@ + /* + * This file is part of the Trinity Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * 2001 Stephan Kulow ([email protected]) + * + * 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 <tdeapplication.h> +#include <tdeconfig.h> +#include <dcopclient.h> +#include <kiconloader.h> +#include <kmimemagic.h> +#include <krun.h> +#include <tdeaboutdata.h> +#include <kdebug.h> +#include <tdehtmlview.h> +#include <tdehtml_settings.h> +#include <tdeaction.h> +#include <kstatusbar.h> +#include <tdestdaccel.h> +#include <kdialogbase.h> + +#include <tqsplitter.h> +#include <tqtextedit.h> +#include <tqlayout.h> + +#include <stdlib.h> +#include <assert.h> + +using namespace KHC; + +class LogDialog : public KDialogBase +{ + public: + LogDialog( TQWidget *parent = 0 ) + : KDialogBase( Plain, i18n("Search Error Log"), Ok, Ok, parent, 0, + false ) + { + TQFrame *topFrame = plainPage(); + + TQBoxLayout *topLayout = new TQVBoxLayout( topFrame ); + + mTextView = new TQTextEdit( topFrame ); + mTextView->setTextFormat( LogText ); + topLayout->addWidget( mTextView ); + + resize( configDialogSize( "logdialog" ) ); + } + + ~LogDialog() + { + saveDialogSize( "logdialog" ); + } + + void setLog( const TQString &log ) + { + mTextView->setText( log ); + } + + private: + TQTextEdit *mTextView; +}; + + +MainWindow::MainWindow() + : TDEMainWindow(0, "MainWindow"), DCOPObject( "KHelpCenterIface" ), + mLogDialog( 0 ) +{ + mSplitter = new TQSplitter( this ); + + mDoc = new View( mSplitter, 0, TQT_TQOBJECT(this), 0, TDEHTMLPart::DefaultGUI, actionCollection() ); + connect( mDoc, TQT_SIGNAL( setWindowCaption( const TQString & ) ), + TQT_SLOT( setCaption( const TQString & ) ) ); + connect( mDoc, TQT_SIGNAL( setStatusBarText( const TQString & ) ), + TQT_SLOT( statusBarMessage( const TQString & ) ) ); + connect( mDoc, TQT_SIGNAL( onURL( const TQString & ) ), + TQT_SLOT( statusBarMessage( const TQString & ) ) ); + connect( mDoc, TQT_SIGNAL( started( TDEIO::Job * ) ), + TQT_SLOT( slotStarted( TDEIO::Job * ) ) ); + connect( mDoc, TQT_SIGNAL( completed() ), + TQT_SLOT( documentCompleted() ) ); + connect( mDoc, TQT_SIGNAL( searchResultCacheAvailable() ), + TQT_SLOT( enableLastSearchAction() ) ); + + connect( mDoc, TQT_SIGNAL( selectionChanged() ), + TQT_SLOT( enableCopyTextAction() ) ); + + statusBar()->insertItem(i18n("Preparing Index"), 0, 1); + statusBar()->setItemAlignment(0, AlignLeft | AlignVCenter); + + connect( mDoc->browserExtension(), + TQT_SIGNAL( openURLRequest( const KURL &, + const KParts::URLArgs & ) ), + TQT_SLOT( slotOpenURLRequest( const KURL &, + const KParts::URLArgs & ) ) ); + + mNavigator = new Navigator( mDoc, mSplitter, "nav" ); + connect( mNavigator, TQT_SIGNAL( itemSelected( const TQString & ) ), + TQT_SLOT( viewUrl( const TQString & ) ) ); + connect( mNavigator, TQT_SIGNAL( glossSelected( const GlossaryEntry & ) ), + TQT_SLOT( slotGlossSelected( const GlossaryEntry & ) ) ); + + mSplitter->moveToFirst(mNavigator); + mSplitter->setResizeMode(mNavigator, TQSplitter::KeepSize); + setCentralWidget( mSplitter ); + TQValueList<int> sizes; + sizes << 220 << 580; + mSplitter->setSizes(sizes); + setGeometry(366, 0, 800, 600); + + TDEConfig *cfg = kapp->config(); + { + TDEConfigGroupSaver groupSaver( cfg, "General" ); + if ( cfg->readBoolEntry( "UseKonqSettings", true ) ) { + TDEConfig konqCfg( "konquerorrc" ); + const_cast<TDEHTMLSettings *>( mDoc->settings() )->init( &konqCfg ); + } + const int zoomFactor = cfg->readNumEntry( "Font zoom factor", 100 ); + mDoc->setZoomFactor( zoomFactor ); + } + + setupActions(); + + actionCollection()->addDocCollection( mDoc->actionCollection() ); + + setupGUI(ToolBar | Keys | StatusBar | Create); + setAutoSaveSettings(); + + History::self().installMenuBarHook( this ); + + connect( &History::self(), TQT_SIGNAL( goInternalUrl( const KURL & ) ), + mNavigator, TQT_SLOT( openInternalUrl( const KURL & ) ) ); + connect( &History::self(), TQT_SIGNAL( goUrl( const KURL & ) ), + mNavigator, TQT_SLOT( selectItem( const KURL & ) ) ); + + statusBarMessage(i18n("Ready")); + enableCopyTextAction(); + + readConfig(); +} + +MainWindow::~MainWindow() +{ + writeConfig(); +} + +void MainWindow::enableCopyTextAction() +{ + mCopyText->setEnabled( mDoc->hasSelection() ); +} + +void MainWindow::saveProperties( TDEConfig *config ) +{ + kdDebug()<<"void MainWindow::saveProperties( TDEConfig *config )" << endl; + config->writePathEntry( "URL" , mDoc->baseURL().url() ); +} + +void MainWindow::readProperties( TDEConfig *config ) +{ + kdDebug()<<"void MainWindow::readProperties( TDEConfig *config )" << endl; + mDoc->slotReload( KURL( config->readPathEntry( "URL" ) ) ); +} + +void MainWindow::readConfig() +{ + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "MainWindowState" ); + TQValueList<int> sizes = config->readIntListEntry( "Splitter" ); + if ( sizes.count() == 2 ) { + mSplitter->setSizes( sizes ); + } + + mNavigator->readConfig(); +} + +void MainWindow::writeConfig() +{ + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "MainWindowState" ); + config->writeEntry( "Splitter", mSplitter->sizes() ); + + mNavigator->writeConfig(); + + Prefs::writeConfig(); +} + +void MainWindow::setupActions() +{ + KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT( close() ), actionCollection() ); + KStdAction::print( TQT_TQOBJECT(this), TQT_SLOT( print() ), actionCollection(), + "printFrame" ); + + TDEAction *prevPage = new TDEAction( i18n( "Previous Page" ), CTRL+Key_PageUp, mDoc, TQT_SLOT( prevPage() ), + actionCollection(), "prevPage" ); + prevPage->setWhatsThis( i18n( "Moves to the previous page of the document" ) ); + + TDEAction *nextPage = new TDEAction( i18n( "Next Page" ), CTRL + Key_PageDown, mDoc, TQT_SLOT( nextPage() ), + actionCollection(), "nextPage" ); + nextPage->setWhatsThis( i18n( "Moves to the next page of the document" ) ); + + TDEAction *home = KStdAction::home( TQT_TQOBJECT(this), TQT_SLOT( slotShowHome() ), actionCollection() ); + home->setText(i18n("Table of &Contents")); + home->setToolTip(i18n("Table of contents")); + home->setWhatsThis(i18n("Go back to the table of contents")); + + mCopyText = KStdAction::copy( TQT_TQOBJECT(this), TQT_SLOT(slotCopySelectedText()), actionCollection(), "copy_text"); + + mLastSearchAction = new TDEAction( i18n("&Last Search Result"), 0, TQT_TQOBJECT(this), + TQT_SLOT( slotLastSearch() ), + actionCollection(), "lastsearch" ); + mLastSearchAction->setEnabled( false ); + + new TDEAction( i18n("Build Search Index..."), 0, TQT_TQOBJECT(mNavigator), + TQT_SLOT( showIndexDialog() ), actionCollection(), "build_index" ); + KStdAction::keyBindings( guiFactory(), TQT_SLOT( configureShortcuts() ), + actionCollection() ); + + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "Debug" ); + if ( cfg->readBoolEntry( "SearchErrorLog", false ) ) { + new TDEAction( i18n("Show Search Error Log"), 0, TQT_TQOBJECT(this), + TQT_SLOT( showSearchStderr() ), actionCollection(), + "show_search_stderr" ); + } + + History::self().setupActions( actionCollection() ); + + new TDEAction( i18n( "Configure Fonts..." ), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT( slotConfigureFonts() ), actionCollection(), "configure_fonts" ); + new TDEAction( i18n( "Increase Font Sizes" ), "viewmag+", TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT( slotIncFontSizes() ), actionCollection(), "incFontSizes" ); + new TDEAction( i18n( "Decrease Font Sizes" ), "viewmag-", TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT( slotDecFontSizes() ), actionCollection(), "decFontSizes" ); +} + +void MainWindow::slotCopySelectedText() +{ + mDoc->copySelectedText(); +} + +void MainWindow::print() +{ + mDoc->view()->print(); +} + +void MainWindow::slotStarted(TDEIO::Job *job) +{ + if (job) + connect(job, TQT_SIGNAL(infoMessage( TDEIO::Job *, const TQString &)), + TQT_SLOT(slotInfoMessage(TDEIO::Job *, const TQString &))); + + History::self().updateActions(); +} + +void MainWindow::goInternalUrl( const KURL &url ) +{ + mDoc->closeURL(); + slotOpenURLRequest( url, KParts::URLArgs() ); +} + +void MainWindow::slotOpenURLRequest( const KURL &url, + const KParts::URLArgs &args ) +{ + kdDebug( 1400 ) << "MainWindow::slotOpenURLRequest(): " << url.url() << endl; + + mNavigator->selectItem( url ); + viewUrl( url, args ); +} + +void MainWindow::viewUrl( const TQString &url ) +{ + viewUrl( KURL( url ) ); +} + +void MainWindow::viewUrl( const KURL &url, const KParts::URLArgs &args ) +{ + stop(); + + TQString proto = url.protocol().lower(); + + if ( proto == "khelpcenter" ) { + History::self().createEntry(); + mNavigator->openInternalUrl( url ); + return; + } + + bool own = false; + + if ( proto == "help" || proto == "glossentry" || proto == "about" || + proto == "man" || proto == "info" || proto == "cgi" || + proto == "ghelp" ) + own = true; + else if ( url.isLocalFile() ) { + KMimeMagicResult *res = KMimeMagic::self()->findFileType( url.path() ); + if ( res->isValid() && res->accuracy() > 40 + && res->mimeType() == "text/html" ) + own = true; + } + + if ( !own ) { + new KRun( url ); + return; + } + + History::self().createEntry(); + + mDoc->browserExtension()->setURLArgs( args ); + + if ( proto == TQString::fromLatin1("glossentry") ) { + TQString decodedEntryId = KURL::decode_string( url.encodedPathAndQuery() ); + slotGlossSelected( mNavigator->glossEntry( decodedEntryId ) ); + mNavigator->slotSelectGlossEntry( decodedEntryId ); + } else { + mDoc->openURL( url ); + } +} + +void MainWindow::documentCompleted() +{ + kdDebug() << "MainWindow::documentCompleted" << endl; + + History::self().updateCurrentEntry( mDoc ); + History::self().updateActions(); +} + +void MainWindow::slotInfoMessage(TDEIO::Job *, const TQString &m) +{ + statusBarMessage(m); +} + +void MainWindow::statusBarMessage(const TQString &m) +{ + statusBar()->changeItem(m, 0); +} + +void MainWindow::openUrl( const TQString &url ) +{ + openUrl( KURL( url ) ); +} + +void MainWindow::openUrl( const TQString &url, const TQCString& startup_id ) +{ + TDEStartupInfo::setNewStartupId( this, startup_id ); + openUrl( KURL( url ) ); +} + +void MainWindow::openUrl( const KURL &url ) +{ + if ( url.isEmpty() ) slotShowHome(); + else { + mNavigator->selectItem( url ); + viewUrl( url ); + } +} + +void MainWindow::slotGlossSelected(const GlossaryEntry &entry) +{ + kdDebug() << "MainWindow::slotGlossSelected()" << endl; + + stop(); + History::self().createEntry(); + mDoc->begin( KURL( "help:/khelpcenter/glossary" ) ); + mDoc->write( Glossary::entryToHtml( entry ) ); + mDoc->end(); +} + +void MainWindow::stop() +{ + kdDebug() << "MainWindow::stop()" << endl; + + mDoc->closeURL(); + 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() +{ + TQString log = mNavigator->searchEngine()->errorLog(); + + if ( !mLogDialog ) { + mLogDialog = new LogDialog( this ); + } + + mLogDialog->setLog( log ); + mLogDialog->show(); + mLogDialog->raise(); +} + +void MainWindow::slotIncFontSizes() +{ + mDoc->slotIncFontSizes(); + updateZoomActions(); +} + +void MainWindow::slotDecFontSizes() +{ + mDoc->slotDecFontSizes(); + updateZoomActions(); +} + +void MainWindow::updateZoomActions() +{ + actionCollection()->action( "incFontSizes" )->setEnabled( mDoc->zoomFactor() + mDoc->zoomStepping() <= 300 ); + actionCollection()->action( "decFontSizes" )->setEnabled( mDoc->zoomFactor() - mDoc->zoomStepping() >= 20 ); + + TDEConfig *cfg = kapp->config(); + { + TDEConfigGroupSaver groupSaver( cfg, "General" ); + cfg->writeEntry( "Font zoom factor", mDoc->zoomFactor() ); + cfg->sync(); + } +} + +void MainWindow::slotConfigureFonts() +{ + FontDialog dlg( this ); + if ( dlg.exec() == TQDialog::Accepted ) + mDoc->slotReload(); +} + +#include "mainwindow.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/mainwindow.h b/khelpcenter/mainwindow.h new file mode 100644 index 000000000..795b6e13c --- /dev/null +++ b/khelpcenter/mainwindow.h @@ -0,0 +1,108 @@ +#ifndef __mainwindow_h__ +#define __mainwindow_h__ + +#include <tqptrlist.h> + +#include <tdemainwindow.h> +#include <tdeio/job.h> +#include <kurl.h> +#include <tdeparts/browserextension.h> +#include <dcopclient.h> +#include <dcopobject.h> + +#include "navigator.h" +#include "glossary.h" + +class TDEHTMLPart; +class TQSplitter; + +class LogDialog; + +namespace KHC { + +class View; + +class MainWindow : public TDEMainWindow, public DCOPObject +{ + Q_OBJECT + K_DCOP + public: + MainWindow(); + ~MainWindow(); + + k_dcop: + void openUrl( const TQString &url ); + void openUrl( const TQString &url, const TQCString& startup_id ); + void showHome(); + void lastSearch(); + + public slots: + void print(); + void statusBarMessage(const TQString &m); + void slotShowHome(); + void slotLastSearch(); + void showSearchStderr(); + /** + Show document corresponding to given URL in viewer part. + */ + void viewUrl( const KURL &url, + const KParts::URLArgs &args = KParts::URLArgs() ); + /** + Show document corresponding to given URL in viewer part. + */ + void viewUrl( const TQString & ); + + /** + Open document corresponding to given URL, i.e. show it in the viewer part + and select the corresponding entry in the navigator widget. + */ + void openUrl( const KURL &url ); + + protected: + void setupActions(); + + virtual void saveProperties( TDEConfig *config ); + virtual void readProperties( TDEConfig *config ); + + void readConfig(); + void writeConfig(); + + protected slots: + void enableLastSearchAction(); + void enableCopyTextAction(); + + private: + void stop(); + + private slots: + void slotGlossSelected(const GlossaryEntry &entry); + void slotStarted(TDEIO::Job *job); + void slotInfoMessage(TDEIO::Job *, const TQString &); + void goInternalUrl( const KURL & ); + /** + This function is called when the user clicks on a link in the viewer part. + */ + void slotOpenURLRequest( const KURL &url, + const KParts::URLArgs &args); + void documentCompleted(); + void slotIncFontSizes(); + void slotDecFontSizes(); + void slotConfigureFonts(); + void slotCopySelectedText(); + +private: + void updateZoomActions(); + + TQSplitter *mSplitter; + View *mDoc; + Navigator *mNavigator; + + TDEAction *mLastSearchAction; + TDEAction *mCopyText; + LogDialog *mLogDialog; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigator.cpp b/khelpcenter/navigator.cpp new file mode 100644 index 000000000..e05671ef2 --- /dev/null +++ b/khelpcenter/navigator.cpp @@ -0,0 +1,678 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <tqdir.h> +#include <tqfile.h> +#include <tqpixmap.h> +#include <tqstring.h> +#include <tqlabel.h> +#include <tqheader.h> +#include <tqdom.h> +#include <tqtextstream.h> +#include <tqregexp.h> +#include <tqlayout.h> +#include <tqlineedit.h> +#include <tqpushbutton.h> +#include <tqtooltip.h> + +#include <tdeaction.h> +#include <tdeapplication.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <tdeglobal.h> +#include <tdelocale.h> +#include <kdebug.h> +#include <tdelistview.h> +#include <tdemessagebox.h> +#include <kiconloader.h> +#include <kprocio.h> +#include <kcharsets.h> +#include <kdialog.h> +#include <kdesktopfile.h> +#include <kprotocolinfo.h> +#include <kservicegroup.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" + +#include "navigator.h" + +using namespace KHC; + +Navigator::Navigator( View *view, TQWidget *parent, const char *name ) + : TQWidget( parent, name ), mIndexDialog( 0 ), + mView( view ), mSelected( false ) +{ + TDEConfig *config = kapp->config(); + config->setGroup("General"); + mShowMissingDocs = config->readBoolEntry("ShowMissingDocs",false); + + mSearchEngine = new SearchEngine( view ); + connect( mSearchEngine, TQT_SIGNAL( searchFinished() ), + TQT_SLOT( slotSearchFinished() ) ); + + DocMetaInfo::self()->scanMetaInfo(); + + TQBoxLayout *topLayout = new TQVBoxLayout( this ); + + mSearchFrame = new TQFrame( this ); + topLayout->addWidget( mSearchFrame ); + + TQBoxLayout *searchLayout = new TQHBoxLayout( mSearchFrame ); + searchLayout->setSpacing( KDialog::spacingHint() ); + searchLayout->setMargin( 6 ); + + TQPushButton *clearButton = new TQPushButton( mSearchFrame ); + clearButton->setIconSet( TDEApplication::reverseLayout() ? + SmallIconSet( "clear_left" ) : SmallIconSet("locationbar_erase") ); + searchLayout->addWidget( clearButton ); + connect( clearButton, TQT_SIGNAL( clicked() ), TQT_SLOT( clearSearch() ) ); + TQToolTip::add( clearButton, i18n("Clear search") ); + + mSearchEdit = new TQLineEdit( mSearchFrame ); + searchLayout->addWidget( mSearchEdit ); + connect( mSearchEdit, TQT_SIGNAL( returnPressed() ), TQT_SLOT( slotSearch() ) ); + connect( mSearchEdit, TQT_SIGNAL( textChanged( const TQString & ) ), + TQT_SLOT( checkSearchButton() ) ); + + mSearchButton = new TQPushButton( i18n("&Search"), mSearchFrame ); + searchLayout->addWidget( mSearchButton ); + connect( mSearchButton, TQT_SIGNAL( clicked() ), TQT_SLOT( slotSearch() ) ); + + clearButton->setFixedHeight( mSearchButton->height() ); + + mTabWidget = new TQTabWidget( this ); + topLayout->addWidget( mTabWidget ); + + setupContentsTab(); + setupGlossaryTab(); + setupSearchTab(); + + insertPlugins(); + + if ( !mSearchEngine->initSearchHandlers() ) { + hideSearch(); + } else { + mSearchWidget->updateScopeList(); + mSearchWidget->readConfig( TDEGlobal::config() ); + } + + connect( mTabWidget, TQT_SIGNAL( currentChanged( QWidget * ) ), + TQT_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 TDEListView( mTabWidget ); + mContentsTree->setFrameStyle(TQFrame::Panel | TQFrame::Sunken); + mContentsTree->addColumn(TQString::null); + mContentsTree->setAllColumnsShowFocus(true); + mContentsTree->header()->hide(); + mContentsTree->setRootIsDecorated(false); + mContentsTree->setSorting(-1, false); + + connect(mContentsTree, TQT_SIGNAL(clicked(TQListViewItem*)), + TQT_SLOT(slotItemSelected(TQListViewItem*))); + connect(mContentsTree, TQT_SIGNAL(returnPressed(TQListViewItem*)), + TQT_SLOT(slotItemSelected(TQListViewItem*))); + mTabWidget->addTab(mContentsTree, i18n("&Contents")); +} + +void Navigator::setupSearchTab() +{ + mSearchWidget = new SearchWidget( mSearchEngine, mTabWidget ); + connect( mSearchWidget, TQT_SIGNAL( searchResult( const TQString & ) ), + TQT_SLOT( slotShowSearchResult( const TQString & ) ) ); + connect( mSearchWidget, TQT_SIGNAL( scopeCountChanged( int ) ), + TQT_SLOT( checkSearchButton() ) ); + connect( mSearchWidget, TQT_SIGNAL( showIndexDialog() ), + TQT_SLOT( showIndexDialog() ) ); + + mTabWidget->addTab( mSearchWidget, i18n("Search Options")); +} + +void Navigator::setupGlossaryTab() +{ + mGlossaryTree = new Glossary( mTabWidget ); + connect( mGlossaryTree, TQT_SIGNAL( entrySelected( const GlossaryEntry & ) ), + this, TQT_SIGNAL( glossSelected( const GlossaryEntry & ) ) ); + mTabWidget->addTab( mGlossaryTree, i18n( "G&lossary" ) ); +} + +void Navigator::insertPlugins() +{ + PluginTraverser t( this, mContentsTree ); + DocMetaInfo::self()->traverseEntries( &t ); + +#if 0 + kdDebug( 1400 ) << "<docmetainfo>" << endl; + DocEntry::List entries = DocMetaInfo::self()->docEntries(); + DocEntry::List::ConstIterator it; + for( it = entries.begin(); it != entries.end(); ++it ) { + (*it)->dump(); + } + kdDebug( 1400 ) << "</docmetainfo>" << endl; +#endif +} + +void Navigator::insertParentAppDocs( const TQString &name, NavigatorItem *topItem ) +{ + kdDebug(1400) << "Requested plugin documents for ID " << name << endl; + + KServiceGroup::Ptr grp = KServiceGroup::childGroup( name ); + if ( !grp ) + return; + + KServiceGroup::List entries = grp->entries(); + KServiceGroup::List::ConstIterator it = entries.begin(); + KServiceGroup::List::ConstIterator end = entries.end(); + for ( ; it != end; ++it ) { + TQString desktopFile = ( *it )->entryPath(); + if ( TQDir::isRelativePath( desktopFile ) ) + desktopFile = locate( "apps", desktopFile ); + createItemFromDesktopFile( topItem, desktopFile ); + } +} + +void Navigator::insertIOSlaveDocs( const TQString &name, NavigatorItem *topItem ) +{ + kdDebug(1400) << "Requested IOSlave documents for ID " << name << endl; + +#if KDE_IS_VERSION( 3, 1, 90 ) + TQStringList list = KProtocolInfo::protocols(); + list.sort(); + + NavigatorItem *prevItem = 0; + for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + { + TQString docPath = KProtocolInfo::docPath(*it); + if ( !docPath.isNull() ) + { + // First parameter is ignored if second is an absolute path + KURL url(KURL("help:/"), docPath); + TQString icon = KProtocolInfo::icon(*it); + if ( icon.isEmpty() ) icon = "document2"; + DocEntry *entry = new DocEntry( *it, url.url(), icon ); + NavigatorItem *item = new NavigatorItem( entry, topItem, prevItem ); + prevItem = item; + item->setAutoDeleteDocEntry( true ); + } + } +#else + Q_UNUSED( topItem ); +#endif +} + +void Navigator::insertAppletDocs( NavigatorItem *topItem ) +{ + TQDir appletDir( locate( "data", TQString::fromLatin1( "kicker/applets/" ) ) ); + appletDir.setNameFilter( TQString::fromLatin1( "*.desktop" ) ); + + TQStringList files = appletDir.entryList( TQDir::Files | TQDir::Readable ); + TQStringList::ConstIterator it = files.begin(); + TQStringList::ConstIterator end = files.end(); + for ( ; it != end; ++it ) + createItemFromDesktopFile( topItem, appletDir.absPath() + "/" + *it ); +} + +void Navigator::createItemFromDesktopFile( NavigatorItem *topItem, + const TQString &file ) +{ + KDesktopFile desktopFile( file ); + TQString docPath = desktopFile.readDocPath(); + if ( !docPath.isNull() ) { + // First parameter is ignored if second is an absolute path + KURL url(KURL("help:/"), docPath); + TQString icon = desktopFile.readIcon(); + if ( icon.isEmpty() ) icon = "document2"; + 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( TQT_TQOBJECT(this) ); + infoTree->build( topItem ); +} + +NavigatorItem *Navigator::insertScrollKeeperDocs( NavigatorItem *topItem, + NavigatorItem *after ) +{ + ScrollKeeperTreeBuilder *builder = new ScrollKeeperTreeBuilder( TQT_TQOBJECT(this) ); + return builder->build( topItem, after ); +} + +void Navigator::selectItem( const KURL &url ) +{ + kdDebug() << "Navigator::selectItem(): " << url.url() << endl; + + 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(TQString::null); + } + + // If the navigator already has the given URL selected, do nothing. + NavigatorItem *item; + item = static_cast<NavigatorItem *>( mContentsTree->selectedItem() ); + if ( item && mSelected ) { + KURL currentURL ( item->entry()->url() ); + if ( (currentURL == url) || (currentURL == alternativeURL) ) { + kdDebug() << "URL already shown." << endl; + return; + } + } + + // First, populate the NavigatorAppItems if we don't want the home page + if ( url != homeURL() ) { + for ( TQListViewItem *item = mContentsTree->firstChild(); item; + item = item->nextSibling() ) { + NavigatorAppItem *appItem = dynamic_cast<NavigatorAppItem *>( item ); + if ( appItem ) appItem->populate( true /* recursive */ ); + for ( TQListViewItem *subitem = item->firstChild(); subitem; + subitem = subitem->nextSibling() ) { + appItem = dynamic_cast<NavigatorAppItem *>( subitem ); + if ( appItem ) appItem->populate( true /* recursive */ ); + } + } + } + + TQListViewItemIterator it( mContentsTree ); + while ( it.current() ) { + NavigatorItem *item = static_cast<NavigatorItem *>( it.current() ); + 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->setSelected(item, true); + item->setOpen( true ); + mContentsTree->ensureItemVisible( item ); + break; + } + ++it; + } + if ( !it.current() ) { + clearSelection(); + } else { + mSelected = true; + } +} + +void Navigator::clearSelection() +{ + mContentsTree->clearSelection(); + mSelected = false; +} + +void Navigator::slotItemSelected( TQListViewItem *currentItem ) +{ + if ( !currentItem ) return; + + mSelected = true; + + NavigatorItem *item = static_cast<NavigatorItem *>( currentItem ); + + kdDebug(1400) << "Navigator::slotItemSelected(): " << item->entry()->name() + << endl; + + if ( item->childCount() > 0 || item->isExpandable() ) + item->setOpen( !item->isOpen() ); + + KURL url ( item->entry()->url() ); + + if ( url.protocol() == "khelpcenter" ) { + mView->closeURL(); + History::self().updateCurrentEntry( mView ); + History::self().createEntry(); + showOverview( item, url ); + } else { + if ( url.protocol() == "help" ) { + kdDebug( 1400 ) << "slotItemSelected(): Got help URL " << url.url() + << endl; + if ( !item->toc() ) { + TOC *tocTree = item->createTOC(); + kdDebug( 1400 ) << "slotItemSelected(): Trying to build TOC for " + << item->entry()->name() << endl; + tocTree->setApplication( url.directory() ); + TQString doc = View::langLookup( url.path() ); + // Enforce the original .docbook version, in case langLookup returns a + // cached version + if ( !doc.isNull() ) { + int pos = doc.find( ".html" ); + if ( pos >= 0 ) { + doc.replace( pos, 5, ".docbook" ); + } + kdDebug( 1400 ) << "slotItemSelected(): doc = " << doc << endl; + + tocTree->build( doc ); + } + } + } + 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 ); + + TQString fileName = locate( "data", "khelpcenter/index.html.in" ); + if ( fileName.isEmpty() ) + return; + + TQFile file( fileName ); + + if ( !file.open( IO_ReadOnly ) ) + return; + + TQTextStream stream( &file ); + TQString res = stream.read(); + + TQString title,name,content; + uint childCount; + + if ( item ) { + title = item->entry()->name(); + name = item->entry()->name(); + + TQString info = item->entry()->info(); + if ( !info.isEmpty() ) content = "<p>" + info + "</p>\n"; + + childCount = item->childCount(); + } else { + title = i18n("Start Page"); + name = i18n("The Trinity Help Center"); + + childCount = mContentsTree->childCount(); + } + + if ( childCount > 0 ) { + TQListViewItem *child; + if ( item ) child = item->firstChild(); + else child = mContentsTree->firstChild(); + + mDirLevel = 0; + + content += createChildrenList( child ); + } + else + content += "<p></p>"; + + res = res.arg(title).arg(name).arg(content); + + mView->write( res ); + + mView->end(); +} + +TQString Navigator::createChildrenList( TQListViewItem *child ) +{ + ++mDirLevel; + + TQString t; + + t += "<ul>\n"; + + while ( child ) { + NavigatorItem *childItem = static_cast<NavigatorItem *>( child ); + + DocEntry *e = childItem->entry(); + + t += "<li><a href=\"" + e->url() + "\">"; + if ( e->isDirectory() ) t += "<b>"; + t += e->name(); + if ( e->isDirectory() ) t += "</b>"; + t += "</a>"; + + if ( !e->info().isEmpty() ) { + t += "<br>" + e->info(); + } + + t += "</li>\n"; + + if ( childItem->childCount() > 0 && mDirLevel < 2 ) { + t += createChildrenList( childItem->firstChild() ); + } + + child = child->nextSibling(); + } + + t += "</ul>\n"; + + --mDirLevel; + + return t; +} + +void Navigator::slotSearch() +{ + kdDebug(1400) << "Navigator::slotSearch()" << endl; + + if ( !checkSearchIndex() ) return; + + if ( mSearchEngine->isRunning() ) return; + + TQString words = mSearchEdit->text(); + TQString method = mSearchWidget->method(); + int pages = mSearchWidget->pages(); + TQString scope = mSearchWidget->scope(); + + kdDebug(1400) << "Navigator::slotSearch() words: " << words << endl; + kdDebug(1400) << "Navigator::slotSearch() scope: " << scope << endl; + + if ( words.isEmpty() || scope.isEmpty() ) return; + + // disable search Button during searches + mSearchButton->setEnabled(false); + TQApplication::setOverrideCursor(tqwaitCursor); + + if ( !mSearchEngine->search( words, method, pages, scope ) ) { + slotSearchFinished(); + KMessageBox::sorry( this, i18n("Unable to run search program.") ); + } +} + +void Navigator::slotShowSearchResult( const TQString &url ) +{ + TQString u = url; + u.replace( "%k", mSearchEdit->text() ); + + emit itemSelected( u ); +} + +void Navigator::slotSearchFinished() +{ + mSearchButton->setEnabled(true); + TQApplication::restoreOverrideCursor(); + + kdDebug( 1400 ) << "Search finished." << endl; +} + +void Navigator::checkSearchButton() +{ + mSearchButton->setEnabled( !mSearchEdit->text().isEmpty() && + mSearchWidget->scopeCount() > 0 ); + mTabWidget->showPage( mSearchWidget ); +} + +void Navigator::hideSearch() +{ + mSearchFrame->hide(); + mTabWidget->removePage( mSearchWidget ); +} + +bool Navigator::checkSearchIndex() +{ + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "Search" ); + if ( cfg->readBoolEntry( "IndexExists", false ) ) return true; + + if ( mIndexDialog && mIndexDialog->isShown() ) return true; + + TQString text = i18n( "A search index does not yet exist. Do you want " + "to create the index now?" ); + + int result = KMessageBox::questionYesNo( this, text, TQString::null, + i18n("Create"), + i18n("Do Not Create"), + "indexcreation" ); + if ( result == KMessageBox::Yes ) { + showIndexDialog(); + return false; + } + + return true; +} + +void Navigator::slotTabChanged( TQWidget *wid ) +{ + if ( wid == mSearchWidget ) checkSearchIndex(); +} + +void Navigator::slotSelectGlossEntry( const TQString &id ) +{ + mGlossaryTree->slotSelectGlossEntry( id ); +} + +KURL Navigator::homeURL() +{ + if ( !mHomeUrl.isEmpty() ) return mHomeUrl; + + TDEConfig *cfg = TDEGlobal::config(); + // We have to reparse the configuration here in order to get a + // language-specific StartUrl, e.g. "StartUrl[de]". + cfg->reparseConfiguration(); + cfg->setGroup( "General" ); + mHomeUrl = cfg->readPathEntry( "StartUrl", "khelpcenter:home" ); + return mHomeUrl; +} + +void Navigator::showIndexDialog() +{ + if ( !mIndexDialog ) { + mIndexDialog = new KCMHelpCenter( mSearchEngine, this ); + connect( mIndexDialog, TQT_SIGNAL( searchIndexUpdated() ), mSearchWidget, + TQT_SLOT( updateScopeList() ) ); + } + mIndexDialog->show(); + mIndexDialog->raise(); +} + +void Navigator::readConfig() +{ + if ( Prefs::currentTab() == Prefs::Search ) { + mTabWidget->showPage( mSearchWidget ); + } else if ( Prefs::currentTab() == Prefs::Glossary ) { + mTabWidget->showPage( mGlossaryTree ); + } else { + mTabWidget->showPage( mContentsTree ); + } +} + +void Navigator::writeConfig() +{ + if ( mTabWidget->currentPage() == mSearchWidget ) { + Prefs::setCurrentTab( Prefs::Search ); + } else if ( mTabWidget->currentPage() == mGlossaryTree ) { + Prefs::setCurrentTab( Prefs::Glossary ); + } else { + Prefs::setCurrentTab( Prefs::Content ); + } +} + +void Navigator::clearSearch() +{ + mSearchEdit->setText( TQString::null ); +} + +#include "navigator.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigator.h b/khelpcenter/navigator.h new file mode 100644 index 000000000..f91de4327 --- /dev/null +++ b/khelpcenter/navigator.h @@ -0,0 +1,153 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 __navigator_h__ +#define __navigator_h__ + +#include "glossary.h" + +#include <tdelistview.h> +#include <kurl.h> + +#include <tqfile.h> +#include <tqtextstream.h> +#include <tqtimer.h> +#include <tqptrlist.h> +#include <tqtabwidget.h> +#include <tqlistview.h> +#include <tqdict.h> + +class TQPushButton; + +class TDEListView; +class KService; +class TDEProcess; +class KProcIO; + +class KCMHelpCenter; + +namespace KHC { + +class NavigatorItem; +class Navigator; +class View; +class SearchEngine; +class SearchWidget; +class Formatter; + +class Navigator : public TQWidget +{ + Q_OBJECT + public: + Navigator(View *, TQWidget *parent=0, const char *name=0); + virtual ~Navigator(); + + KURL homeURL(); + + SearchEngine *searchEngine() const; + Formatter *formatter() const; + + const GlossaryEntry &glossEntry(const TQString &term) const { return mGlossaryTree->entry( term ); } + + void insertParentAppDocs( const TQString &name, NavigatorItem *parent ); + void insertAppletDocs( NavigatorItem *parent ); + NavigatorItem *insertScrollKeeperDocs( NavigatorItem *parentItem, + NavigatorItem *after ); + void insertInfoDocs( NavigatorItem *parentItem ); + void insertIOSlaveDocs(const TQString &, NavigatorItem*parent); + + void createItemFromDesktopFile( NavigatorItem *item, const TQString &name ); + + bool showMissingDocs() const; + + void clearSelection(); + + void showOverview( NavigatorItem *item, const KURL &url ); + + void readConfig(); + void writeConfig(); + + public slots: + void openInternalUrl( const KURL &url ); + void slotItemSelected(TQListViewItem* index); + void slotSearch(); + void slotShowSearchResult( const TQString & ); + void slotSelectGlossEntry( const TQString &id ); + void selectItem( const KURL &url ); + void showIndexDialog(); + + signals: + void itemSelected(const TQString& itemURL); + void glossSelected(const GlossaryEntry &entry); + + protected slots: + void slotSearchFinished(); + void slotTabChanged( TQWidget * ); + void checkSearchButton(); + + bool checkSearchIndex(); + + void clearSearch(); + + protected: + TQString createChildrenList( TQListViewItem *child ); + + private: + void setupContentsTab(); + void setupIndexTab(); + void setupSearchTab(); + void setupGlossaryTab(); + + void insertPlugins(); + void hideSearch(); + + TDEListView *mContentsTree; + Glossary *mGlossaryTree; + + SearchWidget *mSearchWidget; + KCMHelpCenter *mIndexDialog; + + TQTabWidget *mTabWidget; + + TQFrame *mSearchFrame; + TQLineEdit *mSearchEdit; + TQPushButton *mSearchButton; + + TQPtrList<NavigatorItem> manualItems, pluginItems; + + bool mShowMissingDocs; + + SearchEngine *mSearchEngine; + + View *mView; + + KURL mHomeUrl; + + bool mSelected; + + KURL mLastUrl; + + int mDirLevel; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigatorappitem.cpp b/khelpcenter/navigatorappitem.cpp new file mode 100644 index 000000000..b2bee736e --- /dev/null +++ b/khelpcenter/navigatorappitem.cpp @@ -0,0 +1,147 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2001 Waldo Bastian <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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.h> +#include <kservicegroup.h> + +using namespace KHC; + +NavigatorAppItem::NavigatorAppItem( DocEntry *entry, TQListView *parent, + const TQString &relPath ) + : NavigatorItem( entry, parent ), + mRelpath( relPath ), + mPopulated( false ) +{ + setExpandable( true ); +} + +NavigatorAppItem::NavigatorAppItem( DocEntry *entry, TQListViewItem *parent, + const TQString &relPath ) + : NavigatorItem( entry, parent ), + mRelpath( relPath ), + mPopulated( false ) +{ + setExpandable( true ); +} + +NavigatorAppItem::NavigatorAppItem( DocEntry *entry, TQListView *parent, + TQListViewItem *after ) + : NavigatorItem( entry, parent, after ), + mPopulated( false ) +{ + setExpandable( true ); +} + +NavigatorAppItem::NavigatorAppItem( DocEntry *entry, TQListViewItem *parent, + TQListViewItem *after ) + : NavigatorItem( entry, parent, after ), + mPopulated( false ) +{ + setExpandable( true ); +} + +void NavigatorAppItem::setRelpath( const TQString &relpath ) +{ + mRelpath = relpath; +} + +void NavigatorAppItem::setOpen(bool open) +{ + kdDebug() << "NavigatorAppItem::setOpen()" << endl; + + if ( open && (childCount() == 0) && !mPopulated ) + { + kdDebug() << "NavigatorAppItem::setOpen(" << this << ", " + << mRelpath << ")" << endl; + populate(); + } + TQListViewItem::setOpen(open); +} + +void NavigatorAppItem::populate( bool recursive ) +{ + if ( mPopulated ) return; + + KServiceGroup::Ptr root = KServiceGroup::group(mRelpath); + if ( !root ) { + kdWarning() << "No Service groups\n"; + return; + } + KServiceGroup::List list = root->entries(); + + + for ( KServiceGroup::List::ConstIterator it = list.begin(); + it != list.end(); ++it ) + { + KSycocaEntry * e = *it; + KService::Ptr s; + NavigatorItem *item; + KServiceGroup::Ptr g; + TQString url; + + switch ( e->sycocaType() ) { + case KST_KService: + { + s = static_cast<KService*>(e); + url = documentationURL( s ); + if ( !url.isEmpty() ) { + DocEntry *entry = new DocEntry( s->name(), url, s->icon() ); + item = new NavigatorItem( entry, this ); + item->setAutoDeleteDocEntry( true ); + item->setExpandable( true ); + } + break; + } + case KST_KServiceGroup: + { + g = static_cast<KServiceGroup*>(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; + } + } + sortChildItems( 0, true /* ascending */ ); + mPopulated = true; +} + +TQString NavigatorAppItem::documentationURL( KService *s ) +{ + TQString docPath = s->property( "DocPath" ).toString(); + if ( docPath.isEmpty() ) + return TQString::null; + + if ( docPath.startsWith( "file:") || docPath.startsWith( "http:" ) ) + return docPath; + + return TQString( "help:/" ) + docPath; +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigatorappitem.h b/khelpcenter/navigatorappitem.h new file mode 100644 index 000000000..8ae3eac0d --- /dev/null +++ b/khelpcenter/navigatorappitem.h @@ -0,0 +1,58 @@ +/* + * navigatorappitem.h - part of the TDE Help Center + * + * Copyright (C) 2001 Waldo Bastian <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 __navigatorappitem_h___ +#define __navigatorappitem_h___ + +#include "navigatoritem.h" + +class KService; + +namespace KHC { + +class NavigatorAppItem : public NavigatorItem +{ + public: + NavigatorAppItem( DocEntry *entry, TQListView *parent, + const TQString &relPath ); + NavigatorAppItem( DocEntry *entry, TQListViewItem *parent, + const TQString &relPath ); + + NavigatorAppItem( DocEntry *entry, TQListView *parent, + TQListViewItem *after ); + NavigatorAppItem( DocEntry *entry, TQListViewItem *parent, + TQListViewItem *after ); + + void setRelpath( const TQString & ); + + virtual void setOpen(bool); + void populate( bool recursive = false ); + + protected: + TQString documentationURL( KService *s ); + + private: + TQString mRelpath; + bool mPopulated; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigatoritem.cpp b/khelpcenter/navigatoritem.cpp new file mode 100644 index 000000000..e20d979b6 --- /dev/null +++ b/khelpcenter/navigatoritem.cpp @@ -0,0 +1,105 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 <kdebug.h> +#include <kiconloader.h> + +using namespace KHC; + +NavigatorItem::NavigatorItem( DocEntry *entry, TQListView *parent, + TQListViewItem *after ) + : TQListViewItem( parent, after ) +{ + init( entry ); +} + +NavigatorItem::NavigatorItem( DocEntry *entry, TQListViewItem *parent, + TQListViewItem *after ) + : TQListViewItem( parent, after ) +{ + init( entry ); +} + +NavigatorItem::NavigatorItem( DocEntry *entry, TQListView *parent ) + : TQListViewItem( parent ) +{ + init( entry ); +} + +NavigatorItem::NavigatorItem( DocEntry *entry, TQListViewItem *parent ) + : TQListViewItem( 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() ); + setPixmap( 0, SmallIcon( entry()->icon() ) ); +} + +TOC *NavigatorItem::createTOC() +{ + mToc = new TOC( this ); + return mToc; +} + +void NavigatorItem::setOpen( bool open ) +{ + TQListViewItem::setOpen( open ); + + if ( entry()->icon().isEmpty() || entry()->icon() == "contents2" ) { + if ( open && childCount() > 0 ) setPixmap( 0, SmallIcon( "contents" ) ); + else setPixmap( 0, SmallIcon( "contents2" ) ); + } +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/navigatoritem.h b/khelpcenter/navigatoritem.h new file mode 100644 index 000000000..e460f8208 --- /dev/null +++ b/khelpcenter/navigatoritem.h @@ -0,0 +1,68 @@ +/* + * navigatoritem.h - part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 <tqlistview.h> + +namespace KHC { + +class TOC; +class DocEntry; + +class NavigatorItem : public TQListViewItem +{ + public: + NavigatorItem( DocEntry *entry, TQListView *parent ); + NavigatorItem( DocEntry *entry, TQListViewItem *parent ); + + NavigatorItem( DocEntry *entry, TQListView *parent, + TQListViewItem *after ); + NavigatorItem( DocEntry *entry, TQListViewItem *parent, + TQListViewItem *after ); + + ~NavigatorItem(); + + DocEntry *entry() const; + + void setAutoDeleteDocEntry( bool ); + + void updateItem(); + + TOC *toc() const { return mToc; } + + TOC *createTOC(); + + void setOpen( bool open ); + + private: + void init( DocEntry * ); + + TOC *mToc; + + DocEntry *mEntry; + bool mAutoDeleteDocEntry; +}; + +} + +#endif + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/pics/CMakeLists.txt b/khelpcenter/pics/CMakeLists.txt new file mode 100644 index 000000000..31014722a --- /dev/null +++ b/khelpcenter/pics/CMakeLists.txt @@ -0,0 +1,13 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +tde_install_icons( khelpcenter ) +tde_install_icons( helpdoc helpbook helpbook_open DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/icons ) diff --git a/khelpcenter/pics/Makefile.am b/khelpcenter/pics/Makefile.am new file mode 100644 index 000000000..dcfadd16a --- /dev/null +++ b/khelpcenter/pics/Makefile.am @@ -0,0 +1,6 @@ + +KDE_ICON = khelpcenter + +khelpcenter_ICON = helpdoc helpbook helpbook_open +khelpcenterdir = $(kde_datadir)/khelpcenter/icons + diff --git a/khelpcenter/pics/hi128-app-khelpcenter.png b/khelpcenter/pics/hi128-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..949fd3dce --- /dev/null +++ b/khelpcenter/pics/hi128-app-khelpcenter.png diff --git a/khelpcenter/pics/hi16-app-khelpcenter.png b/khelpcenter/pics/hi16-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..d242b4b3e --- /dev/null +++ b/khelpcenter/pics/hi16-app-khelpcenter.png diff --git a/khelpcenter/pics/hi22-app-khelpcenter.png b/khelpcenter/pics/hi22-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..71f59060a --- /dev/null +++ b/khelpcenter/pics/hi22-app-khelpcenter.png diff --git a/khelpcenter/pics/hi32-app-khelpcenter.png b/khelpcenter/pics/hi32-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..79dd450e8 --- /dev/null +++ b/khelpcenter/pics/hi32-app-khelpcenter.png diff --git a/khelpcenter/pics/hi48-app-khelpcenter.png b/khelpcenter/pics/hi48-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..24582cf57 --- /dev/null +++ b/khelpcenter/pics/hi48-app-khelpcenter.png diff --git a/khelpcenter/pics/hi64-app-khelpcenter.png b/khelpcenter/pics/hi64-app-khelpcenter.png Binary files differnew file mode 100644 index 000000000..6ea007cf8 --- /dev/null +++ b/khelpcenter/pics/hi64-app-khelpcenter.png diff --git a/khelpcenter/pics/hisc-app-khelpcenter.svgz b/khelpcenter/pics/hisc-app-khelpcenter.svgz Binary files differnew file mode 100644 index 000000000..65a9d2dc8 --- /dev/null +++ b/khelpcenter/pics/hisc-app-khelpcenter.svgz diff --git a/khelpcenter/plugins/Applications/.directory b/khelpcenter/plugins/Applications/.directory new file mode 100644 index 000000000..d672e64e1 --- /dev/null +++ b/khelpcenter/plugins/Applications/.directory @@ -0,0 +1,59 @@ +[Desktop Entry] +Name=Application Manuals +Name[bg]=Ръководства на аплети +Name[ca]=Manuals de les aplicacions +Name[cs]=Příručky aplikací +Name[csb]=Pòdrãczniczi aplikacëjów +Name[cy]=Llawlyfrau Cymhwysiad +Name[da]=Programmanualer +Name[de]=Handbücher zu Programmen +Name[el]=Εγχειρίδια εφαρμογής +Name[eo]=Manlibroj de Aplikaĵoj +Name[es]=Manuales de las aplicaciones +Name[et]=Rakenduste käsiraamatud +Name[fo]=Forritshandbøkur +Name[fr]=Manuels des applications +Name[hi]=अनुप्रयोग निर्देशिका +Name[hr]=Priručnici aplikacija +Name[hu]=Alkalmazások kézikönyvei +Name[is]=Handbækur forrita +Name[it]=Manuali applicazione +Name[ja]=アプリケーションマニュアル +Name[km]=សៀវភៅកម្មវិធី +Name[ko]=프로그램 사용 설명서 +Name[lo]=ແອບຟີເຄຊັ້ນ +Name[lt]=Programų vadovai +Name[lv]=Programmu rokasgrāmatas +Name[mn]=Програмын гарын авлага +Name[mt]=Manwali tal-Programmi +Name[nb]=Håndbok miniprogrammer +Name[nds]=Programmhandböker +Name[nl]=Programmahandboeken +Name[nn]=Programmanualar +Name[nso]=Di-Manual tsa Tshomiso +Name[pl]=Podręczniki programów +Name[pt]=Manuais das Aplicações +Name[pt_BR]=Manuais de Aplicativos +Name[ro]=Manualele aplicațiilor +Name[ru]=Руководства приложений +Name[sk]=Aplikačné manuály +Name[sl]=Priročniki za programe +Name[sr]=Упутства за програме +Name[sr@Latn]=Uputstva za programe +Name[sv]=Programhandböcker +Name[tg]=Дастури барномаҳо +Name[th]=คู่มือแอพพลิเคชั่น +Name[tr]=Uygulama Kılavuzları +Name[uk]=Підручники програм +Name[ven]=Apulikhesheni +Name[wa]=Esplikêyes do programe +Name[xh]=Isicelo Sesandla +Name[zh_TW]=應用程式手冊 +Name[zu]=Izincwadi zesandla Zomyaleli + +X-DOC-Weight=-500 + +X-TDE-KHelpcenter-Special=apps + +X-DOC-DocumentType=text/docbook +X-DOC-Identifier=tde_application_manuals diff --git a/khelpcenter/plugins/Applications/CMakeLists.txt b/khelpcenter/plugins/Applications/CMakeLists.txt new file mode 100644 index 000000000..d31a92243 --- /dev/null +++ b/khelpcenter/plugins/Applications/CMakeLists.txt @@ -0,0 +1,12 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES .directory DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Applications ) diff --git a/khelpcenter/plugins/Applications/Makefile.am b/khelpcenter/plugins/Applications/Makefile.am new file mode 100644 index 000000000..2aa425cde --- /dev/null +++ b/khelpcenter/plugins/Applications/Makefile.am @@ -0,0 +1,3 @@ + +applications_DATA = .directory +applicationsdir = $(kde_datadir)/khelpcenter/plugins/Applications diff --git a/khelpcenter/plugins/CMakeLists.txt b/khelpcenter/plugins/CMakeLists.txt new file mode 100644 index 000000000..6146d50f0 --- /dev/null +++ b/khelpcenter/plugins/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( Applications ) +add_subdirectory( Manpages ) +# add_subdirectory( Tutorials ) +# add_subdirectory( Scrollkeeper ) + +install( FILES + applets.desktop contact.desktop faq.desktop info.desktop + links.desktop support.desktop userguide.desktop welcome.desktop + hardwaremodules.desktop kcontrolmodules.desktop konqplugins.desktop + tdeioslaves.desktop quickstart.desktop visualdict.desktop adminguide.desktop + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins ) diff --git a/khelpcenter/plugins/Makefile.am b/khelpcenter/plugins/Makefile.am new file mode 100644 index 000000000..f15d537d4 --- /dev/null +++ b/khelpcenter/plugins/Makefile.am @@ -0,0 +1,10 @@ + +# SUBDIRS = Applications Manpages Tutorials Scrollkeeper +SUBDIRS = Applications Manpages + +plugin_DATA = applets.desktop contact.desktop faq.desktop info.desktop \ + links.desktop support.desktop userguide.desktop welcome.desktop \ + kicmodules.desktop kcontrolmodules.desktop konqplugins.desktop \ + tdeioslaves.desktop quickstart.desktop visualdict.desktop adminguide.desktop + +plugindir = $(kde_datadir)/khelpcenter/plugins diff --git a/khelpcenter/plugins/Manpages/.directory b/khelpcenter/plugins/Manpages/.directory new file mode 100644 index 000000000..cfdea1cfd --- /dev/null +++ b/khelpcenter/plugins/Manpages/.directory @@ -0,0 +1,60 @@ +[Desktop Entry] +Name=UNIX manual pages +Name[bg]=Ръководство за UNIX +Name[ca]=Pàgines de manual UNIX +Name[cs]=Unixové manuálové stránky +Name[csb]=Starnë manual UNIX-a +Name[cy]=Tudalennau llawlyfr UNIX +Name[da]=UNIX manualsider +Name[de]=UNIX-Handbuchseiten +Name[el]=Σελίδες man του UNIX +Name[eo]=Uniksaj Manpaĝoj +Name[es]=Páginas de manual de Unix +Name[et]=UNIX-i manuaalileheküljed +Name[fo]=Unix-handbøkur ("man"-snið) +Name[fr]=Pages du manuel UNIX +Name[hi]=यूनिक्स निर्देशिका पृष्� +Name[hr]=UNIX priručnici +Name[hu]=UNIX man oldalak +Name[is]=Síður UNIX handbóka +Name[it]=Pagine manuale UNIX +Name[ja]=UNIX マニュアルページ +Name[km]=ទំព័រសៀវភៅរបស់យូនីក +Name[ko]=UNIX 매뉴얼 페이지 +Name[lo]=ຊຸດຮູບແບບ KWM +Name[lt]=UNIX man (programų vadovų) puslapiai +Name[lv]=UNIX rokasgrāmatas +Name[mn]=UNIX-Гарын авлага хуудсууд +Name[mt]=Paġni tal-manwali UNIX +Name[nb]=Unix manualsider +Name[nds]=UNIX man-Sieden +Name[nl]=Unix-handboeken +Name[nn]=UNIX-manualsider +Name[nso]=Matlakala a manual wa 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[sk]=UNIX-ové manuálové stránky +Name[sl]=Strani priročnika za UNIX +Name[sr]=UNIX упутне стране +Name[sr@Latn]=UNIX uputne strane +Name[sv]=Unix manualsidor +Name[tg]=Дастури UNIX +Name[th]=หน้าคู่มือ UNIX +Name[tr]=UNIX kılavuz sayfaları +Name[uk]=Сторінки довідки UNIX +Name[ven]=Masiatari a UNIX +Name[wa]=Pådjes des esplikêyes UNIX +Name[xh]=UNIX amaphepha esandla +Name[zh_TW]=UNIX 手冊 +Name[zu]=Amakhasi Ezincwadi zesandla ze-UNIX + +DocPath=man:/ + +Icon=document2 + +X-DOC-Weight=500 +X-DOC-DocumentType=text/man +X-DOC-Identifier=manpages diff --git a/khelpcenter/plugins/Manpages/CMakeLists.txt b/khelpcenter/plugins/Manpages/CMakeLists.txt new file mode 100644 index 000000000..d6abb8a15 --- /dev/null +++ b/khelpcenter/plugins/Manpages/CMakeLists.txt @@ -0,0 +1,16 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + .directory man1.desktop man2.desktop man3.desktop + man4.desktop man5.desktop man6.desktop man7.desktop + man8.desktop man9.desktop mann.desktop + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Manpages ) diff --git a/khelpcenter/plugins/Manpages/Makefile.am b/khelpcenter/plugins/Manpages/Makefile.am new file mode 100644 index 000000000..81e2405d0 --- /dev/null +++ b/khelpcenter/plugins/Manpages/Makefile.am @@ -0,0 +1,4 @@ + +ManPages_DATA = .directory man1.desktop man2.desktop man3.desktop man4.desktop \ + man5.desktop man6.desktop man7.desktop man8.desktop man9.desktop mann.desktop +ManPagesdir = $(kde_datadir)/khelpcenter/plugins/Manpages diff --git a/khelpcenter/plugins/Manpages/man1.desktop b/khelpcenter/plugins/Manpages/man1.desktop new file mode 100644 index 000000000..e4b45a78f --- /dev/null +++ b/khelpcenter/plugins/Manpages/man1.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Name=(1) User Commands +Name[af]=(1) Gebruiker Opdragte +Name[ar]=(1) أوامر المستخدم +Name[be]=(1) Каманды карыстальніка +Name[bg]=(1) Потребителски команди +Name[br]=(1) Urzhiadoù arveriad +Name[bs]=(1) Korisničke naredbe +Name[ca]=(1) Ordres 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[eo]=(1) Uzantokomandoj +Name[es]=(1) Órdenes de usuario +Name[et]=(1) Kasutaja käsud +Name[eu]=(1) Erabiltzailearen komandoak +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) Comandos de Usuario +Name[he]=פקודות משתמש (1) +Name[hi]=(1) उपयोक्ता कमांड +Name[hr]=(1) Korisničke naredbe +Name[hu]=(1) Felhasználói parancsok +Name[is]=(1) Notandaskipanir +Name[it]=(1) Comandi utente +Name[ja]=(1) ユーザコマンド +Name[ka]=(1) მომხმარებლის ბრძანებები +Name[kk]=(1) Пайдаланушы командалар +Name[km]=(1) ពាក្យបញ្ជារបស់អ្នកប្រើ +Name[ko]=(1) 사용자 명령 +Name[lt]=(1) Naudotojo komandos +Name[lv]=(1) Lietotāja komandas +Name[mk]=(1) Кориснички команди +Name[ms]=(1) Arahan Pengguna +Name[mt]=(1) Kmandi tal-users +Name[nb]=(1) Brukerkommandoer +Name[nds]=(1) Brukerbefehlen +Name[ne]=(१) प्रयोगकर्ता आदेश +Name[nl]=(1) Gebruikercommando's +Name[nn]=(1) Brukarkommandoar +Name[pa]=(੧) ਉਪਭੋਗੀ ਕਮਾਂਡ +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[rw]= (1) Amabwiriza y'Ukoresha +Name[se]=(1) Geavaheaddjigohččumat +Name[sk]=(1) Používateľské príkazy +Name[sl]=(1) Uporabniški ukazi +Name[sr]=(1) Корисничке наредбе +Name[sr@Latn]=(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[tt]=(1) Qullanuçı Boyırığı +Name[uk]=(1) Команди користувача +Name[uz]=(1) Foydalanuvchi uchun buyruqlar +Name[uz@cyrillic]=(1) Фойдаланувчи учун буйруқлар +Name[vi]=(1) Lệnh của người dùng +Name[wa]=(1) Comandes d' uzeu +Name[zh_CN]=(1) 用户命令 +Name[zh_TW]=(1) 使用者命令 + +DocPath=man:/(1) diff --git a/khelpcenter/plugins/Manpages/man2.desktop b/khelpcenter/plugins/Manpages/man2.desktop new file mode 100644 index 000000000..8e1c68ab7 --- /dev/null +++ b/khelpcenter/plugins/Manpages/man2.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Name=(2) System Calls +Name[af]=(2) Stelsel Oproepe +Name[ar]=(2) نداءات النظام +Name[be]=(2) Сістэмныя выклікі +Name[bg]=(2) Системни сигнали +Name[bn]=(2) সিস্টেম কল +Name[br]=(3) Galvioù reizhiad +Name[bs]=(2) Sistemski pozivi +Name[ca]=(2) Crides al 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[eo]=(2) Sistemvokoj +Name[es]=(2) Llamadas de sistema +Name[et]=(2) Süsteemsed väljakutsed +Name[eu]=(2) Sistemaren 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[he]=קריאות מערכת (2) +Name[hi]=(2) सिस्टम काल्स +Name[hr]=(2) Sistemski pozivi +Name[hu]=(2) Rendszerhívások +Name[is]=(2) Kerfisköll +Name[it]=(2) Chiamate di sistema +Name[ja]=(2) システムコール +Name[ka]=(2) სისტემური გამოძახებები +Name[kk]=(2) Жүйелік шақырулар +Name[km]=(2) ការហៅប្រព័ន្ធ +Name[ko]=(2) 시스템 콜 +Name[lt]=(2) Sisteminiai iškvietimai +Name[lv]=(2) Sistēmas izsaukumi +Name[mk]=(2) Системски повици +Name[ms]=(2) Panggilan Sistem +Name[mt]=(2) Sejħiet tas-sistema +Name[nb]=(2) Systemkall +Name[nds]=(2) Systeemoprööp +Name[ne]=(२) प्रणाली कल +Name[nl]=(2) Systeemaanroepen +Name[nn]=(2) Systemkall +Name[pa]=(੨) ਸਿਸਟਮ ਕਾਲਾਂ +Name[pl]=(2) Funkcje systemowe +Name[pt]=(2) Chamadas do Sistema +Name[pt_BR]=(2) Chamadas de Sistema +Name[ro]=(2) Apeluri de sistem +Name[ru]=(2) Системные вызовы +Name[rw]=(2) Amahamagara Sisitemu +Name[se]=(2) Vuogádatgohččumat +Name[sk]=(2) Systémové volania +Name[sl]=(2) Sistemski klici +Name[sr]=(2) Системски позиви +Name[sr@Latn]=(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[tt]=(2) Sistem Çaqıruları +Name[uk]=(2) Системні виклики +Name[uz]=(2) Tizim chaqiruvlari +Name[uz@cyrillic]=(2) Тизим чақирувлари +Name[vi]=(2) Lệnh gọi hệ thống +Name[wa]=(2) Xhilete do sistinme +Name[zh_CN]=(2) 系统调用 +Name[zh_TW]=(2) 系統呼叫 + +DocPath=man:/(2) diff --git a/khelpcenter/plugins/Manpages/man3.desktop b/khelpcenter/plugins/Manpages/man3.desktop new file mode 100644 index 000000000..dba88eeb9 --- /dev/null +++ b/khelpcenter/plugins/Manpages/man3.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Name=(3) Subroutines +Name[af]=(3) Subroetines +Name[ar]=(3) الاجراءات الفرعية +Name[be]=(3) Падпраграмы +Name[bg]=(3) Подпрограми +Name[bn]=(3) সাবরুটিন +Name[br]=(3) Isroudennadoù +Name[bs]=(3) Podprogrami +Name[ca]=(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[eo]=(3) Subfunkcioj +Name[es]=(3) Subrutinas +Name[et]=(3) Alamfunktsioonid +Name[eu]=(3) Azpi-errutinak +Name[fa]=(۳) زیرروالها +Name[fi]=(3) Aliohjelmat +Name[fr]=(3) Sous-routines +Name[ga]=(3) Foghnáthaimh +Name[gl]=(3) Sub-rutinas +Name[he]=תת־שגרות (3) +Name[hi]=(3) सबरूटीन्स +Name[hr]=(3) Pod-rutine +Name[hu]=(3) Eljárások +Name[is]=(3) Stefjur +Name[it]=(3) Sotto procedure +Name[ja]=(3) サブルーチン +Name[ka]=(3) პროცედურები +Name[kk]=(3) Процедуралар +Name[km]=(3) ទម្រង់ការរង +Name[ko]=(3) 서브루틴 +Name[lo]=ໂດຣເອເທີຍ +Name[lt]=(3) Paprogramės +Name[lv]=(3) Subrutīnas +Name[mk]=(3) Потпрограми +Name[mn]=(3) Дэд горим +Name[ms]=(3) Subrutin +Name[nb]=(3) Delrutiner +Name[nds]=(3) Funkschonen +Name[ne]=(३) सबरुटिन +Name[nn]=(3) Subrutinar +Name[nso]=(3) Ditsejana +Name[pa]=(੩) ਸਬ-ਰੂਟੀਨ +Name[pl]=(3) Podprogramy +Name[pt]=(3) Sub-rotinas +Name[pt_BR]=(3) Subrotinas +Name[ro]=(3) Subrutine +Name[ru]=(3) Процедуры +Name[rw]=(3) Ibiceporogaramu +Name[se]=(3) Vuollerutiinnat +Name[sk]=(3) Podprogramy +Name[sl]=(3) Podrutine +Name[sr]=(3) Подрутине +Name[sr@Latn]=(3) Podrutine +Name[sv]=(3) Subrutiner +Name[ta]=(3)மற்ற நடைமுறைகள் +Name[te]=(3) సబ్ రొటిన్లు +Name[tg]=(3) Маросим +Name[th]=(3) รูทีนย่อย +Name[tr]=(3) Alt yordamlar +Name[tt]=(3) Eçprogram +Name[uk]=(3) Підпрограми +Name[ven]=(3) Ndila +Name[vi]=(3) Chương trình con +Name[wa]=(3) Sorprogrames +Name[xh]=(3) Ulwenzeko rhoqo olusezantsi +Name[zh_CN]=(3) 子例程 +Name[zh_TW]=(3) 子程式 +Name[zu]=(3) iqoqo lemisebenzana + +DocPath=man:/(3) diff --git a/khelpcenter/plugins/Manpages/man4.desktop b/khelpcenter/plugins/Manpages/man4.desktop new file mode 100644 index 000000000..22841b6ce --- /dev/null +++ b/khelpcenter/plugins/Manpages/man4.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Name=(4) Devices +Name[af]=(4) Toestelle +Name[ar]=(4) الأجهزة +Name[be]=(4) Прылады +Name[bg]=(4) Устройства +Name[bn]=(4) ডিভাইস +Name[br]=(4) Trobarzhelloù +Name[bs]=(4) Uređaji +Name[ca]=(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[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[he]=התקנים (4) +Name[hi]=(4) औज़ार +Name[hr]=(4) Uređaji +Name[hu]=(4) Eszközök +Name[is]=(4) Tæki +Name[it]=(4) Dispositivi +Name[ja]=(4) デバイス +Name[ka]=(4) მოწყობილობები +Name[kk]=(4) Құрылғылар +Name[km]=(4) ឧបករណ៍ +Name[ko]=(4) 장치 +Name[lo]=ອຸປະກອນ +Name[lt]=(4) Įrenginiai +Name[lv]=(4) Iekārtas +Name[mk]=(4) Уреди +Name[mn]=(4) Төхөөрөмж +Name[ms]=(4) Peranti +Name[mt]=(4) Apparat +Name[nb]=(4) Enheter +Name[nds]=(4) Reedschappen +Name[ne]=(४) यन्त्र +Name[nl]=(4) Apparaten +Name[nn]=(4) Einingar +Name[nso]=(4) Maano +Name[pa]=(੪) ਜੰਤਰ +Name[pl]=(4) Urządzenia +Name[pt]=(4) Dispositivos +Name[pt_BR]=(4) Dispositivos +Name[ro]=(4) Dispozitive +Name[ru]=(4) Устройства +Name[rw]= (4) Amapareye +Name[se]=(4) Ovttadagat +Name[sk]=(4) Zariadenia +Name[sl]=(4) Naprave +Name[sr]=(4) Уређаји +Name[sr@Latn]=(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[tt]=(4) Cıhazlar +Name[uk]=(4) Пристрої +Name[uz]=(4) Uskunalar +Name[uz@cyrillic]=(4) Ускуналар +Name[ven]=(4)Maano +Name[vi]=(4) Thiết bị +Name[wa]=(4) Éndjins +Name[xh]=(4) Amacebo +Name[zh_CN]=(4) 设备 +Name[zh_TW]=(4) 裝置 +Name[zu]=(4) Amathuluzi anenjongo + +DocPath=man:/(4) diff --git a/khelpcenter/plugins/Manpages/man5.desktop b/khelpcenter/plugins/Manpages/man5.desktop new file mode 100644 index 000000000..8b3fa916c --- /dev/null +++ b/khelpcenter/plugins/Manpages/man5.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Name=(5) File Formats +Name[af]=(5) Lêer Formate +Name[ar]=(5) هيئات الملفات +Name[be]=(5) Фарматы файлаў +Name[bg]=(5) Файлови формати +Name[bn]=(5) ফাইল ফরম্যাট +Name[br]=(5) Furmadoù ar restroù +Name[bs]=(5) Formati datoteka +Name[ca]=(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[eo]=(5) Dosierformatoj +Name[es]=(5) Formatos de archivo +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[gl]=(5) Formatos de Ficheiro +Name[he]=תבניות קבצים (5) +Name[hi]=(5) फ़ाइल फार्मेट्स +Name[hr]=(5) Oblici datoteka +Name[hsb]=(5) Datajowe formaty +Name[hu]=(5) Fájlformátumok +Name[is]=(5) Skráasnið +Name[it]=(5) Formato dei file +Name[ja]=(5) ファイルフォーマット +Name[ka]=(5) ფაილთა ფორმატები +Name[kk]=(5) Файл пішімдері +Name[km]=(5) ទ្រង់ទ្រាយឯកសារ +Name[ko]=(5) 파일 형식 +Name[lo]=ສູດຄະນິດສາດ - K +Name[lt]=(5) Bylų formatai +Name[lv]=(5) Failu formāti +Name[mk]=(5) Формати на датотеки +Name[mn]=(5) Файлын хэлбэр +Name[ms]=(5) Format Fail +Name[mt]=(5) Formats tal-fajls +Name[nb]=(5) Filformat +Name[nds]=(5) Dateiformaten +Name[ne]=(५) फाइल ढाँचा +Name[nl]=(5) Bestandsformaten +Name[nn]=(5) Filformat +Name[nso]=(5) Dithlolego tsa Faele +Name[pa]=(੫) ਫਾਇਲ ਫਾਰਮਿਟ +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[rw]= (5) Imiterere y'Idosiye +Name[se]=(5) Fiilaformáhtat +Name[sk]=(5) Formáty súborov +Name[sl]=(5) Vrste datotek +Name[sr]=(5) Формати фајлова +Name[sr@Latn]=(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[tt]=(5) Birem Töre +Name[uk]=(5) Формати файлів +Name[uz]=(5) Fayl formatlari +Name[uz@cyrillic]=(5) Файл форматлари +Name[ven]=(5) Tshivhumbeo tsha Faela +Name[vi]=(5) Định dạng Tập tin +Name[wa]=(5) Sôres di fitchîs +Name[xh]=(5) Ifomati Yeefayile +Name[zh_CN]=(5) 文件格式 +Name[zh_TW]=(5) 檔案格式 +Name[zu]=(5) Izakhiwo zamafayela + +DocPath=man:/(5) diff --git a/khelpcenter/plugins/Manpages/man6.desktop b/khelpcenter/plugins/Manpages/man6.desktop new file mode 100644 index 000000000..415fe718f --- /dev/null +++ b/khelpcenter/plugins/Manpages/man6.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Name=(6) Games +Name[af]=(6) Speletjies +Name[ar]=(6) الألعاب +Name[be]=(6) Гульні +Name[bg]=(6) Игри +Name[bn]=(6) খেলা +Name[br]=(6) C'hoarioù +Name[bs]=(6) Igre +Name[ca]=(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[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[he]=משחקים (6) +Name[hi]=(6) खेल +Name[hr]=(6) Igre +Name[hsb]=(6) Hry +Name[hu]=(6) Játékok +Name[is]=(6) Leikir +Name[it]=(6) Giochi +Name[ja]=(6) ゲーム +Name[ka]=(6) თამაშები +Name[kk]=(6) Ойындар +Name[km]=(6) ល្បែង +Name[ko]=(6) 게임 +Name[lo]=ເກມສ์ +Name[lt]=(6) Žaidimai +Name[lv]=(6) Spēles +Name[mk]=(6) Игри +Name[mn]=(6) Тоглоом +Name[ms]=(6) Permainan +Name[mt]=(6) Logħob +Name[nb]=(6) Spill +Name[nds]=(6) Spelen +Name[ne]=(६) खेल +Name[nl]=(6) Spelletjes +Name[nn]=(6) Spel +Name[nso]=(6) Dipapadi +Name[pa]=(੬) ਖੇਡਾਂ +Name[pl]=(6) Gry +Name[pt]=(6) Jogos +Name[pt_BR]=(6) Jogos +Name[ro]=(6) Jocuri +Name[ru]=(6) Игры +Name[rw]= (6) Imikino +Name[se]=(6) Spealut +Name[sk]=(6) Hry +Name[sl]=(6) Igre +Name[sr]=(6) Игре +Name[sr@Latn]=(6) Igre +Name[sv]=(6) Spel +Name[ta]=(6) விளையாட்டுகள் +Name[te]=(6) ఆటలు +Name[tg]=(6) Бозиҳо +Name[th]=(6) เกม +Name[tr]=(6) Oyunlar +Name[tt]=(6) Uyınnar +Name[uk]=(6) Ігри +Name[uz]=(6) Oʻyinlar +Name[uz@cyrillic]=(6) Ўйинлар +Name[ven]=(6) Mitambo +Name[vi]=(6) Trò chơi +Name[wa]=(6) Djeus +Name[xh]=(6) Imidlalo +Name[zh_CN]=(6) 游戏 +Name[zh_TW]=(6) 遊戲 +Name[zu]=(6) Imidlalo + +DocPath=man:/(6) diff --git a/khelpcenter/plugins/Manpages/man7.desktop b/khelpcenter/plugins/Manpages/man7.desktop new file mode 100644 index 000000000..24c6e14ef --- /dev/null +++ b/khelpcenter/plugins/Manpages/man7.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Name=(7) Miscellaneous +Name[af]=(7) Allerlei +Name[ar]=(7) المتفرقات +Name[be]=(7) Рознае +Name[bg]=(7) Разни +Name[bn]=(7) বিবিধ +Name[br]=(7) A bep seurt +Name[bs]=(7) Razno +Name[ca]=(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[eo]=(7) Diversaj +Name[es]=(7) Varios +Name[et]=(7) Muud +Name[eu]=(7) Hainbat +Name[fa]=(۷) متفرقه +Name[fi]=(7) Sekalaista +Name[fr]=(7) Divers +Name[fy]=(7) Ferskate +Name[gl]=(7) Miscelánea +Name[he]=שונות (7) +Name[hi]=(7) विविध +Name[hr]=(7) Razno +Name[hu]=(7) Egyéb +Name[is]=(7) Ýmislegt +Name[it]=(7) Varie +Name[ja]=(7) その他 +Name[ka]=(7) სხვადასხვა +Name[kk]=(7) Әр түрлі +Name[km]=(7) ផ្សេងៗ +Name[ko]=(7) 기타 +Name[lo]=ກູ້ລະເບິດ - K +Name[lt]=(7) Įvairūs dalykai +Name[lv]=(7) Dažādi +Name[mk]=(7) Разно +Name[mn]=(7) Юм юмнаас +Name[ms]=(7) Pelbagai +Name[mt]=(7) Imħalltin +Name[nb]=(7) Diverse +Name[nds]=(7) Annerswat +Name[ne]=(७) विविध +Name[nl]=(7) Diversen +Name[nn]=(7) Ymse +Name[nso]=(7) Hlakahlakanego +Name[pa]=(੭) ਫੁਟਕਲ +Name[pl]=(7) Różne +Name[pt]=(7) Diversos +Name[pt_BR]=(7) Outros +Name[ro]=(7) Diverse +Name[ru]=(7) Разное +Name[rw]= (7) Binyuranye +Name[se]=(7) Feará mii +Name[sk]=(7) Rôzne +Name[sl]=(7) Razno +Name[sr]=(7) Разно +Name[sr@Latn]=(7) Razno +Name[sv]=(7) Diverse +Name[ta]=(7) மற்ற +Name[te]=(7) ఇతర +Name[tg]=(7) Гуногун +Name[th]=(7) เบ็ดเตล็ด +Name[tr]=(7) Çeşitli +Name[tt]=(7) Başqalar +Name[uk]=(7) Різне +Name[uz]=(7) Har xil +Name[uz@cyrillic]=(7) Ҳар хил +Name[ven]=(7) Zwisi zwavhudi +Name[vi]=(7) Linh tinh +Name[wa]=(7) Totès sôres +Name[xh]=(7) Ezixubeneyo +Name[zh_CN]=(7) 杂项 +Name[zh_TW]=(7) 雜項 +Name[zu]=(7) Ingxubevange + +DocPath=man:/(7) diff --git a/khelpcenter/plugins/Manpages/man8.desktop b/khelpcenter/plugins/Manpages/man8.desktop new file mode 100644 index 000000000..2caad71dd --- /dev/null +++ b/khelpcenter/plugins/Manpages/man8.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +Name=(8) Sys. Administration +Name[af]=(8) Sys. Administrasie +Name[ar]=(8) إدارة النظام +Name[be]=(8) Сістэмнае адміністраванне +Name[bg]=(8) Администрация +Name[bn]=(8) সিস্টেম অ্যাডমিনস্ট্রেশন +Name[br]=(8) Melestradur ar reizhiad +Name[bs]=(8) Administracija sistema +Name[ca]=(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[eo]=(8) Sistemadministrado +Name[es]=(8) Administración del sistema +Name[et]=(8) Süsteemi administreerimine +Name[eu]=(8) Sist. kudeaketa +Name[fa]=(۸) سرپرستی سیستم +Name[fi]=(8) Järjestelmänhallinta +Name[fr]=(8) Administration système +Name[fy]=(8) Systeembehear +Name[gl]=(8) Administración do Sistema +Name[he]=ניהול המערכת (8) +Name[hi]=(8) तंत्र प्रशासन +Name[hr]=(8) Administracija sustava +Name[hu]=(8) Rendszeradminisztráció +Name[is]=(8) Kerfisstjórnun +Name[it]=(8) Amministrazione di sistema +Name[ja]=(8) システム管理 +Name[ka]=(8) სისტემური ადმინისტრირება +Name[kk]=(8) Жүйе әкімшілігі +Name[km]=(8) ការគ្រប់គ្រងប្រព័ន្ធ +Name[ko]=(8) 시스템 관리 +Name[lo]=SAM - ສຳລັບຜູ້ດູແລລະບົບ +Name[lt]=(8) Sist. administravimas +Name[lv]=(8) Sistēmas Administrācija +Name[mk]=(8) Системска администрација +Name[mn]=(8) Системийн зохион байгуулагч +Name[ms]=(8) Pentadbiran Sistem +Name[mt]=(8) Amministrazzjoni tas-sistema +Name[nb]=(8) Systemadministrasjon +Name[nds]=(8) Systeempleeg +Name[ne]=(८) प्रणाली प्रशासन +Name[nl]=(8) Systeembeheer +Name[nn]=(8) Systemadministrasjon +Name[nso]=(8) Bongwaledi bja System +Name[pa]=(੮) ਸਿਸਟਮ ਪਰਬੰਧਨ +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[rw]= (8) Iyobora rya Sisitemu +Name[se]=(8) Vuogádathálddašeapmi +Name[sk]=(8) Administrácia systému +Name[sl]=(8) Sistemsko upravljanje +Name[sr]=(8) Администрација система +Name[sr@Latn]=(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[tt]=(8) Sistem İdäräse +Name[uk]=(8) Сист. адміністрування +Name[uz]=(8) Tizimni boshqarish +Name[uz@cyrillic]=(8) Тизимни бошқариш +Name[ven]=(8) Ndangulo ya sisitemu +Name[vi]=(8) Quản trị Hệ thống +Name[wa]=(8) Manaedjmint do sistinme +Name[zh_CN]=(8) 系统管理 +Name[zh_TW]=(8) 系統管理 +Name[zu]=(8) Ukugcinwa kwesistimu + +DocPath=man:/(8) diff --git a/khelpcenter/plugins/Manpages/man9.desktop b/khelpcenter/plugins/Manpages/man9.desktop new file mode 100644 index 000000000..9893a028f --- /dev/null +++ b/khelpcenter/plugins/Manpages/man9.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Name=(9) Kernel +Name[ar]=(9) النواة +Name[be]=(9) Ядро +Name[bg]=(9) Ядро +Name[bn]=(9) কার্নেল +Name[br]=(9) Kalon +Name[ca]=(9) Nucli +Name[cs]=(9) Jádro +Name[csb]=(9) Jądro systemë +Name[cy]=(9) Cnewyllen +Name[da]=(9) Kerne +Name[el]=(9) Πυρήνας +Name[eo]=(9) Kerno +Name[es]=(9) Núcleo +Name[eu]=(9) Kernela +Name[fa]=(۹) هسته +Name[fi]=(9) Ydin +Name[fr]=(9) Kernel (Noyau) +Name[ga]=(9) Eithne +Name[gl]=(9) Núcleo +Name[he]=גרעין (9) +Name[hi]=(9) कर्नेल +Name[is]=(9) Kjarni +Name[ja]=(9) カーネル +Name[ka]=(9) ბირთვი +Name[kk]=(9) Өзегі +Name[km]=(9) ខឺណែល +Name[ko]=(9) 커널 +Name[lo]=ເທອຣມີນອລຂອງ X +Name[lt]=(9) Branduolys +Name[lv]=(9) Kodols +Name[mk]=(9) Кернел +Name[mn]=(9) ҮС-н цөм +Name[nb]=(9) Kjerne +Name[nds]=(9) Kernel (Karn vun't Bedriefsysteem) +Name[ne]=(९) कर्नेल +Name[nn]=(9) Kjerne +Name[pa]=(੯) ਕਰਨਲ +Name[pl]=(9) Jądro systemu +Name[pt]=(9) 'Kernel' +Name[ru]=(9) Ядро +Name[rw]= (9) Intima +Name[se]=(9) Čoahkku +Name[sk]=(9) Jadro +Name[sl]=(9) Jedro +Name[sr]=(9) Кернел +Name[sv]=(9) Kärna +Name[ta]=(9) கெர்னல் +Name[te]=(9) కెర్నెల్ +Name[tg]=(9) Асосӣ +Name[th]=(9) เคอร์เนล +Name[tr]=(9) Çekirdek +Name[tt]=(9) Töş +Name[uk]=(9) Ядро +Name[uz@cyrillic]=(9) Кернел +Name[vi]=(9) Nhân Linux +Name[wa]=(9) Fonccions do nawea linux +Name[zh_CN]=(9) 内核 +Name[zh_TW]=(9) 核心 + +DocPath=man:/(9) diff --git a/khelpcenter/plugins/Manpages/mann.desktop b/khelpcenter/plugins/Manpages/mann.desktop new file mode 100644 index 000000000..75c1e227e --- /dev/null +++ b/khelpcenter/plugins/Manpages/mann.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Name=(n) New +Name[af]=(n) Nuwe +Name[ar]=(n) جديد +Name[be]=(n) Новыя +Name[bg]=(n) Нови +Name[bn]=(n) নতুন +Name[br]=(n) Nevez +Name[bs]=(n) Novo +Name[ca]=(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[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[he]=חדש (n) +Name[hi]=(n) नया +Name[hr]=(n) Novo +Name[hu]=(n) Új +Name[is]=(n) Nýtt +Name[it]=(n) Nuovi +Name[ja]=(n) 新規 +Name[ka]=(n) ახალი +Name[kk]=(n) Жаңа +Name[km]=(n) ថ្មី +Name[ko]=(n) 새로운 항목 +Name[lo]=ຂ່າວ - K +Name[lt]=(n) Nauji dalykai +Name[lv]=(n) Jauns +Name[mk]=(n) Нови +Name[mn]=(n) Шинэ +Name[ms]=(n) Baru +Name[mt]=(n) Ġodda +Name[nb]=(n) Ny +Name[nds]=(n) Nieg +Name[ne]=(n) नयाँ +Name[nl]=(n) Nieuw +Name[nn]=(n) Ny +Name[nso]=(n) Ntshwa +Name[pa]=(n) ਨਵਾਂ +Name[pl]=(n) nowe +Name[pt]=(n) Novos +Name[pt_BR]=(n) Novo +Name[ro]=(n) Nou +Name[ru]=(n) Новые +Name[rw]= (n) Gishya +Name[se]=(n) Ođđa +Name[sk]=(n) Nové +Name[sl]=(n) Novo +Name[sr]=(n) Ново +Name[sr@Latn]=(n) Novo +Name[sv]=(n) Ny +Name[ta]=(n) புதிய +Name[te]=(n) కొత్త +Name[tg]=(n) Нав +Name[th]=(n) ใหม่ +Name[tr]=(n) Yeni +Name[tt]=(n) Yaña +Name[uk]=(n) Нові +Name[uz]=(n) Yangi +Name[uz@cyrillic]=(n) Янги +Name[ven]=(n) Tshiswa +Name[vi]=(n) Tin tức +Name[wa]=(n) Novea +Name[xh]=(n) Entsha +Name[zh_CN]=(n) 新建 +Name[zh_TW]=(n) 新 +Name[zu]=(n) Okusha + +DocPath=man:/(n) diff --git a/khelpcenter/plugins/Scrollkeeper/.directory b/khelpcenter/plugins/Scrollkeeper/.directory new file mode 100644 index 000000000..8148db1c5 --- /dev/null +++ b/khelpcenter/plugins/Scrollkeeper/.directory @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Scrollkeeper +Name[eo]=Dokumentara Katalogo +Name[hi]=स्क्रॉलकीपर +Name[hr]=Držač klizanja +Name[km]=ឧបករណ៍រក្សារមូរ +Name[lo]=ໂປຣແກຣມຮັກສາຈໍພາບ +Icon=contents2 +X-DOC-Weight=-400 diff --git a/khelpcenter/plugins/Scrollkeeper/CMakeLists.txt b/khelpcenter/plugins/Scrollkeeper/CMakeLists.txt new file mode 100644 index 000000000..fe2acd80f --- /dev/null +++ b/khelpcenter/plugins/Scrollkeeper/CMakeLists.txt @@ -0,0 +1,14 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + .directory scrollkeeper.desktop + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Scrollkeeper ) diff --git a/khelpcenter/plugins/Scrollkeeper/Makefile.am b/khelpcenter/plugins/Scrollkeeper/Makefile.am new file mode 100644 index 000000000..da5dc8f37 --- /dev/null +++ b/khelpcenter/plugins/Scrollkeeper/Makefile.am @@ -0,0 +1,3 @@ + +applications_DATA = .directory scrollkeeper.desktop +applicationsdir = $(kde_datadir)/khelpcenter/plugins/Scrollkeeper diff --git a/khelpcenter/plugins/Scrollkeeper/scrollkeeper.desktop b/khelpcenter/plugins/Scrollkeeper/scrollkeeper.desktop new file mode 100644 index 000000000..e3449b8c1 --- /dev/null +++ b/khelpcenter/plugins/Scrollkeeper/scrollkeeper.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +X-TDE-KHelpcenter-Special=scrollkeeper diff --git a/khelpcenter/plugins/Tutorials/.directory b/khelpcenter/plugins/Tutorials/.directory new file mode 100644 index 000000000..4601538b8 --- /dev/null +++ b/khelpcenter/plugins/Tutorials/.directory @@ -0,0 +1,107 @@ +[Desktop Entry] +Name=Tutorials +Name[bg]=Ръководства +Name[ca]=Programes d'aprenentatge +Name[cs]=Návody +Name[csb]=Tutoriale +Name[cy]=Hyfforddiadau +Name[da]=Øvelser +Name[de]=Anleitungen +Name[el]=Οδηγός χρήσης +Name[eo]=Eklerniloj +Name[es]=Tutoriales +Name[et]=Õppematerjalid +Name[fo]=Skeið +Name[fr]=Didactitiels +Name[hr]=Praktični vodič +Name[hu]=Bevezetők +Name[id]=Tutorial +Name[is]=Kennsluefni +Name[it]=Esercitazioni +Name[ja]=チュートリアル +Name[km]=បង្រៀន +Name[ko]=따라하기 +Name[lo]=ການສອນ +Name[lt]=Vadovai +Name[mn]=Давтлага +Name[nb]=Veivisere +Name[nds]=Inföhren +Name[nl]=Handleidingen +Name[nn]=Innføringar +Name[nso]=Dithutokopana +Name[oc]=Introduccions +Name[pl]=Podręczniki +Name[pt]=Tutoriais +Name[pt_BR]=Tutoriais +Name[ro]=Tutoriale +Name[ru]=Обучение +Name[sk]=Návody +Name[sl]=Učbeniki +Name[sr]=Туторијали +Name[sr@Latn]=Tutorijali +Name[sv]=Handledningar +Name[tg]=Дастурҳо +Name[th]=ฝึกสอน +Name[tr]=Kılavuzlar +Name[uk]=Посібники +Name[ven]=Dzikilasi dzau haseledza +Name[wa]=Tutoriås +Name[xh]=Izifundo zokuzikhumbuza +Name[zh_TW]=教學 +Name[zu]=izifundo zokubuyekeza +MiniIcon= +Comment=Tutorial and introduction documents. +Comment[az]=Leksika və giriş sənədləri +Comment[bg]=Ръководства и документи. +Comment[br]=Kelennant ha teulioù deraouiñ. +Comment[ca]=Curs d'aprenentatge i documents d'introducció. +Comment[cs]=Návody a základní dokumenty. +Comment[csb]=Tutorial ë wprowadzającé dokùmentë. +Comment[cy]=Dogfenni cyflwyniad a hyfforddiadol +Comment[da]=Øvelses- og introduktionsdokumenter. +Comment[de]=Anleitungen und Einführungen +Comment[el]=Οδηγός χρήσης και έγγραφα παρουσίασης. +Comment[eo]=Eklernilaj kaj enkondukaj dokumentoj +Comment[es]=Tutorial y documentos de introducción. +Comment[et]=Õppematerjalid ja sissejuhatused. +Comment[fr]=Didactitiels et documents de présentation +Comment[hi]=शिक्षण पाठ तथा परिचय दस्तावेज़ +Comment[hr]=Praktični vodič i uvodni dokumenti. +Comment[hu]=Bevezető jellegű dokumentumok. +Comment[id]=Tutorial dan dokumen Pengenalan +Comment[is]=Kennslu- og kynningarefni. +Comment[it]=Esercitazione e documenti introduttivi. +Comment[ja]=チュートリアルと導入用ドキュメント +Comment[km]=ឯកសារបង្រៀន និងណែនាំ ។ +Comment[ko]=소개와 따라하기 글입니다. +Comment[lo]=ການສອນແລະເອກະສານແນະນຳ +Comment[lt]=Vadovai ir įvadiniai dokumentai +Comment[lv]=Ievada un konsultāciju dokumenti. +Comment[mn]=Давтлага ба удиртгал баримтууд +Comment[mt]=Spjega u dokumenti ta' introduzzjoni. +Comment[nb]=Veivisere og introduksjonsdokumenter +Comment[nds]=Anleed- un Inföhrdokmenten +Comment[nl]=Handleiding en inleidende documenten. +Comment[nn]=Innføringar og introduksjonsdokument. +Comment[nso]=Thutokopana le ditokomane tsa matseno. +Comment[oc]=Documents e curs d'introduccion. +Comment[pl]=Podręczniki i dokumenty dla początkujących. +Comment[pt]=Tutoriais e documentos introdutórios. +Comment[pt_BR]=Tutoriais e documentos introdutórios. +Comment[ro]=Documente introductive și tutoriale. +Comment[ru]=Документы по обучению. +Comment[sk]=Dokumenty s úvodom a návodmi. +Comment[sl]=Učbenik in uvodni dokumenti +Comment[sr]=Туторијали и уводни документи. +Comment[sr@Latn]=Tutorijali i uvodni dokumenti. +Comment[sv]=Handlednings- och introduktionsdokument. +Comment[tg]=Дастурҳо ва ҳуҷҷатҳои пешниҳод +Comment[th]=เอกสารแนะนำและฝึกสอน +Comment[tr]=Kılavuzlar ve belgeler +Comment[uk]=Інструктаж і вступні документи. +Comment[ven]=Kilasi yau haseledza na mathomo a manwalwa +Comment[wa]=Tutoriå eyet documints di prezintaedje +Comment[xh]=Isifundo sokuzikhumbuza kunye nesiqalo samaxwebhu. +Comment[zh_TW]=教學與介紹文件。 +Comment[zu]=Ushicilelo lweziqalo kanye nezifundo zokubuyekeza +DocPath= diff --git a/khelpcenter/plugins/Tutorials/CMakeLists.txt b/khelpcenter/plugins/Tutorials/CMakeLists.txt new file mode 100644 index 000000000..2388c6440 --- /dev/null +++ b/khelpcenter/plugins/Tutorials/CMakeLists.txt @@ -0,0 +1,14 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + .directory quickstart.desktop visualdict.desktop + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/plugins/Tutorials ) diff --git a/khelpcenter/plugins/Tutorials/Makefile.am b/khelpcenter/plugins/Tutorials/Makefile.am new file mode 100644 index 000000000..97f855445 --- /dev/null +++ b/khelpcenter/plugins/Tutorials/Makefile.am @@ -0,0 +1,5 @@ + +tut_DATA = .directory quickstart.desktop visualdict.desktop +tutdir = $(kde_datadir)/khelpcenter/plugins/Tutorials + + diff --git a/khelpcenter/plugins/Tutorials/quickstart.desktop b/khelpcenter/plugins/Tutorials/quickstart.desktop new file mode 100644 index 000000000..cb349991e --- /dev/null +++ b/khelpcenter/plugins/Tutorials/quickstart.desktop @@ -0,0 +1,151 @@ +[Desktop Entry] +Name=Quickstart Guide +Name[af]=Woerts-warts Gids +Name[ar]=دليل إرشاد البدء السريع +Name[az]=Sür'ətli Başlama Rehberi +Name[be]=Падручнік для пачаткоўца +Name[bg]=Ръководство за начинаещите +Name[bn]=কুইকস্টার্ট গাইড +Name[br]=Sturier Kregiñ fonnus +Name[bs]=Vodič za brzi početak +Name[ca]=Guia ràpida +Name[cs]=Úvodní seznámení +Name[csb]=Sztartowi prowôdnik +Name[cy]=Canllaw cychwyn cyflym +Name[da]=Kvikstart-guide +Name[de]=Kurzeinführung +Name[el]=Οδηγός γρήγορου ξεκινήματος +Name[eo]=Konciza gvidlibro +Name[es]=Guía rápida +Name[et]=Kiire sissejuhatus +Name[eu]=Gida bizkorra +Name[fa]=راهنمای آغاز سریع +Name[fi]=Pikaohje +Name[fr]=Guide de démarrage rapide +Name[fy]=Fluchstartgids +Name[gl]=Guia de Início Rápido +Name[he]=מדריך התחלה מהירה +Name[hi]=शीघ्रप्रारंभ मार्गदर्शक +Name[hr]=Brzi uvod +Name[hu]=Rövid bevezetés +Name[id]=Petunjuk Memulai Secara Cepat +Name[is]=Skyndileiðbeiningar +Name[it]=Guida rapida +Name[ja]=クイックスタート +Name[ka]=სახელმძღვანელო დამწყებთათვის +Name[kk]=Бастаушы бағыттамасы +Name[km]=មគ្គុទ្ទេសក៍ចាប់ផ្ដើមរហ័ស +Name[ko]=빠른 시작 설명서 +Name[lo]=ຄຳແນະນຳແບບໄວ +Name[lt]=Greitos pradžios gidas +Name[lv]=Ātras sākšanas ceļvedis +Name[mk]=Водич за брзо снаоѓање +Name[mn]=QuickStart-Зааварчилгаа +Name[ms]=Panduan Mula Pantas +Name[mt]=Gwida biex tibda malajr +Name[nb]=Hurtigstart-guide +Name[nds]=Fixstart-Föhrer +Name[ne]=द्रुत सुरुआत मार्गदर्शन +Name[nl]=Snelstartgids +Name[nn]=Snøggstarguide +Name[nso]=Keletso ya Thomiso ya Kapejana +Name[oc]=Guia rapida +Name[pa]=ਚੁਸਤ ਸ਼ੁਰੂਆਤ ਗਾਈਡ +Name[pl]=Przewodnik startowy +Name[pt]=Guia de Iniciação +Name[pt_BR]=Guia Rápido +Name[ro]=Ghid rapid +Name[ru]=Руководство для начинающих в TDE +Name[rw]=Iyobora GutangiraVuba +Name[se]=Oanehis TDE-introdukšuvdna +Name[sk]=Návod na rýchle použitie +Name[sl]=Vodnik za hitri začetek +Name[sr]=Почетни водич +Name[sr@Latn]=Početni vodič +Name[sv]=Snabbstartsguide +Name[ta]=விரைவுதுவக்க வழிகாட்டி. +Name[tg]=Роҳнамоии шурӯъ кунӣ +Name[th]=คำแนะนำด่วน +Name[tr]=Hızlı Başlama Rehberi +Name[tt]=Tizcibärü Qullanması +Name[uk]=Посібник для швидкого старту +Name[uz]=TDE boʻyicha yoʻlkoʻrsatgich +Name[uz@cyrillic]=TDE бўйича йўлкўрсатгич +Name[ven]=Tsumbavhulwo ya mathomele au tavhanya +Name[vi]=Hướng dẫn nhanh +Name[wa]=Guide d' enondaedje al vole +Name[xh]=Isikhombisi Sesiqalo esikhawulezayo +Name[zh_CN]=速成指南 +Name[zh_TW]=快速入門指南 +Name[zu]=Umbonisi wokuqala ngokushesha +Comment=TDE quickstart guide. +Comment[af]=TDE woerts-warts gids. +Comment[ar]=دليل TDE السريع للمبتدئين +Comment[be]=Падручнік для пачаткоўца TDE. +Comment[bg]=Кратко ръководство за начинаещи за TDE. +Comment[bn]=কে.ডি.ই. কুইকস্টার্ট গাইড +Comment[bs]=TDE kratki vodič. +Comment[ca]=Guia ràpida del TDE. +Comment[cs]=Úvodní seznámení s vlastnostmi TDE. +Comment[csb]=Chùtczi prowôdnik pò TDE. +Comment[cy]=Canllaw cychwyn cyflym TDE +Comment[da]=TDE Kvikstart-guide +Comment[de]=Kurzeinführung in TDE +Comment[el]=Οδηγός γρήγορου ξεκινήματος TDE. +Comment[eo]=konciza gvidlibro por TDE +Comment[es]=Guía de inicio rápido de TDE. +Comment[et]=Kiire sissejuhatus TDE-sse +Comment[eu]=TDEren abiatze bizkorreko gida +Comment[fa]=راهنمای آغاز سریع TDE. +Comment[fi]=TDE:n aloitusopas. +Comment[fr]=Guide de démarrage rapide de TDE. +Comment[fy]=TDE's fluchstartgids. +Comment[gl]=Guia para iniciar-se axiña en TDE. +Comment[he]=מדריך התחלה מהירה של TDE. +Comment[hi]=केडीई शीघ्र मार्गदर्शक +Comment[hr]=Brzi uvod u TDE. +Comment[hu]=Rövid bevezetés a TDE-be +Comment[is]=Skyndileiðbeiningar fyrir TDE. +Comment[it]=Guida rapida per iniziare di TDE +Comment[ja]=TDE クイックスタートガイド +Comment[ka]=TDE-ს სახელმძღვანელო დამწყებთათვის +Comment[kk]=TDE бастаушының бағыттамасы. +Comment[km]=មគ្គុទ្ទេសក៍ចាប់ផ្ដើមរហ័ស TDE ។ +Comment[ko]=TDE 빠른 시작 설명서입니다. +Comment[lt]=TDE greitos pradžios gidas. +Comment[lv]=TDE ātras sākšanas rokasgrāmata. +Comment[mk]=TDE Водич за брзо снаоѓање +Comment[mn]=КДЭ-Удиртгал. +Comment[ms]=Panduan mula pantas TDE. +Comment[mt]=Gwida tal-TDE biex tibda malajr +Comment[nb]=Hurtigstart-guide for TDE. +Comment[nds]=Fixe Inföhren na TDE. +Comment[ne]=TDE द्रुत सुरुआत मार्गदर्शनड +Comment[nl]=TDE's snelstartgids. +Comment[nn]=Snøggstartguide for TDE. +Comment[pa]=TDE ਚੁਸਤ ਸ਼ੁਰੂਆਤ ਗਾਈਡ ਹੈ। +Comment[pl]=Szybkie wprowadzenie do TDE. +Comment[pt]=Guia de introdução ao uso do TDE. +Comment[pt_BR]=Guia rápido do TDE. +Comment[ro]=Ghidul rapid pentru TDE. +Comment[ru]=Руководство для начинающих в TDE +Comment[rw]=Inyobora gutangiravuba TDE +Comment[se]=Oanehis TDE-introdukšuvdna +Comment[sk]=Stručný úvod do TDE. +Comment[sl]=Vodnik za hitri zagon TDE +Comment[sr]=TDE-ов почетни водич. +Comment[sr@Latn]=TDE-ov početni vodič. +Comment[sv]=TDE:s snabbstartsguide +Comment[ta]=TDE விரைவுதுவக்க வழிகாட்டி. +Comment[tg]=Роҳнамоӣ барои навшогирдҳои TDE +Comment[th]=คำแนะนำด่วนของ TDE +Comment[tr]=TDE hızlı başlama rehberi. +Comment[tt]=TDE tiz kereşü qullanması. +Comment[uk]=Посібник TDE для швидкого старту. +Comment[uz]=Oʻrganuvchilar uchun TDE boʻyicha yoʻlkoʻrsatgich. +Comment[uz@cyrillic]=Ўрганувчилар учун TDE бўйича йўлкўрсатгич. +Comment[vi]=Hướng dẫn nhanh cho TDE +Comment[wa]=Guide d' enondaedje al vole po TDE +Comment[zh_CN]=TDE 速成指南。 +Comment[zh_TW]=TDE 快速入門指南。 +DocPath=help:/khelpcenter/quickstart/index.html diff --git a/khelpcenter/plugins/Tutorials/visualdict.desktop b/khelpcenter/plugins/Tutorials/visualdict.desktop new file mode 100644 index 000000000..caf159b4d --- /dev/null +++ b/khelpcenter/plugins/Tutorials/visualdict.desktop @@ -0,0 +1,153 @@ +[Desktop Entry] +Name=A Visual Guide to TDE +Name[af]='n Visuele Gids tot TDE +Name[ar]=مرشد مرئي لِــ TDE +Name[az]=TDE Üçün Vəzual Bədəçi +Name[be]=Падручнік TDE па візуальных аб'ектах +Name[bg]=Нагледни пособия +Name[bn]=কে.ডি.ই-র জন্য একটি ভিসুয়াল গাইড +Name[bs]=Vizualni vodič u TDE +Name[ca]=Una guia visual per al TDE +Name[cs]=Názorný průvodce prostředím TDE +Name[csb]=Prowôdnik pò TDE +Name[cy]=Canllaw Gweledol i TDE +Name[da]=En visuel guide til TDE +Name[de]=Visuelle Einführung in TDE +Name[el]=Ένας οπτικός οδηγός για το TDE +Name[eo]=Gvidilo pri TDE +Name[es]=Guía visual de TDE +Name[et]=TDE visuaalne juhend +Name[eu]=TDErako gida bisuala +Name[fa]=یک راهنمای مرئی برای TDE +Name[fi]=Kuvallinen ohje TDE:hen +Name[fr]=Un guide visuel de TDE +Name[fy]=In fisuele TDE-gids +Name[gl]=Unha Guia Visual de TDE +Name[he]=מדריך חזותי ל־TDE +Name[hi]=केडीई के लिए एक दृश्य मार्गदर्शक +Name[hr]=Vizualni vodič u TDE +Name[hu]=A TDE grafikus elemeinek ismertetése +Name[id]=Petunjuk TDE Visual +Name[is]=Myndrænn leiðarvísir að TDE +Name[it]=Una guida visiva di TDE +Name[ja]=TDE のためのビジュアルガイド +Name[ka]=TDE-ს თვალსაჩინო სახელმძღვანელო +Name[kk]=TDE көрнекті бағыттамасы +Name[km]=មគ្គុទ្ទេសក៍រូបភាពមកកាន់ TDE +Name[ko]=TDE 모습 둘러보기 +Name[lo]=ນຳທ່ງວ TDE ແບບສະເຫມື່ອນแบบเสมือน +Name[lt]=Vaizdinis TDE gidas +Name[lv]=Vizuāls Ceļvedis pa TDE +Name[mk]=Визуелен вовед во TDE +Name[mn]=КДЭ-н визуал удиртгал +Name[ms]=Panduan Visual TDE +Name[mt]=Gwida Viżwali għall-TDE +Name[nb]=En visuell guide til TDE +Name[nds]=En visuell Inföhren na TDE +Name[ne]=TDE मा दृश्य मार्गदर्शन +Name[nl]=Een visuele TDE-gids +Name[nn]=Visuell TDE-gaid +Name[nso]=Keletso yeo e Kwagalago ya TDE +Name[pa]=TDE ਲਈ ਇੱਕ ਦਿੱਖ ਗਾਈਡ +Name[pl]=Przewodnik po TDE +Name[pt]=Um Guia Visual para o TDE +Name[pt_BR]=Guia Visual para o TDE +Name[ro]=Ghid vizual TDE +Name[ru]=Наглядное пособие по TDE +Name[rw]=Inyobora Igaragara kuri TDE +Name[se]=Visuella TDE-introdukšuvdna +Name[sk]=Obrázková príručka TDE +Name[sl]=Vodnik po TDE +Name[sr]=Визуелни водич за TDE +Name[sr@Latn]=Vizuelni vodič za TDE +Name[sv]=Visuell guide till TDE +Name[ta]=TDEன் காட்டிசார் வழிகாட்டி +Name[tg]=Роҳнамои басрии TDE +Name[th]=นำเที่ยว TDE +Name[tr]=TDE İçin Görsel Kılavuz +Name[tt]=TDE öçen Kürsätü-Qullanma +Name[uk]=Наочний підручник по TDE +Name[ven]=Tsumbavhulwo ya zwauvhona ya TDE +Name[vi]=Trình Hướng dẫn Sinh động cho TDE +Name[wa]=On guide a vey po TDE +Name[xh]=Isikhombisi esibonakalayo se TDE +Name[zh_CN]=TDE 可视化指南 +Name[zh_TW]=TDE 視覺指南 +Name[zu]=Umbonisi obonakalayo oya kwi-TDE +Comment=Guide to TDE widgets +Comment[af]=Gids na TDE widgets +Comment[az]=TDE mühitinə sür'ətli başlanğıc +Comment[be]=Падручнік па віджэтах TDE +Comment[bg]=Нагледни пособия за TDE, графични елементи, управление и пр. +Comment[bn]=কে.ডি.ই উইজেট সম্বন্ধে জানুন +Comment[bs]=Priručnik za TDE ukrase +Comment[ca]=Guia per als estris a TDE +Comment[cs]=Průvodce prvky uživatelského prostředí TDE +Comment[csb]=Prowôdnik pò elementach òknów TDE +Comment[cy]=Canllaw i declynnau TDE +Comment[da]=Guide til TDE-kontroller +Comment[de]=Einführung in die TDE-Elemente +Comment[el]=Οδηγός για τα γραφικά συστατικά του TDE +Comment[eo]=Gvidilo pri TDE-fenestraĵoj +Comment[es]=Guía de los objetos visuales (widgets) de TDE +Comment[et]=TDE elementide juhend +Comment[eu]=TDEren widget-en gida +Comment[fa]=راهنما برای عناصر TDE +Comment[fi]=Ohje TDE:n työkaluihin +Comment[fr]=Guide des éléments graphiques de TDE +Comment[fy]=Gids foar TDE-widgets +Comment[gl]=Guia dos widgets de TDE +Comment[he]=מדריך לפריטי TDE +Comment[hi]=केडीई विजेट्स के लिए एक मार्गदर्शक +Comment[hr]=Uvod u TDE widgete +Comment[hu]=A TDE grafikai elemeinek ismertetése +Comment[id]=Petunjuk widgets TDE +Comment[is]=Leiðarvísir að viðmótshlutum TDE +Comment[it]=Guida agli elementi grafici di TDE +Comment[ja]=TDE ウィジェットガイド +Comment[ka]=TDE-ს მართვის ელემენტთა სახელმძღვანელო +Comment[kk]=TDE элементтер бағыттамасы +Comment[km]=មគ្គុទ្ទេសក៍វត្ថុមើលឃើញក្នុង TDE +Comment[ko]=TDE 위젯 도움말 +Comment[lo]=ແນະນຳສ່ວນປະກອບຂອງ TDE +Comment[lt]=TDE valdiklių gidas +Comment[lv]=Rokasgrāmata TDE vidžetos +Comment[mk]=Вовед во графичките контроли на TDE +Comment[mn]=КДЭ-Элементүүдийн удиртгал +Comment[ms]=Panduan widget TDE +Comment[mt]=Gwida għall-widgets tal-TDE +Comment[nb]=Guide til TDEs skjermelementer +Comment[nds]=Inföhren för TDE-Bedeenelementen +Comment[ne]=TDE विजेटमा मार्गदर्शन +Comment[nl]=Gids voor TDE-widgets +Comment[nn]=Gaid til skjermelementa i TDE +Comment[nso]=Keletso go di-widget tsa TDE +Comment[pa]=TDE ਝਰੋਖਿਆਂ ਲਈ ਗਾਈਡ ਹੈ +Comment[pl]=Przewodnik po elementach okien TDE +Comment[pt]=Guia para os itens gráficos do TDE +Comment[pt_BR]=Guia para os controles do TDE +Comment[ro]=Un ghid pentru componentele grafice ale TDE +Comment[ru]=Руководство по элементам интерфейса TDE +Comment[rw]=Kuyobora ku marenga TDE +Comment[se]=Introdukšuvdna TDE-ađaide +Comment[sk]=Príručka grafických prvkov TDE +Comment[sl]=Vodnik po gradnikih TDE +Comment[sr]=Водич за TDE контроле +Comment[sr@Latn]=Vodič za TDE kontrole +Comment[sv]=Guide till TDE-komponenter +Comment[ta]=TDE வளைவுகளுக்கான வழிகாட்டி +Comment[tg]=Роҳбарӣ бо ҷузъи робитаи TDE +Comment[th]=แนะนำวิดเจ็ตของ TDE +Comment[tr]=TDE Aletleri için rehber +Comment[tt]=TDE yözarası öçen qullanma +Comment[uk]=Підручник по віджетам TDE +Comment[uz]=TDE vidjetlari boʻyicha yoʻlkoʻrsatgich +Comment[uz@cyrillic]=TDE виджетлари бўйича йўлкўрсатгич +Comment[ven]=Tsumbavhulwo ya widget ya TDE +Comment[vi]=Hướng dẫn cho thành tố điều khiển của TDE +Comment[wa]=Guide po les ahesses di TDE +Comment[xh]=Isikhombisi esiya kwi TDE widgets +Comment[zh_CN]=TDE 部件指南 +Comment[zh_TW]=TDE 視窗元件 (widget) 指南 +Comment[zu]=Umbonisi oya kuma-widget e-TDE +DocPath=help:/khelpcenter/visualdict/index.html diff --git a/khelpcenter/plugins/adminguide.desktop b/khelpcenter/plugins/adminguide.desktop new file mode 100644 index 000000000..bf3c41814 --- /dev/null +++ b/khelpcenter/plugins/adminguide.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/adminguide/index.html + +Name=TDE Admininstrator Guide + +X-DOC-Weight=-1400 +Icon=kmenu diff --git a/khelpcenter/plugins/applets.desktop b/khelpcenter/plugins/applets.desktop new file mode 100644 index 000000000..a4cf6478a --- /dev/null +++ b/khelpcenter/plugins/applets.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] + +Name=Applet Manuals +Name[af]=Miniprogram Handleidings +Name[ar]=كتيّبات إستخدام البريمجات +Name[be]=Даведкі аплетаў +Name[bg]=Ръководства на аплети +Name[bn]=অ্যাপলেট ম্যানুয়াল +Name[br]=Levr-dorn an arloadig +Name[bs]=Priručnici appleta +Name[ca]=Manuals dels applet +Name[cs]=Příručky appletů +Name[csb]=Pòdrãczniczi programików +Name[cy]=Llawlyfr Rhaglennig +Name[da]=Panelprogrammanualer +Name[de]=Handbücher zu Miniprogrammen (Applets) +Name[el]=Εγχειρίδια μικροεφαρμογών +Name[eo]=Manlibroj de Aplikaĵoj +Name[es]=Manuales de las miniaplicaciones +Name[et]=Aplettide käsiraamatud +Name[eu]=Appleten eskuliburuak +Name[fa]=پیمانههای برنامک +Name[fi]=Sovelmien ohjekirjat +Name[fr]=Manuels des applets +Name[fy]=Appletshânliedingen +Name[ga]=Lámhleabhair Fheidhmchláiríní +Name[gl]=Manuais das Applets +Name[he]=ספרי הדרכה של יישומונים +Name[hi]=ऐपलेट निर्देशिका +Name[hr]=Priručnici apleta +Name[hu]=A kisalkalmazások kézikönyvei +Name[is]=Handbækur smáforrita +Name[it]=Manuali applet +Name[ja]=アプレットマニュアル +Name[ka]=აპლეტთა სახელმძღვანელო +Name[kk]=Апплет оқулығы +Name[km]=សៀវភៅអាប់ភ្លេត +Name[ko]=애플릿 설명서 +Name[lo]=ແອບພີເຄຊັ້ນ +Name[lt]=Įskiepių vadovai +Name[lv]=Sīklietotņu rokasgrāmata +Name[mk]=Прирачници за аплети +Name[mn]=Гарын авлага (Applets) +Name[ms]=Manual Aplet +Name[mt]=Manwali tal-applets +Name[nb]=Manualer for miniprogrammer +Name[nds]=Programmhandböker +Name[ne]=एप्लेट म्यानुअल +Name[nl]=Applet-handboeken +Name[nn]=Applet-manualar +Name[nso]=Di-Manual tsa Applet +Name[pa]=ਐਪਲਿਟ ਦਸਤਾਵੇਜ਼ +Name[pl]=Podręczniki programików +Name[pt]=Manuais das 'Applets' +Name[pt_BR]=Manuais de Mini-aplicativos +Name[ro]=Manualele miniaplicațiilor +Name[ru]=Руководства аплетов +Name[rw]=Igitabomikorere Apuleti +Name[se]=Prográmmaš-giehtagirjjit +Name[sk]=Príručky k appletom +Name[sl]=Priročniki za vstavke +Name[sr]=Упутства за аплете +Name[sr@Latn]=Uputstva za aplete +Name[sv]=Miniprogramhandböcker +Name[ta]=குறுநிரல் கையேடு +Name[te]=అప్లెట్ మెన్యువళ్లు +Name[tg]=Дастномаҳои барнома +Name[th]=คู่มือแอพเพล็ต +Name[tr]=Programcık Kılavuzları +Name[tt]=Applet Qullanmaları +Name[uk]=Довідки по аплетам +Name[uz]= Appletlar uchun qoʻllanmalar +Name[uz@cyrillic]= Апплетлар учун қўлланмалар +Name[vi]=Hướng dẫn sử dụng Tiểu ứng dụng +Name[wa]=Esplikêyes des apliketes +Name[xh]=Applet Zesandla +Name[zh_CN]=小应用程序手册 +Name[zh_TW]=面板程式手冊 +Name[zu]=Izincwadi zesandla zama-Applet + +Icon=contents2 + +X-DOC-Weight=-400 + +X-TDE-KHelpcenter-Special=applets diff --git a/khelpcenter/plugins/contact.desktop b/khelpcenter/plugins/contact.desktop new file mode 100644 index 000000000..4c4a34eb6 --- /dev/null +++ b/khelpcenter/plugins/contact.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/index.html?anchor=contact + +Name=Contact Information +Name[af]=Kontak Informasie +Name[ar]=معلومات التراسل +Name[be]=Кантактная інфармацыя +Name[bg]=Информация за връзка +Name[bn]=যোগাযোগ তথ্য +Name[br]=Titouroù diwar-benn an darempred +Name[bs]=Kontakt informacije +Name[ca]=Informació de contacte +Name[cs]=Kontaktní informace +Name[csb]=Wëdowiédzô ò łączbie +Name[cy]=Gwybodaeth Cysylltu +Name[da]=Kontaktinformation +Name[de]=Kontaktinformationen +Name[el]=Πληροφορίες επικοινωνίας +Name[eo]=Kontaktinformoj +Name[es]=Información de contacto +Name[et]=Kontaktinfo +Name[eu]=Harremanetarako informazioa +Name[fa]=اطلاعات تماس +Name[fi]=Yhteystiedot +Name[fr]=Contacter l'équipe TDE +Name[fy]=kontaktynformaasje +Name[ga]=Eolas Teagmhála +Name[gl]=Información de Contacto +Name[he]=מידע ליצירת קשר +Name[hi]=सम्पर्क जानकारी +Name[hr]=Kontaktni podaci +Name[hu]=Kapcsolatfelvétel +Name[is]=Upplýsingar um tengiliði +Name[it]=Informazioni contatti +Name[ja]=コンタクト情報 +Name[ka]=საკონტაქტო ინფორმაცია +Name[kk]=Қатынас мәліметі +Name[km]=ព័ត៌មានទាក់ទង +Name[ko]=연락처 정보 +Name[lo]=ຂໍ້ມູນຕ່າງຯ +Name[lt]=Kontaktai +Name[lv]=Kontaktu Informācija +Name[mk]=Контакт информации +Name[mn]=Холбогдох мэдээлэл +Name[ms]=Maklumat Hubungan +Name[mt]=Informazzjoni dwar kuntatti +Name[nb]=Kontaktinformasjon +Name[nds]=Kontaktinformatschoon +Name[ne]=सम्पर्क सूचना +Name[nl]=Contactinformatie +Name[nn]=Kontaktinformasjon +Name[nso]=Tshedimoso ya Kgokagano +Name[pa]=ਸੰਪਰਕ ਜਾਣਕਾਰੀ +Name[pl]=Informacje kontaktowe +Name[pt]=Informações de Contactos +Name[pt_BR]=Informações de Contato +Name[ro]=Informații de contact +Name[ru]=Контактная информация +Name[rw]=Aho ubarizwa +Name[se]=Oktavuohtadieđut +Name[sk]=Informácie o kontaktoch +Name[sl]=Informacije za stik +Name[sr]=Информације о контактима +Name[sr@Latn]=Informacije o kontaktima +Name[sv]=Kontaktinformation +Name[ta]=தொடர்பு தகவல் +Name[tg]=Иттилооти тамос +Name[th]=ข้อมูลติดต่อ +Name[tr]=Bağlantı Bilgisi +Name[tt]=Elemtä Turında +Name[uk]=Контактна інформація +Name[uz]=Bogʻlanish uchun maʼlumot +Name[uz@cyrillic]=Боғланиш учун маълумот +Name[ven]=Mafhungo nga vhudalo +Name[vi]=Thông tin Liên lạc +Name[wa]=Informåcion sol conoxhance +Name[xh]=Qhagamshelana Nolwazi +Name[zh_CN]=联系信息 +Name[zh_TW]=聯絡資訊 +Name[zu]=Ulwazi lwabangathinteka + +X-DOC-Weight=3000 +Icon=kmenu diff --git a/khelpcenter/plugins/faq.desktop b/khelpcenter/plugins/faq.desktop new file mode 100644 index 000000000..08e1a4969 --- /dev/null +++ b/khelpcenter/plugins/faq.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/faq/index.html + +Name=The TDE FAQ +Name[af]=Die TDE Faq +Name[ar]=أسئلة TDE المتكررة +Name[be]=FAQ TDE +Name[bg]=Често задавани въпроси +Name[bn]=কে.ডি.ই. FAQ +Name[bs]=TDE FAQ +Name[ca]=La PMF del TDE +Name[cs]=Často kladené dotazy TDE +Name[csb]=TDE FAQ +Name[cy]=Y FAQ TDE +Name[da]=TDE OSS +Name[de]=Häufig gestellte Fragen zu TDE (FAQ) +Name[el]=Το TDE FAQ +Name[eo]=La TDE-Oftaj Demandoj +Name[es]=Las PF de TDE +Name[et]=TDE korduma kippuvad küsimused +Name[eu]=TDE FAQa (maiz egiten diren galderak) +Name[fa]=پرسشهای متداول TDE +Name[fi]=TDE FAQ +Name[fr]=La FAQ (questions fréquentes) de TDE +Name[fy]=Protte foarkommende fragen oer TDE +Name[ga]=Ceisteanna Coitianta TDE +Name[gl]=A FAQ de TDE +Name[he]=שאלות נפוצות על TDE +Name[hi]=केडीई एफ़एक्यू +Name[hr]=TDE FAQ +Name[hu]=TDE FAQ +Name[is]=TDE Spurt og Svarað (SoS) +Name[it]=Domande su TDE (FAQ) +Name[ja]=TDE FAQ +Name[ka]=TDE: ძირითადი კითხვები +Name[kk]=TDE сұрақ пен жауаптар +Name[km]=សំណួរដែលសួរដដែលៗអំពី TDE +Name[ko]=TDE 자주 묻는 질문 +Name[lt]=TDE D.U.K.(FAQ) +Name[lv]=TDE BUJ +Name[mk]=TDE ЧПП +Name[mn]=КДЭ-с ихэвчилэн асуугддаг асуултууд (FAQ) +Name[ms]=FAQ TDE +Name[mt]=Mistoqsijiet komuni tal-TDE +Name[nb]=Ofte stilte TDE-spørsmål +Name[nds]=Dat TDE-FAQ +Name[ne]=TDE FAQ +Name[nl]=Veel voorkomde vragen over TDE +Name[nn]=Ofte stilte TDE-spørsmål +Name[nso]=FAQ ya TDE +Name[pa]=TDE ਸਵਾਲ-ਜਵਾਬ +Name[pl]=Często Zadawane Pytania TDE +Name[pt]=A FAQ do TDE +Name[pt_BR]=O FAQ do TDE +Name[ro]=Răspunsuri la întrebări frecvente +Name[ru]=TDE: вопросы и ответы +Name[rw]=Ibibazo Bibazwa Cyane bya TDE +Name[se]=Dávjá jearahuvvon TDE-gažaldagat (TDE-DJG) +Name[sk]=TDE FAQ +Name[sl]=Vprašanja in odgovori o TDE +Name[sr]=Често постављана питања о TDE-у +Name[sr@Latn]=Često postavljana pitanja o TDE-u +Name[sv]=Vanliga frågor om TDE +Name[ta]=TDE FAQ(அடிக்கடி கேட்கப்படும் கேள்விகள்) +Name[te]=కెడిఈ ఎఫ్ ఏ క్యు +Name[tg]=TDE: саволҳо ва ҷавобҳо +Name[th]=คำถามที่ถามบ่อยของ TDE +Name[tr]=TDE SSS +Name[tt]=TDE YBSı +Name[uk]=ЧАП для TDE +Name[uz]=TDE TSS +Name[uz@cyrillic]=TDE ТСС +Name[vi]=Các câu hỏi hay gặp của TDE +Name[wa]=Li dicåce ås kesses (FAQ) TDE +Name[xh]=TDE FAQ +Name[zh_CN]=TDE FAQ +Name[zh_TW]=TDE 常見問題 +Name[zu]=I-FAQ ye-TDE + +X-DOC-Weight=2000 +Icon=kmenu diff --git a/khelpcenter/plugins/hardwaremodules.desktop b/khelpcenter/plugins/hardwaremodules.desktop new file mode 100644 index 000000000..af716857a --- /dev/null +++ b/khelpcenter/plugins/hardwaremodules.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] + +Name=Hardware +Name[af]=Hardeware +Name[ar]=العتاد +Name[be]=Апаратнае забеспячэнне +Name[bg]=Хардуер +Name[bn]=হার্ডওয়্যার +Name[br]=Periantel +Name[bs]=Hardver +Name[csb]=Nôrzãdza +Name[cy]=Caledwedd +Name[el]=Υλικό +Name[eo]=Aparataro +Name[et]=Riistvara +Name[fa]=سختافزار +Name[fi]=Laitteisto +Name[fr]=Matériel +Name[ga]=Crua-Earraí +Name[he]=חומרה +Name[hr]=Hardver +Name[hu]=Hardver +Name[id]=Perangkat Keras +Name[is]=Vélbúnaður +Name[ja]=ハードウェア +Name[ka]=მოწყობილობები +Name[kk]=Жабдықтар +Name[km]=ផ្នែករឹង +Name[ko]=하드웨어 +Name[lt]=Aparatinė įranga +Name[mk]=Хардвер +Name[ms]=Perkakasan +Name[nb]=Maskinvare +Name[ne]=हार्डवेयर +Name[nn]=Maskinvare +Name[pa]=ਜੰਤਰ +Name[pl]=Sprzęt +Name[ru]=Оборудование +Name[rw]=Icyuma +Name[se]=Mašiidnagálvu +Name[sl]=Strojna oprema +Name[sr]=Хардвер +Name[sr@Latn]=Hardver +Name[sv]=Hårdvara +Name[ta]=வன்பொருள் +Name[te]=హార్డ్ వేర్ +Name[tg]=Сахтафзор +Name[th]=อุปกรณ์ภายในเครื่อง +Name[tr]=Donanım +Name[tt]=Cıhazlar +Name[uk]=Обладнання +Name[uz]=Asbob-uskunalar +Name[uz@cyrillic]=Асбоб-ускуналар +Name[vi]=Phần cứng +Name[wa]=Éndjolreye +Name[zh_CN]=硬件 +Name[zh_TW]=硬體 + +Icon=contents2 + +X-DOC-Weight=-400 + +X-TDE-KHelpcenter-Special=kcontrol diff --git a/khelpcenter/plugins/info.desktop b/khelpcenter/plugins/info.desktop new file mode 100644 index 000000000..a7e79046f --- /dev/null +++ b/khelpcenter/plugins/info.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] + +Name=Browse Info Pages +Name[af]=Blaai deur inligting bladsye (Info pages) +Name[ar]=تصفح صفحات المعلومات +Name[be]=Праглядзець старонкі info +Name[bg]=Преглед на страниците Info +Name[bn]=ইনফো পেজ ব্রাউজ করুন +Name[br]=Furchal ar pajennoù titouroù +Name[bs]=Pregled info stranica +Name[ca]=Fulleja 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[eo]=Rigardu info-paĝojn +Name[es]=Navegar por páginas info +Name[et]=Infolehekülgede lehitsemine +Name[eu]=Arakatu info orriak +Name[fa]=مرور صفحات اطلاعات +Name[fi]=Selaa info-sivuja +Name[fr]=Naviguer dans les pages d'information +Name[fy]=ynfo-siden trochblêdzje +Name[ga]=Brabhsáil Leathanaigh Eolais +Name[gl]=Navegar polas páxinas info +Name[he]=עיון בדפי מידע +Name[hi]=इन्फो पृष्ठ ब्राउज़ करें +Name[hr]=Pretraživanje info stranica +Name[hu]=Info oldalak +Name[is]=Flakka um upplýsingasíður +Name[it]=Sfoglia le pagine "info" +Name[ja]=Info ページの参照 +Name[ka]=ცნობარის დათვალიერება +Name[kk]=Info парақтары +Name[km]=រុករកទំព័រព័ត៌មាន +Name[ko]=Info 페이지 탐색 +Name[lt]=Naršyti info puslapius +Name[lv]=Pārlūkot info lapas +Name[mk]=Прелистај ги info страниците +Name[ms]=Layar Halaman Maklumat +Name[mt]=Dur il-paġni Info +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[pa]=ਜਾਣਕਾਰੀ ਸਫੇ ਝਲਕ +Name[pl]=Przeglądanie stron informacyjnych +Name[pt]=Navegar nas Páginas do Info +Name[pt_BR]=Navegar nas Páginas Info +Name[ro]=Pagini info +Name[ru]=Страницы Info +Name[rw]=Gusura Ipaji y'Amakuru +Name[se]=Loga info-siidduid +Name[sk]=Prehliadanie info stránok +Name[sl]=Brskanje po straneh info +Name[sr]=Прегледање инфо страница +Name[sr@Latn]=Pregledanje info stranica +Name[sv]=Bläddra i info-sidor +Name[ta]=தகவல் பக்கங்களில் உலாவவும் +Name[tg]=Саҳифаҳои иттилоотӣ +Name[th]=เรียกดูหน้าข้อมูล (info) +Name[tr]=Bilgi Sayfarlarını Tara +Name[tt]=Info Bitläre +Name[uk]=Навігація сторінок info +Name[uz]=Info varaqlarni koʻrish +Name[uz@cyrillic]=Info варақларни кўриш +Name[vi]=Duyệt Trang Thông tin +Name[wa]=Naivyî ezès pådjes d' informåcion +Name[zh_CN]=浏览信息页面 +Name[zh_TW]=瀏覽資訊頁 +Icon=contents2 + +X-TDE-KHelpcenter-Special=info + +DocPath=info:/dir + +X-DOC-Weight=700 diff --git a/khelpcenter/plugins/kcontrolmodules.desktop b/khelpcenter/plugins/kcontrolmodules.desktop new file mode 100644 index 000000000..9ad0321b5 --- /dev/null +++ b/khelpcenter/plugins/kcontrolmodules.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] + +Name=Control Center Modules +Name[af]=Beheer Sentrum Modules +Name[ar]=وحدات مركز التحكم +Name[be]=Модулі цэнтра кіравання +Name[bg]=Контролен център +Name[bn]=নিয়ন্ত্রণ কেন্দ্র মডিউল +Name[br]=Molladoù ar c'hreizenn ren +Name[bs]=Moduli kontrolnog centra +Name[ca]=Mòduls del Centre de control +Name[cs]=Moduly Ovládacího centra +Name[csb]=Mòdułë centróm kòntrolë +Name[cy]=Modiwlau Canolfan Rheoli +Name[da]=Kontrolcenter-moduler +Name[de]=Kontrollzentrum-Module +Name[el]=Αρθρώματα Κέντρου ελέγχου +Name[en_GB]=Control Centre Modules +Name[eo]=Stircentraj Moduloj +Name[es]=Módulos del Centro de control +Name[et]=Juhtimiskeskuse moodulid +Name[eu]=Kontrol Gunearen moduluak +Name[fa]=پیمانههای مرکز کنترل +Name[fi]=Ohjauskeskuksen moduulit +Name[fr]=Modules du Centre de configuration +Name[fy]=Konfiguraasjemodules +Name[ga]=Modúil an Lárionad Rialaithe +Name[gl]=Módulos do Centro de Control +Name[he]=מודולי מרכז הבקרה +Name[hi]=नियंत्रण केंद्र मॉड्यूल्स +Name[hr]=Moduli upravljačkog središta +Name[hu]=A Vezérlőpult moduljai +Name[is]=Stjórnborðseiningar +Name[it]=Moduli del centro di controllo +Name[ja]=コントロールセンターモジュール +Name[ka]=მართვის ცენტრის მოდულები +Name[kk]=Басқару орталық модульдері +Name[km]=ម៉ូឌុលមជ្ឈមណ្ឌលបញ្ជា +Name[ko]=제어판 모듈 +Name[lo]=ສູນຄວບຄຸມ +Name[lt]=Valdymo centro moduliai +Name[lv]=Kontroles centra moduļi +Name[mk]=Модули од Контролниот Центар +Name[mn]=Удирдах төв-модул +Name[ms]=Modul Pusat Kawalan +Name[mt]=Moduli taċ-Ċentru tal-Kontroll +Name[nb]=Kontrollpanelmoduler +Name[nds]=Kuntrullzentrum-Modulen +Name[ne]=नियन्त्रण केन्द्र मोड्युल +Name[nl]=Configuratiecentrummodules +Name[nn]=Kontrollsentermodular +Name[nso]=Diripa tsa Bogareng bja Taolo +Name[pa]=ਕੰਟਰੋਲ ਕੇਂਦਰ ਮੈਡੀਊਲ +Name[pl]=Moduły centrum sterowania +Name[pt]=Módulos do Centro de Controlo +Name[pt_BR]=Módulos do Centro de Controle +Name[ro]=Module Centru de Control +Name[ru]=Модули Центра управления +Name[rw]=Kugenzura Ibice byo Hagati +Name[se]=Stivrenguovddášmoduvllat +Name[sk]=Moduly Ovládacieho centra +Name[sl]=Moduli nadzornega središča +Name[sr]=Модули контролног центра +Name[sr@Latn]=Moduli kontrolnog centra +Name[sv]=Moduler i Inställningscentralen +Name[ta]=கட்டுப்பாட்டு மைய பகுதிகள் +Name[te]=నియంత్రణా కేంద్రం మాడ్యూళ్లు +Name[tg]=Бахшҳои маркази идоракунӣ +Name[th]=โมดูลของศูนย์ควบคุม +Name[tr]=Kontrol Merkezi Modülleri +Name[tt]=İdärä Üzägeneñ Modulları +Name[uk]=Модулі центру керування +Name[uz]=Boshqaruv markazining modullari +Name[uz@cyrillic]=Бошқарув марказининг модуллари +Name[ven]=Modulu wa Senthara ya vhulanguli +Name[vi]=Trung tâm Điều khiển Mô đun +Name[wa]=Modules do cinte di contrôle di TDE +Name[xh]=Izicatshulwa Zolawulo Ezisembindini +Name[zh_CN]=控制中心模块 +Name[zh_TW]=控制中心模組 +Name[zu]=Izingxenye ze-Control Center + +Icon=kcontrol + +X-DOC-Weight=-400 + +X-TDE-KHelpcenter-Special=kcontrol diff --git a/khelpcenter/plugins/konqplugins.desktop b/khelpcenter/plugins/konqplugins.desktop new file mode 100644 index 000000000..4e60ca07b --- /dev/null +++ b/khelpcenter/plugins/konqplugins.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] + +Name=Konqueror Plugins +Name[af]=Konqueror Inprop modules +Name[ar]=قوابس Konqueror +Name[be]=Утулкі Konqueror +Name[bg]=Приставки за браузъра +Name[bn]=কনকরার প্লাগ-ইন +Name[br]=Lugantoù Konqueror +Name[bs]=Konqueror dodaci +Name[ca]=Connectors per a Konqueror +Name[cs]=Moduly Konqueroru +Name[csb]=Pluginsë Konquerora +Name[cy]=Ategynnau Konqueror +Name[da]=Konqueror-plugin +Name[de]=Konqueror-Plugins +Name[el]=Πρόσθετα Konqueror +Name[eo]=Konkerantaj kromaĵoj +Name[es]=Complementos de Konqueror +Name[et]=Konquerori pluginad +Name[eu]=Konquerorren pluginak +Name[fa]=وصلههای Konqueror +Name[fi]=Konqueror-liitännäiset +Name[fr]=Modules externes de Konqueror +Name[fy]=Konqueror-plugins +Name[ga]=Breiseáin Konqueror +Name[gl]=Plugins de Konqueror +Name[he]=תוספים של Konqueror +Name[hi]=कॉन्करर प्लगइन्स +Name[hr]=Konqueror dodaci +Name[hu]=Konqueror-bővítőmodulok +Name[is]=Konqueror íforrit +Name[it]=Plugin di Konqueror +Name[ja]=Konqueror プラグイン +Name[ka]=Konqueror-ის პლაგინები +Name[kk]=Konqueror модульдері +Name[km]=កម្មវិធីជំនួយខាងក្នុង Konqueror +Name[ko]=Konqueror 창 +Name[lo]=ບາວເຊີ Konqueror +Name[lt]=Konqueror priedai +Name[lv]=Iekarotāja spraudņi +Name[mk]=Приклучоци за Konqueror +Name[mn]=Конкюрор-плугинс +Name[ms]=Plugin Konqueror +Name[mt]=Plagins ta' Konqueror +Name[nb]=Konqueror-programtillegg +Name[nds]=Konqueror-Plugins +Name[ne]=कन्क्वेरर प्लगइन +Name[nl]=Konqueror-plugins +Name[nn]=Konqueror-programtillegg +Name[nso]=Ditsenyo tsa Konqueror +Name[pa]=ਕੋਨਕਿਉਰਰ ਪਲੱਗਇਨ +Name[pl]=Wtyczki Konquerora +Name[pt]='Plugins' do Konqueror +Name[pt_BR]=Plug-Ins do Konqueror +Name[ro]=Module Konqueror +Name[ru]=Модули Konqueror +Name[rw]=Amacomeka Konqueror +Name[se]=Konqueror-lassemoduvllat +Name[sk]=Moduly pre Konqueror +Name[sl]=Vstavki za Konqueror +Name[sr]=Konqueror-ови прикључци +Name[sr@Latn]=Konqueror-ovi priključci +Name[sv]=Konqueror-insticksprogram +Name[ta]=கான்கொரர் செருகு சாதனங்கள் +Name[te]=కాంకెరర్ ప్లగిన్లు +Name[tg]=Мутассалкунандаҳои Konqueror +Name[th]=ปลั้กอินของคอนเควอร์เรอร์ +Name[tr]=Konqueror Eklentileri +Name[tt]=Konqueror Östämäläre +Name[uk]=Втулки для Konqueror +Name[uz]=Konqueror plaginlari +Name[uz@cyrillic]=Konqueror плагинлари +Name[vi]=Trình bổ sung Konqueror +Name[wa]=Tchôke-divins po Konqueror +Name[xh]=Iplagi zangaphakathi ze Konqueror +Name[zh_CN]=Konqueror 插件 +Name[zh_TW]=Konqueror 外掛程式 +Name[zu]=Ama-Plugin e-Konqueror + +Icon=konqueror + +X-DOC-Weight=-400 + +X-TDE-KHelpcenter-Special=konqueror diff --git a/khelpcenter/plugins/links.desktop b/khelpcenter/plugins/links.desktop new file mode 100644 index 000000000..13c838e7b --- /dev/null +++ b/khelpcenter/plugins/links.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/index.html?anchor=links + +Name=TDE on the Web +Name[af]=TDE op die Web +Name[ar]=TDE على الشبكة +Name[be]=TDE у Сеціве +Name[bg]=TDE в Интернет +Name[bn]=ওয়েব-এ কে.ডি.ই. +Name[br]=TDE war ar Gwiad +Name[bs]=TDE na webu +Name[ca]=TDE a la web +Name[cs]=TDE na webu +Name[csb]=TDE w sécë +Name[cy]=TDE ar y We +Name[da]=TDE på nettet +Name[de]=TDE im Web +Name[el]=Το TDE στο διαδίκτυο +Name[eo]=TDE en TTT +Name[es]=TDE en la web +Name[et]=TDE veebis +Name[eu]=TDE Web-ean +Name[fa]=TDE روی وب +Name[fi]=TDE webissä +Name[fr]=TDE sur le web +Name[fy]=TDE op it ynternet +Name[ga]=TDE ar an Ghréasán +Name[gl]=TDE na web +Name[he]=TDE באינטרנט +Name[hi]=केडीई वेब पर +Name[hr]=TDE na Internetu +Name[hu]=A TDE az interneten +Name[is]=TDE á vefnum +Name[it]=TDE su internet +Name[ja]=ウェブ上の TDE +Name[ka]=TDE ინტერნეტში +Name[kk]=TDE Интернетте +Name[km]=TDE លើបណ្ដាញ +Name[ko]=웹에서의 TDE +Name[lt]=TDE žiniatinklyje +Name[lv]=TDE tīklā +Name[mk]=TDE на мрежа +Name[ms]=TDE dalam Web +Name[mt]=TDE fuq il-Web +Name[nb]=TDE på nettet +Name[nds]=TDE in't Nett +Name[ne]=वेबमा केडीई +Name[nl]=TDE op het internet +Name[nn]=TDE på verdsveven +Name[pa]=ਵੈੱਬ 'ਤੇ TDE +Name[pl]=TDE w sieci +Name[pt]=O TDE na Web +Name[pt_BR]=TDE na Web +Name[ro]=TDE pe Internet +Name[ru]=TDE в Интернете +Name[rw]=TDE ku Rubugamakuru +Name[se]=TDE interneahtas +Name[sk]=TDE na WWW +Name[sl]=TDE na spletu +Name[sr]=TDE на вебу +Name[sr@Latn]=TDE na vebu +Name[sv]=TDE på Internet +Name[ta]=வலையத்தில் கேடியி +Name[te]=వెబ్ లొ కెడిఈ +Name[tg]=TDE дар Интернет +Name[th]=TDE บนเว็บ +Name[tr]=Web'de TDE +Name[tt]=TDE Päräwezdä +Name[uk]=TDE в Тенетах +Name[uz]=TDE veb-sahifalari +Name[uz@cyrillic]=TDE веб-саҳифалари +Name[vi]=TDE trên mạng +Name[wa]=TDE sol waibe +Name[zh_CN]=网上 TDE +Name[zh_TW]=TDE 網站 + +X-DOC-Weight=4000 +Icon=kmenu diff --git a/khelpcenter/plugins/quickstart.desktop b/khelpcenter/plugins/quickstart.desktop new file mode 100644 index 000000000..717fd68dd --- /dev/null +++ b/khelpcenter/plugins/quickstart.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Name=Quickstart Guide +Name[af]=Woerts-warts Gids +Name[ar]=دليل إرشاد البدء السريع +Name[az]=Sür'ətli Başlama Rehberi +Name[be]=Падручнік для пачаткоўца +Name[bg]=Ръководство за начинаещите +Name[bn]=কুইকস্টার্ট গাইড +Name[br]=Sturier Kregiñ fonnus +Name[bs]=Vodič za brzi početak +Name[ca]=Guia ràpida +Name[cs]=Úvodní seznámení +Name[csb]=Sztartowi prowôdnik +Name[cy]=Canllaw cychwyn cyflym +Name[da]=Kvikstart-guide +Name[de]=Kurzeinführung +Name[el]=Οδηγός γρήγορου ξεκινήματος +Name[eo]=Konciza gvidlibro +Name[es]=Guía rápida +Name[et]=Kiire sissejuhatus +Name[eu]=Gida bizkorra +Name[fa]=راهنمای آغاز سریع +Name[fi]=Pikaohje +Name[fr]=Guide de démarrage rapide +Name[fy]=Fluchstartgids +Name[gl]=Guia de Início Rápido +Name[he]=מדריך התחלה מהירה +Name[hi]=शीघ्रप्रारंभ मार्गदर्शक +Name[hr]=Brzi uvod +Name[hu]=Rövid bevezetés +Name[id]=Petunjuk Memulai Secara Cepat +Name[is]=Skyndileiðbeiningar +Name[it]=Guida rapida +Name[ja]=クイックスタート +Name[ka]=სახელმძღვანელო დამწყებთათვის +Name[kk]=Бастаушы бағыттамасы +Name[km]=មគ្គុទ្ទេសក៍ចាប់ផ្ដើមរហ័ស +Name[ko]=빠른 시작 설명서 +Name[lo]=ຄຳແນະນຳແບບໄວ +Name[lt]=Greitos pradžios gidas +Name[lv]=Ātras sākšanas ceļvedis +Name[mk]=Водич за брзо снаоѓање +Name[mn]=QuickStart-Зааварчилгаа +Name[ms]=Panduan Mula Pantas +Name[mt]=Gwida biex tibda malajr +Name[nb]=Hurtigstart-guide +Name[nds]=Fixstart-Föhrer +Name[ne]=द्रुत सुरुआत मार्गदर्शन +Name[nl]=Snelstartgids +Name[nn]=Snøggstarguide +Name[nso]=Keletso ya Thomiso ya Kapejana +Name[oc]=Guia rapida +Name[pa]=ਚੁਸਤ ਸ਼ੁਰੂਆਤ ਗਾਈਡ +Name[pl]=Przewodnik startowy +Name[pt]=Guia de Iniciação +Name[pt_BR]=Guia Rápido +Name[ro]=Ghid rapid +Name[ru]=Руководство для начинающих в TDE +Name[rw]=Iyobora GutangiraVuba +Name[se]=Oanehis TDE-introdukšuvdna +Name[sk]=Návod na rýchle použitie +Name[sl]=Vodnik za hitri začetek +Name[sr]=Почетни водич +Name[sr@Latn]=Početni vodič +Name[sv]=Snabbstartsguide +Name[ta]=விரைவுதுவக்க வழிகாட்டி. +Name[tg]=Роҳнамоии шурӯъ кунӣ +Name[th]=คำแนะนำด่วน +Name[tr]=Hızlı Başlama Rehberi +Name[tt]=Tizcibärü Qullanması +Name[uk]=Посібник для швидкого старту +Name[uz]=TDE boʻyicha yoʻlkoʻrsatgich +Name[uz@cyrillic]=TDE бўйича йўлкўрсатгич +Name[ven]=Tsumbavhulwo ya mathomele au tavhanya +Name[vi]=Hướng dẫn nhanh +Name[wa]=Guide d' enondaedje al vole +Name[xh]=Isikhombisi Sesiqalo esikhawulezayo +Name[zh_CN]=速成指南 +Name[zh_TW]=快速入門指南 +Name[zu]=Umbonisi wokuqala ngokushesha +DocPath=help:/khelpcenter/quickstart/index.html + +X-DOC-Weight=-2000 +Icon=kmenu diff --git a/khelpcenter/plugins/support.desktop b/khelpcenter/plugins/support.desktop new file mode 100644 index 000000000..5ae894de1 --- /dev/null +++ b/khelpcenter/plugins/support.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/index.html?anchor=support + +Name=Supporting TDE +Name[af]=Ondersteun TDE +Name[ar]=دعم TDE +Name[be]=Падтрымка TDE +Name[bg]=Подпомагане на TDE +Name[bn]=কে.ডি.ই-কে সহায়তা +Name[br]=Skoazellañ TDE +Name[bs]=Podržite TDE +Name[ca]=Com col·laborar amb el TDE +Name[cs]=Podpora TDE +Name[csb]=Wspiarcë dlô TDE +Name[cy]=Cefnogi TDE +Name[da]=Støt TDE +Name[de]=TDE unterstützen +Name[el]=Υποστήριξη στο TDE +Name[eo]=Subteni TDEon +Name[es]=Colaborando con TDE +Name[et]=TDE toetamine +Name[eu]=TDEri lagunduz +Name[fa]=پشتیبانی TDE +Name[fi]=TDE:n tukeminen +Name[fr]=Aider TDE +Name[fy]=TDE stypje +Name[ga]=Ag Tacú le TDE +Name[gl]=Dar Apoio a TDE +Name[he]=תמיכה ב־TDE +Name[hi]=केडीई को आधार दें +Name[hr]=Podrška TDE-u +Name[hu]=A TDE támogatása +Name[is]=Styðja TDE +Name[it]=Aiutare TDE +Name[ja]=TDE 支援 +Name[ka]=TDE-ს მხარდაჭერა +Name[kk]=TDE-ні қолдау +Name[km]=ការគាំទ្រ TDE +Name[ko]=TDE 지원 +Name[lo]=ເກມກີລາ +Name[lt]=TDE palaikymas +Name[lv]=TDE atbalstīšana +Name[mk]=Поддршка за TDE +Name[mn]=КДЭ дэмжилэг +Name[ms]=TDE Sokongan +Name[mt]=Appoġġja lill-TDE +Name[nb]=Støtt TDE +Name[nds]=TDE ünnerstütten +Name[ne]=केडीई समर्थन +Name[nl]=TDE ondersteunen +Name[nn]=Støtt TDE +Name[nso]=Go Thekga TDE +Name[pa]=TDE ਦੀ ਸਹਾਇਤਾ +Name[pl]=Wspomaganie TDE +Name[pt]=Apoiar o TDE +Name[pt_BR]=Assistência ao TDE +Name[ro]=Cum să ajutați Proiectul TDE +Name[ru]=Поддержка TDE +Name[rw]=Gufasha TDE +Name[se]=Doarjjo TDE +Name[sk]=Podpora TDE +Name[sl]=Podpiranje TDE +Name[sr]=Подржавање TDE-а +Name[sr@Latn]=Podržavanje TDE-a +Name[sv]=Ge TDE ditt stöd +Name[ta]=TDEஐ ஆதரிக்கிறது +Name[te]=కెడిఈ కి సహాయంచెయండి +Name[tg]=Пуштибони TDE +Name[th]=การสนับสนุน TDE +Name[tr]=TDE'yi Destekleyin +Name[tt]=TDE Teräge +Name[uk]=Підтримка TDE +Name[uz]=TDE'ni qoʻllab-quvvatlash +Name[uz@cyrillic]=TDE'ни қўллаб-қувватлаш +Name[ven]=U tikedza TDE +Name[vi]=Hỗ trợ TDE +Name[wa]=Sopoirter TDE +Name[xh]=Ixhasa i TDE +Name[zh_CN]=支持 TDE +Name[zh_TW]=支援 TDE +Name[zu]=Ixhasa i-TDE + +X-DOC-Weight=5000 +Icon=kmenu diff --git a/khelpcenter/plugins/tdeioslaves.desktop b/khelpcenter/plugins/tdeioslaves.desktop new file mode 100644 index 000000000..4bb371d81 --- /dev/null +++ b/khelpcenter/plugins/tdeioslaves.desktop @@ -0,0 +1,228 @@ +[Desktop Entry] +Icon=contents2 +X-DOC-Weight=-400 +X-TDE-KHelpcenter-Special=tdeioslave + +Name=Protocols +Name[af]=Protokolle +Name[ar]=الموافيق +Name[az]=Protokollar +Name[be]=Пратаколы +Name[bg]=Протоколи +Name[bn]=প্রোটোকল +Name[br]=Komenadoù +Name[bs]=Protokoli +Name[cs]=Protokoly +Name[csb]=Protokòłë +Name[cy]=Protocolau +Name[da]=Protokoller +Name[de]=Ein-/Ausgabemodule +Name[el]=Πρωτόκολλα +Name[eo]=Protokoloj +Name[es]=Protocolos +Name[et]=IO moodulid +Name[eu]=Protokoloak +Name[fa]=قراردادها +Name[fi]=Yhteyskäytännöt +Name[fr]=Protocoles +Name[fy]=Protokollen +Name[ga]=Prótacail +Name[gl]=Protocolos +Name[he]=פרוטוקולים +Name[hi]=प्रोटोकॉल्स +Name[hr]=Protokoli +Name[hu]=Protokollok +Name[id]=Protokol +Name[is]=Samskiptareglur +Name[it]=Protocolli +Name[ja]=プロトコル +Name[ka]=პროტოკოლები +Name[kk]=Протоколдар +Name[km]=ពិធីការ +Name[ko]=프로토콜 +Name[lo]=ໂປຣໂຕຄອລ +Name[lt]=Protokolai +Name[lv]=Protokoli +Name[mk]=Протоколи +Name[mn]=Оролт/Гаралт-модул +Name[ms]=Protokol +Name[mt]=Protokolli +Name[nb]=Protokoller +Name[nds]=Protokollen +Name[ne]=प्रोटोकल +Name[nl]=Protocollen +Name[nn]=Protokollar +Name[nso]=Melao +Name[pa]=ਪਰੋਟੋਕਾਲ +Name[pl]=Protokoły +Name[pt]=Protocolos +Name[pt_BR]=Protocolos +Name[ro]=Protocoale +Name[ru]=Протоколы +Name[rw]=Amaporotocole +Name[se]=Protokollat +Name[sk]=Protokoly +Name[sl]=Protokoli +Name[sr]=Протоколи +Name[sr@Latn]=Protokoli +Name[ss]=Imitsetfo yekutfumela +Name[sv]=Protokoll +Name[ta]=நெறிமுறைகள் +Name[te]=ప్రొటొకాల్లు +Name[tg]=Қарордодҳо +Name[th]=โปรโตคอล +Name[tr]=Protokoller +Name[tt]=Protokollar +Name[uk]=Протоколи +Name[uz]=Protokollar +Name[uz@cyrillic]=Протоколлар +Name[ven]=Purotokolo +Name[vi]=Giao thức +Name[wa]=Protocoles +Name[xh]=Umthetho olandelwayo +Name[zh_CN]=协议 +Name[zh_TW]=協定 +Name[zu]=Imithetho elandelwayo +Comment=Information about the available protocols +Comment[af]=Informasie aangaande die beskikbaar protokolle +Comment[ar]=معلومات عن الموافيق المتوفرة +Comment[az]=Mövcud protokollar haqqında mə'lumat +Comment[be]=Інфармацыя аб наяўных пратаколах +Comment[bg]=Информация за поддържаните протоколи +Comment[bn]=বিভিন্ন প্রোটোকল সম্বন্ধে তথ্য +Comment[bs]=Informacije o dostupnim protokolima +Comment[ca]=Informació sobre els protocols disponibles +Comment[cs]=Informace o dostupných protokolech +Comment[csb]=Wëdowiédzô ò przistãpnëch protokòłach +Comment[cy]=Gwybodaeth am y protocolau sydd ar gael +Comment[da]=Information om de tilgængelige protokoller +Comment[de]=Information zu den verfügbaren Ein-/Ausgabemodulen +Comment[el]=Πληροφορίες για τα διαθέσιμα πρωτόκολλα +Comment[eo]=Informo pri la uzeblaj protokoloj +Comment[es]=Información sobre los protocolos disponibles +Comment[et]=Olemasolevate IO moodulite (ioslave) info +Comment[eu]=Produktu eskuragarriei buruzko informazioa +Comment[fa]=اطلاعاتی دربارۀ قراردادهای قابل دسترس +Comment[fi]=Tietoja saatavilla olevista yhteyskäytännöistä +Comment[fr]=Informations sur les protocoles disponibles +Comment[fy]=Ynformaasje oer de beskikbere protokollen +Comment[ga]=Eolas faoi na bprótacail atá ar fáil +Comment[gl]=Información acerca dos protocolos diponíbeis +Comment[he]=מידע על הפרוטוקולים הזמינים +Comment[hi]=उपलब्ध प्रोटोकॉल्स के बारे में जानकारी +Comment[hr]=Podaci o raspoloživim protokolima +Comment[hu]=A rendelkezésre álló protokollok jellemzői +Comment[id]=Informasi tentang protokol yang tersedia +Comment[is]=Upplýsingar um nothæfar samskiptareglur +Comment[it]=Informazioni sui protocolli disponibili +Comment[ja]=利用可能なプロトコルの情報 +Comment[ka]=ინფორმაცია ხელმისაწვდომი პროტოკოების შესახებ +Comment[kk]=Енгізу-шығару протоколдар туралы мәлімет +Comment[km]=ព័ត៌មានអំពីពិធីការដែលអាចរកបាន +Comment[ko]=사용 가능한 프로토콜 정보 +Comment[lo]=ຂໍ້ມູນກ່ງວກັບໂປຣໂຕຄອນທີ່ມີຢູ່ +Comment[lt]=Informacija apie esamus protokolus +Comment[lv]=Informācija par pieejamajiem protokoliem +Comment[mk]=Информации за достапните протоколи +Comment[mn]=Бэлэн байгаа оролт/гаралтын-модулын мэдээлэл +Comment[ms]=Maklumat tentang protokol yang boleh didapatkan +Comment[mt]=Informazzjoni dwar il-protokolli li hawn +Comment[nb]=Informasjon om de tilgjengelige protokollene +Comment[nds]=Informatschoon över de verföögboren Protokollen +Comment[ne]=उपलब्ध प्रोटोकलका बारेमा सूचना +Comment[nl]=Informatie over de beschikbare protocollen +Comment[nn]=Informasjon om dei tilgjengelege protokollane +Comment[nso]=Tshedimoso kaga melao yeo elego gona +Comment[pa]=ਉਪਲੱਬਧ ਪਰੋਟੋਕਾਲ ਬਾਰੇ ਜਾਣਕਾਰੀ +Comment[pl]=Informacje o dostępnych protokołach +Comment[pt]=Informações sobre os protocolos disponíveis +Comment[pt_BR]=Informações sobre os protocolos disponíveis +Comment[ro]=Informații despre protocoalele disponibile +Comment[ru]=Сведения о протоколах ввода-вывода +Comment[rw]=Ibisobanuro birebana na porotokole ziboneka +Comment[se]=Dieđut olamuttus protokollaid birra +Comment[sk]=Informácia o dostupných protokoloch +Comment[sl]=Podatki o razpoložljivih protokolih +Comment[sr]=Информације о доступним протоколима +Comment[sr@Latn]=Informacije o dostupnim protokolima +Comment[sv]=Information om tillgängliga protokoll +Comment[ta]=கிடைக்கக்கூடிய நெறிமுறைகள் பற்றிய தகவல் +Comment[tg]=Иттилооти дар мавриди қарордодҳои мавҷуд буда +Comment[th]=ข้อมูลเกี่ยวกับโปรโตคอลที่มีอยู่ +Comment[tr]=Mevcut protokoller hakkında bilgi +Comment[tt]=Bar bulğan protokollar turında +Comment[uk]=Інформація про наявні протоколи +Comment[uz]=Mavjud protokollar haqida maʼlumot +Comment[uz@cyrillic]=Мавжуд протоколлар ҳақида маълумот +Comment[ven]=Mafhungo ngaha purotokolo ire hone +Comment[vi]=Thông tin về các giao thức có thể dùng +Comment[wa]=Informåcion so les protocoles k' i gn a +Comment[xh]=Ulwazi malunga nemithetho elandelwayo ekhoyo +Comment[zh_CN]=可用协议的信息 +Comment[zh_TW]=可用協定的資訊 +Comment[zu]=Ulwazi mayelana nemithetho elandelwayo ekhona +Keywords=Protocol,IO slaves,Slaves,Network,Information,Timeout +Keywords[ar]=الميفاق,IO Slaves,Slaves,الشبكة,معلومات نفاذ الوقت +Keywords[az]=Protokol, IO Kölələri, Kölələr, Şəbəkə,Mə'lumat, Vaxt Dolması +Keywords[be]=Пратакол,Сетка,Інфармацыя,Тэрмін чакання,Protocol,IO slaves,Slaves,Network,Information,Timeout +Keywords[bg]=информация, система, системна, протокол, протоколи, наличен, поддържан, Protocol, IO slaves, Slaves, Network, Information, Timeout +Keywords[ca]=Protocol,esclaus IO,Esclaus,Xarxa,Informació,Temps d'expiració +Keywords[cs]=Protokol,Vstupně/výstupní moduly,Síť,Informace,Časový limit +Keywords[csb]=Protokół,procedurë wé/wi,wëkonëjący dzéjaniô wé/wi,Séc,wëdowiédzô,Limit czasu +Keywords[cy]=Protocol,Gweision IO,Gweision,Rhwydwaith,Gwybodaeth,Goramser +Keywords[da]=Protokol,IO-slaver,Slaver,Netværk,Information,Tid,Udløb,Timeout +Keywords[de]=Protokolle,Information,Ein/Ausgabe,Ein-/Ausgabemodule,IO-Slaves,Netzwerk,Zeitlimit,Timeout +Keywords[el]=Πρωτόκολλο,slaves ΕΕ,Slaves,Δίκτυο,Πληροφορίες,Χρονικό όριο +Keywords[eo]=Protokolo,Enel-sklavoj,sklavoj,reto,informo,tempolimo +Keywords[es]=Protocolo,Slaves de E/S,Slaves,Red,Información,Tiempo de expiración +Keywords[et]=protokoll,IO moodulid,moodulid,võrk,info,taimaut,aegumine +Keywords[eu]=Protocol,IO morroiak,Morroiak,Sarea,Informazioa,Denbora-muga +Keywords[fa]=قرارداد، IO slaves، Slaves، شبکه، اطلاعات، اتمام وقت +Keywords[fi]=Protokolla,Yhteyskäytäntö,TDEIO,TDEIO-palvelu,Verkko,Aikavalvonta,aikakatkaisu +Keywords[fr]=protocole,modules,entrées/sorties,réseau,informations,délai +Keywords[fy]=protocol,IO slaves,slaves,network,ynformaasje,timeout,netwurk,tiidslimyt +Keywords[gl]=Protocolo,escravos IO,Escravos,Rede,Información,Tempo de agarda,Timeout +Keywords[he]=פרוטוקול,עבדי קלט־פלט,רשת,מידע,זמן מוקצב, Protocol,IO slaves,Slaves,Network,Information,Timeout +Keywords[hi]=प्रोटोकॉल,आईओ स्लैव्स,स्लैव्स,नेटवर्क,जानकारी,टाइमआउट +Keywords[hr]=Protocol,IO slaves,Slaves,Network,Information,Timeout,Protokol,IO podčinjeni,Podčinjeni,Mreža,Podaci,Istek +Keywords[hu]=protokoll,TDE protokollok,protokoll,hálózat,információ,időtúllépés +Keywords[is]=Samskiptareglur,IO þrælar,þrælar,staðarnet,net,upplýsingar,útrunninn tími +Keywords[it]=protocollo,IO slave,slave,rete,informazioni,tempo massimo +Keywords[ja]=プロトコル,IO,スレイブ,スレーブ,ネットワーク,情報,タイムアウト +Keywords[km]=ពិធីការ,IO កូនចៅ,កូនចៅ,បណ្ដាញ,ព័ត៌មាន,អស់ពេល +Keywords[lo]=ໂປຣໂຕຄອນ,IO slaves,Slaves,ລະບົບເຄືອຂ່າຍ,ຂໍ້ມູນ,ຫມົດເວລາ +Keywords[lt]=Protocol,IO slaves,Slaves,Network,Information,Timeout,protokolas,tinklas,informacija,laiko pasibaigimas +Keywords[lv]=Protokols,IO vergi,Vergi,Tīkls,Informācija,Noildze +Keywords[mk]=Protocol,IO slaves,Slaves,Network,Information,Timeout,Протокол,Мрежа,Информации,Истек на време +Keywords[mn]=Протокол,Мэдээлэл,Оролт/Гаралт,IO-Slaves,Сүлжээ, Хугацааны хязгаар,Хугацаа хэтрэлт +Keywords[nb]=Protokoll,IO-slaver,Slaver,Nettverk,Informasjon,Ventetid +Keywords[nds]=Protokoll,In-/Utgaavdeensten,IO,Deensten,Nettwark,Informatschoon,Timeout,Tietgrenz +Keywords[ne]=प्रोटोकल, IO स्लेभ, स्लेभहरू, सञ्जाल, सूचना, समय समाप्त +Keywords[nl]=protocol,IO slaves,slaves,network,informatie,timeout,netwerk,tijdslimiet +Keywords[nn]=protokoll,IU-slavar,slavar,nettverk,informasjon,tidsgrense +Keywords[nso]=Molao,Makgoba a IO,Makgoba,Kgokagano,Tshedimoso, Nako e fedile +Keywords[pa]=Protocol,IO slaves,Slaves,Network,Information,Timeout,ਪਰੋਟੋਕਾਲ,ਨੈਟਵਰਕ +Keywords[pl]=Protokół,procedury we/wy,wykonujący operacje we/wy,Sieć,Informacje,Limit czasu +Keywords[pt]=Protocolo,IO slaves,Slaves,Rede,Informações,Timeout,Tempo-limite +Keywords[pt_BR]=Protocolos,escravos de ES,Escravos,Rede,Informações,Timeout +Keywords[ro]=samba,dispozitive I/O,sclavi,rețea,informații +Keywords[rw]=Porotokole,Abagaragu IO,Abagaragu,Urusobemiyoboro,Amakuru, Igihecyarenze +Keywords[se]=protokolla,SO-slávat,slávat,fierbmi,diehtu,dieđut,áigemearri +Keywords[sk]=Protokol,Klienti IO,klienti,Sieť,Informácie +Keywords[sl]=protokol,podrejeni V/I,podrejeni,omrežje,podatki,zakasnitev +Keywords[sr]=Protocol,IO slaves,Slaves,Network,Information,Timeout,протокол,мрежа,информације,прекорачење времена +Keywords[sr@Latn]=Protocol,IO slaves,Slaves,Network,Information,Timeout,protokol,mreža,informacije,prekoračenje vremena +Keywords[sv]=Protokoll,I/O-slavar,Slavar,Nätverk,Information,Timeout,Tidsgräns +Keywords[ta]=நெறிமுறை,IO சேவகன்,சேவகன்கள்,வலைப்பின்னல்,தகவல்,நேரம் முடிந்தது +Keywords[th]=โปรโตคอล,IO slaves,Slaves,ระบบเครือข่าย,ข้อมูล,หมดเวลา +Keywords[tr]=protokol,G/Ç aracısı,aracı,Ağ,Bilgi,zaman aşımı +Keywords[uk]=протокол,підлеглі В/В,підлеглі,мережа,інформація,тайм-аут +Keywords[uz]=Protokol,KCH-sleyvlar,Sleyvlar,Tarmoq,Maʼlumot,Taymaut +Keywords[uz@cyrillic]=Протокол,КЧ-слейвлар,Слейвлар,Тармоқ,Маълумот,Таймаут +Keywords[ven]=Purotokolo,dziphuli dza IO,Dziphuli,Vhudavhidzani,mafhungo,u fhela ha tshifhinga +Keywords[vi]=Giao thức,Đầy tớ Vào ra (VR),Đầy tớ,Mạng,Thông tin,Hạn định thời gian +Keywords[wa]=Protocole,IO slaves,Slaves,rantoele,Informåcion,Timeout +Keywords[xh]=Imithetho elandelwayo,IO izicaka,Izicaka,Umsebenzi womtya,Ulwazi, Ixesha lokuphuma +Keywords[zh_CN]=Protocol,IO slaves,Slaves,Network,Information,Timeout,协议,网络,信息,超时 +Keywords[zh_TW]=Protocol,IO slaves,Slaves,Network,Information,Timeout,協定,網路,資訊,作業逾時 +Keywords[zu]=Umthetho olandelwayo,IO slaves,Izigqila,Uxhumano olusakazekile, Ulwazi,Isikhathi sokuphuma diff --git a/khelpcenter/plugins/userguide.desktop b/khelpcenter/plugins/userguide.desktop new file mode 100644 index 000000000..94758edaf --- /dev/null +++ b/khelpcenter/plugins/userguide.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/userguide/index.html + +Name=TDE User Guide +Name[af]=TDE gebruiker handleiding +Name[ar]=دليل TDE للمستخدمين +Name[be]=Падручнік карыстальніка TDE +Name[bg]=Ръководство за употреба +Name[bn]=কে.ডি.ই. ব্যবহারকারীদের জন্য ম্যানুয়াল +Name[br]=Levr-dorn arveriaded TDE +Name[bs]=TDE korisnički priručnik +Name[ca]=Manual d'usuari TDE +Name[cs]=Příručka uživatele TDE +Name[csb]=Pòdrãcznik brëkòwnika TDE +Name[cy]=Llawlyfr Defnyddwyr TDE +Name[da]=TDE-brugervejledning +Name[de]=TDE-Benutzerhandbuch +Name[el]=Εγχειρίδιο χρήστη του TDE +Name[eo]=TDE-uzantula manlibro +Name[es]=Manual del usuario de TDE +Name[et]=TDE kasutaja käsiraamat +Name[eu]=TDEren erabiltzailearen eskuliburua +Name[fa]=راهنمای کاربران TDE +Name[fi]=TDE:n käyttöohje +Name[fr]=Manuel de l'utilisateur de TDE +Name[fy]=TDE's hânlieding +Name[ga]=Lámhleabhar TDE d'úsáideoirí +Name[gl]=Manual de usuario de TDE +Name[he]=המדריך למשתמש ב־TDE +Name[hi]=केडीई उपयोक्ता निर्देशिका +Name[hr]=TDE korisnički priručnik +Name[hu]=TDE-felhasználók kézikönyve +Name[is]=TDE notandahandbækur +Name[it]=Manuale degli utenti di TDE +Name[ja]=TDE ユーザマニュアル +Name[ka]=TDE-ს მომხმარებლის სახელმძღვანელო +Name[kk]=TDE пайдаланушының оқулығы +Name[km]=សៀវភៅប្រើ TDE +Name[ko]=TDE 사용자 설명서 +Name[lt]=TDE naudotojo vadovas +Name[lv]=TDE lietotāja rokasgrāmata +Name[mk]=TDE кориснички прирачник +Name[ms]=Manual Pengguna TDE +Name[mt]=Manwal tal-users ta' TDE +Name[nb]=Brukerhandbok for TDE +Name[nds]=TDE-Brukerhandbook +Name[ne]=TDE प्रयोगकर्ता म्यानुअल +Name[nl]=TDE's Gebruikershandboek +Name[nn]=Brukarhandbok for TDE +Name[pa]=TDE ਉਪਭੋਗੀ ਦਸਤਾਵੇਜ਼ +Name[pl]=Podręcznik użytkownika TDE +Name[pt]=Manual do Utilizador do TDE +Name[pt_BR]=Manual do Usuário do TDE +Name[ro]=Manualul utilizatorului TDE +Name[ru]=Руководство пользователя TDE +Name[rw]=TDE Igitabomikorere cy'Ukoresha +Name[se]=TDE giehtagirji +Name[sk]=Príručka pre používateľa TDE +Name[sl]=Uporabniški priročnik TDE +Name[sr]=TDE-ово упутство за кориснике +Name[sr@Latn]=TDE-ovo uputstvo za korisnike +Name[sv]=TDE:s användarhandbok +Name[ta]=TDE பயனர்களின் கையேடு +Name[te]=కెడిఈ యూజర్ మెన్యువల్ +Name[tg]=Дастури корбари TDE +Name[th]=คู่มือผู้ใช้งาน TDE +Name[tr]=TDE Kullanıcı Klavuzu +Name[tt]=TDE Qullanması +Name[uk]=Підручник користувача TDE +Name[uz]=TDE uchun qoʻllanma +Name[uz@cyrillic]=TDE учун қўлланма +Name[vi]=Hướng dẫn sử dụng TDE +Name[wa]=Esplikêyes po l' uzeu di TDE +Name[zh_CN]=TDE 用户手册 +Name[zh_TW]=TDE 使用者手冊 + +X-DOC-Weight=-1500 +Icon=kmenu diff --git a/khelpcenter/plugins/visualdict.desktop b/khelpcenter/plugins/visualdict.desktop new file mode 100644 index 000000000..ca7593032 --- /dev/null +++ b/khelpcenter/plugins/visualdict.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Name=A Visual Guide to TDE +Name[af]='n Visuele Gids tot TDE +Name[ar]=مرشد مرئي لِــ TDE +Name[az]=TDE Üçün Vəzual Bədəçi +Name[be]=Падручнік TDE па візуальных аб'ектах +Name[bg]=Нагледни пособия +Name[bn]=কে.ডি.ই-র জন্য একটি ভিসুয়াল গাইড +Name[bs]=Vizualni vodič u TDE +Name[ca]=Una guia visual per al TDE +Name[cs]=Názorný průvodce prostředím TDE +Name[csb]=Prowôdnik pò TDE +Name[cy]=Canllaw Gweledol i TDE +Name[da]=En visuel guide til TDE +Name[de]=Visuelle Einführung in TDE +Name[el]=Ένας οπτικός οδηγός για το TDE +Name[eo]=Gvidilo pri TDE +Name[es]=Guía visual de TDE +Name[et]=TDE visuaalne juhend +Name[eu]=TDErako gida bisuala +Name[fa]=یک راهنمای مرئی برای TDE +Name[fi]=Kuvallinen ohje TDE:hen +Name[fr]=Un guide visuel de TDE +Name[fy]=In fisuele TDE-gids +Name[gl]=Unha Guia Visual de TDE +Name[he]=מדריך חזותי ל־TDE +Name[hi]=केडीई के लिए एक दृश्य मार्गदर्शक +Name[hr]=Vizualni vodič u TDE +Name[hu]=A TDE grafikus elemeinek ismertetése +Name[id]=Petunjuk TDE Visual +Name[is]=Myndrænn leiðarvísir að TDE +Name[it]=Una guida visiva di TDE +Name[ja]=TDE のためのビジュアルガイド +Name[ka]=TDE-ს თვალსაჩინო სახელმძღვანელო +Name[kk]=TDE көрнекті бағыттамасы +Name[km]=មគ្គុទ្ទេសក៍រូបភាពមកកាន់ TDE +Name[ko]=TDE 모습 둘러보기 +Name[lo]=ນຳທ່ງວ TDE ແບບສະເຫມື່ອນแบบเสมือน +Name[lt]=Vaizdinis TDE gidas +Name[lv]=Vizuāls Ceļvedis pa TDE +Name[mk]=Визуелен вовед во TDE +Name[mn]=КДЭ-н визуал удиртгал +Name[ms]=Panduan Visual TDE +Name[mt]=Gwida Viżwali għall-TDE +Name[nb]=En visuell guide til TDE +Name[nds]=En visuell Inföhren na TDE +Name[ne]=TDE मा दृश्य मार्गदर्शन +Name[nl]=Een visuele TDE-gids +Name[nn]=Visuell TDE-gaid +Name[nso]=Keletso yeo e Kwagalago ya TDE +Name[pa]=TDE ਲਈ ਇੱਕ ਦਿੱਖ ਗਾਈਡ +Name[pl]=Przewodnik po TDE +Name[pt]=Um Guia Visual para o TDE +Name[pt_BR]=Guia Visual para o TDE +Name[ro]=Ghid vizual TDE +Name[ru]=Наглядное пособие по TDE +Name[rw]=Inyobora Igaragara kuri TDE +Name[se]=Visuella TDE-introdukšuvdna +Name[sk]=Obrázková príručka TDE +Name[sl]=Vodnik po TDE +Name[sr]=Визуелни водич за TDE +Name[sr@Latn]=Vizuelni vodič za TDE +Name[sv]=Visuell guide till TDE +Name[ta]=TDEன் காட்டிசார் வழிகாட்டி +Name[tg]=Роҳнамои басрии TDE +Name[th]=นำเที่ยว TDE +Name[tr]=TDE İçin Görsel Kılavuz +Name[tt]=TDE öçen Kürsätü-Qullanma +Name[uk]=Наочний підручник по TDE +Name[ven]=Tsumbavhulwo ya zwauvhona ya TDE +Name[vi]=Trình Hướng dẫn Sinh động cho TDE +Name[wa]=On guide a vey po TDE +Name[xh]=Isikhombisi esibonakalayo se TDE +Name[zh_CN]=TDE 可视化指南 +Name[zh_TW]=TDE 視覺指南 +Name[zu]=Umbonisi obonakalayo oya kwi-TDE +DocPath=help:/khelpcenter/visualdict/index.html + +X-DOC-Weight=-2500 +Icon=kmenu diff --git a/khelpcenter/plugins/welcome.desktop b/khelpcenter/plugins/welcome.desktop new file mode 100644 index 000000000..b6c264efd --- /dev/null +++ b/khelpcenter/plugins/welcome.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +DocPath=help:/khelpcenter/index.html?anchor=welcome + +Name=Welcome to TDE +Name[af]=Welkom by TDE +Name[ar]=مرحباً بك إلى TDE +Name[be]=Сардэчна запрашаем у TDE +Name[bg]=Добре дошли в TDE +Name[bn]=কে.ডি.ই.-তে স্বাগতম্ +Name[br]=Degemer e TDE +Name[bs]=Dobro došli u TDE +Name[ca]=Benvingut al TDE +Name[cs]=Uvítání do TDE +Name[csb]=Witómë w TDE +Name[cy]=Croeso i TDE +Name[da]=Velkommen til TDE +Name[de]=Willkommen bei TDE +Name[el]=Καλωσορίσατε στο TDE +Name[eo]=Bonvenon ĉe TDE +Name[es]=Bienvenido a TDE +Name[et]=Tere tulemast TDE-sse +Name[eu]=Ongi etorria TDEra +Name[fa]=به TDE خوش آمدید +Name[fi]=Tervetuloa TDE:hen +Name[fr]=Bienvenue sur TDE +Name[fy]=Wolkom by TDE +Name[ga]=Fáilte go TDE +Name[gl]=Benvido/a a TDE +Name[he]=ברוכים הבאים אל TDE +Name[hi]=केडीई में आपका स्वागत है +Name[hr]=Dobrodošli u TDE +Name[hu]=Üdvözöljük a TDE-ben! +Name[is]=Velkomin að TDE +Name[it]=Benvenuto in TDE +Name[ja]=TDE へようこそ +Name[ka]=მოგესალმებათ TDE +Name[kk]=TDE-ге қош келдіңіз +Name[km]=ស្វាគមន៍មកកាន់ TDE +Name[ko]=TDE에 오신 것을 환영합니다 +Name[lo]=ພັດທະນາໂປຣແກຣມ +Name[lt]=Jus sveikina TDE +Name[lv]=Laipni lūdzu iekš TDE +Name[mk]=Добредојдовте во TDE +Name[mn]=КДЭ-д тавтай морил +Name[ms]=Selamat Datang ke TDE +Name[mt]=Merħba għal TDE +Name[nb]=Velkommen til TDE +Name[nds]=Willkamen bi TDE +Name[ne]=केडीईमा स्वागत +Name[nl]=Welkom bij TDE +Name[nn]=Velkommen til TDE +Name[nso]=O Amogetswe go TDE +Name[pa]=TDE ਵਲੋਂ ਜੀ ਆਇਆਂ ਨੂੰ +Name[pl]=Witamy w TDE +Name[pt]=Bem-vindo ao TDE +Name[pt_BR]=Bem-vindo ao TDE +Name[ro]=Bine ați venit în TDE +Name[ru]=Добро пожаловать в TDE +Name[rw]=Urakaza neza kuri TDE +Name[se]=Bures boahtin TDE:ii +Name[sk]=Privítanie TDE +Name[sl]=Dobrodošli v TDE +Name[sr]=Добродошли у TDE +Name[sr@Latn]=Dobrodošli u TDE +Name[sv]=Välkommen till TDE +Name[ta]=TDEக்கு நல்வரவு +Name[te]=కెడిఈ కు స్వాగతం +Name[tg]=Хуш омадед ба TDE +Name[th]=ยินดีต้อนรับสู่ TDE +Name[tr]=TDE'ye Hoş Geldiniz +Name[tt]=TDE Räxim İt di</h3> +Name[uk]=Ласкаво просимо до TDE +Name[uz]=TDE'ga marhamat +Name[uz@cyrillic]=TDE'га марҳамат +Name[ven]=Riani tanganedza kha TDE +Name[vi]=Chào mừng bạn đến với TDE +Name[wa]=Bénvnowe dins TDE +Name[xh]=Wamkelekile kwi TDE +Name[zh_CN]=欢迎使用 TDE +Name[zh_TW]=歡迎使用 TDE +Name[zu]=Wamukulekile kwi-TDE + +X-DOC-Weight=-3000 +Icon=kmenu diff --git a/khelpcenter/plugintraverser.cpp b/khelpcenter/plugintraverser.cpp new file mode 100644 index 000000000..ca33664df --- /dev/null +++ b/khelpcenter/plugintraverser.cpp @@ -0,0 +1,116 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 "plugintraverser.h" +#include "docmetainfo.h" +#include "navigator.h" +#include "navigatorappitem.h" +#include "navigatoritem.h" + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kiconloader.h> + +#include <tqlistview.h> + +using namespace KHC; + +PluginTraverser::PluginTraverser( Navigator *navigator, TQListView *parent ) + : DocEntryTraverser(), + mListView( parent ), + mParentItem( 0 ), + mCurrentItem( 0 ), + mNavigator( navigator ) +{ +} + +PluginTraverser::PluginTraverser( Navigator *navigator, NavigatorItem *parent ) + : DocEntryTraverser(), + mListView( 0 ), + mParentItem( parent ), + mCurrentItem( 0 ), + mNavigator( navigator ) +{ +} + +void PluginTraverser::process( DocEntry *entry ) +{ + if ( !mListView && !mParentItem ) { + kdDebug( 1400 ) << "ERROR! Neither mListView nor mParentItem is set." << endl; + return; + } + + if ( !entry->docExists() && !mNavigator->showMissingDocs() ) + return; + +#if 0 + kdDebug() << "PluginTraverser::process(): " << entry->name() + << " (weight: " << entry->weight() << " parent: " + << ( mParentItem ? mParentItem->name() : "0" ) << ")" << endl; +#endif + + if ( entry->khelpcenterSpecial() == "apps" ) { + NavigatorAppItem *appItem; + entry->setIcon( "kmenu" ); + if ( mListView ) + appItem = new NavigatorAppItem( entry, mListView, mCurrentItem ); + else + appItem = new NavigatorAppItem( entry, mParentItem, mCurrentItem ); + TDEConfig *cfg = kapp->config(); + cfg->setGroup( "General" ); + appItem->setRelpath( cfg->readPathEntry( "AppsRoot" ) ); + mCurrentItem = appItem; + } else if ( entry->khelpcenterSpecial() == "scrollkeeper" ) { + if ( mParentItem ) { + mCurrentItem = mNavigator->insertScrollKeeperDocs( mParentItem, mCurrentItem ); + } + return; + } else { + if ( mListView ) + mCurrentItem = new NavigatorItem( entry, mListView, mCurrentItem ); + else + mCurrentItem = new NavigatorItem( entry, mParentItem, mCurrentItem ); + + if (entry->khelpcenterSpecial() == "applets" ) { + mNavigator->insertAppletDocs( mCurrentItem ); + } else if ( entry->khelpcenterSpecial() == "kcontrol" || + entry->khelpcenterSpecial() == "konqueror" ) { + mNavigator->insertParentAppDocs( entry->khelpcenterSpecial(), mCurrentItem ); + } else if ( entry->khelpcenterSpecial() == "tdeioslave" ) { + mNavigator->insertIOSlaveDocs( entry->khelpcenterSpecial(), mCurrentItem ); + } else if ( entry->khelpcenterSpecial() == "info" ) { + mNavigator->insertInfoDocs( mCurrentItem ); + } else { + return; + } + mCurrentItem->setPixmap( 0, SmallIcon( "contents2" ) ); + } +} + +DocEntryTraverser *PluginTraverser::createChild( DocEntry * /*entry*/ ) +{ + if ( mCurrentItem ) { + return new PluginTraverser( mNavigator, mCurrentItem ); + } + kdDebug( 1400 ) << "ERROR! mCurrentItem is not set." << endl; + return 0; +} + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/plugintraverser.h b/khelpcenter/plugintraverser.h new file mode 100644 index 000000000..93b48003c --- /dev/null +++ b/khelpcenter/plugintraverser.h @@ -0,0 +1,52 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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_PLUGINTRAVERSER_H +#define KHC_PLUGINTRAVERSER_H + +#include "docentrytraverser.h" + +class TQListView; +class TQListViewItem; + +namespace KHC { + class Navigator; + class NavigatorItem; + + class PluginTraverser : public DocEntryTraverser + { + public: + PluginTraverser( Navigator *navigator, TQListView *parent ); + PluginTraverser( Navigator *navigator, NavigatorItem *parent ); + + virtual void process( DocEntry *entry ); + + virtual DocEntryTraverser *createChild( DocEntry *entry ); + + private: + TQListView *mListView; + NavigatorItem *mParentItem; + NavigatorItem *mCurrentItem; + + Navigator *mNavigator; + }; +} + +#endif // KHC_PLUGINTRAVERSER_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/prefs.kcfgc b/khelpcenter/prefs.kcfgc new file mode 100644 index 000000000..4742430de --- /dev/null +++ b/khelpcenter/prefs.kcfgc @@ -0,0 +1,6 @@ +# Code generation options for tdeconfig_compiler +File=khelpcenter.kcfg +ClassName=Prefs +Singleton=true +Mutators=true +GlobalEnums=true diff --git a/khelpcenter/scopeitem.h b/khelpcenter/scopeitem.h new file mode 100644 index 000000000..cabbab76e --- /dev/null +++ b/khelpcenter/scopeitem.h @@ -0,0 +1,50 @@ +#ifndef SCOPEITEM_H +#define SCOPEITEM_H + +#include <tqlistview.h> + +#include "docmetainfo.h" + +namespace KHC { + +class ScopeItem : public TQCheckListItem +{ + public: + ScopeItem( TQListView *parent, DocEntry *entry ) + : TQCheckListItem( parent, entry->name(), TQCheckListItem::CheckBox ), + mEntry( entry ), mObserver( 0 ) {} + + ScopeItem( TQListViewItem *parent, DocEntry *entry ) + : TQCheckListItem( parent, entry->name(), TQCheckListItem::CheckBox ), + mEntry( entry ), mObserver( 0 ) {} + + DocEntry *entry()const { return mEntry; } + + int rtti() const { return rttiId(); } + + static int rttiId() { return 734678; } + + class Observer + { + public: + virtual void scopeItemChanged( ScopeItem * ) = 0; + }; + + void setObserver( Observer *o ) { mObserver = o; } + + protected: + void stateChange ( bool ) + { + if ( mObserver ) mObserver->scopeItemChanged( this ); + } + + private: + DocEntry *mEntry; + + Observer *mObserver; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/scrollkeepertreebuilder.cpp b/khelpcenter/scrollkeepertreebuilder.cpp new file mode 100644 index 000000000..87a6861e4 --- /dev/null +++ b/khelpcenter/scrollkeepertreebuilder.cpp @@ -0,0 +1,200 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 "scrollkeepertreebuilder.h" + +#include "navigatoritem.h" +#include "docentry.h" + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <tdeglobal.h> +#include <tdelocale.h> +#include <kprocio.h> + +#include <tqdom.h> +#include <tqfile.h> +#include <tqregexp.h> + +using namespace KHC; + +ScrollKeeperTreeBuilder::ScrollKeeperTreeBuilder( TQObject *parent, const char *name ) + : TQObject( parent, name ) +{ + loadConfig(); +} + +void ScrollKeeperTreeBuilder::loadConfig() +{ + TDEConfig *cfg = kapp->config(); + { + TDEConfigGroupSaver groupSaver( cfg, "ScrollKeeper" ); + mShowEmptyDirs = cfg->readBoolEntry( "ShowEmptyDirs", false ); + } +} + +NavigatorItem *ScrollKeeperTreeBuilder::build( NavigatorItem *parent, + NavigatorItem *after ) +{ + TQString lang = TDEGlobal::locale()->language(); + + kdDebug(1400) << "ScrollKeeper language: " << lang << endl; + + KProcIO proc; + proc << "scrollkeeper-get-content-list"; + proc << lang; + connect(&proc,TQT_SIGNAL(readReady(KProcIO *)),TQT_SLOT(getContentsList(KProcIO *))); + if (!proc.start(TDEProcess::Block)) { + kdDebug(1400) << "Could not execute scrollkeeper-get-content-list" << endl; + return 0; + } + + if (!TQFile::exists(mContentsList)) { + kdDebug(1400) << "Scrollkeeper contents file '" << mContentsList + << "' does not exist." << endl; + return 0; + } + + TQDomDocument doc("ScrollKeeperContentsList"); + TQFile f(mContentsList); + if ( !f.open( IO_ReadOnly ) ) + return 0; + if ( !doc.setContent( &f ) ) { + f.close(); + return 0; + } + f.close(); + + // Create top-level item + mItems.append(parent); + + TQDomElement docElem = doc.documentElement(); + + NavigatorItem *result = 0; + + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if (e.tagName() == "sect") { + NavigatorItem *createdItem; + insertSection( parent, after, e, createdItem ); + if ( createdItem ) result = createdItem; + } + } + n = n.nextSibling(); + } + + return result; +} + +void ScrollKeeperTreeBuilder::getContentsList( KProcIO *proc ) +{ + TQString filename; + proc->readln( filename, true ); + + mContentsList = filename; +} + +int ScrollKeeperTreeBuilder::insertSection( NavigatorItem *parent, + NavigatorItem *after, + const TQDomNode §Node, + NavigatorItem *§Item ) +{ + DocEntry *entry = new DocEntry( "", "", "contents2" ); + sectItem = new NavigatorItem( entry, parent, after ); + sectItem->setAutoDeleteDocEntry( true ); + mItems.append( sectItem ); + + int numDocs = 0; // Number of docs created in this section + + TQDomNode n = sectNode.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if ( e.tagName() == "title" ) { + entry->setName( e.text() ); + sectItem->updateItem(); + } else if (e.tagName() == "sect") { + NavigatorItem *created; + numDocs += insertSection( sectItem, 0, e, created ); + } else if (e.tagName() == "doc") { + insertDoc(sectItem,e); + ++numDocs; + } + } + n = n.nextSibling(); + } + + // Remove empty sections + if (!mShowEmptyDirs && numDocs == 0) { + delete sectItem; + sectItem = 0; + } + + return numDocs; +} + +void ScrollKeeperTreeBuilder::insertDoc( NavigatorItem *parent, + const TQDomNode &docNode ) +{ + DocEntry *entry = new DocEntry( "", "", "document2" ); + NavigatorItem *docItem = new NavigatorItem( entry, parent ); + docItem->setAutoDeleteDocEntry( true ); + mItems.append( docItem ); + + TQString url; + + TQDomNode n = docNode.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if ( e.tagName() == "doctitle" ) { + entry->setName( e.text() ); + docItem->updateItem(); + } else if ( e.tagName() == "docsource" ) { + url.append( e.text() ); + } else if ( e.tagName() == "docformat" ) { + TQString mimeType = e.text(); + if ( mimeType == "text/html") { + // Let the HTML part figure out how to get the doc + } else if ( mimeType == "text/xml" ) { + if ( url.left( 5 ) == "file:" ) url = url.mid( 5 ); + url.prepend( "ghelp:" ); +#if 0 + url.replace( TQRegExp( ".xml$" ), ".html" ); +#endif + } else if ( mimeType == "text/sgml" ) { + // GNOME docs use this type. We don't have a real viewer for this. + url.prepend( "file:" ); + } else if ( mimeType.left(5) == "text/" ) { + url.prepend( "file:" ); + } + } + } + n = n.nextSibling(); + } + + entry->setUrl( url ); +} + +#include "scrollkeepertreebuilder.moc" +// vim:sw=2:ts=2:et diff --git a/khelpcenter/scrollkeepertreebuilder.h b/khelpcenter/scrollkeepertreebuilder.h new file mode 100644 index 000000000..2761a10bf --- /dev/null +++ b/khelpcenter/scrollkeepertreebuilder.h @@ -0,0 +1,59 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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_SCROLLKEEPERTREEBUILDER_H +#define KHC_SCROLLKEEPERTREEBUILDER_H + +#include <tqobject.h> +#include <tqptrlist.h> + +#include "navigatoritem.h" + +class KProcIO; + +class TQDomNode; + +namespace KHC { + +class ScrollKeeperTreeBuilder : public TQObject +{ + Q_OBJECT + public: + ScrollKeeperTreeBuilder( TQObject *parent, const char *name = 0 ); + + NavigatorItem *build( NavigatorItem *parent, NavigatorItem *after ); + + private slots: + void getContentsList( KProcIO *proc ); + + private: + void loadConfig(); + int insertSection( NavigatorItem *parent, NavigatorItem *after, + const TQDomNode §Node, NavigatorItem *&created ); + void insertDoc( NavigatorItem *parent, const TQDomNode &docNode ); + + bool mShowEmptyDirs; + TQString mContentsList; + TQPtrList<NavigatorItem> mItems; +}; + +} + +#endif // KHC_SCROLLKEEPERTREEBUILDER_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/searchengine.cpp b/khelpcenter/searchengine.cpp new file mode 100644 index 000000000..56b6e635c --- /dev/null +++ b/khelpcenter/searchengine.cpp @@ -0,0 +1,502 @@ +#include "stdlib.h" + +#include <tqstylesheet.h> +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kprocess.h> +#include <tdelocale.h> +#include <tdemessagebox.h> + +#include "docmetainfo.h" +#include "formatter.h" +#include "view.h" +#include "searchhandler.h" +#include "prefs.h" + +#include "searchengine.h" + +namespace KHC +{ + +SearchTraverser::SearchTraverser( SearchEngine *engine, int level ) : + mMaxLevel( 999 ), mEngine( engine), mLevel( level ) +{ +#if 0 + kdDebug() << "SearchTraverser(): " << mLevel + << " 0x" << TQString::number( int( this ), 16 ) << endl; +#endif +} + +SearchTraverser::~SearchTraverser() +{ +#if 0 + kdDebug() << "~SearchTraverser(): " << mLevel + << " 0x" << TQString::number( int( this ), 16 ) << endl; +#endif + + TQString section; + if ( parentEntry() ) { + section = parentEntry()->name(); + } else { + section = ("Unknown Section"); + } + + if ( !mResult.isEmpty() ) { + mEngine->view()->writeSearchResult( + mEngine->formatter()->sectionHeader( section ) ); + mEngine->view()->writeSearchResult( mResult ); + } +} + +void SearchTraverser::process( DocEntry * ) +{ + kdDebug() << "SearchTraverser::process()" << endl; +} + +void SearchTraverser::startProcess( DocEntry *entry ) +{ +// kdDebug() << "SearchTraverser::startProcess(): " << entry->name() << " " +// << "SEARCH: '" << entry->search() << "'" << endl; + + if ( !mEngine->canSearch( entry ) || !entry->searchEnabled() ) { + mNotifyee->endProcess( entry, this ); + return; + } + +// kdDebug() << "SearchTraverser::startProcess(): " << entry->identifier() +// << endl; + + SearchHandler *handler = mEngine->handler( entry->documentType() ); + + if ( !handler ) { + TQString txt; + if ( entry->documentType().isEmpty() ) { + txt = i18n("Error: No document type specified."); + } else { + txt = i18n("Error: No search handler for document type '%1'.") + .arg( entry->documentType() ); + } + showSearchError( handler, entry, txt ); + return; + } + + connectHandler( handler ); + + handler->search( entry, mEngine->words(), mEngine->maxResults(), + mEngine->operation() ); + +// kdDebug() << "SearchTraverser::startProcess() done: " << entry->name() << endl; +} + +void SearchTraverser::connectHandler( SearchHandler *handler ) +{ + TQMap<SearchHandler *,int>::Iterator it; + it = mConnectCount.find( handler ); + int count = 0; + if ( it != mConnectCount.end() ) count = *it; + if ( count == 0 ) { + connect( handler, TQT_SIGNAL( searchError( SearchHandler *, DocEntry *, const TQString & ) ), + TQT_SLOT( showSearchError( SearchHandler *, DocEntry *, const TQString & ) ) ); + connect( handler, TQT_SIGNAL( searchFinished( SearchHandler *, DocEntry *, const TQString & ) ), + TQT_SLOT( showSearchResult( SearchHandler *, DocEntry *, const TQString & ) ) ); + } + mConnectCount[ handler ] = ++count; +} + +void SearchTraverser::disconnectHandler( SearchHandler *handler ) +{ + TQMap<SearchHandler *,int>::Iterator it; + it = mConnectCount.find( handler ); + if ( it == mConnectCount.end() ) { + kdError() << "SearchTraverser::disconnectHandler() handler not connected." + << endl; + } else { + int count = *it; + --count; + if ( count == 0 ) { + disconnect( handler, TQT_SIGNAL( searchError( SearchHandler *, DocEntry *, const TQString & ) ), + this, TQT_SLOT( showSearchError( SearchHandler *, DocEntry *, const TQString & ) ) ); + disconnect( handler, TQT_SIGNAL( searchFinished( SearchHandler *, DocEntry *, const TQString & ) ), + this, TQT_SLOT( showSearchResult( SearchHandler *, DocEntry *, const TQString & ) ) ); + } + mConnectCount[ handler ] = count; + } +} + +DocEntryTraverser *SearchTraverser::createChild( DocEntry *parentEntry ) +{ +// kdDebug() << "SearchTraverser::createChild() level " << mLevel << endl; + + if ( mLevel >= mMaxLevel ) { + ++mLevel; + return this; + } else { + DocEntryTraverser *t = new SearchTraverser( mEngine, mLevel + 1 ); + t->setParentEntry( parentEntry ); + return t; + } +} + +DocEntryTraverser *SearchTraverser::parentTraverser() +{ +// kdDebug() << "SearchTraverser::parentTraverser(): level: " << mLevel << endl; + + if ( mLevel > mMaxLevel ) { + return this; + } else { + return mParent; + } +} + +void SearchTraverser::deleteTraverser() +{ +// kdDebug() << "SearchTraverser::deleteTraverser()" << endl; + + if ( mLevel > mMaxLevel ) { + --mLevel; + } else { + delete this; + } +} + +void SearchTraverser::showSearchError( SearchHandler *handler, DocEntry *entry, const TQString &error ) +{ +// kdDebug() << "SearchTraverser::showSearchError(): " << entry->name() +// << endl; + + mResult += mEngine->formatter()->docTitle( entry->name() ); + mResult += mEngine->formatter()->paragraph( error ); + + mEngine->logError( entry, error ); + + disconnectHandler( handler ); + + mNotifyee->endProcess( entry, this ); +} + +void SearchTraverser::showSearchResult( SearchHandler *handler, DocEntry *entry, const TQString &result ) +{ +// kdDebug() << "SearchTraverser::showSearchResult(): " << entry->name() +// << endl; + + mResult += mEngine->formatter()->docTitle( entry->name() ); + mResult += mEngine->formatter()->processResult( result ); + + disconnectHandler( handler ); + + mNotifyee->endProcess( entry, this ); +} + +void SearchTraverser::finishTraversal() +{ +// kdDebug() << "SearchTraverser::finishTraversal()" << endl; + + mEngine->view()->writeSearchResult( mEngine->formatter()->footer() ); + mEngine->view()->endSearchResult(); + + mEngine->finishSearch(); +} + + +SearchEngine::SearchEngine( View *destination ) + : TQObject(), + mProc( 0 ), mSearchRunning( false ), mView( destination ), + mRootTraverser( 0 ) +{ + mLang = TDEGlobal::locale()->language().left( 2 ); +} + +SearchEngine::~SearchEngine() +{ + delete mRootTraverser; +} + +bool SearchEngine::initSearchHandlers() +{ + TQStringList resources = TDEGlobal::dirs()->findAllResources( + "appdata", "searchhandlers/*.desktop" ); + TQStringList::ConstIterator it; + for( it = resources.begin(); it != resources.end(); ++it ) { + TQString filename = *it; + kdDebug() << "SearchEngine::initSearchHandlers(): " << filename << endl; + SearchHandler *handler = SearchHandler::initFromFile( filename ); + if ( !handler || !handler->checkPaths() ) { + TQString txt = i18n("Unable to initialize SearchHandler from file '%1'.") + .arg( filename ); + kdWarning() << txt << endl; +// KMessageBox::sorry( mView->widget(), txt ); + } else { + TQStringList documentTypes = handler->documentTypes(); + TQStringList::ConstIterator it; + for( it = documentTypes.begin(); it != documentTypes.end(); ++it ) { + mHandlers.insert( *it, handler ); + } + } + } + + if ( mHandlers.isEmpty() ) { + TQString txt = i18n("No valid search handler found."); + kdWarning() << txt << endl; +// KMessageBox::sorry( mView->widget(), txt ); + return false; + } + + return true; +} + +void SearchEngine::searchStdout(TDEProcess *, char *buffer, int len) +{ + if ( !buffer || len == 0 ) + return; + + TQString bufferStr; + char *p; + p = (char*) malloc( sizeof(char) * (len+1) ); + p = strncpy( p, buffer, len ); + p[len] = '\0'; + + mSearchResult += bufferStr.fromUtf8(p); + + free(p); +} + +void SearchEngine::searchStderr(TDEProcess *, char *buffer, int len) +{ + if ( !buffer || len == 0 ) + return; + + mStderr.append( TQString::fromUtf8( buffer, len ) ); +} + +void SearchEngine::searchExited(TDEProcess *) +{ + kdDebug() << "Search terminated" << endl; + mSearchRunning = false; +} + +bool SearchEngine::search( TQString words, TQString method, int matches, + TQString scope ) +{ + if ( mSearchRunning ) return false; + + // These should be removed + mWords = words; + mMethod = method; + mMatches = matches; + mScope = scope; + + // Saner variables to store search parameters: + mWordList = TQStringList::split( " ", words ); + mMaxResults = matches; + if ( method == "or" ) mOperation = Or; + else mOperation = And; + + TDEConfig *cfg = TDEGlobal::config(); + cfg->setGroup( "Search" ); + TQString commonSearchProgram = cfg->readPathEntry( "CommonProgram" ); + bool useCommon = cfg->readBoolEntry( "UseCommonProgram", false ); + + if ( commonSearchProgram.isEmpty() || !useCommon ) { + if ( !mView ) { + return false; + } + + TQString txt = i18n("Search Results for '%1':").arg( TQStyleSheet::escape(words) ); + + mStderr = "<b>" + txt + "</b>\n"; + + mView->beginSearchResult(); + mView->writeSearchResult( formatter()->header( i18n("Search Results") ) ); + mView->writeSearchResult( formatter()->title( txt ) ); + + if ( mRootTraverser ) { + kdDebug() << "SearchEngine::search(): mRootTraverser not null." << endl; + return false; + } + mRootTraverser = new SearchTraverser( this, 0 ); + DocMetaInfo::self()->startTraverseEntries( mRootTraverser ); + + return true; + } else { + TQString lang = TDEGlobal::locale()->language().left(2); + + if ( lang.lower() == "c" || lang.lower() == "posix" ) + lang = "en"; + + // if the string contains '&' replace with a '+' and set search method to and + if (mWords.find("&") != -1) { + mWords.replace("&", " "); + method = "and"; + } + + // replace whitespace with a '+' + mWords = mWords.stripWhiteSpace(); + mWords = mWords.simplifyWhiteSpace(); + mWords.replace(TQRegExp("\\s"), "+"); + + commonSearchProgram = substituteSearchQuery( commonSearchProgram ); + + kdDebug() << "Common Search: " << commonSearchProgram << endl; + + mProc = new TDEProcess(); + + TQStringList cmd = TQStringList::split( " ", commonSearchProgram ); + TQStringList::ConstIterator it; + for( it = cmd.begin(); it != cmd.end(); ++it ) { + TQString arg = *it; + if ( arg.left( 1 ) == "\"" && arg.right( 1 ) =="\"" ) { + arg = arg.mid( 1, arg.length() - 2 ); + } + *mProc << arg.utf8(); + } + + connect( mProc, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ), + TQT_SLOT( searchStdout( TDEProcess *, char *, int ) ) ); + connect( mProc, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ), + TQT_SLOT( searchStderr( TDEProcess *, char *, int ) ) ); + connect( mProc, TQT_SIGNAL( processExited( TDEProcess * ) ), + TQT_SLOT( searchExited( TDEProcess * ) ) ); + + mSearchRunning = true; + mSearchResult = ""; + mStderr = "<b>" + commonSearchProgram + "</b>\n\n"; + + mProc->start(TDEProcess::NotifyOnExit, TDEProcess::All); + + while (mSearchRunning && mProc->isRunning()) + kapp->processEvents(); + + if ( !mProc->normalExit() || mProc->exitStatus() != 0 ) { + kdError() << "Unable to run search program '" << commonSearchProgram + << "'" << endl; + delete mProc; + + return false; + } + + delete mProc; + + // modify the search result + mSearchResult = mSearchResult.replace("http://localhost/", "file:/"); + mSearchResult = mSearchResult.mid( mSearchResult.find( '<' ) ); + + mView->beginSearchResult(); + mView->writeSearchResult( mSearchResult ); + mView->endSearchResult(); + + emit searchFinished(); + } + + return true; +} + +TQString SearchEngine::substituteSearchQuery( const TQString &query ) +{ + TQString result = query; + result.replace( "%k", mWords ); + result.replace( "%n", TQString::number( mMatches ) ); + result.replace( "%m", mMethod ); + result.replace( "%l", mLang ); + result.replace( "%s", mScope ); + + return result; +} + +TQString SearchEngine::substituteSearchQuery( const TQString &query, + const TQString &identifier, const TQStringList &words, int maxResults, + Operation operation, const TQString &lang ) +{ + TQString result = query; + result.replace( "%i", identifier ); + result.replace( "%w", words.join( "+" ) ); + result.replace( "%m", TQString::number( maxResults ) ); + TQString o; + if ( operation == Or ) o = "or"; + else o = "and"; + result.replace( "%o", o ); + result.replace( "%d", Prefs::indexDirectory() ); + result.replace( "%l", lang ); + + return result; +} + +Formatter *SearchEngine::formatter() const +{ + return mView->formatter(); +} + +View *SearchEngine::view() const +{ + return mView; +} + +void SearchEngine::finishSearch() +{ + delete mRootTraverser; + mRootTraverser = 0; + + emit searchFinished(); +} + +TQString SearchEngine::errorLog() const +{ + return mStderr; +} + +void SearchEngine::logError( DocEntry *entry, const TQString &msg ) +{ + mStderr += entry->identifier() + ": " + msg; +} + +bool SearchEngine::isRunning() const +{ + return mSearchRunning; +} + +SearchHandler *SearchEngine::handler( const TQString &documentType ) const +{ + TQMap<TQString,SearchHandler *>::ConstIterator it; + it = mHandlers.find( documentType ); + + if ( it == mHandlers.end() ) return 0; + else return *it; +} + +TQStringList SearchEngine::words() const +{ + return mWordList; +} + +int SearchEngine::maxResults() const +{ + return mMaxResults; +} + +SearchEngine::Operation SearchEngine::operation() const +{ + return mOperation; +} + +bool SearchEngine::canSearch( DocEntry *entry ) +{ + return entry->docExists() && !entry->documentType().isEmpty() && + handler( entry->documentType() ); +} + +bool SearchEngine::needsIndex( DocEntry *entry ) +{ + if ( !canSearch( entry ) ) return false; + + SearchHandler *h = handler( entry->documentType() ); + if ( h->indexCommand( entry->identifier() ).isEmpty() ) return false; + + return true; +} + +} + +#include "searchengine.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/searchengine.h b/khelpcenter/searchengine.h new file mode 100644 index 000000000..ac31a9e0a --- /dev/null +++ b/khelpcenter/searchengine.h @@ -0,0 +1,151 @@ +#ifndef SEARCHENGINE_H +#define SEARCHENGINE_H + +#include <tqobject.h> +#include <tqptrlist.h> +#include <tqstring.h> + +#include <kpixmap.h> +#include <tdeio/job.h> + +#include "docentrytraverser.h" + +class TQWidget; +class TDEProcess; +class TDEConfig; +class TDEHTMLPart; + +namespace KHC { + +class Formatter; +class SearchEngine; +class View; +class SearchHandler; + +class SearchTraverser : public TQObject, public DocEntryTraverser +{ + Q_OBJECT + public: + SearchTraverser( SearchEngine *engine, int level ); + ~SearchTraverser(); + + void process( DocEntry * ); + + void startProcess( DocEntry * ); + + DocEntryTraverser *createChild( DocEntry * ); + + DocEntryTraverser *parentTraverser(); + + void deleteTraverser(); + + void finishTraversal(); + + protected: + void connectHandler( SearchHandler *handler ); + void disconnectHandler( SearchHandler *handler ); + + protected slots: + void showSearchResult( SearchHandler *, DocEntry *, const TQString &result ); + void showSearchError( SearchHandler *, DocEntry *, const TQString &error ); + + private: + const int mMaxLevel; + + SearchEngine *mEngine; + int mLevel; + + DocEntry *mEntry; + TQString mJobData; + + TQString mResult; + + TQMap<SearchHandler *, int> mConnectCount; +}; + + +class SearchEngine : public TQObject +{ + Q_OBJECT + public: + enum Operation { And, Or }; + + SearchEngine( View * ); + ~SearchEngine(); + + bool initSearchHandlers(); + + bool search( TQString words, TQString method = "and", int matches = 5, + TQString scope = "" ); + + Formatter *formatter() const; + View *view() const; + + TQString substituteSearchQuery( const TQString &query ); + + static TQString substituteSearchQuery( const TQString &query, + const TQString &identifier, const TQStringList &words, int maxResults, + Operation operation, const TQString &lang ); + + void finishSearch(); + + /** + Append error message to error log. + */ + void logError( DocEntry *entry, const TQString &msg ); + + /** + Return error log. + */ + TQString errorLog() const; + + bool isRunning() const; + + SearchHandler *handler( const TQString &documentType ) const; + + TQStringList words() const; + int maxResults() const; + Operation operation() const; + + bool canSearch( DocEntry * ); + bool needsIndex( DocEntry * ); + + signals: + void searchFinished(); + + protected slots: + void searchStdout(TDEProcess *proc, char *buffer, int buflen); + void searchStderr(TDEProcess *proc, char *buffer, int buflen); + void searchExited(TDEProcess *proc); + + protected: + void processSearchQueue(); + + private: + TDEProcess *mProc; + bool mSearchRunning; + TQString mSearchResult; + + TQString mStderr; + + View *mView; + + TQString mWords; + int mMatches; + TQString mMethod; + TQString mLang; + TQString mScope; + + TQStringList mWordList; + int mMaxResults; + Operation mOperation; + + DocEntryTraverser *mRootTraverser; + + TQMap<TQString, SearchHandler *> mHandlers; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/searchhandler.cpp b/khelpcenter/searchhandler.cpp new file mode 100644 index 000000000..54a0a9a38 --- /dev/null +++ b/khelpcenter/searchhandler.cpp @@ -0,0 +1,249 @@ +/* + This file is part of KHelpCenter. + + Copyright (c) 2005 Cornelius Schumacher <[email protected]> + + 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 "searchhandler.h" + +#include "searchengine.h" +#include "prefs.h" +#include "docentry.h" + +#include <kdesktopfile.h> +#include <kprocess.h> +#include <kdebug.h> +#include <tdemessagebox.h> +#include <tdelocale.h> +#include <kstandarddirs.h> + +#include <stdlib.h> + +using namespace KHC; + +SearchHandler::SearchHandler() +{ + mLang = TDEGlobal::locale()->language().left( 2 ); +} + +SearchHandler *SearchHandler::initFromFile( const TQString &filename ) +{ + SearchHandler *handler = new SearchHandler; + + KDesktopFile file( filename ); + + handler->mSearchCommand = file.readEntry( "SearchCommand" ); + handler->mSearchUrl = file.readEntry( "SearchUrl" ); + handler->mIndexCommand = file.readEntry( "IndexCommand" ); + handler->mDocumentTypes = file.readListEntry( "DocumentTypes" ); + + return handler; +} + +TQStringList SearchHandler::documentTypes() const +{ + return mDocumentTypes; +} + +TQString SearchHandler::indexCommand( const TQString &identifier ) +{ + TQString cmd = mIndexCommand; + cmd.replace( "%i", identifier ); + cmd.replace( "%d", Prefs::indexDirectory() ); + cmd.replace( "%l", mLang ); + return cmd; +} + +bool SearchHandler::checkPaths() const +{ + if ( !mSearchCommand.isEmpty() && !checkBinary( mSearchCommand ) ) + return false; + + if ( !mIndexCommand.isEmpty() && !checkBinary( mIndexCommand ) ) + return false; + + return true; +} + +bool SearchHandler::checkBinary( const TQString &cmd ) const +{ + TQString binary; + + int pos = cmd.find( ' ' ); + if ( pos < 0 ) binary = cmd; + else binary = cmd.left( pos ); + + return !TDEStandardDirs::findExe( binary ).isEmpty(); +} + +void SearchHandler::search( DocEntry *entry, const TQStringList &words, + int maxResults, + SearchEngine::Operation operation ) +{ + kdDebug() << "SearchHandler::search(): " << entry->identifier() << endl; + + if ( !mSearchCommand.isEmpty() ) { + TQString cmdString = SearchEngine::substituteSearchQuery( mSearchCommand, + entry->identifier(), words, maxResults, operation, mLang ); + + kdDebug() << "SearchHandler::search() CMD: " << cmdString << endl; + + TDEProcess *proc = new TDEProcess(); + + TQStringList cmd = TQStringList::split( " ", cmdString ); + TQStringList::ConstIterator it; + for( it = cmd.begin(); it != cmd.end(); ++it ) { + TQString arg = *it; + if ( arg.left( 1 ) == "\"" && arg.right( 1 ) =="\"" ) { + arg = arg.mid( 1, arg.length() - 2 ); + } + *proc << arg.utf8(); + } + + connect( proc, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ), + TQT_SLOT( searchStdout( TDEProcess *, char *, int ) ) ); + connect( proc, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ), + TQT_SLOT( searchStderr( TDEProcess *, char *, int ) ) ); + connect( proc, TQT_SIGNAL( processExited( TDEProcess * ) ), + TQT_SLOT( searchExited( TDEProcess * ) ) ); + + SearchJob *searchJob = new SearchJob; + searchJob->mEntry = entry; + searchJob->mProcess = proc; + searchJob->mCmd = cmdString; + + mProcessJobs.insert( proc, searchJob ); + + if ( !proc->start( TDEProcess::NotifyOnExit, TDEProcess::All ) ) { + TQString txt = i18n("Error executing search command '%1'.").arg( cmdString ); + emit searchFinished( this, entry, txt ); + } + } else if ( !mSearchUrl.isEmpty() ) { + TQString urlString = SearchEngine::substituteSearchQuery( mSearchUrl, + entry->identifier(), words, maxResults, operation, mLang ); + + kdDebug() << "SearchHandler::search() URL: " << urlString << endl; + + TDEIO::TransferJob *job = TDEIO::get( KURL( urlString ) ); + connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), + TQT_SLOT( slotJobResult( TDEIO::Job * ) ) ); + connect( job, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ), + TQT_SLOT( slotJobData( TDEIO::Job *, const TQByteArray & ) ) ); + + SearchJob *searchJob = new SearchJob; + searchJob->mEntry = entry; + searchJob->mKioJob = job; + mKioJobs.insert( job, searchJob ); + } else { + TQString txt = i18n("No search command or URL specified."); + emit searchFinished( this, entry, txt ); + return; + } +} + +void SearchHandler::searchStdout( TDEProcess *proc, char *buffer, int len ) +{ + if ( !buffer || len == 0 ) + return; + + TQString bufferStr; + char *p; + p = (char*) malloc( sizeof(char) * ( len + 1 ) ); + p = strncpy( p, buffer, len ); + p[len] = '\0'; + + TQMap<TDEProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc ); + if ( it != mProcessJobs.end() ) { + (*it)->mResult += bufferStr.fromUtf8( p ); + } + + free( p ); +} + +void SearchHandler::searchStderr( TDEProcess *proc, char *buffer, int len ) +{ + if ( !buffer || len == 0 ) + return; + + TQMap<TDEProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc ); + if ( it != mProcessJobs.end() ) { + (*it)->mError += TQString::fromUtf8( buffer, len ); + } +} + +void SearchHandler::searchExited( TDEProcess *proc ) +{ +// kdDebug() << "SearchHandler::searchExited()" << endl; + + TQString result; + TQString error; + DocEntry *entry = 0; + + TQMap<TDEProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc ); + if ( it != mProcessJobs.end() ) { + SearchJob *j = *it; + entry = j->mEntry; + result = j->mResult; + error = "<em>" + j->mCmd + "</em>\n" + j->mError; + + mProcessJobs.remove( proc ); + delete j; + } else { + kdError() << "No search job for exited process found." << endl; + } + + if ( proc->normalExit() && proc->exitStatus() == 0 ) { + emit searchFinished( this, entry, result ); + } else { + emit searchError( this, entry, error ); + } +} + +void SearchHandler::slotJobResult( TDEIO::Job *job ) +{ + TQString result; + DocEntry *entry = 0; + + TQMap<TDEIO::Job *, SearchJob *>::ConstIterator it = mKioJobs.find( job ); + if ( it != mKioJobs.end() ) { + SearchJob *j = *it; + + entry = j->mEntry; + result = j->mResult; + + mKioJobs.remove( job ); + delete j; + } + + if ( job->error() ) { + emit searchError( this, entry, i18n("Error: %1").arg( job->errorString() ) ); + } else { + emit searchFinished( this, entry, result ); + } +} + +void SearchHandler::slotJobData( TDEIO::Job *job, const TQByteArray &data ) +{ +// kdDebug() << "SearchHandler::slotJobData()" << endl; + + TQMap<TDEIO::Job *, SearchJob *>::ConstIterator it = mKioJobs.find( job ); + if ( it != mKioJobs.end() ) { + (*it)->mResult += data.data(); + } +} + +#include "searchhandler.moc" diff --git a/khelpcenter/searchhandler.h b/khelpcenter/searchhandler.h new file mode 100644 index 000000000..31c3adb1f --- /dev/null +++ b/khelpcenter/searchhandler.h @@ -0,0 +1,97 @@ +/* + This file is part of KHelpCenter. + + Copyright (c) 2005 Cornelius Schumacher <[email protected]> + + 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_SEARCHHANDLER_H +#define KHC_SEARCHHANDLER_H + +#include "searchengine.h" + +#include <tqobject.h> +#include <tqstringlist.h> + +namespace TDEIO { +class Job; +} + +namespace KHC { + +class SearchJob +{ + public: + SearchJob() : mProcess( 0 ), mKioJob( 0 ) {} + + DocEntry *mEntry; + + TDEProcess *mProcess; + TDEIO::Job *mKioJob; + + TQString mCmd; + + TQString mResult; + TQString mError; +}; + +class SearchHandler : public QObject +{ + Q_OBJECT + public: + static SearchHandler *initFromFile( const TQString &filename ); + + void search( DocEntry *, const TQStringList &words, + int maxResults = 10, + SearchEngine::Operation operation = SearchEngine::And ); + + TQString indexCommand( const TQString &identifier ); + + TQStringList documentTypes() const; + + bool checkPaths() const; + + signals: + void searchFinished( SearchHandler *, DocEntry *, const TQString & ); + void searchError( SearchHandler *, DocEntry *, const TQString & ); + + protected: + bool checkBinary( const TQString &cmd ) const; + + protected slots: + void searchStdout( TDEProcess *proc, char *buffer, int buflen ); + void searchStderr( TDEProcess *proc, char *buffer, int buflen ); + void searchExited( TDEProcess *proc ); + + void slotJobResult( TDEIO::Job *job ); + void slotJobData( TDEIO::Job *, const TQByteArray &data ); + + private: + SearchHandler(); + + TQString mLang; + + TQString mSearchCommand; + TQString mSearchUrl; + TQString mIndexCommand; + TQStringList mDocumentTypes; + + TQMap<TDEProcess *,SearchJob *> mProcessJobs; + TQMap<TDEIO::Job *,SearchJob *> mKioJobs; +}; + +} + +#endif diff --git a/khelpcenter/searchhandlers/CMakeLists.txt b/khelpcenter/searchhandlers/CMakeLists.txt new file mode 100644 index 000000000..9c2f7b527 --- /dev/null +++ b/khelpcenter/searchhandlers/CMakeLists.txt @@ -0,0 +1,44 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +set( prefix ${CMAKE_INSTALL_PREFIX} ) +if( NOT DEFINED HTDIG_SEARCH_BINARY ) + message( STATUS "Looking for htsearch" ) + find_program( HTDIG_SEARCH_BINARY htsearch + HINTS + /srv/www/cgi-bin + /usr/lib/cgi-bin + ) + if( HTDIG_SEARCH_BINARY ) + message( STATUS "Looking for htsearch - ${HTDIG_SEARCH_BINARY}" ) + else( HTDIG_SEARCH_BINARY ) + tde_message_fatal( "htsearch not found!\n Please, install htdig or set HTDIG_SEARCH_BINARY." ) + endif( HTDIG_SEARCH_BINARY ) +endif( NOT DEFINED HTDIG_SEARCH_BINARY ) + +configure_file( khc_docbookdig.pl.in khc_docbookdig.pl @ONLY ) +configure_file( khc_htdig.pl.in khc_htdig.pl @ONLY ) +configure_file( khc_htsearch.pl.in khc_htsearch.pl @ONLY ) + +install( FILES + htdig.desktop man.desktop docbook.desktop + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/searchhandlers ) + +install( PROGRAMS + ${CMAKE_CURRENT_BINARY_DIR}/khc_htdig.pl + ${CMAKE_CURRENT_BINARY_DIR}/khc_htsearch.pl + ${CMAKE_CURRENT_BINARY_DIR}/khc_docbookdig.pl + khc_beagle_search.pl khc_mansearch.pl khc_beagle_index.pl + DESTINATION ${BIN_INSTALL_DIR} ) + +install( FILES + htdig_long.html + DESTINATION ${DATA_INSTALL_DIR}/khelpcenter/searchhandlers/htdig ) diff --git a/khelpcenter/searchhandlers/Makefile.am b/khelpcenter/searchhandlers/Makefile.am new file mode 100644 index 000000000..f2ebd57ff --- /dev/null +++ b/khelpcenter/searchhandlers/Makefile.am @@ -0,0 +1,10 @@ +searchhandlers_DATA = htdig.desktop man.desktop docbook.desktop + +searchhandlersdir = $(kde_datadir)/khelpcenter/searchhandlers + +kde_bin_SCRIPTS = khc_htdig.pl khc_htsearch.pl khc_mansearch.pl \ + khc_docbookdig.pl khc_beagle_search.pl khc_beagle_index.pl + +htdigdata_DATA = htdig_long.html + +htdigdatadir = $(kde_datadir)/khelpcenter/searchhandlers/htdig diff --git a/khelpcenter/searchhandlers/README.searchhandlers b/khelpcenter/searchhandlers/README.searchhandlers new file mode 100644 index 000000000..cbbfbbbd7 --- /dev/null +++ b/khelpcenter/searchhandlers/README.searchhandlers @@ -0,0 +1,61 @@ +KHelpcenter Search Handlers +=========================== + +Searching documents in KHelpcenter is handled by document-type-specific search +handlers. Each searchable document provides provides a document type in its meta +data and if a corresponding handler is found, it can be searched. + +Search handlers are described by a desktop file which is put in the khelpcenter +app directory in a "searchhandlers" directory. The desktop file contains the +information about which document types the handler covers, how to do a search +query and how to create a search index. + +A search handler has to provide a command line tool based interface. There has +to be a command to do a query and, if previous creation of an index is required, +a command to create a search index. The search commands returns its results as +HTML on stdout. + + +Search Query +------------ + +KHelpcenter reads the command to execute for submitting a search query from the +search handler's desktop file ("SearchCommand"). The search command can contain +some symbols which are replaced by KHelpcenter with the data for the concrete +search request: + +%i Identifier of document (usually the name of the document's desktop file) +%w Words to be searched for +%o Operation for combining multiple search words. Allowed values: "and" and + "or". +%m Maximum number of results +%d Directory containing search indices + +Search Query Result +------------------- + +The result has to be returned as HTML page. The content of the <body> tag will +be extracted and inserted in the search results page. If there is no body tag, +the complete result text will be inserted. + + +Building a Search Index +----------------------- + +KHelpcenter reads the command to build a search index from the search handler's +desktop file ("IndexCommand"). The indexing command can contain some symbols +which are replaced by KHelpcenter with the data for the concrete index creation +call: + +%i Identifier of document (usually the name of the document's desktop file) +%d Directory containing search indices +%p Path to document to be indexed + +Index Creation Result +--------------------- + +As result of the indexing command an index is created in the directory specified +by KHelpcenter. The format and structure of the index is handler-specific. When +index creation is finished the indexing command has to create a special file +with the name "<identifier>.exists", where <identifier> has to have the value +passed by the %i symbol. This file indicates the existance of the index. diff --git a/khelpcenter/searchhandlers/docbook.desktop b/khelpcenter/searchhandlers/docbook.desktop new file mode 100644 index 000000000..08208c187 --- /dev/null +++ b/khelpcenter/searchhandlers/docbook.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] + +DocumentTypes=text/docbook + +SearchCommand=khc_htsearch.pl --docbook --indexdir=%d --config=%i --words=%w --method=%o --maxnum=%m --lang=en +IndexCommand=khc_docbookdig.pl --indexdir=%d --docpath=%p --identifier=%i diff --git a/khelpcenter/searchhandlers/htdig.desktop b/khelpcenter/searchhandlers/htdig.desktop new file mode 100644 index 000000000..08cff6ec2 --- /dev/null +++ b/khelpcenter/searchhandlers/htdig.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] + +DocumentTypes=text/html + +SearchCommand=khc_htsearch.pl --indexdir=%d --config=%i --words=%w --method=%o --maxnum=%m --lang=%l +IndexCommand=khc_htdig.pl --indexdir=%d --docpath=%p --identifier=%i --lang=%l diff --git a/khelpcenter/searchhandlers/htdig_long.html b/khelpcenter/searchhandlers/htdig_long.html new file mode 100644 index 000000000..a2e6e2188 --- /dev/null +++ b/khelpcenter/searchhandlers/htdig_long.html @@ -0,0 +1,2 @@ +$(STARSRIGHT) <a href="$&(URL)">$&(TITLE) ($(MODIFIED))</a><br> +$(EXCERPT)<br> diff --git a/khelpcenter/searchhandlers/khc_beagle_index.pl b/khelpcenter/searchhandlers/khc_beagle_index.pl new file mode 100644 index 000000000..aaec63607 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_beagle_index.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl +# vim:sw=4:et + +use warnings; + +sub getKDEDocDir() +{ + my $prefix = `tde-config --prefix`; + chomp $prefix; + + $prefix = "/opt/kde" if (not defined($prefix)); + return "$prefix/share/doc"; +} + +sub addRoot() +{ + my $kdedocdir = &getKDEDocDir; + + open (IN, "-|") || exec "beagle-config", "indexing", "ListRoots"; + + my $kdedoc_found = 0; + while(<IN>) { + if (/^$kdedocdir/o) { + $kdedoc_found = 1; + last; + } + } + close(IN); + + if (not $kdedoc_found) { + `beagle-config indexing AddRoot $kdedocdir`; + `beagle-config indexing AddRoot $kdedocdir-bundle`; + } +} + +sub createExistsFile($$) +{ + my ($idir, $ident) = @_; + + open(OUT, ">", "$idir/$idir"); + close(OUT); +} + +my $idir = $ARGV[0]; +my $ident = $ARGV[1]; + +if (addRoot) { + createExistsFile($idir, $ident); +} diff --git a/khelpcenter/searchhandlers/khc_beagle_search.pl b/khelpcenter/searchhandlers/khc_beagle_search.pl new file mode 100644 index 000000000..d7a1f44b8 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_beagle_search.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl -w +# vim:sw=4:et + +use warnings; +use strict; +use Getopt::Long; + +sub isBeagleRunning() +{ + open(IN, "-|") || exec "beagle-ping"; + while(<IN>) { + if (/^Daemon version:/) { + close(IN); + return 1; + } + } + close(IN); + return 0; +} + +sub formatHTML($$) +{ + my ($query, $hits) = @_; + + print "<html>\n<body\n<ul>\n"; + + foreach my $hit(@$hits) { + print "<li>$hit</li>\n"; + } + print "</ul>\n</body>\n</html>\n"; +} + +sub beagleQuery($$$) +{ + my ($words, $method, $maxnum) = @_; + + my @hits = (); + + open(IN, "-|") || exec "beagle-query", "--type", "DocbookEntry", "--type", "File", "--max-hits", $maxnum, @$words, "ext:docbook"; + while(<IN>) { + chop; + next if (/^Debug:/); + + my $uri = $_; + $uri = $1 if ($uri =~ /^file:\/\/(.*)$/); + + print "uri: $uri\n"; + my $helpLink = &makeHelpLink($uri); + + push(@hits, $helpLink) if (!grep { /^$helpLink$/ } @hits); + } + close(IN); + return @hits; +} + +sub makeHelpLink($) +{ + # Try to figure out the name of the application from the path to its index.docbook file + + my ($path) = @_; + my @pathcomponents = split '/', $path; + + my $appName = $pathcomponents[-2]; + my $appName2 = $pathcomponents[-3]; + + if ($appName eq $appName2 or $appName2 eq "doc" + or (-d "/usr/share/locale/$appName2")) { + return "<a href=\"help:/$appName\">$appName</a>"; + } + return "<a href=\"help:/$appName2/$appName\">$appName ($appName2)</a>"; +} + +my $method = "and"; +my $maxnum = 100; + +GetOptions("method=s", \$method, "maxnum=i", \$maxnum); + +my @hits = ("The Beagle daemon is not running, search is not available"); + +my @words = @ARGV; + +if (isBeagleRunning()) { + @hits = beagleQuery(\@words, $method, $maxnum); +} + +@hits = ("There are no search results") if ($#hits < 0); + +formatHTML(\@words, \@hits); diff --git a/khelpcenter/searchhandlers/khc_docbookdig.pl.in b/khelpcenter/searchhandlers/khc_docbookdig.pl.in new file mode 100755 index 000000000..dfc826ab8 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_docbookdig.pl.in @@ -0,0 +1,223 @@ +#!/usr/bin/perl +# +# Wrapper script for creating search indices for htdig. +# +# This file is part of KHelpcenter. +# +# Copyright (C) 2002 SuSE Linux AG, Nuernberg +# +# Author: Cornelius Schumacher <[email protected]> +# +# 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 + +use strict; + +use Getopt::Long; + +my $htdigdata = "/etc/htdig"; +my $htdigbin = "/usr/bin"; +my $kdeprefix = "@prefix@"; +my $kdehtmldir = `tde-config --expandvars --install html`; +chomp $kdeprefix; +chomp $kdehtmldir; + +my $dbg = 1; + +my ($indexdir, $docpath, $identifier, $lang, $help ); + +GetOptions ( + 'indexdir=s' => \$indexdir, + 'docpath=s' => \$docpath, + 'identifier=s' => \$identifier, + 'lang=s' => \$lang, + 'help' => \$help, +); + +if ( $help ) { + usage(); +} + +if ( !$indexdir || !$docpath || !$identifier ) { + print STDERR "Missing arguments.\n"; + usage(); +} + +&dbg( "INDEXDIR: $indexdir" ); + +if ( !$lang ) { $lang = "en"; } + +my $tmpdir = "$indexdir/$identifier.tmp"; +if ( ! -e $tmpdir ) { + mkdir $tmpdir; +} + +print "Creating index for <b>'$identifier'</b>\n"; + +my $htdigconf = $indexdir; +my $htdigdb = $indexdir; + +my $conffile = "$htdigconf/$identifier.conf"; + +my $commondir = "$htdigdata/$lang"; +if ( !$lang || !-e $commondir ) { + $commondir = "$htdigdata/en"; +} +if ( !-e $commondir ) { $commondir = $htdigdata; } + +my $locale; +if ( $lang eq "de" ) { $locale = "de_DE"; } +else { $locale = $lang; } + +my $startfile = "$tmpdir/index.html"; + +if ( !open( START, ">$startfile" ) ) { + print STDERR "Unable to open '$startfile' for writing.\n"; + exit 1; +} + +$ENV{ PATH } = '/bin:/usr/bin'; +$ENV{ CDPATH } = ''; +$ENV{ ENV } = ''; + +my $findpath = "$kdehtmldir/$lang/"; +my $findcmd = "find $findpath -name index.docbook"; + +print STDERR "FINDCMD: $findcmd\n"; + +if ( !open FIND, "$findcmd|" ) { + print STDERR "Unable to find docs.\n"; + exit 1; +} +while ( <FIND> ) { + chomp; + my $path = $_; + $path =~ /$findpath(.*)\/index.docbook$/; + my $app = $1; + print START "<a href=\"help://$app/index.docbook\">$path</a>\n"; +} +close START; + +my $mimetypefile = "$tmpdir/htdig_mime"; +if ( !open( MIME, ">$mimetypefile" ) ) { + print STDERR "Unable to open '$mimetypefile' for writing.\n"; + exit 1; +} +print MIME << "EOT"; +text/html html +text/docbook docbook +EOT +close MIME; + +my $parserfile = "$tmpdir/docbookparser"; +if ( !open( PARSER, ">$parserfile" ) ) { + print STDERR "Unable to open '$parserfile' for writing.\n"; + exit 1; +} +print PARSER << "EOT"; +#! /bin/sh + +file=\$1 +shift +mime=\$1 +shift + +if test "\$#" -gt 0; then + orig=\${1#file:/} + shift +fi + +case "\$orig" in + help:/*) + orig=\${orig#help:/} + orig=\${orig%\/index.docbook} + cd $kdehtmldir/en/\$orig + file=index.docbook + ;; + *) + file=\$orig + cd `dirname \$orig` + ;; +esac + +echo "t apptitle" +$kdeprefix/bin/meinproc --htdig "\$file" +EOT +close PARSER; +chmod 0755, $parserfile; + +if ( !open( CONF, ">$conffile" ) ) { + print STDERR "Unable to open '$conffile' for writing.\n"; + exit 1; +} +print CONF << "EOT"; +# htdig configuration for doc '$identifier' +# +# This file has been automatically created by KHelpcenter +common_dir: $commondir +locale: $locale +database_dir: $htdigdb +database_base: \${database_dir}/$identifier +local_urls: help://=$kdehtmldir/en/ file://=/ +local_urls_only: true +limit_urls_to: file:// help:/ +ignore_noindex: true +max_hop_count: 4 +robotstxt_name: kdedig +compression_level: 6 +template_map: Long long $kdeprefix/share/apps/khelpcenter/searchhandlers/htdig/htdig_long.html +search_algorithm: exact:1 prefix:0.8 +maximum_pages: 1 +matches_per_page: 10 +start_url: file://$tmpdir/index.html +external_parsers: text/docbook $parserfile +valid_extensions: .docbook .html +mime_types: $mimetypefile +EOT +close CONF; + +my $ret = system( "$htdigbin/htdig", "-v", "-s", "-i", "-c", $conffile ); +if ( $ret != 0 ) { + print STDERR "htdig failed\n"; +} else { + $ret = system( "$htdigbin/htmerge", "-c", $conffile ); + if ( $ret != 0 ) { print STDERR "htmerge failed\n"; } +} + +if ( $ret == 0 ) { + my $existsfile = "$indexdir/$identifier.exists"; + + if ( !open( EXISTS, ">$existsfile" ) ) { + print STDERR "Unable to open '$existsfile' for writing.\n"; + exit 1; + } + print EXISTS "$identifier\n"; + close EXISTS; + + print "Finished successfully.\n"; +} + +exit $ret; + +sub dbg($) +{ + $dbg && print STDERR shift, "\n"; +} + +sub usage() +{ + print "Usage: khc_docbookdig.pl --indexdir <indexdir> --docpath <path> "; + print "--identifier <identifier>\n"; + exit 1; +} diff --git a/khelpcenter/searchhandlers/khc_htdig.pl.in b/khelpcenter/searchhandlers/khc_htdig.pl.in new file mode 100755 index 000000000..a9eb25de6 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_htdig.pl.in @@ -0,0 +1,148 @@ +#!/usr/bin/perl +# +# Wrapper script for creating search indices for htdig. +# +# This file is part of the SuSE help system. +# +# Copyright (C) 2002 SuSE Linux AG, Nuernberg +# +# Author: Cornelius Schumacher <[email protected]> +# +# 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 + +use strict; + +use Getopt::Long; + +my $htdigdata = "/etc/htdig"; +my $htdigbin = "/usr/bin"; +my $kdeprefix = "@prefix@"; +chomp $kdeprefix; + +my $dbg = 1; + +my ($indexdir, $docpath, $identifier, $lang, $help ); + +GetOptions ( + 'indexdir=s' => \$indexdir, + 'docpath=s' => \$docpath, + 'identifier=s' => \$identifier, + 'lang=s' => \$lang, + 'help' => \$help, +); + +if ( $help ) { + usage(); +} + +if ( !$indexdir || !$docpath || !$identifier ) { + print STDERR "Missing arguments.\n"; + usage(); +} + +if ( !$lang ) { $lang = "en"; } + +&dbg( "INDEXDIR: $indexdir" ); + +print "Creating index for <b>'$identifier'</b>\n"; + +my $htdigconf = $indexdir; +my $htdigdb = $indexdir; + +my $conffile = "$htdigconf/$identifier.conf"; + +if ( !open( CONF, ">$conffile" ) ) { + print STDERR "Unable to open '$conffile' for writing.\n"; + exit 1; +} + +my $commondir = "$htdigdata/$lang"; +if ( !$lang || !-e $commondir ) { + $commondir = "$htdigdata/en"; +} +if ( !-e $commondir ) { $commondir = $htdigdata; } + +my $locale; +if ( $lang eq "de" ) { $locale = "de_DE"; } +else { $locale = $lang; } + +print CONF << "EOT"; +# htdig configuration for doc '$identifier' +# +# This file has been automatically created by KHelpcenter + +common_dir: $commondir +locale: $locale +database_dir: $htdigdb +local_urls: http://localhost= +local_urls_only: true +limit_urls_to: http://localhost +ignore_noindex: true +max_hop_count: 4 +robotstxt_name: kdedig +compression_level: 6 +template_map: Long long $kdeprefix/share/apps/khelpcenter/searchhandlers/htdig/htdig_long.html \\ + Short short $htdigdata/short.html +search_algorithm: exact:1 prefix:0.8 +maximum_pages: 1 +matches_per_page: 10 +database_base: \${database_dir}/$identifier +start_url: http://localhost/$docpath +# for pdf-files +max_doc_size: 5000000 +external_parsers: application/pdf /usr/share/doc/packages/htdig/contrib/parse_doc.pl application/postscript /usr/share/doc/packages/htdig/contrib/parse_doc.pl +#external_parsers: text/docbook /build/htdig/parser +EOT + +close CONF; + +$ENV{ PATH } = ''; +$ENV{ CDPATH } = ''; +$ENV{ ENV } = ''; + +my $ret = system( "$htdigbin/htdig", "-s", "-i", "-c", $conffile ); +if ( $ret != 0 ) { + print STDERR "htdig failed\n"; +} else { + $ret = system( "$htdigbin/htmerge", "-c", $conffile ); + if ( $ret != 0 ) { print STDERR "htmerge failed\n"; } +} + +if ( $ret == 0 ) { + my $existsfile = "$indexdir/$identifier.exists"; + + if ( !open( EXISTS, ">$existsfile" ) ) { + print STDERR "Unable to open '$existsfile' for writing.\n"; + exit 1; + } + print EXISTS "$identifier\n"; + close EXISTS; + + print "Finished successfully.\n"; +} + +exit $ret; + +sub dbg($) +{ + $dbg && print STDERR shift, "\n"; +} + +sub usage() +{ + print "Usage: khc_htdig.pl --indexdir <indexdir> --docpath <path> "; + print "--identifier <identifier>\n"; + exit 1; +} diff --git a/khelpcenter/searchhandlers/khc_htsearch.pl.in b/khelpcenter/searchhandlers/khc_htsearch.pl.in new file mode 100644 index 000000000..28113bec2 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_htsearch.pl.in @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +use strict; + +use Encode; +use Getopt::Long; + +use open IO => ':utf8'; +use open ':std'; + +my $htsearchpath="@HTDIG_SEARCH_BINARY@"; +my $config; +my $format; +my $method; +my $words; +my $lang; +my $docbook; +my $indexdir; +my $maxnum; + +GetOptions ( + 'binary=s' => \$htsearchpath, + 'config=s' => \$config, + 'format=s' => \$format, + 'method=s' => \$method, + 'words=s' => \$words, + 'lang=s' => \$lang, + 'docbook' => \$docbook, + 'indexdir=s' => \$indexdir, + 'maxnum=s' => \$maxnum +); + +if ( !$indexdir ) { + print STDERR "No index dir given.\n"; + exit 1; +} + +if ( !$lang ) { $lang = "en"; } + +my $charset = langCharset( $lang ); + +$words = encode( $charset, $words ); + +if ( !open( HTSEARCH, "-|", "$htsearchpath", "-c", "$indexdir/$config.conf", + "format=$format&method=$method&words=$words&matchesperpage=$maxnum&exclude=[index.html]" ) ) +{ + print "Can't execute htsearch at '$htsearchpath'.\n"; + exit 1; +} + +my ($body,$liststart,$ref,$link,$error,$errorOut); + +while( <HTSEARCH> ) { + if ( !$body ) { + print; + if ( /^<body/ ) { $body = 1; } + } + if ( /^<h3>/ ) { + print; + print "<ul>\n"; + $liststart = 1; + } + if ( /^<img src.*<a href="(.*)">(.*)<\/a>/ ) { + $ref = $1; + $link = $2; + + print STDERR "REF: $ref LINK: $link\n"; + + $ref =~ s/file:\/\/localhost//; + + $ref =~ s/http:\/\/localhost\//file:\//; + + if ( $docbook ) { + $ref =~ /help:\/\/(.*)\/index.docbook/; + my $app = $1; + $ref = "help:$app"; + + $link =~ s/apptitle/$app/; + } + + print " <li><a href=\"$ref\">$link</a></li>\n"; + } + if ( /^<h1>ht:\/\/Dig error/ ) { + $error = 1; + print "Htdig error:\n"; + } + if ( $error && /^<pre>/ ) { + $errorOut = 1; + } + if ( $errorOut ) { + print; + if ( /^<\/pre>/ ) { $errorOut = 0; } + } +} + +close HTSEARCH; + +if ( $liststart ) { print "</ul>\n"; } + +print "</body></html>\n"; + +if ( $? != 0 ) { exit $?; } + +1; + +# Return charset used for given language +sub langCharset( $ ) +{ + my $lang = shift; + if ( $lang eq "cz" || $lang eq "hu" ) { + return "latin2"; + } elsif ( $lang eq "kr" ) { + return "utf8"; + } else { + return "latin1"; + } +} diff --git a/khelpcenter/searchhandlers/khc_mansearch.pl b/khelpcenter/searchhandlers/khc_mansearch.pl new file mode 100755 index 000000000..a68fde752 --- /dev/null +++ b/khelpcenter/searchhandlers/khc_mansearch.pl @@ -0,0 +1,84 @@ +#!/usr/bin/perl +# +# Script for searching man pages. The result is generated as HTML. +# +# This file is part of KHelpcenter. +# +# Copyright (C) 2002 SuSE Linux AG, Nuernberg +# +# Author: Cornelius Schumacher <[email protected]> +# +# 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 + +use strict; + +use Getopt::Long; + +my ( $words, $maxcount, $lang, $help ); + +GetOptions ( + 'maxcount=s' => \$maxcount, + 'words=s' => \$words, + 'lang=s' => \$lang, + 'help' => \$help +); + +if ( $help ) { + print STDERR "Usage: khc_mansearch.pl --maxcount=n --words=<string> " . + "--lang=<languagecode>\n"; + exit 1; +} + +if ( !$words ) { + print STDERR "No search words given.\n"; + exit; +} + +# Perform search +if ( !open( MAN, "-|", "apropos", $words ) ) { + print "Can't open apropos.\n"; + exit 1; +} +my @results; +while( <MAN> ) { +# print "RAW:$_"; + chop; + /^([^\s]+)\s+\((.*)\)\s+-\s+(.*)$/; + my $page = $1; + my $section = $2; + my $description = $3; + + if ( $page ) { push @results, [ $page, $section, $description ]; } +} +close MAN; + +my $nummatches = @results; + +if ( $nummatches > 0 ) { + print "<ul>\n"; + + my $count = 0; + for my $result ( @results ) { + my ( $page, $section, $description ) = @$result; + my $url = "man:" . $page; + print "<li><a href=\"$url\">"; + print "$page - $description</a></li>\n"; + if ( ++$count == $maxcount ) { last; } + } + + print "</ul>\n"; +} + +1; diff --git a/khelpcenter/searchhandlers/man.desktop b/khelpcenter/searchhandlers/man.desktop new file mode 100644 index 000000000..f9274384e --- /dev/null +++ b/khelpcenter/searchhandlers/man.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] + +DocumentTypes=text/man + +SearchCommand=khc_mansearch.pl --words=%w --maxcount=%m diff --git a/khelpcenter/searchwidget.cpp b/khelpcenter/searchwidget.cpp new file mode 100644 index 000000000..5040a7d81 --- /dev/null +++ b/khelpcenter/searchwidget.cpp @@ -0,0 +1,392 @@ +/* + * searchwidget.cpp - part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * (C) 2000 Matthias Hoelzer-Kluepfel ([email protected]) + * + * 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 <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <tqlayout.h> + +#include <ksimpleconfig.h> +#include <tdeapplication.h> +#include <tdelocale.h> +#include <kdebug.h> +#include <kiconloader.h> + +#include "scopeitem.h" +#include "docentrytraverser.h" +#include "kcmhelpcenter.h" +#include "prefs.h" +#include "searchengine.h" + +#include "searchwidget.h" + +namespace KHC { + +SearchWidget::SearchWidget( SearchEngine *engine, TQWidget *parent ) + : TQWidget( parent ), DCOPObject( "SearchWidget" ), mEngine( engine ), + mScopeCount( 0 ) +{ + TQBoxLayout *topLayout = new TQVBoxLayout( this, 2, 2 ); + + TQBoxLayout *hLayout = new TQHBoxLayout( topLayout ); + + mMethodCombo = new TQComboBox( this ); + mMethodCombo->insertItem( i18n("and") ); + mMethodCombo->insertItem( i18n("or") ); + + TQLabel *l = new TQLabel( mMethodCombo, i18n("&Method:"), this ); + + hLayout->addWidget( l ); + hLayout->addWidget( mMethodCombo ); + + hLayout = new TQHBoxLayout( topLayout ); + + mPagesCombo = new TQComboBox( this ); + mPagesCombo->insertItem( "5" ); + mPagesCombo->insertItem( "10" ); + mPagesCombo->insertItem( "25" ); + mPagesCombo->insertItem( "50" ); + mPagesCombo->insertItem( "1000" ); + + l = new TQLabel( mPagesCombo, i18n("Max. &results:"), this ); + + hLayout->addWidget( l ); + hLayout->addWidget( mPagesCombo ); + + hLayout = new TQHBoxLayout( topLayout ); + + mScopeCombo = new TQComboBox( this ); + for (int i=0; i < ScopeNum; ++i ) { + mScopeCombo->insertItem( scopeSelectionLabel( i ) ); + } + connect( mScopeCombo, TQT_SIGNAL( activated( int ) ), + TQT_SLOT( scopeSelectionChanged( int ) ) ); + + l = new TQLabel( mScopeCombo, i18n("&Scope selection:"), this ); + + hLayout->addWidget( l ); + hLayout->addWidget( mScopeCombo ); + + mScopeListView = new TQListView( this ); + mScopeListView->setRootIsDecorated( true ); + mScopeListView->addColumn( i18n("Scope") ); + topLayout->addWidget( mScopeListView, 1 ); + + TQPushButton *indexButton = new TQPushButton( i18n("Build Search &Index..."), + this ); + connect( indexButton, TQT_SIGNAL( clicked() ), TQT_SIGNAL( showIndexDialog() ) ); + topLayout->addWidget( indexButton ); + +// FIXME: Use SearchHandler on double-clicked document +#if 0 + connect( mScopeListView, TQT_SIGNAL( doubleClicked( TQListViewItem * ) ), + TQT_SLOT( scopeDoubleClicked( TQListViewItem * ) ) ); +#endif + connect( mScopeListView, TQT_SIGNAL( clicked( TQListViewItem * ) ), + TQT_SLOT( scopeClicked( TQListViewItem * ) ) ); +} + + +SearchWidget::~SearchWidget() +{ + writeConfig( TDEGlobal::config() ); +} + + +void SearchWidget::readConfig( TDEConfig *cfg ) +{ + cfg->setGroup( "Search" ); + + int scopeSelection = cfg->readNumEntry( "ScopeSelection", ScopeDefault ); + mScopeCombo->setCurrentItem( scopeSelection ); + if ( scopeSelection != ScopeDefault ) scopeSelectionChanged( scopeSelection ); + + mMethodCombo->setCurrentItem( Prefs::method() ); + mPagesCombo->setCurrentItem( Prefs::maxCount() ); + + if ( scopeSelection == ScopeCustom ) { + cfg->setGroup( "Custom Search Scope" ); + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + item->setOn( cfg->readBoolEntry( item->entry()->identifier(), + item->isOn() ) ); + } + ++it; + } + } + + checkScope(); +} + +void SearchWidget::writeConfig( TDEConfig *cfg ) +{ + cfg->setGroup( "Search" ); + + cfg->writeEntry( "ScopeSelection", mScopeCombo->currentItem() ); + Prefs::setMethod( mMethodCombo->currentItem() ); + Prefs::setMaxCount( mPagesCombo->currentItem() ); + + if ( mScopeCombo->currentItem() == ScopeCustom ) { + cfg->setGroup( "Custom Search Scope" ); + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + cfg->writeEntry( item->entry()->identifier(), item->isOn() ); + } + ++it; + } + } +} + +void SearchWidget::slotSwitchBoxes() +{ + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + item->setOn( !item->isOn() ); + } + ++it; + } + + checkScope(); +} + +void SearchWidget::scopeSelectionChanged( int id ) +{ + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + bool state = item->isOn(); + switch( id ) { + case ScopeDefault: + state = item->entry()->searchEnabledDefault(); + break; + case ScopeAll: + state = true; + break; + case ScopeNone: + state = false; + break; + default: + break; + } + if ( state != item->isOn() ) { + item->setOn( state ); + } + } + ++it; + } + + checkScope(); +} + +TQString SearchWidget::method() +{ + TQString m = "and"; + if ( mMethodCombo->currentItem() == 1) + m = "or"; + + return m; +} + +int SearchWidget::pages() +{ + int p = mPagesCombo->currentText().toInt(); + + return p; +} + +TQString SearchWidget::scope() +{ + TQString scope; + + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + if ( item->isOn() ) { + if ( !scope.isEmpty() ) scope += "&"; + scope += "scope=" + item->entry()->identifier(); + } + } + ++it; + } + + return scope; +} + +class ScopeTraverser : public DocEntryTraverser +{ + public: + ScopeTraverser( SearchWidget *widget, int level ) : + mWidget( widget ), mLevel( level ), mParentItem( 0 ) {} + + ~ScopeTraverser() + { + if( mParentItem && !mParentItem->childCount() ) delete mParentItem; + } + + void process( DocEntry *entry ) + { + if ( mWidget->engine()->canSearch( entry ) && + ( !mWidget->engine()->needsIndex( entry ) || + entry->indexExists( Prefs::indexDirectory() ) ) ) { + ScopeItem *item = 0; + if ( mParentItem ) { + item = new ScopeItem( mParentItem, entry ); + } else { + item = new ScopeItem( mWidget->listView(), entry ); + } + item->setOn( entry->searchEnabled() ); + } + } + + DocEntryTraverser *createChild( DocEntry *entry ) + { + if ( mLevel >= mNestingLevel ) { + ++mLevel; + return this; + } else { + ScopeTraverser *t = new ScopeTraverser( mWidget, mLevel + 1 ); + TQListViewItem *item = 0; + if ( mParentItem ) { + item = new TQListViewItem( mParentItem, entry->name() ); + } else { + item = new TQListViewItem( mWidget->listView(), entry->name() ); + } + item->setOpen( true ); + t->mParentItem = item; + return t; + } + } + + DocEntryTraverser *parentTraverser() + { + if ( mLevel > mNestingLevel ) return this; + else return mParent; + } + + void deleteTraverser() + { + if ( mLevel > mNestingLevel ) --mLevel; + else delete this; + } + + private: + SearchWidget *mWidget; + int mLevel; + TQListViewItem *mParentItem; + + static int mNestingLevel; +}; + +int ScopeTraverser::mNestingLevel = 2; + +void SearchWidget::searchIndexUpdated() +{ + TDEGlobal::config()->reparseConfiguration(); + updateScopeList(); + update(); +} + +void SearchWidget::updateScopeList() +{ + mScopeListView->clear(); + + ScopeTraverser t( this, 0 ); + DocMetaInfo::self()->traverseEntries( &t ); + + checkScope(); +} + +void SearchWidget::scopeDoubleClicked( TQListViewItem *item ) +{ + if ( !item || item->rtti() != ScopeItem::rttiId() ) return; + ScopeItem *scopeItem = static_cast<ScopeItem *>( item ); + + TQString searchUrl = scopeItem->entry()->search(); + + kdDebug() << "DoubleClick: " << searchUrl << endl; + + emit searchResult( searchUrl ); +} + +void SearchWidget::scopeClicked( TQListViewItem * ) +{ + checkScope(); + + mScopeCombo->setCurrentItem( ScopeCustom ); +} + +TQString SearchWidget::scopeSelectionLabel( int id ) const +{ + switch( id ) { + case ScopeCustom: + return i18n("Custom"); + case ScopeDefault: + return i18n("Default"); + case ScopeAll: + return i18n("All"); + case ScopeNone: + return i18n("None"); + default: + return i18n("unknown"); + } +} + +void SearchWidget::checkScope() +{ + mScopeCount = 0; + + TQListViewItemIterator it( mScopeListView ); + while( it.current() ) { + if ( it.current()->rtti() == ScopeItem::rttiId() ) { + ScopeItem *item = static_cast<ScopeItem *>( it.current() ); + if ( item->isOn() ) { + ++mScopeCount; + } + item->entry()->enableSearch( item->isOn() ); + } + ++it; + } + + emit scopeCountChanged( mScopeCount ); +} + +int SearchWidget::scopeCount() const +{ + return mScopeCount; +} + +} + +#include "searchwidget.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/searchwidget.h b/khelpcenter/searchwidget.h new file mode 100644 index 000000000..14801223b --- /dev/null +++ b/khelpcenter/searchwidget.h @@ -0,0 +1,107 @@ +/* + * searchwidget.h - part of the TDE Help Center + * + * Copyright (C) 1999 Matthias Elter ([email protected]) + * + * 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 __searchwidget_h__ +#define __searchwidget_h__ + +#include <tqwidget.h> + +#include <dcopobject.h> + +#include "docmetainfo.h" + +class TQCheckBox; +class TQListView; +class TQListViewItem; +class TQComboBox; + +class KLanguageCombo; +class TDEConfig; + +class KCMHelpCenter; + +namespace KHC { + +class ScopeItem; +class SearchEngine; + +class SearchWidget : public TQWidget, public DCOPObject +{ + Q_OBJECT + K_DCOP + + k_dcop: + ASYNC searchIndexUpdated(); // called from kcmhelpcenter + + public: + SearchWidget ( SearchEngine *, TQWidget *parent = 0 ); + ~SearchWidget(); + + TQString method(); + int pages(); + TQString scope(); + + TQListView *listView() { return mScopeListView; } + + enum { ScopeDefault, ScopeAll, ScopeNone, ScopeCustom, ScopeNum }; + + TQString scopeSelectionLabel( int ) const; + + void readConfig( TDEConfig * ); + void writeConfig( TDEConfig * ); + + int scopeCount() const; + + SearchEngine *engine() const { return mEngine; } + + signals: + void searchResult( const TQString &url ); + void scopeCountChanged( int ); + void showIndexDialog(); + + public slots: + void slotSwitchBoxes(); + void scopeSelectionChanged( int ); + void updateScopeList(); + + protected: + void checkScope(); + + protected slots: + void scopeDoubleClicked( TQListViewItem * ); + void scopeClicked( TQListViewItem * ); + + private: + void loadLanguages(); + + SearchEngine *mEngine; + + TQComboBox *mMethodCombo; + TQComboBox *mPagesCombo; + TQComboBox *mScopeCombo; + TQListView *mScopeListView; + + int mScopeCount; +}; + +} + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/table-of-contents.xslt b/khelpcenter/table-of-contents.xslt new file mode 100644 index 000000000..47b7fbb78 --- /dev/null +++ b/khelpcenter/table-of-contents.xslt @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:template match="book"> +<table-of-contents> +<xsl:apply-templates select="chapter"/> +</table-of-contents> +</xsl:template> + +<xsl:template match="chapter"> +<chapter> +<title><xsl:value-of select="title"/></title> +<anchor><xsl:value-of select="@id"/></anchor> +<xsl:apply-templates select="sect1"/> +</chapter> +</xsl:template> + +<xsl:template match="sect1"> +<section> +<title><xsl:value-of select="title"/></title> +<anchor><xsl:value-of select="@id"/></anchor> +</section> +</xsl:template> + +</xsl:stylesheet> diff --git a/khelpcenter/testmetainfo.cpp b/khelpcenter/testmetainfo.cpp new file mode 100644 index 000000000..2f77ff766 --- /dev/null +++ b/khelpcenter/testmetainfo.cpp @@ -0,0 +1,119 @@ +#include <tqstringlist.h> + +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <tdelocale.h> +#include <tdecmdlineargs.h> + +#include "docmetainfo.h" +#include "docentrytraverser.h" + +using namespace KHC; + +class MyTraverser : public DocEntryTraverser +{ + public: + MyTraverser( const TQString &indent = "" ) : mIndent( indent ) {} + + void process( DocEntry *entry ) + { + kdDebug() << mIndent << entry->name() << " - WEIGHT: " << entry->weight() + << endl; +#if 0 + if ( entry->parent() ) kdDebug() << mIndent << " PARENT: " + << entry->parent()->name() << endl; + if ( entry->nextSibling() ) kdDebug() << mIndent << " NEXT: " + << entry->nextSibling()->name() << endl; +#endif + } + + DocEntryTraverser *createChild( DocEntry * ) + { + return new MyTraverser( mIndent + " " ); + } + + private: + TQString mIndent; +}; + +class LinearTraverser : public DocEntryTraverser +{ + public: + void process( DocEntry *entry ) + { + kdDebug() << "PROCESS: " << entry->name() << endl; + } + + DocEntryTraverser *createChild( DocEntry * ) + { + return this; + } + + DocEntryTraverser *parentTraverser() + { + return this; + } + + void deleteTraverser() {} +}; + +class AsyncTraverser : public DocEntryTraverser +{ + public: + AsyncTraverser( const TQString &indent = "" ) : mIndent( indent ) + { +// kdDebug() << "AsyncTraverser()" << endl; + } + + ~AsyncTraverser() + { +// kdDebug() << "~AsyncTraverser()" << endl; + } + + void process( DocEntry *entry ) + { + kdDebug() << mIndent << entry->name() << endl; + } + + DocEntryTraverser *createChild( DocEntry * ) + { +// kdDebug() << "AsyncTraverser::childTraverser()" << endl; + return new AsyncTraverser( mIndent + " " ); + } + + private: + TQString mIndent; +}; + +int main(int argc,char **argv) +{ + TDEAboutData aboutData("testmetainfo","TestDocMetaInfo","0.1"); + TDECmdLineArgs::init(argc,argv,&aboutData); + + TDEApplication app; + + kdDebug() << "Scanning Meta Info" << endl; + + TQStringList langs; + langs << "en"; +// langs << "de"; + + DocMetaInfo::self()->scanMetaInfo( langs ); + + kdDebug() << "My TRAVERSE start" << endl; + MyTraverser t; + DocMetaInfo::self()->startTraverseEntries( &t ); + kdDebug() << "My TRAVERSE end" << endl; + + kdDebug() << "Linear TRAVERSE start" << endl; + LinearTraverser l; + DocMetaInfo::self()->startTraverseEntries( &l ); + kdDebug() << "Linear TRAVERSE end" << endl; + + kdDebug() << "Async TRAVERSE start" << endl; + AsyncTraverser a; + DocMetaInfo::self()->startTraverseEntries( &a ); + kdDebug() << "Async TRAVERSE end" << endl; +} +// vim:ts=2:sw=2:et diff --git a/khelpcenter/toc.cpp b/khelpcenter/toc.cpp new file mode 100644 index 000000000..19bcb01c0 --- /dev/null +++ b/khelpcenter/toc.cpp @@ -0,0 +1,271 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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 "toc.h" + +#include "docentry.h" + +#include <kiconloader.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kdebug.h> + +#include <tqdir.h> +#include <tqfileinfo.h> + +#include <sys/stat.h> + +using namespace KHC; + +class TOCItem : public NavigatorItem +{ + public: + TOCItem( TOC *parent, TQListViewItem *parentItem, TQListViewItem *after, const TQString &text ); + + const TOC *toc() const { return m_toc; } + + private: + TOC *m_toc; +}; + +class TOCChapterItem : public TOCItem +{ + public: + TOCChapterItem( TOC *toc, NavigatorItem *parent, TQListViewItem *after, const TQString &title, + const TQString &name ); + + virtual TQString url(); + + private: + TQString m_name; +}; + +class TOCSectionItem : public TOCItem +{ + public: + TOCSectionItem( TOC *toc, TOCChapterItem *parent, TQListViewItem *after, const TQString &title, + const TQString &name ); + + virtual TQString url(); + + private: + TQString m_name; +}; + +TOC::TOC( NavigatorItem *parentItem ) +{ + m_parentItem = parentItem; +} + +void TOC::build( const TQString &file ) +{ + TQFileInfo fileInfo( file ); + TQString fileName = fileInfo.absFilePath(); + const TQStringList resourceDirs = TDEGlobal::dirs()->resourceDirs( "html" ); + TQStringList::ConstIterator it = resourceDirs.begin(); + TQStringList::ConstIterator end = resourceDirs.end(); + for ( ; it != end; ++it ) { + if ( fileName.startsWith( *it ) ) { + fileName.remove( 0, ( *it ).length() ); + break; + } + } + + TQString cacheFile = fileName.replace( TQDir::separator(), "__" ); + m_cacheFile = locateLocal( "cache", "help/" + cacheFile ); + m_sourceFile = file; + + if ( cacheStatus() == NeedRebuild ) + buildCache(); + else + fillTree(); +} + +TOC::CacheStatus TOC::cacheStatus() const +{ + if ( !TQFile::exists( m_cacheFile ) || + sourceFileCTime() != cachedCTime() ) + return NeedRebuild; + + return CacheOk; +} + +int TOC::sourceFileCTime() const +{ + struct stat stat_buf; + stat( TQFile::encodeName( m_sourceFile ).data(), &stat_buf ); + + return stat_buf.st_ctime; +} + +int TOC::cachedCTime() const +{ + TQFile f( m_cacheFile ); + if ( !f.open( IO_ReadOnly ) ) + return 0; + + TQDomDocument doc; + if ( !doc.setContent( &f ) ) + return 0; + + TQDomComment timestamp = doc.documentElement().lastChild().toComment(); + + return timestamp.data().stripWhiteSpace().toInt(); +} + +void TOC::buildCache() +{ + TDEProcess *meinproc = new TDEProcess; + connect( meinproc, TQT_SIGNAL( processExited( TDEProcess * ) ), + this, TQT_SLOT( meinprocExited( TDEProcess * ) ) ); + + *meinproc << locate( "exe", "meinproc" ); + *meinproc << "--stylesheet" << locate( "data", "khelpcenter/table-of-contents.xslt" ); + *meinproc << "--output" << m_cacheFile; + *meinproc << m_sourceFile; + + meinproc->start( TDEProcess::NotifyOnExit ); +} + +void TOC::meinprocExited( TDEProcess *meinproc ) +{ + if ( !meinproc->normalExit() || meinproc->exitStatus() != 0 ) { + delete meinproc; + return; + } + + delete meinproc; + + TQFile f( m_cacheFile ); + if ( !f.open( IO_ReadWrite ) ) + return; + + TQDomDocument doc; + if ( !doc.setContent( &f ) ) + return; + + TQDomComment timestamp = doc.createComment( TQString::number( sourceFileCTime() ) ); + doc.documentElement().appendChild( timestamp ); + + f.at( 0 ); + TQTextStream stream( &f ); + stream.setEncoding( TQTextStream::UnicodeUTF8 ); + stream << doc.toString(); + + f.close(); + + fillTree(); +} + +void TOC::fillTree() +{ + TQFile f( m_cacheFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + + TQDomDocument doc; + if ( !doc.setContent( &f ) ) + return; + + TOCChapterItem *chapItem = 0; + TQDomNodeList chapters = doc.documentElement().elementsByTagName( "chapter" ); + for ( unsigned int chapterCount = 0; chapterCount < chapters.count(); chapterCount++ ) { + TQDomElement chapElem = chapters.item( chapterCount ).toElement(); + TQDomElement chapTitleElem = childElement( chapElem, TQString::fromLatin1( "title" ) ); + TQString chapTitle = chapTitleElem.text().simplifyWhiteSpace(); + TQDomElement chapRefElem = childElement( chapElem, TQString::fromLatin1( "anchor" ) ); + TQString chapRef = chapRefElem.text().stripWhiteSpace(); + + chapItem = new TOCChapterItem( this, m_parentItem, chapItem, chapTitle, chapRef ); + + TOCSectionItem *sectItem = 0; + TQDomNodeList sections = chapElem.elementsByTagName( "section" ); + for ( unsigned int sectCount = 0; sectCount < sections.count(); sectCount++ ) { + TQDomElement sectElem = sections.item( sectCount ).toElement(); + TQDomElement sectTitleElem = childElement( sectElem, TQString::fromLatin1( "title" ) ); + TQString sectTitle = sectTitleElem.text().simplifyWhiteSpace(); + TQDomElement sectRefElem = childElement( sectElem, TQString::fromLatin1( "anchor" ) ); + TQString sectRef = sectRefElem.text().stripWhiteSpace(); + + sectItem = new TOCSectionItem( this, chapItem, sectItem, sectTitle, sectRef ); + } + } + + m_parentItem->setOpen( true ); +} + +TQDomElement TOC::childElement( const TQDomElement &element, const TQString &name ) +{ + TQDomElement e; + for ( e = element.firstChild().toElement(); !e.isNull(); e = e.nextSibling().toElement() ) + if ( e.tagName() == name ) + break; + return e; +} + +void TOC::slotItemSelected( TQListViewItem *item ) +{ + TOCItem *tocItem; + if ( ( tocItem = dynamic_cast<TOCItem *>( item ) ) ) + emit itemSelected( tocItem->entry()->url() ); + + item->setOpen( !item->isOpen() ); +} + +TOCItem::TOCItem( TOC *toc, TQListViewItem *parentItem, TQListViewItem *after, const TQString &text ) + : NavigatorItem( new DocEntry( text ), parentItem, after ) +{ + setAutoDeleteDocEntry( true ); + m_toc = toc; +} + +TOCChapterItem::TOCChapterItem( TOC *toc, NavigatorItem *parent, TQListViewItem *after, + const TQString &title, const TQString &name ) + : TOCItem( toc, parent, after, title ), + m_name( name ) +{ + setOpen( false ); + entry()->setUrl(url()); +} + +TQString TOCChapterItem::url() +{ + return "help:" + toc()->application() + "/" + m_name + ".html"; +} + +TOCSectionItem::TOCSectionItem( TOC *toc, TOCChapterItem *parent, TQListViewItem *after, + const TQString &title, const TQString &name ) + : TOCItem( toc, parent, after, title ), + m_name( name ) +{ + setPixmap( 0, SmallIcon( "document" ) ); + entry()->setUrl(url()); +} + +TQString TOCSectionItem::url() +{ + if ( static_cast<TOCSectionItem *>( parent()->firstChild() ) == this ) + return static_cast<TOCChapterItem *>( parent() )->url() + "#" + m_name; + + return "help:" + toc()->application() + "/" + m_name + ".html"; +} + +#include "toc.moc" +// vim:ts=2:sw=2:et diff --git a/khelpcenter/toc.h b/khelpcenter/toc.h new file mode 100644 index 000000000..0a38c2ad5 --- /dev/null +++ b/khelpcenter/toc.h @@ -0,0 +1,72 @@ +/* + * toc.h - part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe ([email protected]) + * + * 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_TOC_H +#define KHC_TOC_H + +#include "navigatoritem.h" + +#include <tqdom.h> +#include <tqlistview.h> +#include <tqobject.h> + +class TDEProcess; + +namespace KHC { + +class TOC : public QObject +{ + Q_OBJECT + public: + TOC( NavigatorItem *parentItem ); + + TQString application() const { return m_application; } + void setApplication( const TQString &application ) { m_application = application; } + + public slots: + void build( const TQString &file ); + + signals: + void itemSelected( const TQString &url ); + + private slots: + void slotItemSelected( TQListViewItem *item ); + void meinprocExited( TDEProcess *meinproc ); + + private: + enum CacheStatus { NeedRebuild, CacheOk }; + + CacheStatus cacheStatus() const; + int sourceFileCTime() const; + int cachedCTime() const; + TQDomElement childElement( const TQDomElement &e, const TQString &name ); + void buildCache(); + void fillTree(); + + TQString m_application; + TQString m_cacheFile; + TQString m_sourceFile; + + NavigatorItem *m_parentItem; +}; + +} + +#endif // KHC_TOC_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/treebuilder.cpp b/khelpcenter/treebuilder.cpp new file mode 100644 index 000000000..b8a0096d9 --- /dev/null +++ b/khelpcenter/treebuilder.cpp @@ -0,0 +1,35 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe <[email protected]> + * + * 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 "treebuilder.h" + +using namespace KHC; + +TreeBuilder::TreeBuilder( TQObject *parent, const char *name ) + : TQObject( parent, name ) +{ +} + +void TreeBuilder::selectURL( const TQString & ) +{ +} + +#include "treebuilder.moc" + +// vim:ts=2:sw=2:et diff --git a/khelpcenter/treebuilder.h b/khelpcenter/treebuilder.h new file mode 100644 index 000000000..443444691 --- /dev/null +++ b/khelpcenter/treebuilder.h @@ -0,0 +1,49 @@ +/* + * This file is part of the TDE Help Center + * + * Copyright (C) 2002 Frerich Raabe <[email protected]> + * + * 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 TREEBUILDER_H +#define TREEBUILDER_H + +#include "tqobject.h" + +#include <kurl.h> + +namespace KHC +{ + +class NavigatorItem; +class TreeBuilder : public TQObject +{ + Q_OBJECT + public: + TreeBuilder( TQObject *parent, const char *name = 0 ); + + virtual void build( NavigatorItem *item ) = 0; + + public slots: + virtual void selectURL( const TQString &url ); + + signals: + void urlSelected( const KURL &url ); +}; + +} + +#endif // TREEBUILDER_H +// vim:ts=2:sw=2:et diff --git a/khelpcenter/version.h b/khelpcenter/version.h new file mode 100644 index 000000000..b8623dbf6 --- /dev/null +++ b/khelpcenter/version.h @@ -0,0 +1,7 @@ +#ifndef __version_h__ +#define __version_h__ + +#define HELPCENTER_VERSION TDE_VERSION_STRING + +#endif +// vim:ts=2:sw=2:et diff --git a/khelpcenter/view.cpp b/khelpcenter/view.cpp new file mode 100644 index 000000000..f0151b3df --- /dev/null +++ b/khelpcenter/view.cpp @@ -0,0 +1,388 @@ +#include "view.h" + +#include "formatter.h" +#include "history.h" + +#include <dom/html_document.h> +#include <dom/html_misc.h> +#include <tdeaction.h> +#include <tdeactioncollection.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <tdehtml_settings.h> +#include <tdehtmlview.h> +#include <tdelocale.h> +#include <tdepopupmenu.h> +#include <kstandarddirs.h> + +#include <tqfileinfo.h> +#include <tqclipboard.h> + +using namespace KHC; + +View::View( TQWidget *parentWidget, const char *widgetName, + TQObject *parent, const char *name, TDEHTMLPart::GUIProfile prof, TDEActionCollection *col ) + : TDEHTMLPart( parentWidget, widgetName, parent, name, prof ), mState( Docu ), mActionCollection(col) +{ + setJScriptEnabled(false); + setJavaEnabled(false); + setPluginsEnabled(false); + + mFormatter = new Formatter; + if ( !mFormatter->readTemplates() ) { + kdDebug() << "Unable to read Formatter templates." << endl; + } + + m_zoomStepping = 10; + + connect( this, TQT_SIGNAL( setWindowCaption( const TQString & ) ), + this, TQT_SLOT( setTitle( const TQString & ) ) ); + connect( this, TQT_SIGNAL( popupMenu( const TQString &, const TQPoint& ) ), + this, TQT_SLOT( showMenu( const TQString &, const TQPoint& ) ) ); + + TQString css = langLookup("common/tde-default.css"); + if (!css.isEmpty()) + { + TQFile css_file(css); + if (css_file.open(IO_ReadOnly)) + { + TQTextStream s(&css_file); + TQString stylesheet = s.read(); + preloadStyleSheet("help:/common/tde-default.css", stylesheet); + } + } + + view()->installEventFilter( this ); +} + +View::~View() +{ + delete mFormatter; +} + +void View::copySelectedText() +{ + kapp->clipboard()->setText( selectedText() ); +} + +bool View::openURL( const KURL &url ) +{ + if ( url.protocol().lower() == "about" ) + { + showAboutPage(); + return true; + } + mState = Docu; + return TDEHTMLPart::openURL( url ); +} + +void View::saveState( TQDataStream &stream ) +{ + stream << mState; + if ( mState == Docu ) + TDEHTMLPart::saveState( stream ); +} + +void View::restoreState( TQDataStream &stream ) +{ + stream >> mState; + if ( mState == Docu ) + TDEHTMLPart::restoreState( stream ); + else if ( mState == About ) + showAboutPage(); +} + +void View::showAboutPage() +{ + TQString file = locate( "data", "khelpcenter/intro.html.in" ); + if ( file.isEmpty() ) + return; + + TQFile f( file ); + + if ( !f.open( IO_ReadOnly ) ) + return; + + mState = About; + + emit started( 0 ); + + TQTextStream t( &f ); + + TQString res = t.read(); + + res = res.arg( i18n("Conquer your Desktop!") ) + .arg( langLookup( "khelpcenter/konq.css" ) ) + .arg( langLookup( "khelpcenter/pointers.png" ) ) + .arg( langLookup( "khelpcenter/khelpcenter.png" ) ) + .arg( i18n("Help Center") ) + .arg( langLookup( "khelpcenter/lines.png" ) ) + .arg( i18n( "Welcome to the Trinity Desktop Environment" ) ) + .arg( i18n( "The TDE team welcomes you to user-friendly UNIX-like computing" ) ) + .arg( i18n( "The Trinity Desktop Environment (TDE) is a graphical desktop\n" + "environment for UNIX-like workstations. The\n" + "Trinity Desktop Environment combines ease of use, contemporary functionality, and\n" + "professional graphical design along with the technical advantages of\n" + "UNIX-like operating systems." ) ) + .arg( i18n( "What is the Trinity Desktop Environment?" ) ) + .arg( i18n( "Contacting the TDE Project Members" ) ) + .arg( i18n( "Supporting the TDE Project" ) ) + .arg( i18n( "Useful links" ) ) + .arg( i18n( "Getting the most out of TDE" ) ) + .arg( i18n( "General Documentation" ) ) + .arg( i18n( "A Quick Start Guide to the Desktop" ) ) + .arg( i18n( "TDE Users' guide" ) ) + .arg( i18n( "Frequently Asked Questions" ) ) + .arg( i18n( "Basic Applications" ) ) + .arg( i18n( "The Kicker Desktop Panel" ) ) + .arg( i18n( "The TDE Control Center" ) ) + .arg( i18n( "The Konqueror File manager and Web Browser" ) ) + .arg( langLookup( "khelpcenter/kdelogo2.png" ) ); + begin( KURL( "about:khelpcenter" ) ); + write( res ); + end(); + emit completed(); +} + +TQString View::langLookup( const TQString &fname ) +{ + TQStringList search; + + // assemble the local search paths + const TQStringList localDoc = TDEGlobal::dirs()->resourceDirs("html"); + + // look up the different languages + for (int id=localDoc.count()-1; id >= 0; --id) + { + TQStringList langs = TDEGlobal::locale()->languageList(); + langs.append( "en" ); + langs.remove( "C" ); + TQStringList::ConstIterator lang; + for (lang = langs.begin(); lang != langs.end(); ++lang) + search.append(TQString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname)); + } + + // try to locate the file + TQStringList::Iterator it; + for (it = search.begin(); it != search.end(); ++it) + { + TQFileInfo info(*it); + if (info.exists() && info.isFile() && info.isReadable()) + return *it; + + // Fall back to the index.docbook for this language if we couldn't find its + // specific docbook file. If we are not looking up docbook (images, + // css etc) then look in other languages first. + if ( ( *it ).endsWith( "docbook" ) ) + { + TQString file = (*it).left((*it).findRev('/')) + "/index.docbook"; + info.setFile(file); + if (info.exists() && info.isFile() && info.isReadable()) + { + return *it; + } + } + } + + return TQString::null; +} + +void View::setTitle( const TQString &title ) +{ + mTitle = title; +} + +void View::beginSearchResult() +{ + mState = Search; + + begin(); + mSearchResult = ""; +} + +void View::writeSearchResult( const TQString &str ) +{ + write( str ); + mSearchResult += str; +} + +void View::endSearchResult() +{ + end(); + if ( !mSearchResult.isEmpty() ) emit searchResultCacheAvailable(); +} + +void View::beginInternal( const KURL &url ) +{ + mInternalUrl = url; + begin(); +} + +KURL View::internalUrl() const +{ + return mInternalUrl; +} + +void View::lastSearch() +{ + if ( mSearchResult.isEmpty() ) return; + + mState = Search; + + begin(); + write( mSearchResult ); + end(); +} + +void View::slotIncFontSizes() +{ + setZoomFactor( zoomFactor() + m_zoomStepping ); +} + +void View::slotDecFontSizes() +{ + setZoomFactor( zoomFactor() - m_zoomStepping ); +} + +void View::showMenu( const TQString& url, const TQPoint& pos) +{ + TDEPopupMenu* pop = new TDEPopupMenu(view()); + if (url.isEmpty()) + { + TDEAction *action; + action = mActionCollection->action("go_home"); + if (action) action->plug(pop); + + pop->insertSeparator(); + + action = mActionCollection->action("prevPage"); + if (action) action->plug(pop); + action = mActionCollection->action("nextPage"); + if (action) action->plug(pop); + + pop->insertSeparator(); + + History::self().m_backAction->plug(pop); + History::self().m_forwardAction->plug(pop); + } + else + { + pop->insertItem(i18n("Copy Link Address"), this, TQT_SLOT(slotCopyLink())); + mCopyURL = completeURL(url).url(); + } + + pop->exec(pos); + delete pop; +} + +void View::slotCopyLink() +{ + TQApplication::clipboard()->setText(mCopyURL); +} + +bool View::prevPage(bool checkOnly) +{ + const DOM::HTMLCollection links = htmlDocument().links(); + + // The first link on a page (top-left corner) would be the Prev link. + const DOM::Node prevLinkNode = links.item( 0 ); + KURL prevURL = urlFromLinkNode( prevLinkNode ); + if (!prevURL.isValid()) + return false; + + if (!checkOnly) + openURL( prevURL ); + return true; +} + +bool View::nextPage(bool checkOnly) +{ + const DOM::HTMLCollection links = htmlDocument().links(); + + KURL nextURL; + + // If we're on the first page, the "Next" link is the last link + if ( baseURL().path().endsWith( "/index.html" ) ) + nextURL = urlFromLinkNode( links.item( links.length() - 1 ) ); + else + nextURL = urlFromLinkNode( links.item( links.length() - 2 ) ); + + if (!nextURL.isValid()) + return false; + + // If we get a mail link instead of a http URL, or the next link points + // to an index.html page (a index.html page is always the first page + // there can't be a Next link pointing to it!) there's probably nowhere + // to go. Next link at all. + if ( nextURL.protocol() == "mailto" || + nextURL.path().endsWith( "/index.html" ) ) + return false; + + if (!checkOnly) + openURL( nextURL ); + return true; +} + +bool View::eventFilter( TQObject *o, TQEvent *e ) +{ + if ( e->type() != TQEvent::KeyPress || + htmlDocument().links().length() == 0 ) + return TDEHTMLPart::eventFilter( o, e ); + + TQKeyEvent *ke = TQT_TQKEYEVENT( e ); + if ( ke->state() & TQt::ShiftButton && ke->key() == Key_Space ) { + // If we're on the first page, it does not make sense to go back. + if ( baseURL().path().endsWith( "/index.html" ) ) + return TDEHTMLPart::eventFilter( o, e ); + + const TQScrollBar * const scrollBar = view()->verticalScrollBar(); + if ( scrollBar->value() == scrollBar->minValue() ) { + if (prevPage()) + return true; + } + } else if ( ke->key() == Key_Space ) { + const TQScrollBar * const scrollBar = view()->verticalScrollBar(); + if ( scrollBar->value() == scrollBar->maxValue() ) { + if (nextPage()) + return true; + } + } + return TDEHTMLPart::eventFilter( o, e ); +} + +KURL View::urlFromLinkNode( const DOM::Node &n ) const +{ + if ( n.isNull() || n.nodeType() != DOM::Node::ELEMENT_NODE ) + return KURL(); + + DOM::Element elem = static_cast<DOM::Element>( n ); + + KURL href ( elem.getAttribute( "href" ).string() ); + if ( !href.protocol().isNull() ) + return href; + + TQString path = baseURL().path(); + path.truncate( path.findRev( '/' ) + 1 ); + path += href.url(); + + KURL url = baseURL(); + url.setRef( TQString::null ); + url.setEncodedPathAndQuery( path ); + + return url; +} + +void View::slotReload( const KURL &url ) +{ + const_cast<TDEHTMLSettings *>( settings() )->init( kapp->config() ); + KParts::URLArgs args = browserExtension()->urlArgs(); + args.reload = true; + browserExtension()->setURLArgs( args ); + if ( url.isEmpty() ) + openURL( baseURL() ); + else + openURL( url ); +} + +#include "view.moc" +// vim:ts=2:sw=2:et diff --git a/khelpcenter/view.h b/khelpcenter/view.h new file mode 100644 index 000000000..2ad17af6b --- /dev/null +++ b/khelpcenter/view.h @@ -0,0 +1,94 @@ +#ifndef __view_h__ +#define __view_h__ + +#include <tdehtml_part.h> + +#include "glossary.h" +#include "navigator.h" + +class TDEActionCollection; + +namespace DOM { + class Node; +} + +namespace KHC { + +class Formatter; + +class View : public TDEHTMLPart +{ + Q_OBJECT + public: + View( TQWidget *parentWidget, const char *widgetName, + TQObject *parent, const char *name, TDEHTMLPart::GUIProfile prof, + TDEActionCollection *col ); + + ~View(); + + virtual bool openURL( const KURL &url ); + + virtual void saveState( TQDataStream &stream ); + virtual void restoreState( TQDataStream &stream ); + + enum State { Docu, About, Search }; + + int state() const { return mState; } + TQString title() const { return mTitle; } + + static TQString langLookup( const TQString &fname ); + + void beginSearchResult(); + void writeSearchResult( const TQString & ); + void endSearchResult(); + + void beginInternal( const KURL & ); + KURL internalUrl() const; + + int zoomStepping() const { return m_zoomStepping; } + + Formatter *formatter() const { return mFormatter; } + + void copySelectedText(); + + public slots: + void lastSearch(); + void slotIncFontSizes(); + void slotDecFontSizes(); + void slotReload( const KURL &url = KURL() ); + void slotCopyLink(); + bool nextPage(bool checkOnly = false); + bool prevPage(bool checkOnly = false); + + signals: + void searchResultCacheAvailable(); + + protected: + bool eventFilter( TQObject *o, TQEvent *e ); + + private slots: + void setTitle( const TQString &title ); + void showMenu( const TQString& url, const TQPoint& pos); + + private: + void showAboutPage(); + KURL urlFromLinkNode( const DOM::Node &n ) const; + + int mState; + TQString mTitle; + + TQString mSearchResult; + KURL mInternalUrl; + + int m_zoomStepping; + + Formatter *mFormatter; + TDEActionCollection *mActionCollection; + TQString mCopyURL; +}; + +} + +#endif + +// vim:ts=2:sw=2:et |