Index: trunk/tools/assistant/LICENSE.GPL
===================================================================
--- trunk/tools/assistant/LICENSE.GPL	(revision 191)
+++ trunk/tools/assistant/LICENSE.GPL	(revision 191)
@@ -0,0 +1,284 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          51 Franklin Steet, 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
Index: trunk/tools/assistant/assistant.pro
===================================================================
--- trunk/tools/assistant/assistant.pro	(revision 191)
+++ trunk/tools/assistant/assistant.pro	(revision 191)
@@ -0,0 +1,73 @@
+TEMPLATE = app
+LANGUAGE = C++
+TARGET	 = assistant
+
+CONFIG	+= qt warn_off
+
+PROJECTNAME	= Assistant
+DESTDIR		= ../../bin
+
+SOURCES	+= main.cpp \
+	helpwindow.cpp \
+	topicchooserimpl.cpp \
+	docuparser.cpp \
+	helpdialogimpl.cpp \
+	settingsdialogimpl.cpp \
+	index.cpp \
+        profile.cpp \
+        config.cpp 
+
+HEADERS	+= helpwindow.h \
+	topicchooserimpl.h \
+	docuparser.h \
+	helpdialogimpl.h \
+	settingsdialogimpl.h \
+	index.h \
+        profile.h \
+        config.h
+
+#DEFINES +=  QT_PALMTOPCENTER_DOCS
+DEFINES	+= QT_INTERNAL_NETWORK QT_INTERNAL_XML
+include( ../../src/qt_professional.pri )
+
+win32:RC_FILE = assistant.rc
+mac:RC_FILE = assistant.icns
+os2:RC_FILE = assistant_os2.rc
+
+target.path = $$bins.path
+INSTALLS += target
+
+assistanttranslations.files = *.qm
+assistanttranslations.path = $$translations.path
+INSTALLS += assistanttranslations
+
+TRANSLATIONS	= assistant_de.ts \
+		  assistant_fr.ts
+
+unix:!zlib:LIBS	+= -lz
+
+FORMS	= mainwindow.ui \
+	topicchooser.ui \
+	finddialog.ui \
+	helpdialog.ui \
+	settingsdialog.ui \
+	tabbedbrowser.ui
+IMAGES	= images/editcopy.png \
+	images/find.png \
+	images/home.png \
+	images/next.png \
+	images/previous.png \
+	images/print.png \
+	images/whatsthis.xpm \
+	images/book.png \
+	images/designer.png \
+	images/assistant.png \
+	images/linguist.png \
+	images/qt.png \
+	images/zoomin.png \
+	images/zoomout.png \
+	images/splash.png \
+	images/appicon.png \
+	images/addtab.png \
+	images/closetab.png \
+	images/d_closetab.png
Index: trunk/tools/assistant/assistant.rc
===================================================================
--- trunk/tools/assistant/assistant.rc	(revision 191)
+++ trunk/tools/assistant/assistant.rc	(revision 191)
@@ -0,0 +1,1 @@
+IDI_ICON1		ICON		DISCARDABLE	"assistant.ico"
Index: trunk/tools/assistant/assistant_de.ts
===================================================================
--- trunk/tools/assistant/assistant_de.ts	(revision 191)
+++ trunk/tools/assistant/assistant_de.ts	(revision 191)
@@ -0,0 +1,1084 @@
+<!DOCTYPE TS><TS>
+<context>
+    <name>Assistant</name>
+    <message>
+        <source>Welcome to the &lt;b&gt;Qt Assistant&lt;/b&gt;. Qt Assistant will give you quicker access to help and tips while using applications like Qt Designer.</source>
+        <translation type="obsolete">Wilkommen bei &lt;b&gt;Qt Assistant&lt;/b&gt;. Qt Assistant ermÃ¶glicht einen schnellen Zugriff der Onlinehilfe wÃ€hrend dem Arbeiten mit Programmen wie dem Qt Designer.</translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation type="obsolete">Qt Assistant</translation>
+    </message>
+</context>
+<context>
+    <name>AssistantServer</name>
+    <message>
+        <source>Qt Assistant</source>
+        <translation>Qt Assistant</translation>
+    </message>
+    <message>
+        <source>Failed to bind to port %1</source>
+        <translation>Kann Port %1 nicht binden</translation>
+    </message>
+</context>
+<context>
+    <name>FindDialog</name>
+    <message>
+        <source>Find Text</source>
+        <translation type="obsolete">Textsuche</translation>
+    </message>
+    <message>
+        <source>&amp;Find:</source>
+        <translation type="obsolete">&amp;Suchen:</translation>
+    </message>
+    <message>
+        <source>&amp;Find</source>
+        <translation>&amp;Suchen</translation>
+    </message>
+    <message>
+        <source>Close</source>
+        <translation type="obsolete">SchlieÃen</translation>
+    </message>
+    <message>
+        <source>&amp;Direction</source>
+        <translation>Rich&amp;tung</translation>
+    </message>
+    <message>
+        <source>Forwar&amp;d</source>
+        <translation type="obsolete">&amp;VorwÃ€rts</translation>
+    </message>
+    <message>
+        <source>&amp;Backward</source>
+        <translation>&amp;RÃŒckwÃ€rts</translation>
+    </message>
+    <message>
+        <source>&amp;Options</source>
+        <translation>&amp;Optionen</translation>
+    </message>
+    <message>
+        <source>&amp;Whole words only</source>
+        <translation>&amp;Ganze WÃ¶rter</translation>
+    </message>
+    <message>
+        <source>&amp;Case sensitive</source>
+        <translation>GroÃ- und &amp;Kleinschreibung beachten</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Find Text</source>
+        <translation>Qt Assistant - Textsuche</translation>
+    </message>
+    <message>
+        <source>Enter the text you are looking for.</source>
+        <translation>Geben Sie den Suchtext ein.</translation>
+    </message>
+    <message>
+        <source>Search reached end of the document</source>
+        <translation>Die Suche hat das Ende des Dokuments erreicht</translation>
+    </message>
+    <message>
+        <source>Search reached start of the document</source>
+        <translation>Die Suche hat den Anfang des Dokuments erreicht</translation>
+    </message>
+    <message>
+        <source>Text not found</source>
+        <translation>Text nicht gefunden</translation>
+    </message>
+    <message>
+        <source>Fo&amp;rward</source>
+        <translation>Vo&amp;rwÃ€rts</translation>
+    </message>
+    <message>
+        <source>F&amp;ind:</source>
+        <translation>Su&amp;chen:</translation>
+    </message>
+    <message>
+        <source>C&amp;lose</source>
+        <translation>Sch&amp;lieÃen</translation>
+    </message>
+    <message>
+        <source>Alt+L</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Alt+F</source>
+        <translation></translation>
+    </message>
+</context>
+<context>
+    <name>HelpDialog</name>
+    <message>
+        <source>Index</source>
+        <translation>Index</translation>
+    </message>
+    <message>
+        <source>Bookmarks</source>
+        <translation>Lesezeichen</translation>
+    </message>
+    <message>
+        <source>Con&amp;tents</source>
+        <translation type="obsolete">Inhal&amp;t</translation>
+    </message>
+    <message>
+        <source>Qt Reference Documentation</source>
+        <translation type="obsolete">Qt Referenzdokumentation</translation>
+    </message>
+    <message>
+        <source>Qt Designer Manual</source>
+        <translation type="obsolete">Qt Designer Handbuch</translation>
+    </message>
+    <message>
+        <source>Qt Linguist Manual</source>
+        <translation type="obsolete">Qt Linguist Handbuch</translation>
+    </message>
+    <message>
+        <source>Qt Assistant Manual</source>
+        <translation type="obsolete">Qt Assistant Handbuch</translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation>Qt Assistant</translation>
+    </message>
+    <message>
+        <source>Open Link in Current Window</source>
+        <translation type="obsolete">Ãffne Link im aktuellen Fenster</translation>
+    </message>
+    <message>
+        <source>Open Link in New Window</source>
+        <translation>Ãffne Link in neuem Fenster</translation>
+    </message>
+    <message>
+        <source>Contents</source>
+        <translation>Inhalt</translation>
+    </message>
+    <message>
+        <source>Search</source>
+        <translation>Suche</translation>
+    </message>
+    <message>
+        <source>Prepare...</source>
+        <translation>Initialisiere...</translation>
+    </message>
+    <message>
+        <source>Cannot open the index file %1</source>
+        <translation>Kann Indexdatei %1 nicht Ã¶ffnen</translation>
+    </message>
+    <message>
+        <source>Warning</source>
+        <translation>Warnung</translation>
+    </message>
+    <message>
+        <source>Documentation file %1 does not exist!
+Skipping file.</source>
+        <translation>Dokumentation %1 existiert nicht!
+Ãberspringe Datei.</translation>
+    </message>
+    <message>
+        <source>Parse Error</source>
+        <translation>Syntaxfehler</translation>
+    </message>
+    <message>
+        <source>Done</source>
+        <translation>Fertig</translation>
+    </message>
+    <message>
+        <source>Indexing files...</source>
+        <translation>Indiziere Dokumentation...</translation>
+    </message>
+    <message>
+        <source>Reading dictionary...</source>
+        <translation>Lese Suchindex...</translation>
+    </message>
+    <message>
+        <source>Full Text Search</source>
+        <translation>Volltextsuche</translation>
+    </message>
+    <message>
+        <source>Using a wildcard within phrases is not allowed.</source>
+        <translation>Wildcards innerhalb von Phrasen sind nicht zugelassen.</translation>
+    </message>
+    <message>
+        <source>The closing quotation mark is missing.</source>
+        <translation>Das schlieÃende AnfÃŒhrungszeichen fehlt.</translation>
+    </message>
+    <message>
+        <source>Open Link in Current Tab</source>
+        <translation>Link im Aktuellen Tab Ã¶ffnen</translation>
+    </message>
+    <message>
+        <source>Open Link in New Tab</source>
+        <translation>Link in einem neuen Tab Ã¶ffnen</translation>
+    </message>
+    <message>
+        <source>Failed to load keyword index file
+Assistant will not work!</source>
+        <translation>Die Indexdatei konnte nicht geladen werden.
+Der Assistent ist nicht einsatzbereit!</translation>
+    </message>
+    <message>
+        <source>Documentation file %1 is not compatible!
+Skipping file.</source>
+        <translation>Dokumentation %1 ist nicht kompatibel! Datei wird ÃŒbersprungen.</translation>
+    </message>
+    <message>
+        <source>Failed to save fulltext search index
+Assistant will not work!</source>
+        <translation>Der Index fÃŒr die Volltextsuche konnte nicht gespeichert werden.
+Der Assistent ist nicht einsatzbereit!</translation>
+    </message>
+</context>
+<context>
+    <name>HelpDialogBase</name>
+    <message>
+        <source>Help</source>
+        <translation>Hilfe</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Help&lt;/b&gt;&lt;p&gt;Choose the topic you need help for from the contents list, or search the index for keywords.&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;b&gt;Hilfe&lt;/b&gt;&lt;p&gt;WÃ€hlen Sie ein Thema vom Inhaltsverzeichnis oder suchen Sie im Index nach SchlÃŒsselwÃ¶rtern.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>Displays help topics organized by category, index or bookmarks</source>
+        <translation type="obsolete">Zeigt die Hilfethemen unterteilt in Kategorien, Indizes oder Lesezeichen an</translation>
+    </message>
+    <message>
+        <source>Con&amp;tents</source>
+        <translation>Inhal&amp;t</translation>
+    </message>
+    <message>
+        <source>Column 1</source>
+        <translation>Spalte 1</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Help topics organized by category.&lt;/b&gt;&lt;p&gt;Double-click an item to see which topics are in that category. To view a topic, select it, and then click &lt;b&gt;Display&lt;/b&gt;.&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;b&gt;Die Hilfethemen sind nach Kategorien organisiert.&lt;/b&gt;&lt;p&gt;Ein Doppelklick auf einen Eintrag zeigt die Themen dieser Kategorie an. Um ein Thema anzuzeigen, wÃ€hlen Sie es aus und drÃŒcken Sie &lt;b&gt;Anzeigen&lt;/b&gt;.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&amp;Index</source>
+        <translation>&amp;Index</translation>
+    </message>
+    <message>
+        <source>&amp;Look For:</source>
+        <translation>Suchen &amp;nach:</translation>
+    </message>
+    <message>
+        <source>Enter keyword</source>
+        <translation>Geben Sie ein SchlÃŒsselwort ein</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Enter a keyword.&lt;/b&gt;&lt;p&gt;The list will select an item that matches the entered string best.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Geben Sie ein SchlÃŒsselwort ein.&lt;/b&gt;&lt;p&gt;Es wird dann der Eintrag aus der Liste ausgewÃ€hlt, der am besten mit dem eingegebenen Begriff ÃŒbereinstimmt.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;List of available help topics.&lt;/b&gt;&lt;p&gt;Double-click on an item to open up the help page for this topic. You will have to choose the right page if more than one are found.&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;b&gt;Liste aller verfÃŒgbaren Hilfethemen.&lt;/b&gt;&lt;p&gt;Ein Doppelklick auf einen Eintrag Ã¶ffnet die dazugehÃ¶rige Hilfeseite. Wenn es mehrere Seiten zu einem Eintrag gibt, wÃ€hlen Sie die gewÃŒnschte aus.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&amp;Bookmarks</source>
+        <translation>L&amp;esezeichen</translation>
+    </message>
+    <message>
+        <source>Displays the list of bookmarks.</source>
+        <translation>Zeigt alle Lesezeichen an.</translation>
+    </message>
+    <message>
+        <source>&amp;New Bookmark</source>
+        <translation type="obsolete">&amp;Neues Lesezeichen</translation>
+    </message>
+    <message>
+        <source>Add new bookmark</source>
+        <translation>FÃŒge neues Lesezeichen hinzu</translation>
+    </message>
+    <message>
+        <source>Add the current displayed page as new bookmark to the list.</source>
+        <translation type="obsolete">FÃŒge die aktuelle Seite als Lesezeichen hinzu.</translation>
+    </message>
+    <message>
+        <source>D&amp;elete Bookmark</source>
+        <translation type="obsolete">&amp;LÃ¶sche Lesezeichen</translation>
+    </message>
+    <message>
+        <source>Delete bookmark</source>
+        <translation>LÃ¶sche Lesezeichen</translation>
+    </message>
+    <message>
+        <source>Delete the selected bookmark from the list.</source>
+        <translation type="obsolete">LÃ¶sche markiertes Lesezeichen.</translation>
+    </message>
+    <message>
+        <source>Preparing...</source>
+        <translation>Initialisiere...</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Help&lt;/b&gt;&lt;p&gt;Choose the topic you want help on from the contents list, or search the index for keywords.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Hilfe&lt;/b&gt;&lt;p&gt;WÃ€hlen Sie ein Hilfethema aus dem Inhalt oder suchen Sie im Index nach SchlÃŒsselwÃ¶rtern.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</source>
+        <translation>Zeigt Hilfethemen geordnet nach Kategorie, Index oder Lesezeichen an. Ein weiterer Abschnitt enthÃ€lt die Volltextsuche.</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Help topics organized by category.&lt;/b&gt;&lt;p&gt;Double-click an item to see the topics in that category. To view a topic, just double-click it.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Hilfethemen geordnet nach Kategorie.&lt;/b&gt;&lt;p&gt;Doppelklicken Sie einen Eintrag, um die Themen dieser Kategorie zu sehen. Doppelklicken Sie ein Thema, um es angezeigt zu bekommen.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;List of available help topics.&lt;/b&gt;&lt;p&gt;Double-click on an item to open its help page. If more than one is found, you must specify which page you want.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Liste aller verfÃŒgbaren Hilfethemen.&lt;/b&gt;&lt;p&gt;Doppelklicken Sie auf einen Eintrag, um die Hilfe zu Ã¶ffnen. Wenn mehr als eine Seite gefunden wurde, wÃ€hlen Sie die gewÃŒnschte Seite aus.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&amp;New</source>
+        <translation>&amp;Neu</translation>
+    </message>
+    <message>
+        <source>Add the currently displayed page as a new bookmark.</source>
+        <translation>FÃŒge aktuelle Seite zu den Lesezeichen hinzu.</translation>
+    </message>
+    <message>
+        <source>&amp;Delete</source>
+        <translation>&amp;LÃ¶schen</translation>
+    </message>
+    <message>
+        <source>Delete the selected bookmark.</source>
+        <translation>LÃ¶sche markiertes Lesezeichen.</translation>
+    </message>
+    <message>
+        <source>&amp;Search</source>
+        <translation>&amp;Suche</translation>
+    </message>
+    <message>
+        <source>Searching f&amp;or:</source>
+        <translation>Suche &amp;nach:</translation>
+    </message>
+    <message>
+        <source>Enter searchword(s).</source>
+        <translation>Suchebegriff(e).</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Enter search word(s).&lt;/b&gt;&lt;p&gt;Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Geben Sie Suchbegriffe ein.&lt;/b&gt;&lt;p&gt;Geben Sie hier die gesuchten Begriffe ein. Die Begriffe kÃ¶nnen Wildcards (*) enthalten. Eine Phrase muÃ in AnfÃŒhrungszeichen stehen.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;Found documents&lt;/b&gt;&lt;p&gt;This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.&lt;/p&gt;</source>
+        <translation>&lt;b&gt;Gefundene Dokumente&lt;/b&gt;&lt;p&gt;Diese Liste beinhaltet alle gefundenen Dokumente der letzten Suche. Die Dokumente sind nach der HÃ€ufigkeit der Treffer geordnet.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>Found &amp;Documents:</source>
+        <translation>Gefundene &amp;Dokumente:</translation>
+    </message>
+    <message>
+        <source>He&amp;lp</source>
+        <translation>Hi&amp;lfe</translation>
+    </message>
+    <message>
+        <source>Display the help page.</source>
+        <translation>Zeigt die Hilfe an.</translation>
+    </message>
+    <message>
+        <source>Display the help page for the full text search.</source>
+        <translation>Zeigt die Hilfeseite fÃŒr die Volltextsuche an.</translation>
+    </message>
+    <message>
+        <source>Start searching.</source>
+        <translation>Starte Suche.</translation>
+    </message>
+    <message>
+        <source>Pressing this button starts the search.</source>
+        <translation>Startet die Suche.</translation>
+    </message>
+</context>
+<context>
+    <name>HelpWindow</name>
+    <message>
+        <source>Qt Assistant by Trolltech - %1</source>
+        <translation type="obsolete">Qt Assistant von Trolltech - %1</translation>
+    </message>
+    <message>
+        <source>Help</source>
+        <translation>Hilfe</translation>
+    </message>
+    <message>
+        <source>Can&apos;t load and display non-local file
+%1</source>
+        <translation>Kann gewÃŒnschte Datei nicht laden:
+%1</translation>
+    </message>
+    <message>
+        <source>Open Link in New Window<byte value="x9"/>Shift+LMB</source>
+        <translation>Ãffne Link in neuem Fenster</translation>
+    </message>
+    <message>
+        <source>Currently no Web browser is selected.
+Please use the settings dialog to specify one!
+</source>
+        <translation>Es ist kein Webbrowser ausgewÃ€hlt.
+Ãffnen Sie bitten den &quot;Einstellungen&quot; Dialog um einen Webbrowser auszuwÃ€hlen.
+</translation>
+    </message>
+    <message>
+        <source>Qt Assistant by Trolltech - %1%2</source>
+        <translation type="obsolete">Qt Assistant von Trolltech - %1%2</translation>
+    </message>
+    <message>
+        <source>No PDF Viewer has been specified
+Please use the settings dialog to specify one!
+</source>
+        <translation>Es wurde kein PDF Betrachter angegeben.
+Bitte diesen im Menue Einstellungen festlegen!
+</translation>
+    </message>
+    <message>
+        <source>Qt Assistant is unable to start the PDF Viewer
+
+%1
+
+Please make sure that the executable exists and is located at
+the specified location.</source>
+        <translation>Der Qt Assistent konnte den PDF betrachter
+%1 nicht laden.
+Bitte ÃŒberprÃŒfen Sie, das dieser an der angegeben Stelle existiert.</translation>
+    </message>
+    <message>
+        <source>Open Link in New Tab</source>
+        <translation>Link in einenm neuen Tab Ã¶ffnen</translation>
+    </message>
+</context>
+<context>
+    <name>Index</name>
+    <message>
+        <source>Untitled</source>
+        <translation>Unbenannt</translation>
+    </message>
+</context>
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Qt Assistant by Trolltech</source>
+        <translation>Qt Assistant von Trolltech</translation>
+    </message>
+    <message>
+        <source>Toolbar</source>
+        <translation>Werkzeugleiste</translation>
+    </message>
+    <message>
+        <source>Print</source>
+        <translation>Drucken</translation>
+    </message>
+    <message>
+        <source>&amp;Print...</source>
+        <translation>&amp;Drucken...</translation>
+    </message>
+    <message>
+        <source>Exit</source>
+        <translation>Beenden</translation>
+    </message>
+    <message>
+        <source>E&amp;xit</source>
+        <translation>&amp;Beenden</translation>
+    </message>
+    <message>
+        <source>Copy</source>
+        <translation>Kopieren</translation>
+    </message>
+    <message>
+        <source>&amp;Copy</source>
+        <translation>&amp;Kopieren</translation>
+    </message>
+    <message>
+        <source>Find in Text</source>
+        <translation>Textsuche</translation>
+    </message>
+    <message>
+        <source>&amp;Find in Text...</source>
+        <translation>Text&amp;suche...</translation>
+    </message>
+    <message>
+        <source>Home</source>
+        <translation>Startseite</translation>
+    </message>
+    <message>
+        <source>&amp;Home</source>
+        <translation>St&amp;artseite</translation>
+    </message>
+    <message>
+        <source>Previous</source>
+        <translation>Vorherige</translation>
+    </message>
+    <message>
+        <source>&amp;Previous</source>
+        <translation>&amp;Vorherige</translation>
+    </message>
+    <message>
+        <source>Next</source>
+        <translation>NÃ€chste</translation>
+    </message>
+    <message>
+        <source>&amp;Next</source>
+        <translation>&amp;NÃ€chste</translation>
+    </message>
+    <message>
+        <source>About</source>
+        <translation type="obsolete">Ãber</translation>
+    </message>
+    <message>
+        <source>About Qt</source>
+        <translation type="obsolete">Ãber Qt</translation>
+    </message>
+    <message>
+        <source>Qt Class Reference</source>
+        <translation type="obsolete">Qt Klassenreferenz</translation>
+    </message>
+    <message>
+        <source>Qt Designer Manual</source>
+        <translation type="obsolete">Qt Designer Handbuch</translation>
+    </message>
+    <message>
+        <source>Zoom in</source>
+        <translation>VergrÃ¶Ãern</translation>
+    </message>
+    <message>
+        <source>Zoom &amp;in</source>
+        <translation>Ver&amp;grÃ¶Ãern</translation>
+    </message>
+    <message>
+        <source>Zoom out</source>
+        <translation>Verkleinern</translation>
+    </message>
+    <message>
+        <source>Zoom &amp;out</source>
+        <translation>Ver&amp;kleinern</translation>
+    </message>
+    <message>
+        <source>Qt Linguist Manual</source>
+        <translation type="obsolete">Qt Linguist Handbuch</translation>
+    </message>
+    <message>
+        <source>&amp;Settings</source>
+        <translation type="obsolete">&amp;Einstellungen</translation>
+    </message>
+    <message>
+        <source>&amp;Settings...</source>
+        <translation>&amp;Einstellungen...</translation>
+    </message>
+    <message>
+        <source>New Window</source>
+        <translation>Neues Fenster</translation>
+    </message>
+    <message>
+        <source>New Window...</source>
+        <translation type="obsolete">Neues Fenster...</translation>
+    </message>
+    <message>
+        <source>Close</source>
+        <translation>SchlieÃen</translation>
+    </message>
+    <message>
+        <source>Vie&amp;ws</source>
+        <translation>A&amp;nsicht</translation>
+    </message>
+    <message>
+        <source>Ctrl+T</source>
+        <translation>Strg+T
+</translation>
+    </message>
+    <message>
+        <source>Ctrl+I</source>
+        <translation>Strg+I</translation>
+    </message>
+    <message>
+        <source>Ctrl+B</source>
+        <translation>Strg+E</translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation>Qt Assistant</translation>
+    </message>
+    <message>
+        <source>&amp;Add Bookmark</source>
+        <translation>&amp;FÃŒge Lesezeichen hinzu</translation>
+    </message>
+    <message>
+        <source>Qt Reference Documentation</source>
+        <translation type="obsolete">Qt Referenzdokumention</translation>
+    </message>
+    <message>
+        <source>&amp;File</source>
+        <translation>&amp;Datei</translation>
+    </message>
+    <message>
+        <source>&amp;Edit</source>
+        <translation>&amp;Bearbeiten</translation>
+    </message>
+    <message>
+        <source>&amp;View</source>
+        <translation>&amp;Ansicht</translation>
+    </message>
+    <message>
+        <source>&amp;Go</source>
+        <translation>&amp;Gehe zu</translation>
+    </message>
+    <message>
+        <source>Boo&amp;kmarks</source>
+        <translation>&amp;Lesezeichen</translation>
+    </message>
+    <message>
+        <source>&amp;Help</source>
+        <translation>&amp;Hilfe</translation>
+    </message>
+    <message>
+        <source>Print the currently displayed page.</source>
+        <translation>Drucke aktuelle Seite.</translation>
+    </message>
+    <message>
+        <source>Ctrl+P</source>
+        <translation>Strg+P</translation>
+    </message>
+    <message>
+        <source>Quit Qt Assistant.</source>
+        <translation>Beende Qt Assistant.</translation>
+    </message>
+    <message>
+        <source>Ctrl+Q</source>
+        <translation>Strg+Q</translation>
+    </message>
+    <message>
+        <source>Copy the selected text to the clipboard.</source>
+        <translation>Kopiere den markierten Text in die Zwischenablage.</translation>
+    </message>
+    <message>
+        <source>Ctrl+C</source>
+        <translation>Strg+C</translation>
+    </message>
+    <message>
+        <source>Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter.</source>
+        <translation>Ãffne den Suchdialog. Qt Assistant sucht in der aktuellen Seite nach dem eingegebenen Text.</translation>
+    </message>
+    <message>
+        <source>Ctrl+F</source>
+        <translation>Strg+F</translation>
+    </message>
+    <message>
+        <source>Go to the home page. Qt Assistant&apos;s home page is the Qt Reference Documentation.</source>
+        <translation>Gehe zur Startseite. Qt Assistants Startseite ist die Qt Referenzdokumentation.</translation>
+    </message>
+    <message>
+        <source>Ctrl+Home</source>
+        <translation>Strg+Pos1</translation>
+    </message>
+    <message>
+        <source>Go to the previous page.</source>
+        <translation>Gehe zur vorherigen Seite.</translation>
+    </message>
+    <message>
+        <source>Alt+Left</source>
+        <translation>Alt+Links</translation>
+    </message>
+    <message>
+        <source>Go to the next page.</source>
+        <translation>Gehe zur nÃ€chsten Seite.</translation>
+    </message>
+    <message>
+        <source>Alt+Right</source>
+        <translation>Alt+Rechts</translation>
+    </message>
+    <message>
+        <source>Display further information about Qt Assistant.</source>
+        <translation>Zeigt weitere Informationen zu Qt Assistant an.</translation>
+    </message>
+    <message>
+        <source>Display further information about Qt.</source>
+        <translation type="obsolete">Zeigt weitere Informationen zu Qt an.</translation>
+    </message>
+    <message>
+        <source>Display the Qt Reference Documentation.</source>
+        <translation type="obsolete">Zeigt die Qt Referenzdokumentation an.</translation>
+    </message>
+    <message>
+        <source>Display the Qt Designer manual.</source>
+        <translation type="obsolete">Zeigt das Qt Designer Handbuch an.</translation>
+    </message>
+    <message>
+        <source>Zoom in on the document, i.e. increase the font size.</source>
+        <translation>VergrÃ¶Ãert die Schrift.</translation>
+    </message>
+    <message>
+        <source>Ctrl++</source>
+        <translation>Strg++</translation>
+    </message>
+    <message>
+        <source>Zoom out on the document, i.e. decrease the font size.</source>
+        <translation>Verkleinert die Schrift.</translation>
+    </message>
+    <message>
+        <source>Ctrl+-</source>
+        <translation>Strg+-</translation>
+    </message>
+    <message>
+        <source>Display the Guide to the Qt Translation Tools.</source>
+        <translation type="obsolete">Zeigt die Anleitung zu den Qt Ãbersetzungswerkzeugen an.</translation>
+    </message>
+    <message>
+        <source>Open the settings dialog.</source>
+        <translation>Ãffnet den &quot;Einstellungen&quot; Dialog.</translation>
+    </message>
+    <message>
+        <source>Open a new window.</source>
+        <translation>Ãffnet ein neues Fenster.</translation>
+    </message>
+    <message>
+        <source>Ctrl+N</source>
+        <translation>Strg+N</translation>
+    </message>
+    <message>
+        <source>&amp;Close</source>
+        <translation>&amp;SchlieÃen</translation>
+    </message>
+    <message>
+        <source>Close the current window.</source>
+        <translation>SchlieÃt das aktuelle Fenster.</translation>
+    </message>
+    <message>
+        <source>Qt Assistant Manual</source>
+        <translation>Qt Assistant Handbuch</translation>
+    </message>
+    <message>
+        <source>Display the Qt Assistant manual.</source>
+        <translation type="obsolete">Zeigt das Qt Assistant Handbuch an.</translation>
+    </message>
+    <message>
+        <source>F1</source>
+        <translation>F1</translation>
+    </message>
+    <message>
+        <source>Add the currently displayed page as a new bookmark.</source>
+        <translation>FÃŒge aktuelle Seite zu den Lesezeichen hinzu.</translation>
+    </message>
+    <message>
+        <source>What&apos;s This?</source>
+        <translation>Direkthilfe</translation>
+    </message>
+    <message>
+        <source>&quot;What&apos;s This?&quot; context sensitive help.</source>
+        <translation>Kontextbezogene Direkthilfe.</translation>
+    </message>
+    <message>
+        <source>Shift+F1</source>
+        <translation>Umschalt+F1</translation>
+    </message>
+    <message>
+        <source>Ctrl+S</source>
+        <translation>Strg+S</translation>
+    </message>
+    <message>
+        <source>Initializing Qt Assistant...</source>
+        <translation>Initialisiere Qt Assistant...</translation>
+    </message>
+    <message>
+        <source>Go</source>
+        <translation>Gehe zu</translation>
+    </message>
+    <message>
+        <source>Find &amp;Next</source>
+        <translation>&amp;NÃ€chste finden</translation>
+    </message>
+    <message>
+        <source>Find Next</source>
+        <translation>NÃ€chste finden</translation>
+    </message>
+    <message>
+        <source>F3</source>
+        <translation>F3</translation>
+    </message>
+    <message>
+        <source>Find &amp;Previous</source>
+        <translation>&amp;Vorigen finden</translation>
+    </message>
+    <message>
+        <source>Find Previous</source>
+        <translation>Vorigen finden</translation>
+    </message>
+    <message>
+        <source>Shift+F3</source>
+        <translation>Umschalt+F3</translation>
+    </message>
+    <message>
+        <source>About Qt Assistant</source>
+        <translation>Ãber den Qt Assistent</translation>
+    </message>
+    <message>
+        <source>Settings</source>
+        <translation>Einstellungen</translation>
+    </message>
+    <message>
+        <source>Add Bookmark</source>
+        <translation>Lesezeichen einfÃŒgen</translation>
+    </message>
+    <message>
+        <source>Add Tab</source>
+        <translation>Tab einfÃŒgen</translation>
+    </message>
+    <message>
+        <source>Ctrl+Alt+N</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Next Tab</source>
+        <translation>NÃ€chster Tab</translation>
+    </message>
+    <message>
+        <source>Ctrl+Alt+Right</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Previous Tab</source>
+        <translation>Voriger Tab</translation>
+    </message>
+    <message>
+        <source>Ctrl+Alt+Left</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Close Tab</source>
+        <translation>Tab schlieÃen</translation>
+    </message>
+    <message>
+        <source>Ctrl+Alt+Q</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Failed to open about application contents in file: &apos;%1&apos;</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Failed to open link: &apos;%1&apos;</source>
+        <translation>Der Link &apos;%1&apos; konnte nicht geÃ¶ffnet werden</translation>
+    </message>
+    <message>
+        <source>&lt;div align=&quot;center&quot;&gt;&lt;h1&gt;The page could not be found!&lt;/h1&gt;&lt;br&gt;&lt;h3&gt;&apos;%1&apos;&lt;/h3&gt;&lt;/div&gt;</source>
+        <translation>&lt;div align=&quot;Hauptseite nicht gefunden!&lt;/h1&gt;</translation>
+    </message>
+    <message>
+        <source>Error...</source>
+        <translation>Fehler ...</translation>
+    </message>
+</context>
+<context>
+    <name>SettingsDialog</name>
+    <message>
+        <source>all</source>
+        <translation type="obsolete">Alle</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Add Documentation</source>
+        <translation type="obsolete">Qt Assistant - HinzufÃŒgen von Dokumentation</translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation type="obsolete">Qt Assistant</translation>
+    </message>
+    <message>
+        <source>Parse Error</source>
+        <translation type="obsolete">Syntaxfehler</translation>
+    </message>
+    <message>
+        <source>This item can not be deleted!</source>
+        <translation type="obsolete">Dieser Eintrag kann nicht gelÃ¶scht werden!</translation>
+    </message>
+    <message>
+        <source>This branch is not empty!
+Firstly, all contents have to be removed.</source>
+        <translation type="obsolete">Dieser Zweig ist nicht leer!
+Es mÃŒssen zuerst alle Inhalte gelÃ¶scht werden.</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Set Web Browser</source>
+        <translation>Qt Assistant - Setze Webbrowser</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Set PDF Browser</source>
+        <translation>Qt Assistent - Setze PDF Betrachter</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Set Homepage</source>
+        <translation>Qt Assistent - Setzte Startseite</translation>
+    </message>
+</context>
+<context>
+    <name>SettingsDialogBase</name>
+    <message>
+        <source>Settings</source>
+        <translation type="obsolete">Einstellungen</translation>
+    </message>
+    <message>
+        <source>Font:</source>
+        <translation type="obsolete">Schriften:</translation>
+    </message>
+    <message>
+        <source>Link color:</source>
+        <translation>Linkfarbe:</translation>
+    </message>
+    <message>
+        <source>Underline links</source>
+        <translation type="obsolete">Unterstreiche Links</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation type="obsolete">OK</translation>
+    </message>
+    <message>
+        <source>Cancel</source>
+        <translation type="obsolete">Abbrechen</translation>
+    </message>
+    <message>
+        <source>Fixed font:</source>
+        <translation type="obsolete">Nicht-proportionale Schrift:</translation>
+    </message>
+    <message>
+        <source>Qt Assistant - Settings</source>
+        <translation>Qt Assistant - Einstellungen</translation>
+    </message>
+    <message>
+        <source>General</source>
+        <translation type="obsolete">Allgemein</translation>
+    </message>
+    <message>
+        <source>Fix&amp;ed font:</source>
+        <translation>&amp;Nicht-proportionale Schrift:</translation>
+    </message>
+    <message>
+        <source>&amp;Font:</source>
+        <translation>&amp;Schrift:</translation>
+    </message>
+    <message>
+        <source>&amp;Underline links</source>
+        <translation>&amp;Unterstreiche Links</translation>
+    </message>
+    <message>
+        <source>Web</source>
+        <translation type="obsolete">Web</translation>
+    </message>
+    <message>
+        <source>&amp;Web Browser Application:</source>
+        <translation type="obsolete">&amp;Webbrowser Anwendung:</translation>
+    </message>
+    <message>
+        <source>...</source>
+        <translation>...</translation>
+    </message>
+    <message>
+        <source>Documentation</source>
+        <translation type="obsolete">Dokumentation</translation>
+    </message>
+    <message>
+        <source>&amp;Delete</source>
+        <translation type="obsolete">&amp;LÃ¶sche</translation>
+    </message>
+    <message>
+        <source>&amp;Add...</source>
+        <translation type="obsolete">&amp;HinzufÃŒgen...</translation>
+    </message>
+    <message>
+        <source>Categories</source>
+        <translation type="obsolete">Kategorien</translation>
+    </message>
+    <message>
+        <source>Category &amp;Name:</source>
+        <translation type="obsolete">Kategorie&amp;name:</translation>
+    </message>
+    <message>
+        <source>&amp;Add</source>
+        <translation type="obsolete">&amp;HinzufÃŒgen</translation>
+    </message>
+    <message>
+        <source>&amp;OK</source>
+        <translation>&amp;OK</translation>
+    </message>
+    <message>
+        <source>&amp;Cancel</source>
+        <translation>&amp;Abbrechen</translation>
+    </message>
+    <message>
+        <source>&amp;General</source>
+        <translation>&amp;Haupt</translation>
+    </message>
+    <message>
+        <source>&amp;Web</source>
+        <translation>&amp;Web</translation>
+    </message>
+    <message>
+        <source>Web &amp;Browser Application:</source>
+        <translation>Web&amp;browser:</translation>
+    </message>
+    <message>
+        <source>&amp;Home page</source>
+        <translation>&amp;Startseite</translation>
+    </message>
+    <message>
+        <source>&amp;PDF</source>
+        <translation>&amp;PDF</translation>
+    </message>
+    <message>
+        <source>PDF &amp;Application</source>
+        <translation>PDF &amp;Betrachter</translation>
+    </message>
+</context>
+<context>
+    <name>TabbedBrowser</name>
+    <message>
+        <source>TabbedBrowser</source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>Untitled</source>
+        <translation>Unbenannt</translation>
+    </message>
+    <message>
+        <source>Add page</source>
+        <translation>Seite einfÃŒgen</translation>
+    </message>
+    <message>
+        <source>Close page</source>
+        <translation>Seite schlieÃen</translation>
+    </message>
+</context>
+<context>
+    <name>TopicChooser</name>
+    <message>
+        <source>Choose a topic for &lt;b&gt;%1&lt;/b&gt;</source>
+        <translation>WÃ€hlen Sie ein Thema fÃŒr &lt;b&gt;%1&lt;/b&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>TopicChooserBase</name>
+    <message>
+        <source>Choose Topic</source>
+        <translation>Thema wÃ€hlen</translation>
+    </message>
+    <message>
+        <source>Select a topic from the list and click the &lt;b&gt;Display&lt;/b&gt;-button to open the online help.</source>
+        <translation>WÃ€hlen Sie ein Thema aus der Liste aus und klicken Sie &lt;b&gt;Anzeigen&lt;/b&gt; um die Hilfe zu Ã¶ffnen.</translation>
+    </message>
+    <message>
+        <source>&amp;Topics</source>
+        <translation>&amp;Themen</translation>
+    </message>
+    <message>
+        <source>Displays a list of available help topics for the keyword.</source>
+        <translation>Zeigt eine Liste der verfÃŒgbaren Hilfethemen fÃŒr diesen Begriff an.</translation>
+    </message>
+    <message>
+        <source>&amp;Display</source>
+        <translation>&amp;Anzeigen</translation>
+    </message>
+    <message>
+        <source>Open the topic selected in the list.</source>
+        <translation>Ãffne das gewÃ€hlte Thema aus der Liste.</translation>
+    </message>
+    <message>
+        <source>&amp;Close</source>
+        <translation>&amp;SchlieÃen</translation>
+    </message>
+    <message>
+        <source>Close the Dialog.</source>
+        <translation>SchlieÃt den Dialog.</translation>
+    </message>
+</context>
+</TS>
Index: trunk/tools/assistant/assistant_fr.ts
===================================================================
--- trunk/tools/assistant/assistant_fr.ts	(revision 191)
+++ trunk/tools/assistant/assistant_fr.ts	(revision 191)
@@ -0,0 +1,426 @@
+<!DOCTYPE TS><TS>
+<context>
+    <name>Assistant</name>
+    <message>
+        <source>Welcome to the &lt;b&gt;Qt Assistant&lt;/b&gt;. Qt Assistant will give you quicker access to help and tips while using applications like Qt Designer.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context encoding="UTF-8">
+    <name>FindDialog</name>
+    <message encoding="UTF-8">
+        <source>Find Text</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Find:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Find</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Close</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Direction</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Forwar&amp;d</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Backward</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Options</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Whole words only</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Case sensitive</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>HelpDialog</name>
+    <message>
+        <source>Index</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Bookmarks</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Con&amp;tents</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Reference Documentation</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Designer Manual</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Linguist Manual</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Assistant Manual</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context encoding="UTF-8">
+    <name>HelpDialogBase</name>
+    <message encoding="UTF-8">
+        <source>Help</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&lt;b&gt;Help&lt;/b&gt;&lt;p&gt;Choose the topic you need help for from the contents list, or search the index for keywords.&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Displays help topics organized by category, index or bookmarks</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Con&amp;tents</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Column 1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&lt;b&gt;Help topics organized by category.&lt;/b&gt;&lt;p&gt;Double-click an item to see which topics are in that category. To view a topic, select it, and then click &lt;b&gt;Display&lt;/b&gt;.&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Index</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Look For:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Enter keyword</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&lt;b&gt;Enter a keyword.&lt;/b&gt;&lt;p&gt;The list will select an item that matches the entered string best.&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&lt;b&gt;List of available help topics.&lt;/b&gt;&lt;p&gt;Double-click on an item to open up the help page for this topic. You will have to choose the right page if more than one are found.&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Bookmarks</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Displays the list of bookmarks.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;New Bookmark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Add new bookmark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Add the current displayed page as new bookmark to the list.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>D&amp;elete Bookmark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Delete bookmark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Delete the selected bookmark from the list.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Preparing...</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>HelpWindow</name>
+    <message>
+        <source>Qt Assistant by Trolltech - %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Help</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Can&apos;t load and display non-local file
+%1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Open Link in New Window<byte value="x9"/>Shift+LMB</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MainWindow</name>
+    <message encoding="UTF-8">
+        <source>Qt Assistant by Trolltech</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Toolbar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Print</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Print...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Exit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>E&amp;xit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Copy</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Copy</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Find in Text</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Find in Text...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Home</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Home</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Previous</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Previous</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Next</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Next</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>About Qt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>About Qt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Qt Class Reference</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Designer Manual</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Zoom in</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Zoom &amp;in</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Zoom out</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Zoom &amp;out</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Linguist Manual</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Settings</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Settings...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>New Window</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>New Window...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Close</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Vie&amp;ws</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Ctrl+T</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Ctrl+I</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Ctrl+B</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Assistant</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>&amp;Add Bookmark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Qt Reference Documentation</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context encoding="UTF-8">
+    <name>SettingsDialogBase</name>
+    <message encoding="UTF-8">
+        <source>Settings</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Font:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Link color:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Underline links</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>OK</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Fixed font:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>TopicChooser</name>
+    <message>
+        <source>Choose a topic for &lt;b&gt;%1&lt;/b&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context encoding="UTF-8">
+    <name>TopicChooserBase</name>
+    <message encoding="UTF-8">
+        <source>Choose Topic</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Select a topic from the list and click the &lt;b&gt;Display&lt;/b&gt;-button to open the online help.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Topics</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Displays a list of available help topics for the keyword.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Open the topic selected in the list.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>&amp;Close</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message encoding="UTF-8">
+        <source>Close the Dialog.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
Index: trunk/tools/assistant/assistant_os2.rc
===================================================================
--- trunk/tools/assistant/assistant_os2.rc	(revision 191)
+++ trunk/tools/assistant/assistant_os2.rc	(revision 191)
@@ -0,0 +1,1 @@
+ICON	1	"assistant_os2.ico"
Index: trunk/tools/assistant/book/assistant.book
===================================================================
--- trunk/tools/assistant/book/assistant.book	(revision 191)
+++ trunk/tools/assistant/book/assistant.book	(revision 191)
@@ -0,0 +1,6 @@
+\title Qt Assistant Manual
+
+\granularity chapter
+
+\input assistant.leaf
+
Index: trunk/tools/assistant/book/assistant.leaf
===================================================================
--- trunk/tools/assistant/book/assistant.leaf	(revision 191)
+++ trunk/tools/assistant/book/assistant.leaf	(revision 191)
@@ -0,0 +1,563 @@
+\chapter Introduction
+
+This document introduces \QA, a tool for presenting on-line
+documentation. It also introduces the Qt Reference Documentation which
+is accessible using \QA, or with a web browser. The document is
+divided into the following sections:
+
+\list
+\i Introduction to the Qt Reference Documentation
+\i The 1 Minute Guide to using Qt Assistant
+\i Qt Assistant in More Detail
+\i Full Text Searching
+\i Customizing Qt Assistant 
+\endlist
+
+\chapter Introduction to the Qt Reference Documentation
+
+The documentation for the Qt library is written in-line in the \File
+.cpp files by the developers themselves. The documentation team
+revises the documentation to ensure that it is accurate and usable,
+and to provide quality control. The documentation team also writes the
+larger texts, such as the class descriptions that introduce a class
+along with the concepts the class uses, as well as introducing the
+functions and properties that the class provides. 
+
+The documentation focuses on the API rather than the internals, since
+we make great efforts to keep our API consistent and compatible with
+each new version, but we may change the internals considerably to improve
+performance and enhance functionality.
+
+The Qt Reference Documentation consists of almost 1,500 HTML pages
+(over 2,500 printed pages). The overwhelming majority of pages
+document Qt classes. Since developers differ in the way they
+think and work we provide a variety of approaches to navigating the
+documentation set: 
+
+\list
+
+\i The \link classes.html All Classes\endlink page lists every class
+in Qt's public API, and consists of several hundred classes.
+
+\i The \link mainclasses.html Main Classes\endlink page lists the
+classes you're most likely to use most often, and provides a much
+shorter and more managable list than the All Classes list.
+
+\i The \link groups.html Grouped Classes\endlink page presents a list
+of groups, each of which leads to a list of related classes, for
+example, the \link advanced.html Advanced Widgets\endlink list.
+
+\i The \link hierarchy.html Inheritance Hierarchy\endlink page
+presents a list of classes in terms of the hierarchy of Qt classes.
+
+\i The \link functions.html All Functions\endlink page lists all the
+functions provided by Qt classes, each one with links to the class(es)
+in which it appears.
+
+\endlist
+
+No matter where you find yourself in the Qt documentation, you will
+find extensive cross-referencing. Even snippets of example code
+contain clickable links, so that for example, if you come across a
+class declaration in a code example, the class name will be a
+clickable link to the class's documentation.
+
+In addition to the class documentation some of Qt's modules have
+extensive descriptions, and there are many overview documents which
+describe various aspects of the Qt library; all these are linked from
+the reference documentation home page. There are also two tutorials
+and numerous example programs in the examples subdirectory of the Qt
+distribution.
+
+\chapter The 1 Minute Guide to Using Qt Assistant
+
+Under Windows, \QA is available as a menu option on the Qt menu. On
+Unix, run \c{assistant} from an xterm.
+
+When you start up \QA, you will be presented with a standard
+main-window style application, with a menu bar and toolbar. Below
+these, on the left hand side is a navigation window called the \e
+Sidebar, and on the right, taking up most of the space, is the
+documentation window. By default, the Qt Reference Documentation's home
+page is shown in the documentation window.
+
+\QA works in a similar way to a web browser. If you click underlined
+text (which signifies a cross-reference), the documentation window will
+present the relevant page. You can bookmark pages of particular
+interest and you can click the \Toolbutton Previous and \Toolbutton
+Next toolbar buttons to navigate within the pages you've visited. 
+
+Although \QA can be used just like a web browser to navigate through
+the Qt documentation set, \QA offers a powerful means of navigation
+that web browsers don't provide. \QA uses an intelligent algorithm to
+index all the pages in the documentation sets that it presents so that
+you can search for particular words and phrases.
+
+To perform an index search, click the \Toolbutton Index tab on the Sidebar
+(or click \Key Ctrl+I). In the 'Look For' line edit enter a word, e.g.
+'homedirpath'. As you type, words are found and highlighted in a list
+beneath the line edit. If the highlighted text matches what you're
+looking for, double click it, (or press \Key Enter) and the
+documentation window will display the relevant page. You rarely have
+to type in the whole word before \QA finds a match. Note that for some
+words there may be more than one possible page that is relevant. 
+
+\QA also provides full text searching for finding specific words in
+the documentation. Documents with the highest occurrences of the word
+that you are looking for appear first, and every occurrence of the
+word within the documentation is highlighted. 
+
+\omit
+For example, enter 'setenabled' in the 'Look For' line edit.
+As you type, words are found and highlighted in the list beneath the
+line edit, as before. Once the highlighted text matches what you're
+looking for, double click it, (or press \Key Enter). In the case of
+setEnabled, it is a function name which occurs in several classes, so
+a dialog pops up listing the possible choices. Click the choice you're
+interested in (or move to it using the \Key Up and \Key Down arrow
+keys and press \Key Enter). The relevant page will display in the
+documentation window. 
+\endomit
+
+\QA can be customized by creating profiles, a collection of
+documentation. Profiles can be created for your own use, or for an
+application you will distribute. With profiles, you can select which
+documentation you want the end user of your application to be able to
+view.
+
+\chapter Qt Assistant in More Detail
+
+\img assistant.png
+\caption Qt Assistant
+
+\section1 The Sidebar
+
+\img sidebar.png
+
+The sidebar provides four ways of navigating documentation:
+\list 1
+\i The \Toolbutton Contents tab presents a tree view of the
+documentation sets that are available. If you click an item, its
+documentation will appear in the documentation window. If you double
+click an item or click a '+' sign to the left of an item, the item's
+sub-items will appear. Click a sub-item to make its page appear in the
+documentation window. Click a '-' sign to the left of an item to hide
+its sub-items.
+\i The \Toolbutton Index tab is used to look up key words or phrases.
+See \l{The 1 Minute Guide to using Qt Assistant} for how to use this
+tab.
+\i The \Toolbutton Bookmarks tab lists any bookmarks you've made.
+Double click a bookmark to make its page appear in the documentation
+window. The \Toolbutton Bookmarks tab has a \Button{New Bookmark}
+button and a \Button{Delete Bookmark} button at the bottom. Click
+\Button{New Bookmark} to bookmark the page that is showing in the
+documentation window. Click a bookmark in the list, then click 
+\Button{Delete Bookmark} to delete the highlighted bookmark.
+\i The \Toolbutton Search tab provides full text search of \e all
+the documents. See \l{Full Text Searching} for more information about
+this feature.
+\endlist
+
+If you want the documentation window to use as much space as possible,
+you can easily hide or show the Sidebar. If the Sidebar is showing,
+press \Key Ctrl+T, \Key Ctrl+I, \Key Ctrl+B or \Key Ctrl+S to hide it.
+If the Sidebar is hidden, press \Key Ctrl+T to show it on the Contents
+tab, or press \Key Ctrl+I to show it on the Index tab (with the focus
+in the 'Look For' line edit box), or press \Key Ctrl+B to show it on
+the Bookmarks tab, or press \Key Ctrl+S to show it on the (full text)
+Search tab.
+
+The Sidebar is a dock window, so you can drag it to the top, left,
+right or bottom of \QA's window, or you can drag it outside \QA to
+float it.
+
+\section1 The Documentation Window
+
+\img docwindow.png
+
+The documentation window offers a feature for viewing documentation by
+enabling you to create tabs for each documentation page that you view.
+Click the \Button {Add Tab} button and a new tab will appear with the
+page name as the tab's caption. This makes it convenient to switch
+between pages when you are working with different documentation. You
+can delete a tab by clicking the \Button {Close Tab} button located
+on the right side of the documentation window.
+
+\section1 The Toolbar
+
+\img toolbar1.png
+
+The toolbar provides fast access to the most common actions.
+\list
+\i \Toolbutton Previous takes you to the previous page. The menu
+option is \Menu Go|Previous and the keyboard shortcut is \Key{Alt+Left
+Arrow}.
+\i \Toolbutton Next takes you to the next page. The menu
+option is \Menu Go|Next and the keyboard shortcut is \Key{Alt+Right
+Arrow}.
+\i \Toolbutton Home takes you to the home page (normally the home page
+of the Qt Reference Documentation). The menu
+option is \Menu Go|Home and the keyboard shortcut is \Key{Ctrl+Home}.
+\i \Toolbutton Copy copies any selected text to the clipboard. The menu
+option is \Menu Edit|Copy and the keyboard shortcut is \Key{Ctrl+C}.
+\i \Toolbutton{Find in Text} invokes the \Dialog{Find Text} dialog. The menu
+option is \Menu{Edit|Find in Text} and the keyboard shortcut is \Key{Ctrl+F}.
+\i \Toolbutton{Print} invokes the \Dialog{Print} dialog. The menu
+option is \Menu{File|Print} and the keyboard shortcut is \Key{Ctrl+P}.
+\i \Toolbutton{Zoom in} increases the font size. The menu
+option is \Menu{View|Zoom in} and the keyboard shortcut is \Key{Ctrl++}.
+\i \Toolbutton{Zoom out} decreases the font size. The menu
+option is \Menu{View|Zoom out} and the keyboard shortcut is \Key{Ctrl+-}.
+\i \Toolbutton{What's This?} provides a description of a \QA feature.
+The menu option is \Menu{Help|What's This?} and the keyboard shortcut
+is \Key{Shift+F1}.
+\endlist
+
+The remaining toolbar buttons are bookmarks and will vary depending on
+your configuration.
+
+\section1 The Menus
+
+\section2 The File Menu
+
+\list
+\i \Menu{File|Print} invokes the \Dialog{Print} dialog.
+\i \Menu{File|Exit} terminates \QA.
+\endlist
+
+\section2 The Edit Menu
+
+\list
+\i \Menu{Edit|Copy} copies any selected text to the clipboard.
+\i \Menu{Edit|Find in Text} invokes the \Dialog{Find Text} dialog.
+\i \Menu{Edit|Settings} invokes the \Dialog{Settings} dialog.
+\endlist
+
+\section2 The View Menu
+
+\list
+\i \Menu{View|Zoom in} increases the font size.
+\i \Menu{View|Zoom out} decreases the font size.
+\i \Menu{View|Views|Sidebar} toggles the display of the Sidebar.
+\i \Menu{View|Views|Toolbar} toggles the display of the Toolbar.
+\i \Menu{View|Views|Line up} lines up the toolbar buttons in the
+Toolbar.
+\endlist
+
+\section2 The Go Menu
+
+\list
+\i \Menu{Go|Previous} displays the previous page.
+\i \Menu{Go|Next} displays the next page.
+\i \Menu{Go|home} goes to the home page.
+\endlist
+This menu also has additional items; these are pre-defined bookmarks
+that vary depending on your configuration.
+
+\section2 The Bookmarks Menu
+
+\list
+\i \Menu{Bookmarks|Add} adds the current page to the list of bookmarks.
+\endlist
+This menu may have additional items, i.e. any bookmarks that you have
+already made. If you want to delete a bookmark go to the Bookmarks tab
+on the Sidebar.
+
+\section1 The Dialogs
+
+\section2 The Print Dialog
+
+This dialog is platform-specific. It gives access to various printer
+options and can be used to print the current page.
+
+\section2 The Find Text Dialog
+
+This dialog is used to find text in the current page. Enter the text
+you want to find in the Find line edit. If you check the 'Whole words
+only' checkbox, the search will only consider whole words, i.e. if you
+search for 'spin' with this checkbox checked it will not match
+'spinbox', but will match 'spin'. If you check the 'Case sensitive'
+check box then, for example, 'spin' will match 'spin' but not 'Spin'.
+You can search Forward or Backward from your current position in the
+page by clicking one of the Direction radio buttons. Click the \Button
+Find button to search (or search again), and click the \Button Close
+button to finish.
+
+\section2 The Settings Dialog
+
+The Settings dialog is used to set your preferences for \QA. The
+dialog has four tabs: General Settings, Web Settings, PDF Settings,
+and Profiles. \QA will remember your settings between sessions,
+including window sizes and positions, and which pages you have open.
+Each of the tabs is discussed as follows: 
+
+\list
+\i General Settings
+
+\img general.png
+
+To change the base font used throughout \QA, select a 
+font type from the Font combobox. To choose a new fixed-width 
+font, for example, to show code snippets, choose a font type from 
+the 'Fixed font' combobox. To change the color of hypertext 
+links, click the 'Link color' color button. Uncheck the 
+'Underline links' checkbox if you don't want underlined links. 
+
+\i Web Settings 
+
+\img web.png
+
+Some pages contain links to external web pages. In order to display
+these links, you must specify a web browser. Type the name of your
+browser's executable in the Web Browser Application line edit.
+Alternatively, click the \Button {(ellipsis)} button to invoke the
+\Widget {Set Web Browser} dialog and navigate until you find the web
+browser you want to use. Click \Button {Save} to accept the selection.
+
+To change \QA's default home page, enter the file name in the Home
+Page line edit. Alternatively, click the \Button {(ellipsis)} button
+to invoke the \Widget {Set Homepage} dialog. Navigate until you find
+the home page file you want to use and then click \Button {Save} to
+accept the selection.
+
+\i PDF Settings
+
+\img pdf1.png
+
+Some pages contain links to PDF documents. In order to display these
+links, you must specify a PDF viewer. Type in the name of your PDF viewer's
+executable in the line edit. Alternatively, click the \Button {(ellipsis)}
+button to invoke the \Widget {Set PDF Browser} dialog and navigate
+until you find the PDF viewer you want to use. Click \Button Save to
+accept the selection. 
+
+\chapter Full Text Searching
+
+\img search.png
+
+\QA provides a powerful full text search engine. To search
+for certain words or text, click the 'Search' tab in the sidebar. Then
+enter the text you want to look for and press \Key Enter or click
+\Button Search. The search is not case sensitive, so Foo, fOo and
+FOO are all treated as the same. The following are examples of common search
+patterns:
+
+\list
+\i \c deep -- lists all the documents that contain the word 'deep'
+
+\i \c{deep*} -- lists all the documents that contain a word beginning
+with 'deep'
+
+\i \c{deep copy} -- lists all documents that contain both 'deep' \e
+and 'copy'
+
+\i \c{"deep copy"} -- list all documents that contain the phrase 'deep copy'
+\endlist
+
+The wildcard (*) character cannot be used within quotes. 
+
+The list of documents found is ordered according to the number of
+occurrences of the search text they contain, therefore those with the
+highest number of occurrences appearing first. Simply click any
+document in the list to display it in the document window.
+
+If the documentation has changed, i.e. if documents have been added or
+removed, \QA will reindex.
+
+\chapter Customizing Qt Assistant
+
+\QA can be customized by adding and removing documentation from its
+documentation set. In addition, \QA introduces the profiles option,
+which enables its properties to change, for example, the default
+startup page, and application icon.
+
+\section1 Modifying the Default Documentation Set
+
+When it is started without any options, \QA displays a default set of
+documentation. When Qt is installed, the default documentation set in
+\QA contains the Qt reference documentation as well as the tools that
+come with Qt, such as \QD and qmake.
+
+Documentation can be added or removed from \QA by
+adding and removing the content files. The format of the content files are
+specified below.  To add a content file, type the following command line
+option: \c{-addContentFile docfile}. To remove a content file from the
+default set, type the following command line option:
+\c{-removeContentFile docfile}. For example: 
+
+\code
+1: > assistant -addContentFile file.dcf
+2: > assistant
+3: > assistant -removeContentFile file.dcf
+\endcode
+
+In line one, we add the content file \c file.dcf. In line two, we start
+\QA. The default set will now be extended with the doc file
+\c file.dcf. In line three we remove the file \c file.dcf from the default
+documentation set so that subsequent use of \QA will not contain this
+file.
+
+\section2 Documentation Content File Format
+
+The Documentation Content File must contain the documentation's table
+of contents and all important keywords for the index. In addition, it
+may inherit an icon for the documentation which is displayed in the
+\QA toolbar. You can also specify an extra directory path for
+additional images used in the documentation.
+
+An example of a content file that uses all the available tags and
+attributes is shown below:
+\code
+<assistantconfig version="3.2.0">
+    <DCF ref="demo.html" icon="handbook.png" imagedir="../img/"
+         title="Development Demo Handbook">
+        <section ref="./chap1/chap1.html" title="Chapter1">
+            <section ref="./chap1/section1.html" title="Section1">
+    	        <keyword ref="./chap1/section1.html#foo">foo</keyword>
+		<keyword ref="./chap1/section1.html#bla">bla</keyword>
+		<section ref="./chap1/section1.html#subsection1" title="Subsection 1"/>
+	    	<section ref="./chap1/section1.html#subsection2" title="Subsection 2"/>
+	    	<section ref="./chap1/section1.html#subsection3" title="Subsection 3"/>
+            </section>
+            <section ref="./chap1/section2" title="Section2">
+	        <section ref="./chap1/section2.html#subsection1" title="Subsection 1"/>
+	        <section ref="./chap1/section2.html#subsection2" title="Subsection 2"/>
+	        <section ref="./chap1/section2.html#subsection3" title="Subsection 3"/>
+            </section>
+        </section>
+        <section ref="./chap2/chap2.html" title="Chapter2">
+            <keyword ref="./chap2/chap2.html#foo">foo</keyword>
+            <section ref="./chap2/section1.html" title="Section1"/>
+        </section>
+    </DCF>
+</assistantconfig>
+\endcode
+
+Sections may be nested as deeply as necessary. All references should
+be related. 
+
+Note that any \c keyword tags for a given section must appear \e
+before any sections nested within the given section.
+
+The paths in the \c refs attribute are always written Unix-style
+(forward slashes) and are relative to the location of the
+documentation content file itself.
+
+Since the introduction of the new root tag \c assistantconfig in the
+fileformat from Qt version 3.2.0, it is possible to specify multiple DCF tags in
+one file. Note that the old document contents file format, used up to
+Qt 3.2 is still valid.
+
+\section1 Profiles
+
+Profiles enable \QA to act as a specialized help tool for displaying
+documentation for applications. With profiles, the documentation
+writer can change properties such as \QA's title, application icons, and
+'about' dialogs. In addition, profiles can be used to run specialized
+documentation sets that are separate from the Qt docs. \QA can be
+customized by changing the following properties:
+
+\list
+
+\i Name- This property is used to name the profile. If multiple
+profiles are used for the same installation of \QA, this
+parameter is crucial to keep their profile specific settings
+apart. The property name is \c name
+
+\i Title- This property is used to specify a caption for \QA. The
+property name is \c title
+
+\i Application Icon- This property describes an icon that will be used
+as \QA application icon. The location of the icon is relative to the
+location of the profile. The property name is \c applicationicon
+
+\i Start Page- This property specifies which page \QA should initially
+display when the profile is used. Usually, this is the HTML file which
+contains the documentation's table of contents. This property also
+describes the default location to go to when pressing the home button
+in \QA's main user interface. The start page is specified relative to 
+the location of the profile. The property name is \c startpage
+
+\i About Menu Text- This property describes the text that appears in
+the \Menu Help menu, e.g. About Application. The property name is \c
+aboutmenutext
+
+\i About URL- This property can be used to point to an HTML file that
+describes the contents in the About dialog that is opened for the
+\Menu Help menu, e.g. About Application. The url is specified relative
+to the location of the profile. The property name is \c abouturl
+
+\i \QA Documentation- This property describes the location of
+the \QA documentation. This is required since \QA provides
+self help, such as the full text search help and the \QA
+Manual option in the \Menu Help menu. The location is a directory
+relative to the location of the profile. The property name is \c
+assistantdocs.
+
+\endlist
+
+To define a profile, one needs to specify a \QA Document
+Profile, usually abbreviated \c{.adp}. The profile is an extension of
+the Documentation Content File described above. We add a \c profile
+tag containing \c property tags to the format. 
+
+An example of a document profile file is shown below:
+
+\c helpdemo.adp
+
+\code
+<assistantconfig version="3.2.0">
+
+    <profile>
+	<property name="name">HelpExample</property>
+        <property name="title">Help Example</property>
+        <property name="applicationicon">logo.png</property>
+        <property name="startpage">index.html</property>
+        <property name="aboutmenutext">About Help</property>
+        <property name="abouturl">../about.txt</property>
+        <property name="assistantdocs">../../../doc/html</property>
+    </profile>
+
+    <DCF ref="index.html" icon="handbook.png" title="Help example">
+        <section ref="./manual.html" title="How to use this Example">
+            <keyword ref="./manual.html#installdocs">Install Docs</keyword>
+	    <keyword ref="./manual.html#onlydoc">Example Profile</keyword>
+	    <keyword ref="./manual.html#hide">Hide Sidebar</keyword>
+	    <keyword ref="./manual.html#openqabutton">Open</keyword>
+	    <keyword ref="./manual.html#closeqabutton">Close</keyword>
+	    <keyword ref="./manual.html#display">Display</keyword>
+        </section>
+   </DCF>
+
+</assistantconfig>
+\endcode
+
+These files are XML files. Characters such as \c{<}, \c{>}, and \c{&}
+must be written as entities (e.g., \c{&lt;}, \c{&gt;}, \c{&amp;}).
+
+\section2 Using Profiles
+
+To use a profile, run \QA with the option \c {-profile filename}.
+This will load the profile specified in the file and will customize
+\QA accordingly. For example, to run \QA with the example
+file above, \c helpdemo.adp, we would run the command as follows:
+
+\code 
+> assistant -profile helpdemo.adp
+\endcode
+
+See the HelpDemo example in the Qt distribution for a demonstration
+on how to use \QA with profiles for your own applications.
+
+When distributing \QA with your application, you will also need to
+copy the icon files from the \c QTDIR/tools/assistant/images
+directory so that \QA finds its icons.
+
+\omit
+For small documentation sets, the sidebar may not be necessary. You
+can hide the sidebar on startup with the following:
+\code
+assistant -hideSidebar
+\endcode
+\endomit
+
Index: trunk/tools/assistant/config.cpp
===================================================================
--- trunk/tools/assistant/config.cpp	(revision 191)
+++ trunk/tools/assistant/config.cpp	(revision 191)
@@ -0,0 +1,372 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "config.h"
+#include "profile.h"
+#include "docuparser.h"
+
+#include <qapplication.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qsettings.h>
+#include <qxml.h>
+
+static Config *static_configuration = 0;
+
+inline QString getVersionString()
+{
+    return QString::number( (QT_VERSION >> 16) & 0xff )
+	+ "." + QString::number( (QT_VERSION >> 8) & 0xff );
+}
+
+Config::Config()
+    : hideSidebar( FALSE ), profil( 0 ), maximized(FALSE)
+{
+    fontSiz = qApp->font().pointSize();
+    if( !static_configuration ) {
+	static_configuration = this;
+    } else {
+	qWarning( "Multiple configurations not allowed!" );
+    }
+}
+
+Config *Config::loadConfig(const QString &profileFileName)
+{
+    Config *config = new Config();
+
+    if (profileFileName.isEmpty()) { // no profile
+	config->profil = Profile::createDefaultProfile();
+	config->load();
+	config->loadDefaultProfile();
+	return config;
+    }
+
+    QFile file(profileFileName);
+    if (!file.exists()) {
+	qWarning( "File does not exist: " + profileFileName );
+	return 0;
+    }
+    DocuParser *parser = DocuParser::createParser( profileFileName );
+    if (!parser) {
+	qWarning( "Failed to create parser for file: " + profileFileName );
+	return 0;
+    }
+    if (parser->parserVersion() < DocuParser::Qt320) {
+	qWarning( "File does not contain profile information" );
+	return 0;
+    }
+    DocuParser320 *profileParser = static_cast<DocuParser320*>(parser);
+    parser->parse(&file);
+    config->profil = profileParser->profile();
+    if (!config->profil) {
+	qWarning( "Config::loadConfig(), no profile in: " + profileFileName );
+	return 0;
+    }
+    config->profil->setProfileType(Profile::UserProfile);
+    config->profil->setDocuParser(profileParser);
+    config->load();
+    return config;
+}
+
+Config *Config::configuration()
+{
+    Q_ASSERT( static_configuration );
+    return static_configuration;
+}
+
+void Config::load()
+{
+    const QString key = "/Qt Assistant/" + getVersionString() + "/";
+    const QString profkey = key + "Profile/" + profil->props["name"] + "/";
+
+    QSettings settings;
+    settings.insertSearchPath( QSettings::Windows, "/Trolltech" );
+
+    webBrows = settings.readEntry( key + "Webbrowser" );
+    home = settings.readEntry( profkey + "Homepage" );
+    pdfApp = settings.readEntry( key + "PDFApplication" );
+    linkUnder = settings.readBoolEntry( key + "LinkUnderline", TRUE );
+    linkCol = settings.readEntry( key + "LinkColor", "#0000FF" );
+    src = settings.readListEntry( profkey + "Source" );
+    sideBar = settings.readNumEntry( key + "SideBarPage" );
+    if (qApp->type() != QApplication::Tty) {
+	fontFam = settings.readEntry( key + "Family", qApp->font().family() );
+
+	fontFix = settings.readEntry( key + "FixedFamily", "courier" );
+	fontSiz = settings.readNumEntry( key + "Size", -1 );
+	if ( fontSiz < 4 ) {
+	    fontSiz = qApp->font().pointSize();
+	}
+
+	geom.setRect( settings.readNumEntry( key + "GeometryX", QApplication::desktop()->availableGeometry().x() ),
+		      settings.readNumEntry( key + "GeometryY", QApplication::desktop()->availableGeometry().y() ),
+		      settings.readNumEntry( key + "GeometryWidth", 800 ),
+		      settings.readNumEntry( key + "GeometryHeight", 600 ) );
+	maximized = settings.readBoolEntry( key + "GeometryMaximized", FALSE );
+    }
+    mainWinLayout = settings.readEntry( key + "MainwindowLayout" );
+    rebuildDocs = settings.readBoolEntry( key + "RebuildDocDB", TRUE );
+
+    profileNames = settings.entryList( key + "Profile" );
+}
+
+void Config::save()
+{
+    saveSettings();
+    saveProfile( profil );
+}
+
+void Config::saveSettings()
+{
+    const QString key = "/Qt Assistant/" + getVersionString() + "/";
+    const QString profkey = key + "Profile/" + profil->props["name"] + "/";
+
+    QSettings settings;
+    settings.insertSearchPath( QSettings::Windows, "/Trolltech" );
+
+    settings.writeEntry( key + "Webbrowser", webBrows );
+    settings.writeEntry( profkey + "Homepage", home );
+    settings.writeEntry( key + "PDFApplication", pdfApp );
+    settings.writeEntry( key + "LinkUnderline", linkUnder );
+    settings.writeEntry( key + "LinkColor", linkCol );
+    settings.writeEntry( profkey + "Source", src );
+    settings.writeEntry( key + "SideBarPage", sideBarPage() );
+    if (qApp->type() != QApplication::Tty) {
+	settings.writeEntry( key + "GeometryX", geom.x() );
+	settings.writeEntry( key + "GeometryY", geom.y() );
+	settings.writeEntry( key + "GeometryWidth", geom.width() );
+	settings.writeEntry( key + "GeometryHeight", geom.height() );
+	settings.writeEntry( key + "GeometryMaximized", maximized );
+	settings.writeEntry( key + "Family",  fontFam );
+	settings.writeEntry( key + "Size",  fontSiz < 4 ? qApp->font().pointSize() : fontSiz );
+	settings.writeEntry( key + "FixedFamily", fontFix );
+    }
+    if ( !hideSidebar )
+	settings.writeEntry( key + "MainwindowLayout", mainWinLayout );
+    settings.writeEntry( key + "RebuildDocDB", rebuildDocs );
+}
+
+#ifdef ASSISTANT_DEBUG
+static void dumpmap( const QMap<QString,QString> &m, const QString &header )
+{
+    qDebug( header );
+    QMap<QString,QString>::ConstIterator it = m.begin();
+    while (it != m.end()) {
+	qDebug( "  " + it.key() + ":\t\t" + *it );
+	++it;
+    }
+}
+#endif
+
+void Config::loadDefaultProfile()
+{
+    QSettings settings;
+    settings.insertSearchPath( QSettings::Windows, "/Trolltech" );
+    const QString key = "/Qt Assistant/" + QString(QT_VERSION_STR) + "/Profile";
+    const QString profKey = key + "/default/";
+
+    if( settings.entryList( key + "/default" ).count() == 0 ) {
+	return;
+    }
+
+    // Override the defaults with settings in registry.
+    profil->icons.clear();
+    profil->indexPages.clear();
+    profil->imageDirs.clear();
+    profil->docs.clear();
+    profil->dcfTitles.clear();
+
+    QStringList titles = settings.readListEntry( profKey + "Titles" );
+    QStringList iconLst = settings.readListEntry( profKey + "DocIcons" );
+    QStringList indexLst = settings.readListEntry( profKey + "IndexPages" );
+    QStringList imgDirLst = settings.readListEntry( profKey + "ImageDirs" );
+    QStringList dcfs = settings.readListEntry( profKey + "DocFiles" );
+
+    QStringList::ConstIterator it = titles.begin();
+    QValueListConstIterator<QString> iconIt = iconLst.begin();
+    QValueListConstIterator<QString> indexIt = indexLst.begin();
+    QValueListConstIterator<QString> imageIt = imgDirLst.begin();
+    QValueListConstIterator<QString> dcfIt = dcfs.begin();
+    for( ; it != titles.end();
+	++it, ++iconIt, ++indexIt, ++imageIt, ++dcfIt )
+    {
+	profil->addDCFIcon( *it, *iconIt );
+	profil->addDCFIndexPage( *it, *indexIt );
+	profil->addDCFImageDir( *it, *imageIt );
+	profil->addDCFTitle( *dcfIt, *it );
+    }
+#if ASSISTANT_DEBUG
+    dumpmap( profil->icons, "Icons" );
+    dumpmap( profil->indexPages, "IndexPages" );
+    dumpmap( profil->imageDirs, "ImageDirs" );
+    dumpmap( profil->dcfTitles, "dcfTitles" );
+    qDebug( "Docfiles: \n  " + profil->docs.join( "\n  " ) );
+#endif
+}
+
+void Config::saveProfile( Profile *profile )
+{
+    if (profil && profil->profileType() == Profile::UserProfile)
+	return;
+    QSettings settings;
+    settings.insertSearchPath( QSettings::Windows, "/Trolltech" );
+    QString versionString = (profile->props["name"] == "default")
+	? QString(QT_VERSION_STR)
+	: getVersionString();
+    const QString key = "/Qt Assistant/" + versionString + "/";
+    const QString profKey = key + "Profile/" + profile->props["name"] + "/";
+
+    QStringList indexes, icons, imgDirs, dcfs;
+    QValueList<QString> titles = profile->dcfTitles.keys();
+    QValueListConstIterator<QString> it = titles.begin();
+    for ( ; it != titles.end(); ++it ) {
+	indexes << profile->indexPages[*it];
+	icons << profile->icons[*it];
+	imgDirs << profile->imageDirs[*it];
+	dcfs << profile->dcfTitles[*it];
+    }
+
+    settings.writeEntry( profKey + "Titles", titles );
+    settings.writeEntry( profKey + "DocFiles", dcfs );
+    settings.writeEntry( profKey + "IndexPages", indexes );
+    settings.writeEntry( profKey + "DocIcons", icons );
+    settings.writeEntry( profKey + "ImageDirs", imgDirs );
+
+#if ASSISTANT_DEBUG
+    qDebug( "Titles:\n  - " + ( (QStringList*) &titles )->join( "\n  - " ) );
+    qDebug( "Docfiles:\n  - " + dcfs.join( "\n  - " ) );
+    qDebug( "IndexPages:\n  - " + indexes.join( "\n  - " ) );
+    qDebug( "DocIcons:\n  - " + icons.join( "\n  - " ) );
+    qDebug( "ImageDirs:\n  - " + imgDirs.join( "\n  - " ) );
+#endif
+}
+
+QStringList Config::mimePaths()
+{
+    static QStringList lst;
+
+    if( lst.count() > 0 )
+	return lst;
+
+    for (QMap<QString,QString>::ConstIterator it = profil->dcfTitles.begin();
+	 it != profil->dcfTitles.end(); ++it ) {
+
+	// Mime source for .dcf file path
+	QFileInfo info( *it );
+	QString dcfPath = info.dirPath(TRUE);
+	if (lst.contains(dcfPath) == 0)
+	    lst << dcfPath;
+
+	// Image dir for .dcf
+	QString imgDir = QDir::convertSeparators( dcfPath + QDir::separator()
+						  + profil->imageDirs[it.key()] );
+	if (lst.contains(imgDir) == 0)
+	    lst << imgDir;
+    }
+    return lst;
+}
+
+QStringList Config::profiles() const
+{
+    return profileNames;
+}
+
+QString Config::title() const
+{
+    return profil->props[ "title" ];
+}
+
+QString Config::aboutApplicationMenuText() const
+{
+    return profil->props[ "aboutmenutext" ];
+}
+
+QString Config::aboutURL() const
+{
+    return profil->props[ "abouturl" ];
+}
+
+QString Config::homePage() const
+{
+    return home.isEmpty() ? profil->props["startpage"] : home;
+}
+
+QStringList Config::source() const
+{
+    return src.size() == 0 ? QStringList(profil->props["startpage"]) : src;
+}
+
+QStringList Config::docFiles() const
+{
+    return profil->docs;
+}
+
+QPixmap Config::docIcon( const QString &title ) const
+{
+    // ### To allow qdoc generated dcf files to reference the doc icons from qmake_image_col
+    if (!QFile::exists(profil->icons[title]))
+	return QPixmap::fromMimeSource( QFileInfo(profil->icons[title]).fileName() );
+    return QPixmap::fromMimeSource( profil->icons[title] );
+}
+
+QPixmap Config::applicationIcon() const
+{
+    return QPixmap::fromMimeSource( profil->props["applicationicon"] );
+}
+
+QStringList Config::docTitles() const
+{
+    return QStringList(profil->indexPages.keys());
+}
+
+QString Config::docImageDir( const QString &docfile ) const
+{
+    return profil->imageDirs[docfile];
+}
+
+QString Config::indexPage( const QString &title ) const
+{
+    return profil->indexPages
+	[title];
+}
+
+void Config::hideSideBar( bool b )
+{
+    hideSidebar = b;
+}
+
+bool Config::sideBarHidden() const
+{
+    return hideSidebar;
+}
+
+QString Config::assistantDocPath() const
+{
+    return profil->props["assistantdocs"].isEmpty()
+	? QString( qInstallPathDocs() ) + "/html"
+	: profil->props["assistantdocs"];
+}
Index: trunk/tools/assistant/config.h
===================================================================
--- trunk/tools/assistant/config.h	(revision 191)
+++ trunk/tools/assistant/config.h	(revision 191)
@@ -0,0 +1,145 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "profile.h"
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qmap.h>
+
+class Profile;
+
+class Config
+{
+public:
+
+    Config();
+
+    void load();
+    void save();
+    Profile *profile() const { return profil; }
+    QString profileName() const { return profil->props["name"]; }
+    bool validProfileName() const;
+    void hideSideBar( bool b );
+    bool sideBarHidden() const;
+    QStringList mimePaths();
+
+    // From profile, read only
+    QStringList docFiles() const;
+    QStringList docTitles() const;
+    QString indexPage( const QString &title ) const;
+    QString docImageDir( const QString &title ) const;
+    QPixmap docIcon( const QString &title ) const;
+
+    QStringList profiles() const;
+    QString title() const;
+    QString aboutApplicationMenuText() const;
+    QString aboutURL() const;
+    QPixmap applicationIcon() const;
+
+    // From QSettings, read / write
+    QString webBrowser() const { return webBrows; }
+    void setWebBrowser( const QString &cmd ) { webBrows = cmd; }
+
+    QString homePage() const;
+    void setHomePage( const QString &hom ) { home = hom; }
+
+    QString pdfReader() const { return pdfApp; }
+    void setPdfReader( const QString &cmd ) { pdfApp = cmd; }
+
+    int fontSize() const { return fontSiz; }
+    void setFontSize( int size ) { fontSiz = size; }
+
+    QString fontFamily() const { return fontFam; }
+    void setFontFamily( const QString &fam ) { fontFam = fam; }
+
+    QString fontFixedFamily() const { return fontFix; }
+    void setFontFixedFamily( const QString &fn ) { fontFix = fn; }
+
+    QString linkColor() const { return linkCol; }
+    void setLinkColor( const QString &col ) { linkCol = col; }
+
+    QStringList source() const;
+    void setSource( const QStringList &s ) { src = s; }
+
+    int sideBarPage() const { return sideBar; }
+    void setSideBarPage( int sbp ) { sideBar = sbp; }
+
+    QRect geometry() const { return geom; }
+    void setGeometry( const QRect &geo ) { geom = geo; }
+
+    bool isMaximized() const { return maximized; }
+    void setMaximized( bool max ) { maximized = max; }
+
+    bool isLinkUnderline() const { return linkUnder; }
+    void setLinkUnderline( bool ul ) { linkUnder = ul; }
+
+    QString mainWindowLayout() const { return mainWinLayout; }
+    void setMainWindowLayout( const QString &layout ) { mainWinLayout = layout; }
+
+    QString assistantDocPath() const;
+
+    bool docRebuild() const { return rebuildDocs; }
+    void setDocRebuild( bool rb ) { rebuildDocs = rb; }
+
+    void saveProfile( Profile *profile );
+    void loadDefaultProfile();
+
+    static Config *configuration();
+    static Config *loadConfig(const QString &profileFileName);
+
+private:
+    Config( const Config &c );
+    Config& operator=( const Config &c );
+
+    void saveSettings();
+
+private:
+    Profile *profil;
+
+    QStringList profileNames;
+    QString webBrows;
+    QString home;
+    QString pdfApp;
+    QString fontFam;
+    QString fontFix;
+    QString linkCol;
+    QStringList src;
+    QString mainWinLayout;
+    QRect geom;
+    int sideBar;
+    int fontSiz;
+    bool maximized;
+    bool linkUnder;
+    bool hideSidebar;
+    bool rebuildDocs;
+};
+
+#endif
Index: trunk/tools/assistant/docuparser.cpp
===================================================================
--- trunk/tools/assistant/docuparser.cpp	(revision 191)
+++ trunk/tools/assistant/docuparser.cpp	(revision 191)
@@ -0,0 +1,390 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "docuparser.h"
+#include "profile.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qxml.h>
+
+QDataStream &operator>>( QDataStream &s, ContentItem &ci )
+{
+    s >> ci.title;
+    s >> ci.reference;
+    s >> ci.depth;
+    return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const ContentItem &ci )
+{
+    s << ci.title;
+    s << ci.reference;
+    s << ci.depth;
+    return s;
+}
+
+const QString DocuParser::DocumentKey = "/Qt Assistant/" + QString(QT_VERSION_STR) + "/";
+
+DocuParser *DocuParser::createParser( const QString &fileName )
+{
+    QFile file( fileName );
+    if( !file.open( IO_ReadOnly ) ) {	
+	return 0;	
+    }
+    
+    QString str;
+    int read = 0;
+    int maxlen = 1024;
+    int majVer = 0, minVer = 0, serVer = 0;
+    static QRegExp re( "assistantconfig +version=\"(\\d)\\.(\\d)\\.(\\d)\"", FALSE );
+    Q_ASSERT( re.isValid() );
+    while( read != -1 ) {
+ 	read = file.readLine( str, maxlen );
+	if( re.search( str ) >= 0 ) {
+	    majVer = re.cap( 1 ).toInt();
+	    minVer = re.cap( 2 ).toInt();
+	    serVer = re.cap( 3 ).toInt();
+	}
+    }
+
+    if( majVer == 3 && minVer >= 2 ) 
+	return new DocuParser320;
+    
+    return new DocuParser310;	
+}
+
+
+bool DocuParser::parse( QFile *file )
+{
+    QXmlInputSource source( file );
+    QXmlSimpleReader reader;
+    reader.setContentHandler( this );
+    reader.setErrorHandler( this );
+    setFileName( QFileInfo( *file ).absFilePath() );
+    return reader.parse( source );
+}
+
+
+QString DocuParser::errorProtocol() const
+{
+    return errorProt;
+}
+
+
+QValueList<ContentItem> DocuParser::getContentItems()
+{
+    return contentList;
+}
+
+
+QPtrList<IndexItem> DocuParser::getIndexItems()
+{
+    return indexList;
+}
+
+QString DocuParser::absolutify( const QString &name ) const
+{
+    QFileInfo orgPath( name );
+    if( orgPath.isRelative() )
+	return QFileInfo( fname ).dirPath() + QDir::separator() + name;
+    return name;
+}
+
+
+void DocuParser310::addTo( Profile *p )
+{
+    p->addDCFTitle( fname, docTitle );
+    p->addDCFIcon( docTitle, iconName );
+    p->addDCFIndexPage( docTitle, conURL );
+}
+
+
+bool DocuParser310::startDocument()
+{
+    state = StateInit;
+    errorProt = "";
+
+    contentRef = "";
+    indexRef = "";
+    depth = 0;
+    contentList.clear();
+    indexList.clear();
+
+    return TRUE;
+}
+
+
+bool DocuParser310::startElement( const QString &, const QString &,
+			       const QString &qname,
+			       const QXmlAttributes &attr )
+{
+    if (qname == "DCF" && state == StateInit) {
+	state = StateContent;
+	contentRef = absolutify( attr.value( "ref" ) );
+	conURL = contentRef;
+	docTitle = attr.value( "title" );
+	iconName = absolutify( attr.value( "icon" ) );
+	contentList.append( ContentItem( docTitle, contentRef, depth ) );
+    } else if (qname == "section" && (state == StateContent || state == StateSect)) {
+	state = StateSect;
+	contentRef = absolutify( attr.value( "ref" ) );
+	title = attr.value( "title" );
+	depth++;
+	contentList.append( ContentItem( title, contentRef, depth ) );
+    } else if (qname == "keyword" && state == StateSect) {
+	state = StateKeyword;
+	indexRef = absolutify( attr.value( "ref" ) );
+    } else
+	return FALSE;
+    return TRUE;
+}
+
+bool DocuParser310::endElement( const QString &nameSpace, const QString &localName,
+			     const QString &qName )
+{
+    switch( state ) {
+    case StateInit:
+	break;
+    case StateContent:
+	state = StateInit;
+	break;
+    case StateSect:
+	state = --depth ? StateSect : StateContent;
+	break;
+    case StateKeyword:
+	state = StateSect;
+	break;
+    }
+    return TRUE;
+}
+
+
+bool DocuParser310::characters( const QString& ch )
+{
+    QString str = ch.simplifyWhiteSpace();
+    if ( str.isEmpty() )
+	return TRUE;
+
+    switch ( state ) {
+	case StateInit:
+        case StateContent:
+        case StateSect:
+            return FALSE;
+	    break;
+        case StateKeyword:
+	    indexList.append( new IndexItem( str, indexRef ) );
+	    break;
+	default:
+            return FALSE;
+    }
+    return TRUE;
+}
+
+
+bool DocuParser310::fatalError( const QXmlParseException& exception )
+{
+    errorProt += QString( "fatal parsing error: %1 in line %2, column %3\n" )
+        .arg( exception.message() )
+        .arg( exception.lineNumber() )
+        .arg( exception.columnNumber() );
+
+    return QXmlDefaultHandler::fatalError( exception );
+}
+
+
+DocuParser320::DocuParser320()
+    : prof( new Profile )
+{
+}
+
+
+void DocuParser320::addTo( Profile *p )
+{
+    QMap<QString,QString>::ConstIterator it;
+
+    for (it = prof->dcfTitles.begin(); it != prof->dcfTitles.end(); ++it)
+	p->dcfTitles[it.key()] = *it;
+
+    for (it = prof->icons.begin(); it != prof->icons.end(); ++it)
+	p->icons[it.key()] = *it;
+
+    for (it = prof->indexPages.begin(); it != prof->indexPages.end(); ++it)
+	p->indexPages[it.key()] = *it;
+}
+
+
+bool DocuParser320::startDocument()
+{
+    state = StateInit;
+    errorProt = "";
+
+    contentRef = "";
+    indexRef = "";
+    depth = 0;
+    contentList.clear();
+    indexList.clear();
+
+    prof->addDCF( fname );
+
+    return TRUE;
+}
+
+bool DocuParser320::startElement( const QString &, const QString &,
+			       const QString &qname,
+			       const QXmlAttributes &attr )
+{
+    QString lower = qname.lower();
+
+    switch( state ) {
+	
+    case StateInit:
+	if( lower == "assistantconfig" )	    
+	    state = StateDocRoot;
+	break;
+
+    case StateDocRoot:
+	if( lower == "dcf" ) {
+	    state = StateContent;
+	    contentRef = absolutify( attr.value( "ref" ) );
+	    conURL = contentRef;
+	    docTitle = attr.value( "title" );
+	    iconName = absolutify( attr.value( "icon" ) );
+	    contentList.append( ContentItem( docTitle, contentRef, depth ) );
+	} else if( lower == "profile" ) {
+	    state = StateProfile;
+	}
+	break;
+
+    case StateSect:
+	if ( lower == "keyword" && state == StateSect ) {
+	    state = StateKeyword;
+	    indexRef = absolutify( attr.value( "ref" ) );
+	    break;
+	} // else if (lower == "section")
+    case StateContent:
+	if( lower == "section" ) {
+	    state = StateSect;
+	    contentRef = absolutify( attr.value( "ref" ) );
+	    title = attr.value( "title" );
+	    depth++;
+	    contentList.append( ContentItem( title, contentRef, depth ) );
+	}
+	break;
+
+    case StateProfile:
+	if( lower == "property" ) {
+	    state = StateProperty;
+	    propertyName = attr.value( "name" );
+	}
+	break;
+
+    case StateProperty:
+	break;
+    }    
+    
+    return TRUE;
+}
+
+bool DocuParser320::endElement( const QString &nameSpace,
+				const QString &localName,
+				const QString &qName )
+{
+    switch( state ) {
+    case StateInit:
+	break;
+    case StateDocRoot:
+	state = StateInit;
+	break;
+    case StateProfile:
+	state = StateDocRoot;
+	break;
+    case StateProperty:
+	state = StateProfile;
+	if( propertyName.isEmpty() || propertyValue.isEmpty() )
+	    return FALSE;
+	{
+	    static const QStringList lst = QStringList() << "startpage" << "abouturl"
+							 << "applicationicon" << "assistantdocs";
+	    if (lst.contains(propertyName))
+		propertyValue = absolutify( propertyValue );
+	}
+	prof->addProperty( propertyName, propertyValue );
+	break;
+    case StateContent:
+	if( !iconName.isEmpty() ) prof->addDCFIcon( docTitle, iconName );
+	if( contentRef.isEmpty() )
+	    return FALSE;
+	prof->addDCFIndexPage( docTitle, conURL );
+	prof->addDCFTitle( fname, docTitle );
+	state = StateDocRoot;
+	break;
+    case StateSect:
+	state = --depth ? StateSect : StateContent;
+	break;
+    case StateKeyword:
+	state = StateSect;
+	break;
+    }
+    return TRUE;
+}
+
+bool DocuParser320::characters( const QString& ch )
+{
+    QString str = ch.simplifyWhiteSpace();
+    if ( str.isEmpty() )
+	return TRUE;
+
+    switch ( state ) {
+    case StateInit:
+    case StateContent:
+    case StateSect:
+	return FALSE;
+	break;
+    case StateKeyword:
+	indexList.append( new IndexItem( str, indexRef ) );
+	break;
+    case StateProperty:
+        propertyValue = ch;	
+	break;
+    default:
+	return FALSE;
+    }
+    return TRUE;
+}
+
+bool DocuParser320::fatalError( const QXmlParseException& exception )
+{
+    errorProt += QString( "fatal parsing error: %1 in line %2, column %3\n" )
+        .arg( exception.message() )
+        .arg( exception.lineNumber() )
+        .arg( exception.columnNumber() );
+
+    return QXmlDefaultHandler::fatalError( exception );
+}
Index: trunk/tools/assistant/docuparser.h
===================================================================
--- trunk/tools/assistant/docuparser.h	(revision 191)
+++ trunk/tools/assistant/docuparser.h	(revision 191)
@@ -0,0 +1,144 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef DOCUPARSER_H
+#define DOCUPARSER_H
+
+#include <qxml.h>
+#include <qptrlist.h>
+#include <qmap.h>
+
+class Profile;
+
+struct ContentItem {
+    ContentItem()
+	: title( QString::null ), reference( QString::null ), depth( 0 ) {}
+    ContentItem( const QString &t, const QString &r, int d )
+	: title( t ), reference( r ), depth( d ) {}
+    QString title;
+    QString reference;
+    int depth;
+    Q_DUMMY_COMPARISON_OPERATOR(ContentItem)
+};
+
+QDataStream &operator>>( QDataStream &s, ContentItem &ci );
+QDataStream &operator<<( QDataStream &s, const ContentItem &ci );
+
+struct IndexItem {
+    IndexItem( const QString &k, const QString &r )
+	: keyword( k ), reference( r ) {}
+    QString keyword;
+    QString reference;
+};
+
+
+
+class DocuParser : public QXmlDefaultHandler
+{
+public:
+    enum ParserVersion { Qt310, Qt320 };
+    // Since We don't want problems with documentation
+    // from version to version, this string stores the correct
+    // version string to save documents.
+    static const QString DocumentKey;
+
+    static DocuParser *createParser( const QString &fileName );
+
+    virtual bool parse( QFile *file );
+    
+    QValueList<ContentItem> getContentItems();
+    QPtrList<IndexItem> getIndexItems();
+
+    QString errorProtocol() const;
+    QString contentsURL() const { return conURL; }
+
+    virtual ParserVersion parserVersion() const = 0;
+    virtual void addTo( Profile *p ) = 0;
+
+    QString fileName() const { return fname; }
+    void setFileName( const QString &file ) { fname = file; }
+
+protected:
+    QString absolutify( const QString &input ) const;
+    
+    QString contentRef, indexRef, errorProt, conURL;
+    QString docTitle, title, iconName;
+    QValueList<ContentItem> contentList;
+    QPtrList<IndexItem> indexList;
+    QString fname;
+};
+
+
+class DocuParser310 : public DocuParser
+{
+public:
+    enum States{ StateInit, StateContent, StateSect, StateKeyword };
+    
+    bool startDocument();
+    bool startElement( const QString&, const QString&, const QString& ,
+                       const QXmlAttributes& );
+    bool endElement( const QString&, const QString&, const QString& );
+    bool characters( const QString & );
+    bool fatalError( const QXmlParseException& exception );
+
+    virtual ParserVersion parserVersion() const { return Qt310; }
+    virtual void addTo( Profile *p );
+    
+private:
+    States state;
+    int depth;
+};
+
+
+class DocuParser320 : public DocuParser
+{
+public:
+    enum States { StateInit, StateDocRoot, StateProfile, StateProperty,
+		  StateContent, StateSect, StateKeyword };
+
+    DocuParser320();    
+    
+    bool startDocument();
+    bool startElement( const QString&, const QString&, const QString& ,
+                       const QXmlAttributes& );
+    bool endElement( const QString&, const QString&, const QString& );
+    bool characters( const QString & );
+    bool fatalError( const QXmlParseException& exception );
+
+    virtual ParserVersion parserVersion() const { return Qt320; }
+    virtual void addTo( Profile *p );
+    Profile *profile() const { return prof; }    
+
+private:
+    
+    States state;
+    int depth;
+    int docfileCounter;
+    QString propertyValue;
+    QString propertyName;
+    Profile *prof;
+};
+#endif //DOCUPARSER_H
Index: trunk/tools/assistant/finddialog.ui
===================================================================
--- trunk/tools/assistant/finddialog.ui	(revision 191)
+++ trunk/tools/assistant/finddialog.ui	(revision 191)
@@ -0,0 +1,279 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>FindDialog</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>FindDialog</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>362</width>
+            <height>156</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Qt Assistant - Find Text</string>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>0</number>
+        </property>
+        <widget class="QLayoutWidget">
+            <property name="name">
+                <cstring>Layout5</cstring>
+            </property>
+            <grid>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <property name="margin">
+                    <number>11</number>
+                </property>
+                <widget class="QButtonGroup" row="1" column="1" rowspan="2" colspan="1">
+                    <property name="name">
+                        <cstring>ButtonGroup2</cstring>
+                    </property>
+                    <property name="title">
+                        <string>&amp;Direction</string>
+                    </property>
+                    <vbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <property name="margin">
+                            <number>11</number>
+                        </property>
+                        <property name="spacing">
+                            <number>6</number>
+                        </property>
+                        <widget class="QRadioButton">
+                            <property name="name">
+                                <cstring>radioForward</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Fo&amp;rward</string>
+                            </property>
+                            <property name="checked">
+                                <bool>true</bool>
+                            </property>
+                        </widget>
+                        <widget class="QRadioButton">
+                            <property name="name">
+                                <cstring>radioBackward</cstring>
+                            </property>
+                            <property name="text">
+                                <string>&amp;Backward</string>
+                            </property>
+                        </widget>
+                    </vbox>
+                </widget>
+                <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+                    <property name="name">
+                        <cstring>Layout1</cstring>
+                    </property>
+                    <hbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <property name="margin">
+                            <number>0</number>
+                        </property>
+                        <property name="spacing">
+                            <number>6</number>
+                        </property>
+                        <widget class="QLabel">
+                            <property name="name">
+                                <cstring>TextLabel1</cstring>
+                            </property>
+                            <property name="text">
+                                <string>F&amp;ind:</string>
+                            </property>
+                            <property name="buddy" stdset="0">
+                                <cstring>comboFind</cstring>
+                            </property>
+                        </widget>
+                        <widget class="QComboBox">
+                            <property name="name">
+                                <cstring>comboFind</cstring>
+                            </property>
+                            <property name="sizePolicy">
+                                <sizepolicy>
+                                    <hsizetype>7</hsizetype>
+                                    <vsizetype>0</vsizetype>
+                                    <horstretch>0</horstretch>
+                                    <verstretch>0</verstretch>
+                                </sizepolicy>
+                            </property>
+                            <property name="editable">
+                                <bool>true</bool>
+                            </property>
+                            <property name="duplicatesEnabled">
+                                <bool>false</bool>
+                            </property>
+                        </widget>
+                    </hbox>
+                </widget>
+                <spacer row="2" column="2">
+                    <property name="name">
+                        <cstring>Spacer2</cstring>
+                    </property>
+                    <property name="orientation">
+                        <enum>Vertical</enum>
+                    </property>
+                    <property name="sizeType">
+                        <enum>Expanding</enum>
+                    </property>
+                    <property name="sizeHint">
+                        <size>
+                            <width>31</width>
+                            <height>0</height>
+                        </size>
+                    </property>
+                </spacer>
+                <widget class="QPushButton" row="1" column="2">
+                    <property name="name">
+                        <cstring>PushButton2</cstring>
+                    </property>
+                    <property name="text">
+                        <string>C&amp;lose</string>
+                    </property>
+                    <property name="accel">
+                        <string>Alt+L</string>
+                    </property>
+                </widget>
+                <widget class="QButtonGroup" row="1" column="0" rowspan="2" colspan="1">
+                    <property name="name">
+                        <cstring>ButtonGroup1</cstring>
+                    </property>
+                    <property name="title">
+                        <string>&amp;Options</string>
+                    </property>
+                    <vbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <property name="margin">
+                            <number>11</number>
+                        </property>
+                        <property name="spacing">
+                            <number>6</number>
+                        </property>
+                        <widget class="QCheckBox">
+                            <property name="name">
+                                <cstring>checkWords</cstring>
+                            </property>
+                            <property name="text">
+                                <string>&amp;Whole words only</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox">
+                            <property name="name">
+                                <cstring>checkCase</cstring>
+                            </property>
+                            <property name="text">
+                                <string>&amp;Case sensitive</string>
+                            </property>
+                        </widget>
+                    </vbox>
+                </widget>
+                <widget class="QPushButton" row="0" column="2">
+                    <property name="name">
+                        <cstring>PushButton1</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&amp;Find</string>
+                    </property>
+                    <property name="accel">
+                        <string>Alt+F</string>
+                    </property>
+                    <property name="default">
+                        <bool>true</bool>
+                    </property>
+                </widget>
+            </grid>
+        </widget>
+    </vbox>
+</widget>
+<connections>
+    <connection>
+        <sender>PushButton1</sender>
+        <signal>clicked()</signal>
+        <receiver>FindDialog</receiver>
+        <slot>doFind()</slot>
+    </connection>
+    <connection>
+        <sender>PushButton2</sender>
+        <signal>clicked()</signal>
+        <receiver>FindDialog</receiver>
+        <slot>reject()</slot>
+    </connection>
+</connections>
+<tabstops>
+    <tabstop>comboFind</tabstop>
+    <tabstop>checkWords</tabstop>
+    <tabstop>checkCase</tabstop>
+    <tabstop>radioForward</tabstop>
+    <tabstop>radioBackward</tabstop>
+    <tabstop>PushButton1</tabstop>
+    <tabstop>PushButton2</tabstop>
+</tabstops>
+<includes>
+    <include location="global" impldecl="in implementation">qstatusbar.h</include>
+    <include location="global" impldecl="in implementation">qtextbrowser.h</include>
+    <include location="local" impldecl="in implementation">mainwindow.h</include>
+    <include location="local" impldecl="in implementation">tabbedbrowser.h</include>
+    <include location="local" impldecl="in implementation">finddialog.ui.h</include>
+</includes>
+<forwards>
+    <forward>class QTextBrowser;</forward>
+    <forward>class QStatusBar;</forward>
+    <forward>class MainWindow;</forward>
+</forwards>
+<variables>
+    <variable>QStatusBar *sb;</variable>
+    <variable>bool onceFound;</variable>
+    <variable>QString findExpr;</variable>
+    <variable>QTextBrowser *lastBrowser;</variable>
+</variables>
+<slots>
+    <slot access="protected">init()</slot>
+    <slot access="protected">destroy()</slot>
+    <slot>doFind()</slot>
+    <slot>doFind(bool)</slot>
+    <slot>statusMessage(const QString &amp;message)</slot>
+</slots>
+<functions>
+    <function specifier="non virtual" returnType="MainWindow *">mainWindow()</function>
+    <function specifier="non virtual" returnType="bool">hasFindExpression()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/finddialog.ui.h
===================================================================
--- trunk/tools/assistant/finddialog.ui.h	(revision 191)
+++ trunk/tools/assistant/finddialog.ui.h	(revision 191)
@@ -0,0 +1,101 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qapplication.h>
+
+void FindDialog::init()
+{
+    lastBrowser = 0;
+    onceFound = FALSE;
+    findExpr = "";
+    sb = new QStatusBar( this );
+    FindDialogLayout->addWidget( sb );
+    sb->message( tr( "Enter the text you are looking for." ) );
+}
+
+void FindDialog::destroy()
+{
+}
+
+void FindDialog::doFind()
+{
+    doFind(radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+    QTextBrowser *browser = (QTextBrowser*) mainWindow()->browsers()->currentBrowser();
+    sb->clear();
+
+    if (comboFind->currentText() != findExpr || lastBrowser != browser)
+	onceFound = false;
+    findExpr = comboFind->currentText();
+
+    bool found;
+    if (browser->hasSelectedText()) { // Search either forward or backward from cursor.
+	found = browser->find(findExpr, checkCase->isChecked(), checkWords->isChecked(),
+			      forward);
+    } else {
+	int para = forward ? 0 : INT_MAX;
+	int index = forward ? 0 : INT_MAX;
+	found = browser->find(findExpr, checkCase->isChecked(), checkWords->isChecked(),
+			      forward, &para, &index);
+    }
+
+    if (!found) {
+	if (onceFound) {
+	    if (forward)
+		statusMessage(tr("Search reached end of the document"));
+	    else
+		statusMessage(tr("Search reached start of the document"));
+	} else {
+	    statusMessage(tr( "Text not found" ));
+	}
+    }
+    onceFound |= found;
+    lastBrowser = browser;
+}
+
+
+
+MainWindow* FindDialog::mainWindow()
+{
+    return (MainWindow*) parent();
+}
+
+bool FindDialog::hasFindExpression()
+{
+    return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+    if (isVisible())
+	sb->message(message);
+    else
+	((MainWindow*) parent())->statusBar()->message(message, 2000);
+
+}
Index: trunk/tools/assistant/helpdialog.ui
===================================================================
--- trunk/tools/assistant/helpdialog.ui	(revision 191)
+++ trunk/tools/assistant/helpdialog.ui	(revision 191)
@@ -0,0 +1,499 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>HelpDialogBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QWidget">
+    <property name="name">
+        <cstring>HelpDialogBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>268</width>
+            <height>448</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Help</string>
+    </property>
+    <property name="whatsThis" stdset="0">
+        <string>&lt;b&gt;Help&lt;/b&gt;&lt;p&gt;Choose the topic you want help on from the contents list, or search the index for keywords.&lt;/p&gt;</string>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>0</number>
+        </property>
+        <property name="spacing">
+            <number>6</number>
+        </property>
+        <widget class="QTabWidget">
+            <property name="name">
+                <cstring>tabWidget</cstring>
+            </property>
+            <property name="whatsThis" stdset="0">
+                <string>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</string>
+            </property>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>contentPage</cstring>
+                </property>
+                <attribute name="title">
+                    <string>Con&amp;tents</string>
+                </attribute>
+                <vbox>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <property name="margin">
+                        <number>5</number>
+                    </property>
+                    <property name="spacing">
+                        <number>6</number>
+                    </property>
+                    <widget class="QListView">
+                        <column>
+                            <property name="text">
+                                <string>Column 1</string>
+                            </property>
+                            <property name="clickable">
+                                <bool>true</bool>
+                            </property>
+                            <property name="resizable">
+                                <bool>true</bool>
+                            </property>
+                        </column>
+                        <property name="name">
+                            <cstring>listContents</cstring>
+                        </property>
+                        <property name="rootIsDecorated">
+                            <bool>true</bool>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>&lt;b&gt;Help topics organized by category.&lt;/b&gt;&lt;p&gt;Double-click an item to see the topics in that category. To view a topic, just double-click it.&lt;/p&gt;</string>
+                        </property>
+                    </widget>
+                </vbox>
+            </widget>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>Widget8</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;Index</string>
+                </attribute>
+                <vbox>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <property name="margin">
+                        <number>5</number>
+                    </property>
+                    <property name="spacing">
+                        <number>6</number>
+                    </property>
+                    <widget class="QLabel">
+                        <property name="name">
+                            <cstring>TextLabel1</cstring>
+                        </property>
+                        <property name="text">
+                            <string>&amp;Look For:</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>editIndex</cstring>
+                        </property>
+                    </widget>
+                    <widget class="QLineEdit">
+                        <property name="name">
+                            <cstring>editIndex</cstring>
+                        </property>
+                        <property name="toolTip" stdset="0">
+                            <string>Enter keyword</string>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>&lt;b&gt;Enter a keyword.&lt;/b&gt;&lt;p&gt;The list will select an item that matches the entered string best.&lt;/p&gt;</string>
+                        </property>
+                    </widget>
+                    <widget class="QListBox">
+                        <property name="name">
+                            <cstring>listIndex</cstring>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>&lt;b&gt;List of available help topics.&lt;/b&gt;&lt;p&gt;Double-click on an item to open its help page. If more than one is found, you must specify which page you want.&lt;/p&gt;</string>
+                        </property>
+                    </widget>
+                </vbox>
+            </widget>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>Widget9</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;Bookmarks</string>
+                </attribute>
+                <vbox>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <property name="margin">
+                        <number>5</number>
+                    </property>
+                    <property name="spacing">
+                        <number>6</number>
+                    </property>
+                    <widget class="QListView">
+                        <column>
+                            <property name="text">
+                                <string>Column 1</string>
+                            </property>
+                            <property name="clickable">
+                                <bool>true</bool>
+                            </property>
+                            <property name="resizable">
+                                <bool>true</bool>
+                            </property>
+                        </column>
+                        <property name="name">
+                            <cstring>listBookmarks</cstring>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>Displays the list of bookmarks.</string>
+                        </property>
+                    </widget>
+                    <widget class="QLayoutWidget">
+                        <property name="name">
+                            <cstring>Layout3</cstring>
+                        </property>
+                        <hbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <property name="margin">
+                                <number>0</number>
+                            </property>
+                            <property name="spacing">
+                                <number>6</number>
+                            </property>
+                            <spacer>
+                                <property name="name">
+                                    <cstring>Spacer1</cstring>
+                                </property>
+                                <property name="orientation">
+                                    <enum>Horizontal</enum>
+                                </property>
+                                <property name="sizeType">
+                                    <enum>Expanding</enum>
+                                </property>
+                                <property name="sizeHint">
+                                    <size>
+                                        <width>20</width>
+                                        <height>20</height>
+                                    </size>
+                                </property>
+                            </spacer>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>buttonAdd</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>&amp;New</string>
+                                </property>
+                                <property name="toolTip" stdset="0">
+                                    <string>Add new bookmark</string>
+                                </property>
+                                <property name="whatsThis" stdset="0">
+                                    <string>Add the currently displayed page as a new bookmark.</string>
+                                </property>
+                            </widget>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>buttonRemove</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>&amp;Delete</string>
+                                </property>
+                                <property name="toolTip" stdset="0">
+                                    <string>Delete bookmark</string>
+                                </property>
+                                <property name="whatsThis" stdset="0">
+                                    <string>Delete the selected bookmark.</string>
+                                </property>
+                            </widget>
+                        </hbox>
+                    </widget>
+                </vbox>
+            </widget>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>searchTab</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;Search</string>
+                </attribute>
+                <grid>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <property name="margin">
+                        <number>5</number>
+                    </property>
+                    <property name="spacing">
+                        <number>6</number>
+                    </property>
+                    <spacer row="3" column="0">
+                        <property name="name">
+                            <cstring>Spacer3</cstring>
+                        </property>
+                        <property name="orientation">
+                            <enum>Vertical</enum>
+                        </property>
+                        <property name="sizeType">
+                            <enum>Fixed</enum>
+                        </property>
+                        <property name="sizeHint">
+                            <size>
+                                <width>20</width>
+                                <height>20</height>
+                            </size>
+                        </property>
+                    </spacer>
+                    <widget class="QLabel" row="0" column="0">
+                        <property name="name">
+                            <cstring>TextLabel1_2</cstring>
+                        </property>
+                        <property name="text">
+                            <string>Searching f&amp;or:</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>termsEdit</cstring>
+                        </property>
+                    </widget>
+                    <widget class="QLineEdit" row="1" column="0">
+                        <property name="name">
+                            <cstring>termsEdit</cstring>
+                        </property>
+                        <property name="toolTip" stdset="0">
+                            <string>Enter searchword(s).</string>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>&lt;b&gt;Enter search word(s).&lt;/b&gt;&lt;p&gt;Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.&lt;/p&gt;</string>
+                        </property>
+                    </widget>
+                    <widget class="QListBox" row="5" column="0">
+                        <property name="name">
+                            <cstring>resultBox</cstring>
+                        </property>
+                        <property name="whatsThis" stdset="0">
+                            <string>&lt;b&gt;Found documents&lt;/b&gt;&lt;p&gt;This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.&lt;/p&gt;</string>
+                        </property>
+                    </widget>
+                    <widget class="QLabel" row="4" column="0">
+                        <property name="name">
+                            <cstring>TextLabel2</cstring>
+                        </property>
+                        <property name="text">
+                            <string>Found &amp;Documents:</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>resultBox</cstring>
+                        </property>
+                    </widget>
+                    <widget class="QLayoutWidget" row="2" column="0">
+                        <property name="name">
+                            <cstring>Layout2</cstring>
+                        </property>
+                        <hbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>helpButton</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>He&amp;lp</string>
+                                </property>
+                                <property name="toolTip" stdset="0">
+                                    <string>Display the help page.</string>
+                                </property>
+                                <property name="whatsThis" stdset="0">
+                                    <string>Display the help page for the full text search.</string>
+                                </property>
+                            </widget>
+                            <spacer>
+                                <property name="name">
+                                    <cstring>Spacer2</cstring>
+                                </property>
+                                <property name="orientation">
+                                    <enum>Horizontal</enum>
+                                </property>
+                                <property name="sizeType">
+                                    <enum>Expanding</enum>
+                                </property>
+                                <property name="sizeHint">
+                                    <size>
+                                        <width>61</width>
+                                        <height>21</height>
+                                    </size>
+                                </property>
+                            </spacer>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>searchButton</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>&amp;Search</string>
+                                </property>
+                                <property name="toolTip" stdset="0">
+                                    <string>Start searching.</string>
+                                </property>
+                                <property name="whatsThis" stdset="0">
+                                    <string>Pressing this button starts the search.</string>
+                                </property>
+                            </widget>
+                        </hbox>
+                    </widget>
+                </grid>
+            </widget>
+        </widget>
+        <widget class="QFrame">
+            <property name="name">
+                <cstring>framePrepare</cstring>
+            </property>
+            <property name="frameShape">
+                <enum>StyledPanel</enum>
+            </property>
+            <property name="frameShadow">
+                <enum>Raised</enum>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <property name="margin">
+                    <number>3</number>
+                </property>
+                <property name="spacing">
+                    <number>6</number>
+                </property>
+                <widget class="QLabel">
+                    <property name="name">
+                        <cstring>labelPrepare</cstring>
+                    </property>
+                    <property name="text">
+                        <string>Preparing...</string>
+                    </property>
+                </widget>
+                <widget class="QProgressBar">
+                    <property name="name">
+                        <cstring>progressPrepare</cstring>
+                    </property>
+                </widget>
+            </hbox>
+        </widget>
+    </vbox>
+</widget>
+<connections>
+    <connection>
+        <sender>buttonAdd</sender>
+        <signal>clicked()</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>addBookmark()</slot>
+    </connection>
+    <connection>
+        <sender>buttonRemove</sender>
+        <signal>clicked()</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>removeBookmark()</slot>
+    </connection>
+    <connection>
+        <sender>termsEdit</sender>
+        <signal>returnPressed()</signal>
+        <receiver>searchButton</receiver>
+        <slot>animateClick()</slot>
+    </connection>
+    <connection>
+        <sender>helpButton</sender>
+        <signal>clicked()</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>showSearchHelp()</slot>
+    </connection>
+    <connection>
+        <sender>searchButton</sender>
+        <signal>clicked()</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>startSearch()</slot>
+    </connection>
+    <connection>
+        <sender>resultBox</sender>
+        <signal>returnPressed(QListBoxItem*)</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>showResultPage(QListBoxItem*)</slot>
+    </connection>
+    <connection>
+        <sender>resultBox</sender>
+        <signal>mouseButtonClicked(int, QListBoxItem*, const QPoint &amp;)</signal>
+        <receiver>HelpDialogBase</receiver>
+        <slot>showResultPage(int, QListBoxItem*, const QPoint &amp; )</slot>
+    </connection>
+</connections>
+<tabstops>
+    <tabstop>tabWidget</tabstop>
+    <tabstop>listContents</tabstop>
+    <tabstop>editIndex</tabstop>
+    <tabstop>listIndex</tabstop>
+    <tabstop>listBookmarks</tabstop>
+    <tabstop>buttonAdd</tabstop>
+    <tabstop>buttonRemove</tabstop>
+    <tabstop>termsEdit</tabstop>
+    <tabstop>searchButton</tabstop>
+    <tabstop>helpButton</tabstop>
+    <tabstop>resultBox</tabstop>
+</tabstops>
+<slots>
+    <slot access="protected">init()</slot>
+    <slot access="protected">destroy()</slot>
+    <slot access="protected">addBookmark()</slot>
+    <slot access="protected">currentBookmarkChanged( QListViewItem * )</slot>
+    <slot access="protected">currentIndexChanged( QListBoxItem * )</slot>
+    <slot access="protected">currentTabChanged( const QString &amp; )</slot>
+    <slot access="protected">loadIndexFile()</slot>
+    <slot access="protected">currentContentsChanged( QListViewItem * )</slot>
+    <slot access="protected">removeBookmark()</slot>
+    <slot access="protected">searchInIndex( const QString &amp; )</slot>
+    <slot access="protected">showTopic()</slot>
+    <slot access="protected">showTopic( int, QListBoxItem *, const QPoint &amp; )</slot>
+    <slot access="protected">showSearchHelp()</slot>
+    <slot access="protected">startSearch()</slot>
+    <slot access="protected">showResultPage( QListBoxItem * )</slot>
+    <slot access="protected">showResultPage( int, QListBoxItem *, const QPoint &amp; )</slot>
+    <slot access="protected">showResultPage( int, QListViewItem *, const QPoint &amp; )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/helpdialogimpl.cpp
===================================================================
--- trunk/tools/assistant/helpdialogimpl.cpp	(revision 191)
+++ trunk/tools/assistant/helpdialogimpl.cpp	(revision 191)
@@ -0,0 +1,1154 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "helpdialogimpl.h"
+#include "helpwindow.h"
+#include "topicchooserimpl.h"
+#include "docuparser.h"
+#include "mainwindow.h"
+#include "config.h"
+#include "tabbedbrowser.h"
+
+#include <qaccel.h>
+#include <qapplication.h>
+#include <qcursor.h>
+#include <qdir.h>
+#include <qeventloop.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qheader.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qprogressbar.h>
+#include <qptrlist.h>
+#include <qptrstack.h>
+#include <qpushbutton.h>
+#include <qregexp.h>
+#include <qsettings.h>
+#include <qstatusbar.h>
+#include <qtabwidget.h>
+#include <qtextbrowser.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qurl.h>
+#include <qvalidator.h>
+
+#include <stdlib.h>
+#include <limits.h>
+
+static QString stripAmpersand( const QString &str )
+{
+    QString s( str );
+    s = s.replace( '&', "" );
+    return s;
+}
+
+static bool verifyDirectory(const QString &str)
+{
+    QFileInfo dirInfo(str);
+    if (!dirInfo.exists())
+	return QDir().mkdir(str);
+    if (!dirInfo.isDir()) {
+	qWarning("'%s' exists but is not a directory", str.latin1());
+	return FALSE;
+    }
+    return TRUE;
+}
+
+struct IndexKeyword {
+    IndexKeyword( const QString &kw, const QString &l )
+	: keyword( kw ), link( l ) {}
+    IndexKeyword() : keyword( QString::null ), link( QString::null ) {}
+    bool operator<( const IndexKeyword &ik ) const {
+	return keyword.lower() < ik.keyword.lower();
+    }
+    bool operator<=( const IndexKeyword &ik ) const {
+	return keyword.lower() <= ik.keyword.lower();
+    }
+    bool operator>( const IndexKeyword &ik ) const {
+	return keyword.lower() > ik.keyword.lower();
+    }
+    Q_DUMMY_COMPARISON_OPERATOR( IndexKeyword )
+    QString keyword;
+    QString link;
+};
+
+QDataStream &operator>>( QDataStream &s, IndexKeyword &ik )
+{
+    s >> ik.keyword;
+    s >> ik.link;
+    return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const IndexKeyword &ik )
+{
+    s << ik.keyword;
+    s << ik.link;
+    return s;
+}
+
+QValidator::State SearchValidator::validate( QString &str, int & ) const
+{
+    for ( int i = 0; i < (int) str.length(); ++i ) {
+	QChar c = str[i];
+	if ( !c.isLetterOrNumber() && c != '\'' && c != '`'
+	    && c != '\"' && c != ' ' && c != '-' && c != '_'
+	    && c!= '*' )
+	    return QValidator::Invalid;
+    }
+    return QValidator::Acceptable;
+}
+
+HelpNavigationListItem::HelpNavigationListItem( QListBox *ls, const QString &txt )
+    : QListBoxText( ls, txt )
+{
+}
+
+void HelpNavigationListItem::addLink( const QString &link )
+{
+    int hash = link.find( '#' );
+    if ( hash == -1 ) {
+	linkList << link;
+	return;
+    }
+
+    QString preHash = link.left( hash );
+    if ( linkList.grep( preHash, FALSE ).count() > 0 )
+	return;
+    linkList << link;
+}
+
+HelpNavigationContentsItem::HelpNavigationContentsItem( QListView *v, QListViewItem *after )
+    : QListViewItem( v, after )
+{
+}
+
+HelpNavigationContentsItem::HelpNavigationContentsItem( QListViewItem *v, QListViewItem *after )
+    : QListViewItem( v, after )
+{
+}
+
+void HelpNavigationContentsItem::setLink( const QString &lnk )
+{
+    theLink = lnk;
+}
+
+QString HelpNavigationContentsItem::link() const
+{
+    return theLink;
+}
+
+
+
+HelpDialog::HelpDialog( QWidget *parent, MainWindow *h )
+    : HelpDialogBase( parent, 0, FALSE ),  lwClosed( FALSE ), help( h )
+{
+}
+
+void HelpDialog::initialize()
+{
+    connect( tabWidget, SIGNAL( selected(const QString&) ),
+	     this, SLOT( currentTabChanged(const QString&) ) );
+    connect( listContents, SIGNAL( mouseButtonClicked(int, QListViewItem*, const QPoint &, int ) ),
+	     this, SLOT( showTopic(int,QListViewItem*, const QPoint &) ) );
+    connect( listContents, SIGNAL( currentChanged(QListViewItem*) ),
+	     this, SLOT( currentContentsChanged(QListViewItem*) ) );
+    connect( listContents, SIGNAL( selectionChanged(QListViewItem*) ),
+	     this, SLOT( currentContentsChanged(QListViewItem*) ) );
+    connect( listContents, SIGNAL( doubleClicked(QListViewItem*) ),
+	     this, SLOT( showTopic(QListViewItem*) ) );
+    connect( listContents, SIGNAL( returnPressed(QListViewItem*) ),
+	     this, SLOT( showTopic(QListViewItem*) ) );
+    connect( listContents, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ),
+	     this, SLOT( showItemMenu( QListViewItem*, const QPoint& ) ) );
+    connect( editIndex, SIGNAL( returnPressed() ),
+	     this, SLOT( showTopic() ) );
+    connect( editIndex, SIGNAL( textChanged(const QString&) ),
+	     this, SLOT( searchInIndex(const QString&) ) );
+
+    connect( listIndex, SIGNAL( selectionChanged(QListBoxItem*) ),
+	     this, SLOT( currentIndexChanged(QListBoxItem*) ) );
+    connect( listIndex, SIGNAL( returnPressed(QListBoxItem*) ),
+	     this, SLOT( showTopic() ) );
+    connect( listIndex, SIGNAL( mouseButtonClicked(int, QListBoxItem*, const QPoint &) ),
+	     this, SLOT( showTopic( int, QListBoxItem *, const QPoint & ) ) );
+    connect( listIndex, SIGNAL( currentChanged(QListBoxItem*) ),
+	     this, SLOT( currentIndexChanged(QListBoxItem*) ) );
+    connect( listIndex, SIGNAL( contextMenuRequested( QListBoxItem*, const QPoint& ) ),
+	     this, SLOT( showItemMenu( QListBoxItem*, const QPoint& ) ) );
+
+    connect( listBookmarks, SIGNAL( mouseButtonClicked(int, QListViewItem*, const QPoint&, int ) ),
+	     this, SLOT( showTopic(int, QListViewItem*, const QPoint &) ) );
+    connect( listBookmarks, SIGNAL( returnPressed(QListViewItem*) ),
+	     this, SLOT( showTopic(QListViewItem*) ) );
+    connect( listBookmarks, SIGNAL( selectionChanged(QListViewItem*) ),
+	     this, SLOT( currentBookmarkChanged(QListViewItem*) ) );
+    connect( listBookmarks, SIGNAL( currentChanged(QListViewItem*) ),
+	     this, SLOT( currentBookmarkChanged(QListViewItem*) ) );
+    connect( listBookmarks, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ),
+	     this, SLOT( showItemMenu( QListViewItem*, const QPoint& ) ) );
+    connect( resultBox, SIGNAL( contextMenuRequested( QListBoxItem*, const QPoint& ) ),
+	     this, SLOT( showItemMenu( QListBoxItem*, const QPoint& ) ) );
+
+    cacheFilesPath = QDir::homeDirPath() + "/.assistant/"; //### Find a better location for the dbs
+
+    editIndex->installEventFilter( this );
+    listBookmarks->header()->hide();
+    listBookmarks->header()->setStretchEnabled( TRUE );
+    listContents->header()->hide();
+    listContents->header()->setStretchEnabled( TRUE );
+    framePrepare->hide();
+    connect( qApp, SIGNAL(lastWindowClosed()), SLOT(lastWinClosed()) );
+
+    termsEdit->setValidator( new SearchValidator( termsEdit ) );
+
+    itemPopup = new QPopupMenu( this );
+    itemPopup->insertItem( tr( "Open Link in Current Tab" ), 0 );
+    itemPopup->insertItem( tr( "Open Link in New Window" ), 1 );
+    itemPopup->insertItem( tr( "Open Link in New Tab" ), 2 );
+
+    contentList.setAutoDelete( TRUE );
+    contentList.clear();
+
+    initDoneMsgShown = FALSE;
+    fullTextIndex = 0;
+    indexDone = FALSE;
+    titleMapDone = FALSE;
+    contentsInserted = FALSE;
+    bookmarksInserted = FALSE;
+    setupTitleMap();
+}
+
+
+void HelpDialog::processEvents()
+{
+    qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
+}
+
+
+void HelpDialog::lastWinClosed()
+{
+    lwClosed = TRUE;
+}
+
+
+void HelpDialog::removeOldCacheFiles()
+{
+    QString dir = cacheFilesPath; // ### remove the last '/' ?
+    if (!verifyDirectory(cacheFilesPath)) {
+	qWarning( "Failed to created assistant directory" );
+	return;
+    }
+    QString pname = "." + Config::configuration()->profileName();
+
+    QStringList fileList;
+    fileList <<  "indexdb" << "indexdb.dict" << "indexdb.doc" << "contentdb";
+    QStringList::iterator it = fileList.begin();
+    for ( ; it != fileList.end(); ++it ) {
+	if ( QFile::exists( cacheFilesPath + *it + pname ) ) {
+	    QFile f( cacheFilesPath + *it + pname );
+	    f.remove();
+	}
+    }
+}
+
+void HelpDialog::timerEvent(QTimerEvent *e)
+{
+    static int opacity = 255;
+    // To allow patching of 3.2.3 assistant for qsa.
+#if QT_VERSION >= 0x030300
+    help->setWindowOpacity((opacity-=4)/255.0);
+    if (opacity<=0)
+#endif
+	qApp->quit();
+}
+
+
+void HelpDialog::loadIndexFile()
+{
+    if ( indexDone )
+	return;
+
+    setCursor( waitCursor );
+    indexDone = TRUE;
+    labelPrepare->setText( tr( "Prepare..." ) );
+    framePrepare->show();
+    processEvents();
+
+    QProgressBar *bar = progressPrepare;
+    bar->setTotalSteps( 100 );
+    bar->setProgress( 0 );
+
+    keywordDocuments.clear();
+    QValueList<IndexKeyword> lst;
+    QFile indexFile( cacheFilesPath + "indexdb." +
+		     Config::configuration()->profileName() );
+    if ( !indexFile.open( IO_ReadOnly ) ) {
+	buildKeywordDB();
+	processEvents();
+	if( lwClosed )
+	    return;
+	if (!indexFile.open(IO_ReadOnly)) {
+	    QMessageBox::warning(help, tr("Qt Assistant"), tr("Failed to load keyword index file\n"
+							      "Assistant will not work!"));
+#if defined Q_WS_WIN || defined Q_WS_MACX
+	    startTimer(50);
+#endif
+	    return;
+	}
+    }
+
+    editIndex->setEnabled(FALSE);
+
+    QDataStream ds( &indexFile );
+    Q_UINT32 fileAges;
+    ds >> fileAges;
+    if ( fileAges != getFileAges() ) {
+	indexFile.close();
+	buildKeywordDB();
+	if ( !indexFile.open( IO_ReadOnly ) ) {
+	    QMessageBox::warning( help, tr( "Qt Assistant" ),
+		tr( "Cannot open the index file %1" ).arg( QFileInfo( indexFile ).absFilePath() ) );
+	    editIndex->setEnabled(TRUE);
+	    return;
+	}
+	ds.setDevice( &indexFile );
+	ds >> fileAges;
+    }
+    ds >> lst;
+    indexFile.close();
+
+    bar->setProgress( bar->totalSteps() );
+    processEvents();
+
+    listIndex->clear();
+    HelpNavigationListItem *lastItem = 0;
+    QString lastKeyword = QString::null;
+    QValueList<IndexKeyword>::ConstIterator it = lst.begin();
+    for ( ; it != lst.end(); ++it ) {
+        if ( lastKeyword.lower() != (*it).keyword.lower() )
+            lastItem = new HelpNavigationListItem( listIndex, (*it).keyword );
+        lastItem->addLink( (*it).link );
+        lastKeyword = (*it).keyword;
+
+        QString lnk = (*it).link;
+        int i = lnk.findRev('#');
+        if ( i > -1 )
+            lnk = lnk.left( i );
+        if (!keywordDocuments.contains(lnk))
+            keywordDocuments.append(lnk);
+    }
+    framePrepare->hide();
+    showInitDoneMessage();
+    setCursor( arrowCursor );
+    editIndex->setEnabled(TRUE);
+}
+
+Q_UINT32 HelpDialog::getFileAges()
+{
+    QStringList addDocuFiles = Config::configuration()->docFiles();
+    QStringList::const_iterator i = addDocuFiles.begin();
+
+    Q_UINT32 fileAges = 0;
+    for( ; i != addDocuFiles.end(); ++i ) {
+	QFileInfo fi( *i );
+	if ( fi.exists() )
+	    fileAges += fi.lastModified().toTime_t();
+    }
+
+    return fileAges;
+}
+
+void HelpDialog::buildKeywordDB()
+{
+    QStringList addDocuFiles = Config::configuration()->docFiles();
+    QStringList::iterator i = addDocuFiles.begin();
+
+    int steps = 0;
+    for( ; i != addDocuFiles.end(); i++ )
+	steps += QFileInfo( *i ).size();
+
+    labelPrepare->setText( tr( "Prepare..." ) );
+    progressPrepare->setTotalSteps( steps );
+    progressPrepare->setProgress( 0 );
+    processEvents();
+
+    QValueList<IndexKeyword> lst;
+    Q_UINT32 fileAges = 0;
+    for( i = addDocuFiles.begin(); i != addDocuFiles.end(); i++ ){
+	QFile file( *i );
+	if ( !file.exists() ) {
+	    QMessageBox::warning( this, tr( "Warning" ),
+		tr( "Documentation file %1 does not exist!\n"
+		    "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) );
+	    continue;
+        }
+	fileAges += QFileInfo( file ).lastModified().toTime_t();
+	DocuParser *handler = DocuParser::createParser( *i );
+	bool ok = handler->parse( &file );
+	file.close();
+	if( !ok ){
+	    QString msg = QString( "In file %1:\n%2" )
+			  .arg( QFileInfo( file ).absFilePath() )
+			  .arg( handler->errorProtocol() );
+	    QMessageBox::critical( this, tr( "Parse Error" ), tr( msg ) );
+	    delete handler;
+	    continue;
+	}
+
+	QPtrList<IndexItem> indLst = handler->getIndexItems();
+	QPtrListIterator<IndexItem> it( indLst );
+	IndexItem *indItem;
+	int counter = 0;
+	while ( ( indItem = it.current() ) != 0 ) {
+	    QFileInfo fi( indItem->reference );
+	    lst.append( IndexKeyword( indItem->keyword, fi.absFilePath() ) );
+	    if ( progressPrepare )
+		progressPrepare->setProgress( progressPrepare->progress() +
+					      int(fi.absFilePath().length() * 1.6) );
+
+	    if( ++counter%100 == 0 ) {
+		processEvents();
+		if( lwClosed ) {
+		    return;
+		}
+	    }
+	    ++it;
+	}
+	delete handler;
+    }
+    if ( !lst.isEmpty() )
+	qHeapSort( lst );
+
+    QFile indexout( cacheFilesPath + "indexdb." + Config::configuration()->profileName() );
+    if ( verifyDirectory(cacheFilesPath) && indexout.open( IO_WriteOnly ) ) {
+	QDataStream s( &indexout );
+	s << fileAges;
+	s << lst;
+	indexout.close();
+    }
+}
+
+void HelpDialog::setupTitleMap()
+{
+    if ( titleMapDone )
+	return;
+    if ( Config::configuration()->docRebuild() ) {
+	removeOldCacheFiles();
+	Config::configuration()->setDocRebuild( FALSE );
+	Config::configuration()->saveProfile( Config::configuration()->profile() );
+    }
+    if ( contentList.isEmpty() )
+	getAllContents();
+
+    titleMapDone = TRUE;
+    titleMap.clear();
+    QDictIterator<ContentList> lstIt( contentList );
+    for ( ; lstIt.current(); ++lstIt ) {
+	QValueList<ContentItem> &lst = *(lstIt.current());
+	QValueListConstIterator<ContentItem> it;
+	for ( it = lst.begin(); it != lst.end(); ++it ) {
+	    QFileInfo link( (*it).reference.simplifyWhiteSpace() );
+	    titleMap[ link.absFilePath() ] = (*it).title.stripWhiteSpace();
+	}
+    }
+    processEvents();
+}
+
+void HelpDialog::getAllContents()
+{
+    QFile contentFile( cacheFilesPath + "contentdb." + Config::configuration()->profileName() );
+    contentList.clear();
+    if ( !contentFile.open( IO_ReadOnly ) ) {
+	buildContentDict();
+	return;
+    }
+
+    QDataStream ds( &contentFile );
+    Q_UINT32 fileAges;
+    ds >> fileAges;
+    if ( fileAges != getFileAges() ) {
+	contentFile.close();
+	buildContentDict();
+	return;
+    }
+    QString key;
+    QValueList<ContentItem> lst;
+    while ( !ds.atEnd() ) {
+	ds >> key;
+	ds >> lst;
+	contentList.insert( key, new QValueList<ContentItem>( lst ) );
+    }
+    contentFile.close();
+    processEvents();
+
+}
+
+void HelpDialog::buildContentDict()
+{
+    QStringList docuFiles = Config::configuration()->docFiles();
+
+    Q_UINT32 fileAges = 0;
+    for( QStringList::iterator it = docuFiles.begin(); it != docuFiles.end(); it++ ) {
+	QFile file( *it );
+	if ( !file.exists() ) {
+	    QMessageBox::warning( this, tr( "Warning" ),
+	    tr( "Documentation file %1 does not exist!\n"
+	        "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) );
+	    continue;
+        }
+	fileAges += QFileInfo( file ).lastModified().toTime_t();
+	DocuParser *handler = DocuParser::createParser( *it );
+	if( !handler ) {
+	    QMessageBox::warning( this, tr( "Warning" ),
+	    tr( "Documentation file %1 is not compatible!\n"
+	        "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) );
+	    continue;
+	}
+	bool ok = handler->parse( &file );
+	file.close();
+	if( ok ) {
+	    contentList.insert( *it, new QValueList<ContentItem>( handler->getContentItems() ) );
+	    delete handler;
+	} else {
+	    QString msg = QString( "In file %1:\n%2" )
+			  .arg( QFileInfo( file ).absFilePath() )
+			  .arg( handler->errorProtocol() );
+	    QMessageBox::critical( this, tr( "Parse Error" ), tr( msg ) );
+	    continue;
+	}
+    }
+
+    QString pname = Config::configuration()->profileName();
+    QFile contentOut( cacheFilesPath + "contentdb." + pname );
+    QFile::remove( cacheFilesPath + "indexdb.dict." + pname );
+    QFile::remove( cacheFilesPath + "indexdb.doc." + pname );
+    if ( contentOut.open( IO_WriteOnly ) ) {
+	QDataStream s( &contentOut );
+	s << fileAges;
+	QDictIterator<ContentList> it( contentList );
+	for ( ; it.current(); ++it ) {
+	    s << it.currentKey();
+	    s << *(it.current());
+	}
+	contentOut.close();
+    }
+}
+
+void HelpDialog::currentTabChanged( const QString &s )
+{
+    if ( stripAmpersand( s ).contains( tr( "Index" ) ) )
+	QTimer::singleShot( 0, this, SLOT( loadIndexFile() ) );
+    else if ( stripAmpersand( s ).contains( tr( "Bookmarks" ) ) )
+	insertBookmarks();
+    else if ( stripAmpersand( s ).contains( tr( "Contents" ) ) )
+	QTimer::singleShot( 0, this, SLOT( insertContents() ) );
+    else if ( stripAmpersand( s ).contains( tr( "Search" ) ) )
+	QTimer::singleShot( 0, this, SLOT( setupFullTextIndex() ) );
+}
+
+void HelpDialog::showInitDoneMessage()
+{
+    if ( initDoneMsgShown )
+	return;
+    initDoneMsgShown = TRUE;
+    help->statusBar()->message( tr( "Done" ), 3000 );
+}
+
+void HelpDialog::currentIndexChanged( QListBoxItem * )
+{
+}
+
+
+void HelpDialog::showTopic( int button, QListBoxItem *item,
+			    const QPoint & )
+{
+    if( button == LeftButton && item )
+	showTopic();
+}
+
+void HelpDialog::showTopic( int button, QListViewItem *item,
+			    const QPoint & )
+{
+    if( button == LeftButton && item )
+	showTopic();
+}
+
+void HelpDialog::showTopic( QListViewItem *item )
+{
+    if( item )
+	showTopic();
+}
+
+void HelpDialog::showTopic()
+{
+    if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) )
+	showIndexTopic();
+    else if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Bookmarks" ) ) )
+	showBookmarkTopic();
+    else if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Contents" ) ) )
+	showContentsTopic();
+}
+
+void HelpDialog::showIndexTopic()
+{
+    QListBoxItem *i = listIndex->item( listIndex->currentItem() );
+    if ( !i )
+	return;
+
+    editIndex->blockSignals( TRUE );
+    editIndex->setText( i->text() );
+    editIndex->blockSignals( FALSE );
+
+    HelpNavigationListItem *item = (HelpNavigationListItem*)i;
+
+    QStringList links = item->links();
+    if ( links.count() == 1 ) {
+	emit showLink( links.first() );
+    } else {
+	qHeapSort( links );
+	QStringList::Iterator it = links.begin();
+	QStringList linkList;
+	QStringList linkNames;
+	for ( ; it != links.end(); ++it ) {
+	    linkList << *it;
+	    linkNames << titleOfLink( *it );
+	}
+	QString link = TopicChooser::getLink( this, linkNames, linkList, i->text() );
+	if ( !link.isEmpty() )
+	    emit showLink( link );
+    }
+}
+
+void HelpDialog::searchInIndex( const QString &s )
+{
+    QListBoxItem *i = listIndex->firstItem();
+    QString sl = s.lower();
+    while ( i ) {
+	QString t = i->text();
+	if ( t.length() >= sl.length() &&
+	     i->text().left(s.length()).lower() == sl ) {
+	    listIndex->setCurrentItem( i );
+	    listIndex->setTopItem(listIndex->index(i));
+	    break;
+	}
+	i = i->next();
+    }
+}
+
+QString HelpDialog::titleOfLink( const QString &link )
+{
+    QString s( link );
+    s.remove( s.find( '#' ), s.length() );
+    s = titleMap[ s ];
+    if ( s.isEmpty() )
+	return link;
+    return s;
+}
+
+bool HelpDialog::eventFilter( QObject * o, QEvent * e )
+{
+    if ( !o || !e )
+	return TRUE;
+
+    if ( o == editIndex && e->type() == QEvent::KeyPress ) {
+	QKeyEvent *ke = (QKeyEvent*)e;
+	if ( ke->key() == Key_Up ) {
+	    int i = listIndex->currentItem();
+	    if ( --i >= 0 ) {
+		listIndex->setCurrentItem( i );
+		editIndex->blockSignals( TRUE );
+		editIndex->setText( listIndex->currentText() );
+		editIndex->blockSignals( FALSE );
+	    }
+	    return TRUE;
+	} else if ( ke->key() == Key_Down ) {
+	    int i = listIndex->currentItem();
+	    if ( ++i < int(listIndex->count()) ) {
+		listIndex->setCurrentItem( i );
+		editIndex->blockSignals( TRUE );
+		editIndex->setText( listIndex->currentText() );
+		editIndex->blockSignals( FALSE );
+	    }
+	    return TRUE;
+	} else if ( ke->key() == Key_Next || ke->key() == Key_Prior ) {
+	    QApplication::sendEvent( listIndex, e);
+	    editIndex->blockSignals( TRUE );
+	    editIndex->setText( listIndex->currentText() );
+	    editIndex->blockSignals( FALSE );
+	}
+    }
+
+    return QWidget::eventFilter( o, e );
+}
+
+void HelpDialog::addBookmark()
+{
+    if ( !bookmarksInserted )
+	insertBookmarks();
+    QString link = QUrl(  help->browsers()->currentBrowser()->context(),
+			  help->browsers()->currentBrowser()->source() ).path();
+    QString title = help->browsers()->currentBrowser()->documentTitle();
+    if ( title.isEmpty() )
+	title = titleOfLink( link );
+    HelpNavigationContentsItem *i = new HelpNavigationContentsItem( listBookmarks, 0 );
+    i->setText( 0, title );
+    i->setLink( link );
+    saveBookmarks();
+    help->updateBookmarkMenu();
+}
+
+void HelpDialog::removeBookmark()
+{
+    if ( !listBookmarks->currentItem() )
+	return;
+
+    delete listBookmarks->currentItem();
+    saveBookmarks();
+    if ( listBookmarks->firstChild() ) {
+	listBookmarks->setSelected( listBookmarks->firstChild(), TRUE );
+    }
+    help->updateBookmarkMenu();
+}
+
+void HelpDialog::insertBookmarks()
+{
+    if ( bookmarksInserted )
+	return;
+    bookmarksInserted = TRUE;
+    listBookmarks->clear();
+    QFile f( cacheFilesPath + "bookmarks." + Config::configuration()->profileName() );
+    if ( !f.open( IO_ReadOnly ) )
+	return;
+    QTextStream ts( &f );
+    while ( !ts.atEnd() ) {
+	HelpNavigationContentsItem *i = new HelpNavigationContentsItem( listBookmarks, 0 );
+	i->setText( 0, ts.readLine() );
+	i->setLink( ts.readLine() );
+    }
+    help->updateBookmarkMenu();
+    showInitDoneMessage();
+}
+
+void HelpDialog::currentBookmarkChanged( QListViewItem * )
+{
+}
+
+void HelpDialog::showBookmarkTopic()
+{
+    if ( !listBookmarks->currentItem() )
+	return;
+
+    HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)listBookmarks->currentItem();
+    QString absPath = "";
+    if ( QFileInfo( i->link() ).isRelative() )
+	absPath = documentationPath + "/";
+    emit showLink( absPath + i->link() );
+}
+
+void HelpDialog::saveBookmarks()
+{
+    QFile f( cacheFilesPath + "bookmarks." + Config::configuration()->profileName() );
+    if ( !f.open( IO_WriteOnly ) )
+	return;
+    QTextStream ts( &f );
+    QListViewItemIterator it( listBookmarks );
+    for ( ; it.current(); ++it ) {
+	HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)it.current();
+	ts << i->text( 0 ) << endl;
+	ts << i->link() << endl;
+    }
+    f.close();
+}
+
+void HelpDialog::insertContents()
+{
+    if ( contentsInserted )
+	return;
+
+    if ( contentList.isEmpty() )
+	getAllContents();
+
+    contentsInserted = TRUE;
+    listContents->clear();
+    setCursor( waitCursor );
+    if ( !titleMapDone )
+	setupTitleMap();
+
+    listContents->setSorting( -1 );
+
+    QDictIterator<ContentList> lstIt( contentList );
+    for ( ; lstIt.current(); ++lstIt ) {
+	HelpNavigationContentsItem *newEntry;
+
+	HelpNavigationContentsItem *contentEntry = 0;
+	QPtrStack<HelpNavigationContentsItem> stack;
+	stack.clear();
+	int depth = 0;
+	bool root = FALSE;
+
+	HelpNavigationContentsItem *lastItem[64];
+	for( int j = 0; j < 64; ++j )
+	    lastItem[j] = 0;
+
+
+	QValueList<ContentItem> &lst = *(lstIt.current());
+	QValueListConstIterator<ContentItem> it;
+	for( it = lst.begin(); it != lst.end(); ++it ){
+	    ContentItem item = *it;
+	    if( item.depth == 0 ){
+		newEntry = new HelpNavigationContentsItem( listContents, 0 );
+		newEntry->setPixmap( 0, QPixmap::fromMimeSource( "book.png" ) );
+		newEntry->setText( 0, item.title );
+		newEntry->setLink( item.reference );
+		stack.push( newEntry );
+		depth = 1;
+		root = TRUE;
+	    }
+	    else{
+		if( (item.depth > depth) && root ) {
+		    depth = item.depth;
+		    stack.push( contentEntry );
+		}
+		if( item.depth == depth ) {
+		    contentEntry = new HelpNavigationContentsItem( stack.top(), lastItem[ depth ] );
+		    lastItem[ depth ] = contentEntry;
+		    contentEntry->setText( 0, item.title );
+		    contentEntry->setLink( item.reference );
+		}
+		else if( item.depth < depth ) {
+		    stack.pop();
+		    depth--;
+		    item = *(--it);
+		}
+	    }
+	}
+	processEvents();
+    }
+    setCursor( arrowCursor );
+    showInitDoneMessage();
+}
+
+void HelpDialog::currentContentsChanged( QListViewItem * )
+{
+}
+
+void HelpDialog::showContentsTopic()
+{
+    HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)listContents->currentItem();
+    if ( !i )
+	return;
+    emit showLink( i->link() );
+}
+
+void HelpDialog::toggleContents()
+{
+    if ( !isVisible() || tabWidget->currentPageIndex() != 0 ) {
+	tabWidget->setCurrentPage( 0 );
+	parentWidget()->show();
+    }
+    else
+	parentWidget()->hide();
+}
+
+void HelpDialog::toggleIndex()
+{
+    if ( !isVisible() || tabWidget->currentPageIndex() != 1 || !editIndex->hasFocus() ) {
+	tabWidget->setCurrentPage( 1 );
+	parentWidget()->show();
+	editIndex->setFocus();
+    }
+    else
+	parentWidget()->hide();
+}
+
+void HelpDialog::toggleBookmarks()
+{
+    if ( !isVisible() || tabWidget->currentPageIndex() != 2 ) {
+	tabWidget->setCurrentPage( 2 );
+	parentWidget()->show();
+    }
+    else
+	parentWidget()->hide();
+}
+
+void HelpDialog::toggleSearch()
+{
+    if ( !isVisible() || tabWidget->currentPageIndex() != 3 ) {
+	tabWidget->setCurrentPage( 3 );
+	parentWidget()->show();
+    }
+    else
+	parentWidget()->hide();
+}
+
+void HelpDialog::setupFullTextIndex()
+{
+    if ( fullTextIndex )
+	return;
+
+    QStringList documentList;    
+    QString pname = Config::configuration()->profileName();
+    fullTextIndex = new Index( documentList, QDir::homeDirPath() ); // ### Is this correct ?
+    if (!verifyDirectory(cacheFilesPath)) {
+        QMessageBox::warning(help, tr("Qt Assistant"),
+            tr("Failed to save fulltext search index\n"
+            "Assistant will not work!"));
+        return;
+    }
+    searchButton->setEnabled(FALSE);
+    helpButton->setEnabled(FALSE);
+    termsEdit->setEnabled(FALSE);
+
+    fullTextIndex->setDictionaryFile( cacheFilesPath + "indexdb.dict." + pname );
+    fullTextIndex->setDocListFile( cacheFilesPath + "indexdb.doc." + pname );
+    processEvents();
+
+    connect( fullTextIndex, SIGNAL( indexingProgress( int ) ),
+        this, SLOT( setIndexingProgress( int ) ) );
+    QFile f( cacheFilesPath + "indexdb.dict." + pname );
+    if ( !f.exists() ) {
+        QMap<QString, QString>::ConstIterator it = titleMap.begin();
+        QString documentName;
+        for ( ; it != titleMap.end(); ++it ) {
+            documentName = it.key();
+            int i = documentName.findRev('#');
+            if ( i > -1 )
+                documentName = documentName.left( i );
+
+            if (!documentList.contains(documentName))
+                documentList << documentName;
+        }
+        loadIndexFile();
+        for (QStringList::Iterator it2 = keywordDocuments.begin(); it2 != keywordDocuments.end(); ++it2) {
+            if (!documentList.contains(*it2))
+                documentList << *it2;
+        }
+        fullTextIndex->setDocList( documentList );
+
+        help->statusBar()->clear();
+        setCursor( waitCursor );
+        labelPrepare->setText( tr( "Indexing files..." ) );
+        progressPrepare->setTotalSteps( 100 );
+        progressPrepare->reset();
+        progressPrepare->show();
+        framePrepare->show();
+        processEvents();
+        if ( fullTextIndex->makeIndex() != -1 ) {
+            fullTextIndex->writeDict();
+            progressPrepare->setProgress( 100 );
+            framePrepare->hide();
+            setCursor( arrowCursor );
+            showInitDoneMessage();
+            keywordDocuments.clear();
+        }
+    } else {
+        setCursor( waitCursor );
+        help->statusBar()->message( tr( "Reading dictionary..." ) );
+        processEvents();
+        fullTextIndex->readDict();
+        help->statusBar()->message( tr( "Done" ), 3000 );
+        setCursor( arrowCursor );
+    }
+    searchButton->setEnabled(TRUE);
+    termsEdit->setEnabled(TRUE);
+    helpButton->setEnabled(TRUE);
+}
+
+void HelpDialog::setIndexingProgress( int prog )
+{
+    progressPrepare->setProgress( prog );
+    processEvents();
+}
+
+void HelpDialog::startSearch()
+{
+    QString str = termsEdit->text();
+    str = str.replace( "\'", "\"" );
+    str = str.replace( "`", "\"" );
+    QString buf = str;
+    str = str.replace( "-", " " );
+    str = str.replace( QRegExp( "\\s[\\S]?\\s" ), " " );
+    terms = QStringList::split( " ", str );
+    QStringList termSeq;
+    QStringList seqWords;
+    QStringList::iterator it = terms.begin();
+    for ( ; it != terms.end(); ++it ) {
+	(*it) = (*it).simplifyWhiteSpace();
+	(*it) = (*it).lower();
+	(*it) = (*it).replace( "\"", "" );
+    }
+    if ( str.contains( '\"' ) ) {
+	if ( (str.contains( '\"' ))%2 == 0 ) {
+	    int beg = 0;
+	    int end = 0;
+	    QString s;
+	    beg = str.find( '\"', beg );
+	    while ( beg != -1 ) {
+		beg++;
+		end = str.find( '\"', beg );
+		s = str.mid( beg, end - beg );
+		s = s.lower();
+		s = s.simplifyWhiteSpace();
+		if ( s.contains( '*' ) ) {
+		    QMessageBox::warning( this, tr( "Full Text Search" ),
+			tr( "Using a wildcard within phrases is not allowed." ) );
+		    return;
+		}
+		seqWords += QStringList::split( ' ', s );
+		termSeq << s;
+		beg = str.find( '\"', end + 1);
+	    }
+	} else {
+	    QMessageBox::warning( this, tr( "Full Text Search" ),
+		tr( "The closing quotation mark is missing." ) );
+	    return;
+	}
+    }
+    setCursor( waitCursor );
+    foundDocs.clear();
+    foundDocs = fullTextIndex->query( terms, termSeq, seqWords );
+    QString msg( QString( "%1 documents found." ).arg( foundDocs.count() ) );
+    help->statusBar()->message( tr( msg ), 3000 );
+    resultBox->clear();
+    for ( it = foundDocs.begin(); it != foundDocs.end(); ++it )
+	resultBox->insertItem( fullTextIndex->getDocumentTitle( *it ) );
+
+    terms.clear();
+    bool isPhrase = FALSE;
+    QString s = "";
+    for ( int i = 0; i < (int)buf.length(); ++i ) {
+	if ( buf[i] == '\"' ) {
+	    isPhrase = !isPhrase;
+	    s = s.simplifyWhiteSpace();
+	    if ( !s.isEmpty() )
+		terms << s;
+	    s = "";
+	} else if ( buf[i] == ' ' && !isPhrase ) {
+	    s = s.simplifyWhiteSpace();
+	    if ( !s.isEmpty() )
+		terms << s;
+	    s = "";
+	} else
+	    s += buf[i];
+    }
+    if ( !s.isEmpty() )
+	terms << s;
+
+    setCursor( arrowCursor );
+}
+
+void HelpDialog::showSearchHelp()
+{
+    emit showLink( Config::configuration()->assistantDocPath() + "/assistant-5.html" );
+}
+
+void HelpDialog::showResultPage( int button, QListBoxItem *i, const QPoint & )
+{
+    if( button == LeftButton ) {
+	showResultPage( i );
+    }
+}
+
+void HelpDialog::showResultPage( QListBoxItem *i )
+{
+    if( !i )
+	return;
+    emit showSearchLink( foundDocs[resultBox->index( i )], terms );
+}
+
+void HelpDialog::showItemMenu( QListBoxItem *item, const QPoint &pos )
+{
+    if ( !item )
+	return;
+    int id = itemPopup->exec( pos );
+    if ( id == 0 ) {
+	if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) )
+	    showTopic();
+	else {
+	    showResultPage( item );
+	}
+    } else if ( id > 0 ) {
+	HelpWindow *hw = help->browsers()->currentBrowser();
+	if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) ) {
+	    editIndex->blockSignals( TRUE );
+	    editIndex->setText( item->text() );
+	    editIndex->blockSignals( FALSE );
+
+	    HelpNavigationListItem *hi = (HelpNavigationListItem*)item;
+
+	    QStringList links = hi->links();
+	    if ( links.count() == 1 ) {
+		if ( id == 1 )
+		    hw->openLinkInNewWindow( links.first() );
+		else
+		    hw->openLinkInNewPage( links.first() );
+	    } else {
+		QStringList::Iterator it = links.begin();
+		QStringList linkList;
+		QStringList linkNames;
+		for ( ; it != links.end(); ++it ) {
+		    linkList << *it;
+		    linkNames << titleOfLink( *it );
+		}
+		QString link = TopicChooser::getLink( this, linkNames, linkList, item->text() );
+		if ( !link.isEmpty() ) {
+		    if ( id == 1 )
+			hw->openLinkInNewWindow( link );
+		    else
+			hw->openLinkInNewPage( link );
+		}
+	    }
+	} else {
+	    QString link = foundDocs[ resultBox->index( item ) ];
+	    if ( id == 1 )
+		hw->openLinkInNewWindow( link );
+	    else
+		hw->openLinkInNewPage( link );
+	}
+    }
+}
+
+void HelpDialog::showItemMenu( QListViewItem *item, const QPoint &pos )
+{
+    if ( !item )
+	return;
+    int id = itemPopup->exec( pos );
+    if ( id == 0 ) {
+	if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Contents" ) ) )
+	    showContentsTopic();
+	else
+	    showBookmarkTopic();
+    } else if ( id > 0 ) {
+	HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)item;
+	if ( id == 1 )
+	    help->browsers()->currentBrowser()->openLinkInNewWindow( i->link() );
+	else
+	    help->browsers()->currentBrowser()->openLinkInNewPage( i->link() );
+    }
+}
Index: trunk/tools/assistant/helpdialogimpl.h
===================================================================
--- trunk/tools/assistant/helpdialogimpl.h	(revision 191)
+++ trunk/tools/assistant/helpdialogimpl.h	(revision 191)
@@ -0,0 +1,164 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef HELPDIALOGIMPL_H
+#define HELPDIALOGIMPL_H
+
+#include "helpdialog.h"
+#include "index.h"
+#include "helpwindow.h"
+#include "docuparser.h"
+
+#include <qlistbox.h>
+#include <qlistview.h>
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qvalidator.h>
+#include <qpopupmenu.h>
+#include <qdict.h>
+#include <qpopupmenu.h>
+
+class QProgressBar;
+class MainWindow;
+class QTextBrowser;
+
+class HelpNavigationListItem : public QListBoxText
+{
+public:
+    HelpNavigationListItem( QListBox *ls, const QString &txt );
+
+    void addLink( const QString &link );
+    QStringList links() const { return linkList; }
+private:
+    QStringList linkList;
+
+};
+
+class SearchValidator : public QValidator
+{
+    Q_OBJECT
+public:
+    SearchValidator( QObject *parent, const char *name = 0 )
+	: QValidator( parent, name ) {}
+    ~SearchValidator() {}
+    QValidator::State validate( QString &str, int & ) const;
+};
+
+class HelpNavigationContentsItem : public QListViewItem
+{
+public:
+    HelpNavigationContentsItem( QListView *v, QListViewItem *after );
+    HelpNavigationContentsItem( QListViewItem *v, QListViewItem *after );
+
+    void setLink( const QString &lnk );
+    QString link() const;
+
+private:
+    QString theLink;
+};
+
+class HelpDialog : public HelpDialogBase
+{
+    Q_OBJECT
+
+public:
+    HelpDialog( QWidget *parent, MainWindow *h );
+
+    QString titleOfLink( const QString &link );
+    bool eventFilter( QObject *, QEvent * );
+    bool lastWindowClosed() { return lwClosed; }
+
+    void timerEvent(QTimerEvent *e);
+
+protected slots:
+    void showTopic( int, QListBoxItem *, const QPoint & );
+    void showTopic( int, QListViewItem *, const QPoint & );
+    void showTopic( QListViewItem * );
+    void loadIndexFile();
+    void insertContents();
+    void setupFullTextIndex();
+    void currentTabChanged( const QString &s );
+    void currentIndexChanged( QListBoxItem *i );
+    void showTopic();
+    void searchInIndex( const QString &s );
+    void addBookmark();
+    void removeBookmark();
+    void currentBookmarkChanged( QListViewItem *i );
+    void currentContentsChanged( QListViewItem *i );
+    void startSearch();
+    void showSearchHelp();
+
+public slots:
+    void initialize();
+    void toggleContents();
+    void toggleIndex();
+    void toggleBookmarks();
+    void toggleSearch();
+
+
+signals:
+    void showLink( const QString &s );
+    void showSearchLink( const QString &s, const QStringList &terms );
+
+private slots:
+    void lastWinClosed();
+    void showResultPage( int button, QListBoxItem *i, const QPoint &p );
+    void showResultPage( QListBoxItem *i );
+    void setIndexingProgress( int prog );
+    void showItemMenu( QListBoxItem *item, const QPoint &pos );
+    void showItemMenu( QListViewItem *item, const QPoint &pos );
+    void insertBookmarks();
+    void processEvents();
+
+private:
+    typedef QValueList<ContentItem> ContentList;
+    void removeOldCacheFiles();
+    void buildKeywordDB();
+    Q_UINT32 getFileAges();
+    void showIndexTopic();
+    void showBookmarkTopic();
+    void setupTitleMap();
+    void saveBookmarks();
+    void showContentsTopic();
+    void showInitDoneMessage();
+    void buildContentDict();
+
+    QMap<QString, QString> titleMap;
+    bool indexDone, bookmarksInserted, titleMapDone, contentsInserted;
+    bool lwClosed;
+    MainWindow *help;
+    QString documentationPath;
+    Index *fullTextIndex;
+    QStringList terms, foundDocs;
+    bool initDoneMsgShown;
+    void getAllContents();
+    QDict<ContentList> contentList;
+    QPopupMenu *itemPopup;
+    QString cacheFilesPath;
+    QStringList keywordDocuments;
+};
+
+#endif
Index: trunk/tools/assistant/helpwindow.cpp
===================================================================
--- trunk/tools/assistant/helpwindow.cpp	(revision 191)
+++ trunk/tools/assistant/helpwindow.cpp	(revision 191)
@@ -0,0 +1,275 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "helpwindow.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpdialogimpl.h"
+#include "config.h"
+
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qurl.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qprocess.h>
+#include <qpopupmenu.h>
+#include <qaction.h>
+#include <qfileinfo.h>
+#include <qevent.h>
+#include <qtextstream.h>
+#include <qtextcodec.h>
+
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#endif
+
+HelpWindow::HelpWindow( MainWindow *w, QWidget *parent, const char *name )
+    : QTextBrowser( parent, name ), mw( w ), blockScroll( FALSE ),
+      shiftPressed( FALSE ), newWindow( FALSE )
+{
+    connect(this, SIGNAL(forwardAvailable(bool)), this, SLOT(updateForward(bool)));
+    connect(this, SIGNAL(backwardAvailable(bool)), this, SLOT(updateBackward(bool)));
+}
+
+void HelpWindow::setSource( const QString &name )
+{
+    if ( name.isEmpty() )
+	return;
+
+    if (newWindow || shiftPressed) {
+	removeSelection();
+	mw->saveSettings();
+	mw->saveToolbarSettings();
+	MainWindow *nmw = new MainWindow;
+
+	QFileInfo currentInfo( source() );
+	QFileInfo linkInfo( name );
+	QString target = name;
+	if( linkInfo.isRelative() )
+	    target = currentInfo.dirPath( TRUE ) + "/" + name;
+
+	nmw->setup();	
+	nmw->move( mw->geometry().topLeft() );
+	if ( mw->isMaximized() )
+	    nmw->showMaximized();
+	else
+	    nmw->show();
+    nmw->showLink( target );
+    return;
+    }
+
+    if ( name.left( 7 ) == "http://" || name.left( 6 ) == "ftp://" ) {
+	QString webbrowser = Config::configuration()->webBrowser();
+	if ( webbrowser.isEmpty() ) {
+#if defined(Q_OS_WIN32)
+	    QT_WA( {
+		ShellExecute( winId(), 0, (TCHAR*)name.ucs2(), 0, 0, SW_SHOWNORMAL );
+	    } , {
+		ShellExecuteA( winId(), 0, name.local8Bit(), 0, 0, SW_SHOWNORMAL );
+	    } );
+#elif defined(Q_OS_MACX)
+	    webbrowser = "/usr/bin/open";
+#else
+	    int result = QMessageBox::information( mw, tr( "Help" ),
+			 tr( "Currently no Web browser is selected.\nPlease use the settings dialog to specify one!\n" ),
+			 "Open", "Cancel" );
+	    if ( result == 0 ) {
+		emit chooseWebBrowser();
+		webbrowser = Config::configuration()->webBrowser();
+	    }
+#endif
+	    if ( webbrowser.isEmpty() )
+		return;
+	}
+	QProcess *proc = new QProcess(this);
+
+	proc->addArgument( webbrowser );
+        QObject::connect(proc, SIGNAL(processExited()), proc, SLOT(deleteLater()));
+	proc->addArgument( name );
+	proc->start();
+	return;
+    }
+
+    if ( name.right( 3 ) == "pdf" ) {
+	QString pdfbrowser = Config::configuration()->pdfReader();
+	if ( pdfbrowser.isEmpty() ) {
+#if defined(Q_OS_MACX)
+	    pdfbrowser = "/usr/bin/open";
+#else
+	    QMessageBox::information( mw,
+				      tr( "Help" ),
+				      tr( "No PDF Viewer has been specified\n"
+					  "Please use the settings dialog to specify one!\n" ) );
+	    return;
+#endif
+	}
+	QFileInfo info( pdfbrowser );
+	if( !info.exists() ) {
+	    QMessageBox::information( mw,
+				      tr( "Help" ),
+				      tr( "Qt Assistant is unable to start the PDF Viewer\n\n"
+					  "%1\n\n"
+					  "Please make sure that the executable exists and is located at\n"
+					  "the specified location." ).arg( pdfbrowser ) );
+	    return;
+	}
+	QProcess *proc = new QProcess(this);
+        QObject::connect(proc, SIGNAL(processExited()), proc, SLOT(deleteLater()));
+	proc->addArgument( pdfbrowser );
+	proc->addArgument( name );
+	proc->start();
+
+	return;
+    }
+
+    QUrl u( context(), name );
+    if ( !u.isLocalFile() ) {
+	QMessageBox::information( mw, tr( "Help" ), tr( "Can't load and display non-local file\n"
+		    "%1" ).arg( name ) );
+	return;
+    }
+
+    setText("<body bgcolor=\"" + paletteBackgroundColor().name() + "\">");
+    QTextBrowser::setSource( name );
+}
+
+
+void HelpWindow::openLinkInNewWindow()
+{
+    if ( lastAnchor.isEmpty() )
+	return;
+    newWindow = TRUE;
+    setSource(lastAnchor);
+    newWindow = FALSE;
+}
+
+void HelpWindow::openLinkInNewWindow( const QString &link )
+{
+    lastAnchor = link;
+    openLinkInNewWindow();
+}
+
+void HelpWindow::openLinkInNewPage()
+{
+    if( lastAnchor.isEmpty() )
+	return;
+    mw->browsers()->newTab( lastAnchor );
+    lastAnchor = QString::null;
+}
+
+void HelpWindow::openLinkInNewPage( const QString &link )
+{
+    lastAnchor = link;
+    openLinkInNewPage();
+}
+
+QPopupMenu *HelpWindow::createPopupMenu( const QPoint& pos )
+{
+    QPopupMenu *m = new QPopupMenu(0);
+    lastAnchor = anchorAt( pos );
+    if ( !lastAnchor.isEmpty() ) {
+	if ( lastAnchor.at( 0 ) == '#' ) {
+	    QString src = source();
+	    int hsh = src.find( '#' );
+	    lastAnchor = ( hsh>=0 ? src.left( hsh ) : src ) + lastAnchor;
+	}
+	m->insertItem( tr("Open Link in New Window\tShift+LMB"),
+		       this, SLOT( openLinkInNewWindow() ) );
+	m->insertItem( tr("Open Link in New Tab"),
+		       this, SLOT( openLinkInNewPage() ) );
+    }
+    mw->actionNewWindow->addTo( m );
+    mw->actionOpenPage->addTo( m );
+    mw->actionClosePage->addTo( m );
+    m->insertSeparator();
+    mw->actionGoPrevious->addTo( m );
+    mw->actionGoNext->addTo( m );
+    mw->actionGoHome->addTo( m );
+    m->insertSeparator();
+    mw->actionZoomIn->addTo( m );
+    mw->actionZoomOut->addTo( m );
+    m->insertSeparator();
+    mw->actionEditCopy->addTo( m );
+    mw->actionEditFind->addTo( m );
+    return m;
+}
+
+void HelpWindow::blockScrolling( bool b )
+{
+    blockScroll = b;
+}
+
+void HelpWindow::ensureCursorVisible()
+{
+    if ( !blockScroll )
+	QTextBrowser::ensureCursorVisible();
+}
+
+void HelpWindow::contentsMousePressEvent(QMouseEvent *e)
+{
+    shiftPressed = ( e->state() & ShiftButton );
+    QTextBrowser::contentsMousePressEvent(e);
+}
+
+void HelpWindow::keyPressEvent(QKeyEvent *e)
+{
+    shiftPressed = ( e->state() & ShiftButton );
+    QTextBrowser::keyPressEvent(e);
+}
+
+void HelpWindow::copy()
+{
+    if (textFormat() == PlainText) {
+	QTextEdit::copy();
+    } else {
+	TextFormat oldTf = textFormat();
+	setTextFormat(PlainText);
+	QString selectText = selectedText();
+	selectText.replace("<br>", "\n");
+	selectText.replace("\xa0", " ");
+	selectText.replace("&gt;", ">");
+	selectText.replace("&lt;", "<");
+	selectText.replace("&amp;", "&");
+
+	QClipboard *cb = QApplication::clipboard();
+	if (cb->supportsSelection())
+	    cb->setText(selectText, QClipboard::Selection);
+	cb->setText(selectText, QClipboard::Clipboard);
+	setTextFormat(oldTf);
+    }
+}
+
+void HelpWindow::updateForward(bool fwd)
+{
+    fwdAvail = fwd;
+}
+
+void HelpWindow::updateBackward(bool back)
+{
+    backAvail = back;
+}
Index: trunk/tools/assistant/helpwindow.h
===================================================================
--- trunk/tools/assistant/helpwindow.h	(revision 191)
+++ trunk/tools/assistant/helpwindow.h	(revision 191)
@@ -0,0 +1,80 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef HELPWINDOW_H
+#define HELPWINDOW_H
+
+#include <qtextbrowser.h>
+
+class MainWindow;
+class QKeyEvent;
+class QMime;
+class QMouseEvent;
+
+class HelpWindow : public QTextBrowser
+{
+    Q_OBJECT
+public:
+    HelpWindow( MainWindow *m, QWidget *parent = 0, const char *name = 0 );
+    void setSource( const QString &name );
+    QPopupMenu *createPopupMenu( const QPoint& pos );
+    void blockScrolling( bool b );
+    void openLinkInNewWindow( const QString &link );
+    void openLinkInNewPage( const QString &link );
+    void addMimePath( const QString &path );
+
+    void contentsMousePressEvent(QMouseEvent *e);
+    void keyPressEvent(QKeyEvent *);
+
+    bool isBackwardAvailable() const { return backAvail; }
+    bool isForwardAvailable() const { return fwdAvail; }
+
+signals:
+    void chooseWebBrowser();
+
+public slots:
+    void copy();
+protected slots:
+    void ensureCursorVisible();
+
+private slots:
+    void openLinkInNewWindow();
+    void openLinkInNewPage();
+    void updateForward(bool);
+    void updateBackward(bool);
+
+private:
+    MainWindow *mw;
+    QString lastAnchor;
+    bool blockScroll;
+    bool shiftPressed;
+    bool newWindow;
+    QMimeSourceFactory *mimeSourceFactory;
+    bool fwdAvail;
+    bool backAvail;
+};
+
+#endif
Index: trunk/tools/assistant/images/whatsthis.xpm
===================================================================
--- trunk/tools/assistant/images/whatsthis.xpm	(revision 191)
+++ trunk/tools/assistant/images/whatsthis.xpm	(revision 191)
@@ -0,0 +1,26 @@
+/* XPM */
+static char *whatsthis[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 3 1",
+/* colors */
+"# c None",
+". c #000000",
+"a c #000083",
+/* pixels */
+".########aaaaa##",
+"..######aaa#aaa#",
+"...####aaa###aaa",
+"....###aa#####aa",
+".....##aa#####aa",
+"......##a####aaa",
+".......#####aaa#",
+"........###aaa##",
+".........#aaa###",
+".....#####aaa###",
+"..#...##########",
+".##...####aaa###",
+"####...###aaa###",
+"####...#########",
+"#####...########",
+"#####...########"
+};
Index: trunk/tools/assistant/index.cpp
===================================================================
--- trunk/tools/assistant/index.cpp	(revision 191)
+++ trunk/tools/assistant/index.cpp	(revision 191)
@@ -0,0 +1,519 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "index.h"
+
+#include <qfile.h>
+#include <qdir.h>
+#include <qstringlist.h>
+#include <qdict.h>
+#include <qapplication.h>
+
+#include <ctype.h>
+
+int TermList::compareItems( QPtrCollection::Item i1, QPtrCollection::Item i2 )
+{
+    if( ( (Term*)i1 )->frequency == ( (Term*)i2 )->frequency )
+	return 0;
+    if( ( (Term*)i1 )->frequency < ( (Term*)i2 )->frequency )
+	return -1;
+    return 1;
+}
+
+QDataStream &operator>>( QDataStream &s, Document &l )
+{
+    s >> l.docNumber;
+    s >> l.frequency;
+    return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const Document &l )
+{
+    s << (Q_INT16)l.docNumber;
+    s << (Q_INT16)l.frequency;
+    return s;
+}
+
+Index::Index( const QString &dp, const QString &hp )
+    : QObject( 0, 0 ), dict( 8999 ), docPath( dp )
+{
+    alreadyHaveDocList = FALSE;
+    lastWindowClosed = FALSE;
+    connect( qApp, SIGNAL( lastWindowClosed() ),
+	     this, SLOT( setLastWinClosed() ) );
+}
+
+Index::Index( const QStringList &dl, const QString &hp )
+    : QObject( 0, 0 ), dict( 8999 )
+{
+    docList = dl;
+    alreadyHaveDocList = TRUE;
+    lastWindowClosed = FALSE;
+    connect( qApp, SIGNAL( lastWindowClosed() ),
+	     this, SLOT( setLastWinClosed() ) );
+}
+
+void Index::setLastWinClosed()
+{
+    lastWindowClosed = TRUE;
+}
+
+void Index::setDictionaryFile( const QString &f )
+{
+    dictFile = f;
+}
+
+void Index::setDocListFile( const QString &f )
+{
+    docListFile = f;
+}
+
+void Index::setDocList( const QStringList &lst )
+{
+    docList = lst;
+}
+
+int Index::makeIndex()
+{
+    if ( !alreadyHaveDocList )
+	setupDocumentList();
+    if ( docList.isEmpty() )
+	return 1;
+    QStringList::Iterator it = docList.begin();
+    int steps = docList.count() / 100;
+    if ( !steps )
+	steps++;
+    int prog = 0;
+    for ( int i = 0; it != docList.end(); ++it, ++i ) {
+	if ( lastWindowClosed ) {
+	    return -1;
+	}
+	parseDocument( *it, i );
+	if ( i%steps == 0 ) {
+	    prog++;
+	    emit indexingProgress( prog );
+	}
+    }
+    return 0;
+}
+
+void Index::setupDocumentList()
+{
+    QDir d( docPath );
+    QStringList lst = d.entryList( "*.html" );
+    QStringList::ConstIterator it = lst.begin();
+    for ( ; it != lst.end(); ++it )
+	docList.append( docPath + "/" + *it );
+}
+
+void Index::insertInDict( const QString &str, int docNum )
+{
+    if ( strcmp( str, "amp" ) == 0 || strcmp( str, "nbsp" ) == 0 )
+	return;
+    Entry *e = 0;
+    if ( dict.count() )
+	e = dict[ str ];
+
+    if ( e ) {
+	if ( e->documents.first().docNumber != docNum )
+	    e->documents.prepend( Document( docNum, 1 ) );
+	else
+	    e->documents.first().frequency++;
+    } else {
+	dict.insert( str, new Entry( docNum ) );
+    }
+}
+
+void Index::parseDocument( const QString &filename, int docNum )
+{
+    QFile file( filename );
+    if ( !file.open( IO_ReadOnly ) ) {
+	qWarning( "can not open file " + filename );
+	return;
+    }
+
+    QTextStream s( &file );
+    QString text = s.read();
+    if (text.isNull())
+        return;
+
+    bool valid = TRUE;
+    const QChar *buf = text.unicode();
+    QChar str[64];
+    QChar c = buf[0];
+    int j = 0;
+    int i = 0;
+    while ( (uint)j < text.length() ) {
+	if ( c == '<' || c == '&' ) {
+	    valid = FALSE;
+	    if ( i > 1 )
+		insertInDict( QString(str,i), docNum );
+	    i = 0;
+	    c = buf[++j];
+	    continue;
+	}
+	if ( ( c == '>' || c == ';' ) && !valid ) {
+	    valid = TRUE;
+	    c = buf[++j];
+	    continue;
+	}
+	if ( !valid ) {
+	    c = buf[++j];
+	    continue;
+	}
+	if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) {
+	    str[i] = c.lower();
+	    ++i;
+	} else {
+	    if ( i > 1 )
+		insertInDict( QString(str,i), docNum );
+	    i = 0;
+	}
+	c = buf[++j];
+    }
+    if ( i > 1 )
+	insertInDict( QString(str,i), docNum );
+    file.close();
+}
+
+void Index::writeDict()
+{
+    QDictIterator<Entry> it( dict );
+    QFile f( dictFile );
+    if ( !f.open( IO_WriteOnly ) )
+	return;
+    QDataStream s( &f );
+    for( ; it.current(); ++it ) {
+        Entry *e = it.current();
+	s << it.currentKey();
+	s << e->documents;
+    }
+    f.close();
+    writeDocumentList();
+}
+
+void Index::writeDocumentList()
+{
+    QFile f( docListFile );
+    if ( !f.open( IO_WriteOnly ) )
+	return;
+    QDataStream s( &f );
+    s << docList;
+}
+
+void Index::readDict()
+{
+    QFile f( dictFile );
+    if ( !f.open( IO_ReadOnly ) )
+	return;
+
+    dict.clear();
+    QDataStream s( &f );
+    QString key;
+    QValueList<Document> docs;
+    while ( !s.atEnd() ) {
+	s >> key;
+	s >> docs;
+	dict.insert( key, new Entry( docs ) );
+    }
+    f.close();
+    readDocumentList();
+}
+
+void Index::readDocumentList()
+{
+    QFile f( docListFile );
+    if ( !f.open( IO_ReadOnly ) )
+	return;
+    QDataStream s( &f );
+    s >> docList;
+}
+
+QStringList Index::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords )
+{
+    TermList termList;
+
+    QStringList::ConstIterator it = terms.begin();
+    for ( it = terms.begin(); it != terms.end(); ++it ) {
+	Entry *e = 0;
+	if ( (*it).contains( '*' ) ) {
+	    QValueList<Document> wcts = setupDummyTerm( getWildcardTerms( *it ) );
+	    termList.append( new Term( "dummy", wcts.count(), wcts ) );
+	} else if ( dict[ *it ] ) {
+	    e = dict[ *it ];
+	    termList.append( new Term( *it, e->documents.count(), e->documents ) );
+	} else {
+	    return QStringList();
+	}
+    }
+    termList.sort();
+
+    Term *minTerm = termList.first();
+    if ( !termList.count() )
+	return QStringList();
+    termList.removeFirst();
+
+    QValueList<Document> minDocs = minTerm->documents;
+    QValueList<Document>::iterator C;
+    QValueList<Document>::ConstIterator It;
+    Term *t = termList.first();
+    for ( ; t; t = termList.next() ) {
+	QValueList<Document> docs = t->documents;
+	C = minDocs.begin();
+	while ( C != minDocs.end() ) {
+	    bool found = FALSE;
+	    for ( It = docs.begin(); It != docs.end(); ++It ) {
+		if ( (*C).docNumber == (*It).docNumber ) {
+		    (*C).frequency += (*It).frequency;
+		    found = TRUE;
+		    break;
+		}
+	    }
+	    if ( !found )
+		C = minDocs.remove( C );
+	    else
+		++C;
+	}
+    }
+
+    QStringList results;
+    qHeapSort( minDocs );
+    if ( termSeq.isEmpty() ) {
+	for ( C = minDocs.begin(); C != minDocs.end(); ++C )
+	    results << docList[ (int)(*C).docNumber ];
+	return results;
+    }
+
+    QString fileName;
+    for ( C = minDocs.begin(); C != minDocs.end(); ++C ) {
+	fileName =  docList[ (int)(*C).docNumber ];
+	if ( searchForPattern( termSeq, seqWords, fileName ) )
+	    results << fileName;
+    }
+    return results;
+}
+
+QString Index::getDocumentTitle( const QString &fileName )
+{
+    QFile file( fileName );
+    if ( !file.open( IO_ReadOnly ) ) {
+	qWarning( "cannot open file " + fileName );
+	return fileName;
+    }
+    QTextStream s( &file );
+    QString text = s.read();
+
+    int start = text.find( "<title>", 0, FALSE ) + 7;
+    int end = text.find( "</title>", 0, FALSE );
+
+    QString title = ( end - start <= 0 ? tr("Untitled") : text.mid( start, end - start ) );
+    return title;
+}
+
+QStringList Index::getWildcardTerms( const QString &term )
+{
+    QStringList lst;
+    QStringList terms = split( term );
+    QValueList<QString>::iterator iter;
+
+    QDictIterator<Entry> it( dict );
+    for( ; it.current(); ++it ) {
+	int index = 0;
+	bool found = FALSE;
+	QString text( it.currentKey() );
+	for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
+	    if ( *iter == "*" ) {
+		found = TRUE;
+		continue;
+	    }
+	    if ( iter == terms.begin() && (*iter)[0] != text[0] ) {
+		found = FALSE;
+		break;
+	    }
+	    index = text.find( *iter, index );
+	    if ( *iter == terms.last() && index != (int)text.length()-1 ) {
+		index = text.findRev( *iter );
+		if ( index != (int)text.length() - (int)(*iter).length() ) {
+		    found = FALSE;
+		    break;
+		}
+	    }
+	    if ( index != -1 ) {
+		found = TRUE;
+		index += (*iter).length();
+		continue;
+	    } else {
+		found = FALSE;
+		break;
+	    }
+	}
+	if ( found )
+	    lst << text;
+    }
+
+    return lst;
+}
+
+QStringList Index::split( const QString &str )
+{
+    QStringList lst;
+    int j = 0;
+    int i = str.find( '*', j );
+
+    while ( i != -1 ) {
+	if ( i > j && i <= (int)str.length() ) {
+	    lst << str.mid( j, i - j );
+	    lst << "*";
+	}
+	j = i + 1;
+	i = str.find( '*', j );
+    }
+
+    int l = str.length() - 1;
+    if ( str.mid( j, l - j + 1 ).length() > 0 )
+	lst << str.mid( j, l - j + 1 );
+
+    return lst;
+}
+
+QValueList<Document> Index::setupDummyTerm( const QStringList &terms )
+{
+    TermList termList;
+    QStringList::ConstIterator it = terms.begin();
+    for ( ; it != terms.end(); ++it ) {
+	Entry *e = 0;
+	if ( dict[ *it ] ) {
+	    e = dict[ *it ];
+	    termList.append( new Term( *it, e->documents.count(), e->documents ) );
+	}
+    }
+    termList.sort();
+
+    QValueList<Document> maxList;
+
+    if ( !termList.count() )
+	return maxList;
+    maxList = termList.last()->documents;
+    termList.removeLast();
+
+    QValueList<Document>::iterator docIt;
+    Term *t = termList.first();
+    while ( t ) {
+	QValueList<Document> docs = t->documents;
+	for ( docIt = docs.begin(); docIt != docs.end(); ++docIt ) {
+	    if ( maxList.findIndex( *docIt ) == -1 )
+		maxList.append( *docIt );
+	}
+	t = termList.next();
+    }
+    return maxList;
+}
+
+void Index::buildMiniDict( const QString &str )
+{
+    if ( miniDict[ str ] )
+	miniDict[ str ]->positions.append( wordNum );
+    ++wordNum;
+}
+
+bool Index::searchForPattern( const QStringList &patterns, const QStringList &words, const QString &fileName )
+{
+    QFile file( fileName );
+    if ( !file.open( IO_ReadOnly ) ) {
+	qWarning( "cannot open file " + fileName );
+	return FALSE;
+    }
+
+    wordNum = 3;
+    miniDict.clear();
+    QStringList::ConstIterator cIt = words.begin();
+    for ( ; cIt != words.end(); ++cIt )
+	miniDict.insert( *cIt, new PosEntry( 0 ) );
+
+    QTextStream s( &file );
+    QString text = s.read();
+    bool valid = TRUE;
+    const QChar *buf = text.unicode();
+    QChar str[64];
+    QChar c = buf[0];
+    int j = 0;
+    int i = 0;
+    while ( (uint)j < text.length() ) {
+	if ( c == '<' || c == '&' ) {
+	    valid = FALSE;
+	    if ( i > 1 )
+		buildMiniDict( QString(str,i) );
+	    i = 0;
+	    c = buf[++j];
+	    continue;
+	}
+	if ( ( c == '>' || c == ';' ) && !valid ) {
+	    valid = TRUE;
+	    c = buf[++j];
+	    continue;
+	}
+	if ( !valid ) {
+	    c = buf[++j];
+	    continue;
+	}
+	if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) {
+	    str[i] = c.lower();
+	    ++i;
+	} else {
+	    if ( i > 1 )
+		buildMiniDict( QString(str,i) );
+	    i = 0;
+	}
+	c = buf[++j];
+    }
+    if ( i > 1 )
+	buildMiniDict( QString(str,i) );
+    file.close();
+
+    QStringList::ConstIterator patIt = patterns.begin();
+    QStringList wordLst;
+    QValueList<uint> a, b;
+    QValueList<uint>::iterator aIt;
+    for ( ; patIt != patterns.end(); ++patIt ) {
+	wordLst = QStringList::split( ' ', *patIt );
+	a = miniDict[ wordLst[0] ]->positions;
+	for ( int j = 1; j < (int)wordLst.count(); ++j ) {
+	    b = miniDict[ wordLst[j] ]->positions;
+	    aIt = a.begin();
+	    while ( aIt != a.end() ) {
+		if ( b.find( *aIt + 1 ) != b.end() ) {
+		    (*aIt)++;
+		    ++aIt;
+		} else {
+		    aIt = a.remove( aIt );
+		}
+	    }
+	}
+    }
+    if ( a.count() )
+	return TRUE;
+    return FALSE;
+}
Index: trunk/tools/assistant/index.h
===================================================================
--- trunk/tools/assistant/index.h	(revision 191)
+++ trunk/tools/assistant/index.h	(revision 191)
@@ -0,0 +1,124 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef INDEX_H
+#define INDEX_H
+
+#include <qstringlist.h>
+#include <qdict.h>
+#include <qdatastream.h>
+#include <qobject.h>
+
+struct Document {
+    Document( int d, int f ) : docNumber( d ), frequency( f ) {}
+    Document() : docNumber( -1 ), frequency( 0 ) {}
+    bool operator==( const Document &doc ) const {
+	return docNumber == doc.docNumber;
+    }
+    bool operator<( const Document &doc ) const {
+	return frequency > doc.frequency;
+    }
+    bool operator<=( const Document &doc ) const {
+	return frequency >= doc.frequency;
+    }
+    bool operator>( const Document &doc ) const {
+	return frequency < doc.frequency;
+    }
+    Q_INT16 docNumber;
+    Q_INT16 frequency;
+};
+
+QDataStream &operator>>( QDataStream &s, Document &l );
+QDataStream &operator<<( QDataStream &s, const Document &l );
+
+class Index : public QObject
+{
+    Q_OBJECT
+public:
+    struct Entry {
+	Entry( int d ) { documents.append( Document( d, 1 ) ); }
+	Entry( QValueList<Document> l ) : documents( l ) {}
+	QValueList<Document> documents;
+    };
+    struct PosEntry {
+	PosEntry( int p ) { positions.append( p ); }
+	QValueList<uint> positions;
+    };
+
+    Index( const QString &dp, const QString &hp );
+    Index( const QStringList &dl, const QString &hp );
+    void writeDict();
+    void readDict();
+    int makeIndex();
+    QStringList query( const QStringList&, const QStringList&, const QStringList& );
+    QString getDocumentTitle( const QString& );
+    void setDictionaryFile( const QString& );
+    void setDocListFile( const QString& );
+    void setDocList( const QStringList & );
+
+signals:
+    void indexingProgress( int );
+
+private slots:
+    void setLastWinClosed();
+
+private:
+    void setupDocumentList();
+    void parseDocument( const QString&, int );
+    void insertInDict( const QString&, int );
+    void writeDocumentList();
+    void readDocumentList();
+    QStringList getWildcardTerms( const QString& );
+    QStringList split( const QString& );
+    QValueList<Document> setupDummyTerm( const QStringList& );
+    bool searchForPattern( const QStringList&, const QStringList&, const QString& );
+    void buildMiniDict( const QString& );
+    QStringList docList;
+    QDict<Entry> dict;
+    QDict<PosEntry> miniDict;
+    uint wordNum;
+    QString docPath;
+    QString dictFile, docListFile;
+    bool alreadyHaveDocList;
+    bool lastWindowClosed;
+};
+
+struct Term {
+    Term( const QString &t, int f, QValueList<Document> l )
+	: term( t ), frequency( f ), documents( l ) {}
+    QString term;
+    int frequency;
+    QValueList<Document>documents;
+};
+
+class TermList : public QPtrList<Term>
+{
+public:
+    TermList() : QPtrList<Term>() {}
+    int compareItems( QPtrCollection::Item i1, QPtrCollection::Item i2 );
+};
+
+#endif
Index: trunk/tools/assistant/lib/lib.pro
===================================================================
--- trunk/tools/assistant/lib/lib.pro	(revision 191)
+++ trunk/tools/assistant/lib/lib.pro	(revision 191)
@@ -0,0 +1,23 @@
+TEMPLATE        = lib
+TARGET		= qassistantclient
+VERSION		= 1.0
+
+CONFIG		+= qt warn_on release
+CONFIG		+= staticlib
+CONFIG		-= dll
+
+SOURCES		= qassistantclient.cpp
+HEADERS         += $$QT_SOURCE_TREE/include/qassistantclient.h
+
+
+DEFINES		+= QT_INTERNAL_NETWORK
+include( ../../../src/qt_professional.pri )
+
+DESTDIR		= ../../../lib
+
+unix {
+	target.path=$$libs.path
+	QMAKE_CFLAGS += $$QMAKE_CFLAGS_SHLIB
+	QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SHLIB
+	INSTALLS        += target
+}
Index: trunk/tools/assistant/lib/qassistantclient.cpp
===================================================================
--- trunk/tools/assistant/lib/qassistantclient.cpp	(revision 191)
+++ trunk/tools/assistant/lib/qassistantclient.cpp	(revision 191)
@@ -0,0 +1,327 @@
+/**********************************************************************
+** Copyright (C) 2005-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the QAssistantClient library.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qassistantclient.h"
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include <qprocess.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+class QAssistantClientPrivate
+{
+    friend class QAssistantClient;
+    QStringList arguments;
+};
+
+static QMap<const QAssistantClient*,QAssistantClientPrivate*> *dpointers = 0;
+
+static QAssistantClientPrivate *data( const QAssistantClient *client, bool create=FALSE )
+{
+    if( !dpointers )
+	dpointers = new QMap<const QAssistantClient*,QAssistantClientPrivate*>;
+    QAssistantClientPrivate *d = (*dpointers)[client];
+    if( !d && create ) {
+	d = new QAssistantClientPrivate;
+	dpointers->insert( client, d );
+    }
+    return d;
+}
+
+/*!
+    \class QAssistantClient
+    \brief The QAssistantClient class provides a means of using Qt
+    Assistant as an application's help tool.
+
+    Using Qt Assistant is simple: Create a QAssistantClient instance,
+    then call showPage() as often as necessary to show your help
+    pages. When you call showPage(), Qt Assistant will be launched if
+    it isn't already running.
+
+    The QAssistantClient instance can open (openAssistant()) or close
+    (closeAssistant()) Qt Assistant whenever required. If Qt Assistant
+    is open, isOpen() returns TRUE.
+
+    One QAssistantClient instance interacts with one Qt Assistant
+    instance, so every time you call openAssistant(), showPage() or
+    closeAssistant() they are applied to the particular Qt Assistant
+    instance associated with the QAssistantClient.
+
+    When you call openAssistant() the assistantOpened() signal is
+    emitted. Similarly when closeAssistant() is called,
+    assistantClosed() is emitted. In either case, if an error occurs,
+    error() is emitted.
+
+    This class is not included in the Qt library itself. To use it you
+    must link against \c libqassistantclient.a (Unix) or \c
+    qassistantclient.lib (Windows), which is built into \c INSTALL/lib
+    if you built the Qt tools (\c INSTALL is the directory where Qt is
+    installed). If you use qmake, then you can simply add the following
+    line to your pro file:
+
+    \code
+	LIBS += -lqassistantclient
+    \endcode
+
+    See also "Adding Documentation to Qt Assistant" in the \link
+    assistant.book Qt Assistant manual\endlink.
+*/
+
+/*!
+    \fn void QAssistantClient::assistantOpened()
+
+    This signal is emitted when Qt Assistant is open and the
+    client-server communication is set up.
+*/
+
+/*!
+    \fn void QAssistantClient::assistantClosed()
+
+    This signal is emitted when the connection to Qt Assistant is
+    closed. This happens when the user exits Qt Assistant, or when an
+    error in the server or client occurs, or if closeAssistant() is
+    called.
+*/
+
+/*!
+    \fn void QAssistantClient::error( const QString &msg )
+
+    This signal is emitted if Qt Assistant cannot be started or if an
+    error occurs during the initialization of the connection between
+    Qt Assistant and the calling application. The \a msg provides an
+    explanation of the error.
+*/
+
+/*!
+    Constructs an assistant client object. The \a path specifies the
+    path to the Qt Assistant executable. If \a path is an empty
+    string the system path (\c{%PATH%} or \c $PATH) is used.
+
+    The assistant client object is a child of \a parent and is called
+    \a name.
+*/
+QAssistantClient::QAssistantClient( const QString &path, QObject *parent, const char *name )
+    : QObject( parent, name ), host ( "localhost" )
+{
+    if ( path.isEmpty() )
+	assistantCommand = "assistant";
+    else {
+	QFileInfo fi( path );
+	if ( fi.isDir() )
+	    assistantCommand = path + "/assistant";
+	else
+	    assistantCommand = path;
+    }
+
+#if defined(Q_OS_MACX)
+    assistantCommand += ".app/Contents/MacOS/assistant";
+#elif defined(Q_WS_WIN)
+    if (!assistantCommand.endsWith(".exe"))
+        assistantCommand += ".exe";
+#endif
+    socket = new QSocket( this );
+    connect( socket, SIGNAL( connected() ),
+	    SLOT( socketConnected() ) );
+    connect( socket, SIGNAL( connectionClosed() ),
+	    SLOT( socketConnectionClosed() ) );
+    connect( socket, SIGNAL( error( int ) ),
+	    SLOT( socketError( int ) ) );
+    opened = FALSE;
+    proc = new QProcess( this );
+    port = 0;
+    pageBuffer = "";
+    connect( proc, SIGNAL( readyReadStderr() ),
+	     this, SLOT( readStdError() ) );
+}
+
+/*!
+    Destroys the assistant client object and frees up all allocated
+    resources.
+*/
+QAssistantClient::~QAssistantClient()
+{
+    if ( proc && proc->isRunning() ) {
+	proc->tryTerminate();
+	proc->kill();
+    }
+
+    if( dpointers ) {
+	QAssistantClientPrivate *d = (*dpointers)[ this ];
+	if( d ) {
+	    dpointers->remove( this );
+	    delete d;
+	    if( dpointers->isEmpty() ) {
+		delete dpointers;
+		dpointers = 0;
+	    }
+	}
+    }
+}
+
+/*!
+    This function opens Qt Assistant and sets up the client-server
+    communiction between the application and Qt Assistant. If it is
+    already open, this function does nothing. If an error occurs,
+    error() is emitted.
+
+    \sa assistantOpened()
+*/
+void QAssistantClient::openAssistant()
+{
+    if ( proc->isRunning() )
+	return;
+    proc->clearArguments();
+    proc->addArgument( assistantCommand );
+    proc->addArgument( "-server" );
+    if( !pageBuffer.isEmpty() ) {
+        proc->addArgument( "-file" );
+        proc->addArgument( pageBuffer );
+    }
+
+    QAssistantClientPrivate *d = data( this );
+    if( d ) {
+	QStringList::ConstIterator it = d->arguments.begin();
+	while( it!=d->arguments.end() ) {
+	    proc->addArgument( *it );
+	    ++it;
+	}
+    }
+
+    if ( !proc->launch( QString::null ) ) {
+	emit error( tr( "Cannot start Qt Assistant '%1'" )
+		    .arg( proc->arguments().join( " " ) ) );
+	return;
+    }
+    connect( proc, SIGNAL( readyReadStdout() ),
+	     this, SLOT( readPort() ) );
+}
+
+void QAssistantClient::readPort()
+{
+    QString p = proc->readLineStdout();
+    Q_UINT16 port = p.toUShort();
+    if ( port == 0 ) {
+	emit error( tr( "Cannot connect to Qt Assistant." ) );
+	return;
+    }
+    socket->connectToHost( host, port );
+    disconnect( proc, SIGNAL( readyReadStdout() ),
+		this, SLOT( readPort() ) );
+}
+
+/*!
+    Use this function to close Qt Assistant.
+
+    \sa assistantClosed()
+*/
+void QAssistantClient::closeAssistant()
+{
+    if ( !opened )
+	return;
+    proc->tryTerminate();
+    proc->kill();
+}
+
+/*!
+    Call this function to make Qt Assistant show a particular \a page.
+    The \a page is a filename (e.g. \c myhelpfile.html). See "Adding
+    Documentation to Qt Assistant" in the \link assistant.book Qt
+    Assistant manual\endlink for further information.
+
+    If Qt Assistant hasn't been \link openAssistant() opened\endlink
+    yet, this function will do nothing. You can use isOpen() to
+    determine whether Qt Assistant is up and running, or you can
+    connect to the asssistantOpened() signal.
+
+    \sa isOpen(), assistantOpened()
+*/
+void QAssistantClient::showPage( const QString &page )
+{
+    if ( !opened ) {
+	pageBuffer = page;
+	openAssistant();
+	pageBuffer = QString::null;	
+	return;
+    }
+    QTextStream os( socket );
+    os << page << "\n";
+}
+
+/*!
+    \property QAssistantClient::open
+    \brief Whether Qt Assistant is open.
+
+*/
+bool QAssistantClient::isOpen() const
+{
+    return opened;
+}
+
+void QAssistantClient::socketConnected()
+{
+    opened = TRUE;
+    if ( !pageBuffer.isEmpty() )
+	showPage( pageBuffer );
+    emit assistantOpened();
+}
+
+void QAssistantClient::socketConnectionClosed()
+{
+    opened = FALSE;
+    emit assistantClosed();
+}
+
+void QAssistantClient::socketError( int i )
+{
+    if ( i == QSocket::ErrConnectionRefused )
+	emit error( tr( "Could not connect to Assistant: Connection refused" ) );
+    else if ( i == QSocket::ErrHostNotFound )
+	emit error( tr( "Could not connect to Assistant: Host not found" ) );
+    else
+	emit error( tr( "Communication error" ) );
+}
+
+void QAssistantClient::readStdError()
+{
+    QString errmsg;
+    while ( proc->canReadLineStderr() ) {
+	errmsg += proc->readLineStderr();
+	errmsg += "\n";
+    }
+    if (!errmsg.isEmpty())
+	emit error( tr( errmsg.simplifyWhiteSpace() ) );
+}
+
+/*!
+    Sets the command line arguments used when Qt Assistant is
+    started to \a args.
+*/
+void QAssistantClient::setArguments( const QStringList &args )
+{
+    QAssistantClientPrivate *d = data( this, TRUE );
+    d->arguments = args;
+}
Index: trunk/tools/assistant/lib/qassistantclient.h
===================================================================
--- trunk/tools/assistant/lib/qassistantclient.h	(revision 191)
+++ trunk/tools/assistant/lib/qassistantclient.h	(revision 191)
@@ -0,0 +1,73 @@
+/**********************************************************************
+** Copyright (C) 2005-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the QAssistantClient library.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QASSISTANTCLIENT_H
+#define QASSISTANTCLIENT_H
+
+#include <qobject.h>
+
+class QSocket;
+class QProcess;
+
+class QAssistantClient : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY( bool open READ isOpen )
+
+public:
+    QAssistantClient( const QString &path, QObject *parent = 0, const char *name = 0 );
+    ~QAssistantClient();
+
+    bool isOpen() const;
+
+    void setArguments( const QStringList &args );
+
+public slots:
+    virtual void openAssistant();
+    virtual void closeAssistant();
+    virtual void showPage( const QString &page );
+
+signals:
+    void assistantOpened();
+    void assistantClosed();
+    void error( const QString &msg );
+
+private slots:
+    void socketConnected();
+    void socketConnectionClosed();
+    void readPort();
+    void socketError( int );
+    void readStdError();
+
+private:
+    QSocket *socket;
+    QProcess *proc;
+    Q_UINT16 port;
+    QString host, assistantCommand, pageBuffer;
+    bool opened;
+};
+
+#endif
Index: trunk/tools/assistant/main.cpp
===================================================================
--- trunk/tools/assistant/main.cpp	(revision 191)
+++ trunk/tools/assistant/main.cpp	(revision 191)
@@ -0,0 +1,335 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+#include "helpdialogimpl.h"
+#include "config.h"
+
+#include <qapplication.h>
+#include <qserversocket.h>
+#include <qsocket.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qdir.h>
+#include <qmessagebox.h>
+#include <qguardedptr.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <qtextcodec.h>
+
+#if defined(Q_WS_WIN) || defined(Q_WS_PM)
+#define INDEX_CHECK( text ) if( i+1 >= argc ) { QMessageBox::information( 0, "Qt Assistant", text ); return 1; }
+#else
+#define INDEX_CHECK( text ) if( i+1 >= argc ) { fprintf( stderr, text "\n" ); return 1; }
+#endif
+
+static bool allowFirstRun = TRUE;
+
+class AssistantSocket : public QSocket
+{
+    Q_OBJECT
+public:
+    AssistantSocket( int sock, QObject *parent = 0 );
+    ~AssistantSocket() {}
+
+signals:
+    void showLinkRequest( const QString& );
+
+private slots:
+    void readClient();
+    void connectionClosed();
+};
+
+
+class AssistantServer : public QServerSocket
+{
+    Q_OBJECT
+public:
+    AssistantServer( QObject* parent = 0 );
+    void newConnection( int socket );
+    Q_UINT16 getPort() const;
+
+signals:
+    void showLinkRequest( const QString& );
+    void newConnect();
+
+private:
+    Q_UINT16 p;
+};
+
+
+AssistantSocket::AssistantSocket( int sock, QObject *parent )
+    : QSocket( parent, 0 )
+{
+    connect( this, SIGNAL( readyRead() ),
+	     SLOT( readClient() ) );
+    connect( this, SIGNAL( connectionClosed() ),
+	     SLOT( connectionClosed() ) );
+    setSocket( sock );
+}
+
+void AssistantSocket::readClient()
+{
+    QString link = QString::null;
+    while ( canReadLine() )
+	link = readLine();
+    if ( !link.isNull() ) {
+	link = link.replace( "\n", "" );
+	link = link.replace( "\r", "" );
+	emit showLinkRequest( link );
+    }
+}
+
+void AssistantSocket::connectionClosed()
+{
+    delete this;
+}
+
+AssistantServer::AssistantServer( QObject *parent )
+    : QServerSocket( 0x7f000001, 0, 1, parent )
+{
+    if ( !ok() ) {
+	QMessageBox::critical( 0, tr( "Qt Assistant" ),
+		tr( "Failed to bind to port %1" ).arg( port() ) );
+        exit( 1 );
+    }
+    p = port();
+}
+
+Q_UINT16 AssistantServer::getPort() const
+{
+    return p;
+}
+
+void AssistantServer::newConnection( int socket )
+{
+    AssistantSocket *as = new AssistantSocket( socket, this );
+    connect( as, SIGNAL( showLinkRequest( const QString& ) ),
+	     this, SIGNAL( showLinkRequest( const QString& ) ) );
+    emit newConnect();
+}
+
+int main( int argc, char ** argv )
+{
+    bool withGUI = TRUE;
+    if ( argc > 1 ) {
+	QString arg( argv[1] );
+	arg = arg.lower();
+	if ( arg == "-addcontentfile"
+	    || arg == "-removecontentfile"
+#if !defined(Q_WS_WIN) && !defined(Q_WS_PM)
+	    || arg == "-help"
+#endif
+	    )
+	    withGUI = FALSE;
+    }
+    QApplication a(argc, argv, withGUI);
+
+    QString resourceDir;
+    AssistantServer *as = 0;
+    QStringList catlist;
+    QString file, profileName, aDocPath;
+    bool server = FALSE;
+    bool hideSidebar = FALSE;
+    bool startClean = FALSE;
+    bool configLoaded = FALSE;
+    if ( argc == 2 ) {
+	if ( (argv[1])[0] != '-' )
+	    file = argv[1];
+    }
+    if ( file.isEmpty() ) {
+	for ( int i = 1; i < argc; i++ ) {
+        if ( QString( argv[i] ).lower() == "-file" ) {
+		INDEX_CHECK( "Missing file argument!" );
+		i++;
+		file = argv[i];
+	    } else if ( QString( argv[i] ).lower() == "-server" ) {
+	        server = TRUE;
+	    } else if ( QString( argv[i] ).lower() == "-profile" ) {
+		INDEX_CHECK( "Missing profile argument!" );
+		profileName = argv[++i];
+	    } else if ( QString( argv[i] ).lower() == "-addcontentfile" ) {
+		INDEX_CHECK( "Missing content file!" );
+		Config *c = Config::loadConfig( QString::null );
+		QFileInfo file( argv[i+1] );
+		if( !file.exists() ) {
+		    fprintf( stderr, "Could not locate content file: '%s'\n",
+			     file.absFilePath().latin1() );
+		    fflush( stderr );
+		    return 1;
+		}
+		DocuParser *parser = DocuParser::createParser( file.absFilePath() );
+		if( parser ) {
+		    QFile f( argv[i+1] );
+		    if( !parser->parse( &f ) ) {
+			fprintf( stderr, "Failed to parse file: '%s'\n, ",
+				 file.absFilePath().latin1() );
+			fflush( stderr );
+			return 1;
+		    }
+		    parser->addTo( c->profile() );
+		    c->setDocRebuild( TRUE );
+		    c->save();
+		}
+		return 0;
+	    } else if ( QString( argv[i] ).lower() == "-removecontentfile" ) {
+		INDEX_CHECK( "Missing content file!" );
+		Config *c = Config::loadConfig( QString::null );
+		Profile *profile = c->profile();
+		QStringList entries = profile->docs.grep(argv[i+1]);
+		if (entries.count() == 0) {
+		    fprintf(stderr, "Could not locate content file: '%s'\n",
+			    argv[i+1]);
+		    fflush(stderr);
+		    return 1;
+        } else if (entries.count() > 1) {
+		    fprintf(stderr, "More than one entry matching file name found, "
+			"please specify full path to file");
+		    fflush(stderr);
+		    return 1;
+        } else {
+		    QFileInfo file(entries[0]);
+		    if( !file.exists() ) {
+			fprintf( stderr, "Could not locate content file: '%s'\n",
+			    file.absFilePath().latin1() );
+			fflush( stderr );
+			return 1;
+		    }
+		    profile->removeDocFileEntry( file.absFilePath() );
+		    c->setDocRebuild( TRUE );
+		    c->save();
+        }
+		return 0;
+        } else if ( QString( argv[i] ).lower() == "-docpath" ) {
+            INDEX_CHECK( "Missing path!" );
+            QDir dir( argv[i+1] );
+            if ( dir.exists() ) {
+                Config *c = Config::loadConfig( QString::null );
+                c->saveProfile(Profile::createDefaultProfile(dir.absPath()));
+                c->loadDefaultProfile();
+                c->setDocRebuild( TRUE );
+                c->save();
+                configLoaded = TRUE;
+                ++i;
+            } else {
+                fprintf( stderr, "The specified path does not exist!\n");
+                fflush( stderr );
+                return 1;
+            }
+        } else if ( QString( argv[i] ).lower() == "-hidesidebar" ) {
+		hideSidebar = TRUE;
+	    } else if ( QString( argv[i] ).lower() == "-help" ) {
+		QString helpText( "Usage: assistant [option]\n"
+				  "Options:\n"
+				  " -file Filename             assistant opens the specified file\n"
+				  " -server                    reads commands from a socket after\n"
+				  "                            assistant has started\n"
+				  " -profile fileName          starts assistant and displays the\n"
+				  "                            profile specified in the file fileName.\n"
+				  " -addContentFile file       adds the content file 'file' to the set of\n"
+				  "                            documentation available by default\n"
+				  " -removeContentFile file    removes the content file 'file' from the\n"
+				  "                            documentation available by default\n"
+                  " -docPath path              sets the Qt documentation root path to\n"
+                  "                            'path' and starts assistant\n"
+				  " -hideSidebar               assistant will hide the sidebar.\n"
+				  " -resourceDir               assistant will load translations from\n"
+                  "                            this directory.\n"
+				  " -help                      shows this help.");
+#if defined(Q_WS_WIN) || defined(Q_WS_PM)
+		QMessageBox::information( 0, "Qt Assistant", "<pre>" + helpText + "</pre>" );
+#else
+		printf( "%s\n", helpText.latin1() );
+#endif
+		exit( 0 );
+	    } else if ( QString( argv[i] ).lower() == "-resourcedir" ) {
+		INDEX_CHECK( "Missing resource directory argument!" );
+		resourceDir = QString( argv[++i] );
+        } else {
+            fprintf( stderr, "Unrecognized option '%s'. Try -help to get help.\n",
+                argv[i] );
+            fflush( stderr );
+            return 1;
+        }
+	}
+    }
+
+    if( resourceDir.isNull() )
+	resourceDir = qInstallPathTranslations();
+
+    QTranslator translator( 0 );
+    translator.load( QString("assistant_") + QTextCodec::locale(), resourceDir );
+    a.installTranslator( &translator );
+
+    QTranslator qtTranslator( 0 );
+    qtTranslator.load( QString("qt_") + QTextCodec::locale(), resourceDir );
+    a.installTranslator( &qtTranslator );
+
+
+    Config *conf = 0;
+    if (configLoaded)
+        conf = Config::configuration();
+    else
+        conf = Config::loadConfig( profileName );
+    if (!conf) {
+        fprintf( stderr, "Profile '%s' does not exist!\n", profileName.latin1() );
+        fflush( stderr );
+        return -1;
+    }
+
+    bool max = conf->isMaximized();
+    QStringList links = conf->source();
+    conf->hideSideBar( hideSidebar );
+
+    QGuardedPtr<MainWindow> mw = new MainWindow( 0, "Assistant" );
+
+    if ( server ) {
+	as = new AssistantServer();
+	printf("%d\n", as->port() );
+	fflush( stdout );
+	as->connect( as, SIGNAL( showLinkRequest( const QString& ) ),
+		     mw, SLOT( showLinkFromClient( const QString& ) ) );
+    }
+
+    if ( max )
+	mw->showMaximized();
+    else
+	mw->show();
+
+    if ( !file.isEmpty() )
+	mw->showLink( file );
+    else if ( file.isEmpty() )
+	mw->showLinks( links );
+
+    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
+
+    int appExec = a.exec();
+    delete (MainWindow*)mw;
+    return appExec;
+}
+
+#include "main.moc"
Index: trunk/tools/assistant/mainwindow.ui
===================================================================
--- trunk/tools/assistant/mainwindow.ui	(revision 191)
+++ trunk/tools/assistant/mainwindow.ui	(revision 191)
@@ -0,0 +1,663 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>MainWindow</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QMainWindow">
+    <property name="name">
+        <cstring>MainWindow</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>949</width>
+            <height>670</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Qt Assistant by Trolltech</string>
+    </property>
+</widget>
+<menubar>
+    <property name="name">
+        <cstring>menubar</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>949</width>
+            <height>29</height>
+        </rect>
+    </property>
+    <item text="&amp;File" name="fileMenu">
+        <action name="actionNewWindow"/>
+        <action name="actionOpenPage"/>
+        <action name="actionClosePage"/>
+        <separator/>
+        <action name="actionFilePrint"/>
+        <separator/>
+        <action name="actionClose"/>
+        <action name="actionFileExit"/>
+    </item>
+    <item text="&amp;Edit" name="editMenu">
+        <action name="actionEditCopy"/>
+        <action name="actionEditFind"/>
+	<action name="actionEditFindAgain"/>
+	<action name="actionEditFindAgainPrev"/>
+        <separator/>
+        <action name="actionSettings"/>
+    </item>
+    <item text="&amp;View" name="PopupMenu">
+        <action name="actionZoomIn"/>
+        <action name="actionZoomOut"/>
+        <separator/>
+    </item>
+    <item text="&amp;Go" name="goMenu">
+        <action name="actionGoPrevious"/>
+        <action name="actionGoNext"/>
+        <action name="actionGoHome"/>
+        <separator/>
+        <action name="actionNextPage"/>
+        <action name="actionPrevPage"/>
+    </item>
+    <item text="Boo&amp;kmarks" name="bookmarkMenu">
+    </item>
+    <item text="&amp;Help" name="helpMenu">
+        <action name="actionHelpAssistant"/>
+        <separator/>
+        <action name="helpAbout_Qt_AssistantAction"/>
+        <action name="actionAboutApplication"/>
+        <separator/>
+        <action name="actionHelpWhatsThis"/>
+    </item>
+</menubar>
+<toolbars>
+    <toolbar dock="2">
+        <property name="name">
+            <cstring>Toolbar</cstring>
+        </property>
+        <property name="label">
+            <string>Toolbar</string>
+        </property>
+        <action name="actionGoPrevious"/>
+        <action name="actionGoNext"/>
+        <action name="actionGoHome"/>
+        <separator/>
+        <action name="actionEditCopy"/>
+        <action name="actionEditFind"/>
+        <action name="actionFilePrint"/>
+        <separator/>
+        <action name="actionZoomIn"/>
+        <action name="actionZoomOut"/>
+        <separator/>
+        <action name="actionHelpWhatsThis"/>
+    </toolbar>
+    <toolbar dock="2">
+        <property name="name">
+            <cstring>goActionToolbar</cstring>
+        </property>
+        <property name="label">
+            <string>Go</string>
+        </property>
+    </toolbar>
+</toolbars>
+<actions>
+    <action>
+        <property name="name">
+            <cstring>actionFilePrint</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>print.png</iconset>
+        </property>
+        <property name="text">
+            <string>Print</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Print...</string>
+        </property>
+        <property name="whatsThis">
+            <string>Print the currently displayed page.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+P</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionFileExit</cstring>
+        </property>
+        <property name="text">
+            <string>Exit</string>
+        </property>
+        <property name="menuText">
+            <string>E&amp;xit</string>
+        </property>
+        <property name="whatsThis">
+            <string>Quit Qt Assistant.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Q</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionEditCopy</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>editcopy.png</iconset>
+        </property>
+        <property name="text">
+            <string>Copy</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Copy</string>
+        </property>
+        <property name="whatsThis">
+            <string>Copy the selected text to the clipboard.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+C</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionEditFind</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>find.png</iconset>
+        </property>
+        <property name="text">
+            <string>Find in Text</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Find in Text...</string>
+        </property>
+        <property name="whatsThis">
+            <string>Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+F</string>
+        </property>
+    </action>
+    <action>
+	<property name="name">
+	    <cstring>actionEditFindAgain</cstring>
+	</property>
+	<property name="menuText">
+	    <string>Find &amp;Next</string>
+	</property>
+	<property name="text">
+	    <string>Find Next</string>
+	</property>
+	<property name="accel">
+	    <string>F3</string>
+	</property>
+    </action>
+    <action>
+	<property name="name">
+	    <cstring>actionEditFindAgainPrev</cstring>
+	</property>
+	<property name="menuText">
+	    <string>Find &amp;Previous</string>
+	</property>
+	<property name="text">
+	    <string>Find Previous</string>
+	</property>
+	<property name="accel">
+	    <string>Shift+F3</string>
+	</property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionGoHome</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>home.png</iconset>
+        </property>
+        <property name="text">
+            <string>Home</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Home</string>
+        </property>
+        <property name="whatsThis">
+            <string>Go to the home page. Qt Assistant's home page is the Qt Reference Documentation.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Home</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionGoPrevious</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>previous.png</iconset>
+        </property>
+        <property name="text">
+            <string>Previous</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Previous</string>
+        </property>
+        <property name="whatsThis">
+            <string>Go to the previous page.</string>
+        </property>
+        <property name="accel">
+            <string>Alt+Left</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionGoNext</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>next.png</iconset>
+        </property>
+        <property name="text">
+            <string>Next</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Next</string>
+        </property>
+        <property name="whatsThis">
+            <string>Go to the next page.</string>
+        </property>
+        <property name="accel">
+            <string>Alt+Right</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>helpAbout_Qt_AssistantAction</cstring>
+        </property>
+        <property name="text">
+            <string>About Qt Assistant</string>
+        </property>
+        <property name="menuText">
+            <string>About Qt Assistant</string>
+        </property>
+        <property name="whatsThis">
+            <string>Display further information about Qt Assistant.</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionAboutApplication</cstring>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionZoomIn</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>zoomin.png</iconset>
+        </property>
+        <property name="text">
+            <string>Zoom in</string>
+        </property>
+        <property name="menuText">
+            <string>Zoom &amp;in</string>
+        </property>
+        <property name="whatsThis">
+            <string>Zoom in on the document, i.e. increase the font size.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl++</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionZoomOut</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>zoomout.png</iconset>
+        </property>
+        <property name="text">
+            <string>Zoom out</string>
+        </property>
+        <property name="menuText">
+            <string>Zoom &amp;out</string>
+        </property>
+        <property name="whatsThis">
+            <string>Zoom out on the document, i.e. decrease the font size.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+-</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionSettings</cstring>
+        </property>
+        <property name="text">
+            <string>Settings</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Settings...</string>
+        </property>
+        <property name="whatsThis">
+            <string>Open the settings dialog.</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionNewWindow</cstring>
+        </property>
+        <property name="text">
+            <string>New Window</string>
+        </property>
+        <property name="menuText">
+            <string>New Window</string>
+        </property>
+        <property name="whatsThis">
+            <string>Open a new window.</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+N</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionClose</cstring>
+        </property>
+        <property name="text">
+            <string>Close</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Close</string>
+        </property>
+        <property name="whatsThis">
+            <string>Close the current window.</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionAddBookmark</cstring>
+        </property>
+        <property name="text">
+            <string>Add Bookmark</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Add Bookmark</string>
+        </property>
+        <property name="whatsThis">
+            <string>Add the currently displayed page as a new bookmark.</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionHelpWhatsThis</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>whatsthis.xpm</iconset>
+        </property>
+        <property name="text">
+            <string>What's This?</string>
+        </property>
+        <property name="statusTip">
+            <string>"What's This?" context sensitive help.</string>
+        </property>
+        <property name="whatsThis">
+            <string>"What's This?" context sensitive help.</string>
+        </property>
+        <property name="accel">
+            <string>Shift+F1</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionOpenPage</cstring>
+        </property>
+        <property name="text">
+            <string>Add Tab</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Alt+N</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionNextPage</cstring>
+        </property>
+        <property name="text">
+            <string>Next Tab</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Alt+Right</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionPrevPage</cstring>
+        </property>
+        <property name="text">
+            <string>Previous Tab</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Alt+Left</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionClosePage</cstring>
+        </property>
+        <property name="text">
+            <string>Close Tab</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Alt+Q</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>actionHelpAssistant</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>assistant.png</iconset>
+        </property>
+        <property name="text">
+            <string>Qt Assistant Manual</string>
+        </property>
+        <property name="accel">
+            <string>F1</string>
+        </property>
+    </action>
+</actions>
+<connections>
+    <connection>
+        <sender>actionGoHome</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>goHome()</slot>
+    </connection>
+    <connection>
+        <sender>helpAbout_Qt_AssistantAction</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>about()</slot>
+    </connection>
+    <connection>
+        <sender>actionEditFind</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>find()</slot>
+    </connection>
+    <connection>
+        <sender>actionEditFindAgain</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>findAgain()</slot>
+    </connection>
+    <connection>
+        <sender>actionEditFindAgainPrev</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>findAgainPrev()</slot>
+    </connection>
+    <connection>
+        <sender>actionFilePrint</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>print()</slot>
+    </connection>
+    <connection>
+        <sender>actionSettings</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>showSettingsDialog()</slot>
+    </connection>
+    <connection>
+        <sender>actionNewWindow</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>newWindow()</slot>
+    </connection>
+    <connection>
+        <sender>actionClose</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>close()</slot>
+    </connection>
+    <connection>
+        <sender>actionHelpWhatsThis</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>whatsThis()</slot>
+    </connection>
+    <connection>
+        <sender>actionHelpAssistant</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>showAssistantHelp()</slot>
+    </connection>
+    <connection>
+        <sender>actionAboutApplication</sender>
+        <signal>activated()</signal>
+        <receiver>MainWindow</receiver>
+        <slot>aboutApplication()</slot>
+    </connection>
+</connections>
+<includes>
+    <include location="global" impldecl="in implementation">qtoolbutton.h</include>
+    <include location="local" impldecl="in implementation">settingsdialogimpl.h</include>
+    <include location="global" impldecl="in implementation">qmessagebox.h</include>
+    <include location="global" impldecl="in implementation">qfontdatabase.h</include>
+    <include location="global" impldecl="in implementation">qaccel.h</include>
+    <include location="global" impldecl="in implementation">qcombobox.h</include>
+    <include location="global" impldecl="in implementation">qpaintdevicemetrics.h</include>
+    <include location="global" impldecl="in implementation">qsimplerichtext.h</include>
+    <include location="global" impldecl="in implementation">qfileinfo.h</include>
+    <include location="global" impldecl="in implementation">qtextstream.h</include>
+    <include location="global" impldecl="in implementation">qdockwindow.h</include>
+    <include location="global" impldecl="in implementation">stdlib.h</include>
+    <include location="global" impldecl="in implementation">qmime.h</include>
+    <include location="local" impldecl="in implementation">helpwindow.h</include>
+    <include location="global" impldecl="in implementation">qstylesheet.h</include>
+    <include location="global" impldecl="in implementation">qapplication.h</include>
+    <include location="local" impldecl="in implementation">helpdialogimpl.h</include>
+    <include location="global" impldecl="in implementation">qdir.h</include>
+    <include location="global" impldecl="in implementation">qprinter.h</include>
+    <include location="global" impldecl="in implementation">qpainter.h</include>
+    <include location="global" impldecl="in implementation">qurl.h</include>
+    <include location="global" impldecl="in implementation">qstatusbar.h</include>
+    <include location="global" impldecl="in implementation">qlineedit.h</include>
+    <include location="global" impldecl="in implementation">qsettings.h</include>
+    <include location="global" impldecl="in implementation">qcheckbox.h</include>
+    <include location="local" impldecl="in implementation">tabbedbrowser.h</include>
+    <include location="global" impldecl="in declaration">qptrlist.h</include>
+    <include location="global" impldecl="in declaration">qguardedptr.h</include>
+    <include location="global" impldecl="in declaration">qmap.h</include>
+    <include location="local" impldecl="in declaration">finddialog.h</include>
+    <include location="global" impldecl="in declaration">qstringlist.h</include>
+    <include location="local" impldecl="in declaration">helpwindow.h</include>
+    <include location="local" impldecl="in implementation">mainwindow.ui.h</include>
+</includes>
+<forwards>
+    <forward>class SettingsDialog;</forward>
+    <forward>class HelpDialog;</forward>
+    <forward>class TabbedBrowser;</forward>
+    <forward>class QTimerEvent;</forward>
+</forwards>
+<variables>
+    <variable>QPtrList&lt;QAction&gt; *goActions;</variable>
+    <variable>int setupCompleted:1;</variable>
+    <variable>TabbedBrowser *tabs;</variable>
+    <variable>SettingsDialog * settingsDia;</variable>
+    <variable>QMap&lt;int, QString&gt; bookmarks;</variable>
+    <variable>HelpDialog *helpDock;</variable>
+    <variable>QDockWindow *dw;</variable>
+    <variable>QGuardedPtr&lt;FindDialog&gt; findDialog;</variable>
+    <variable>static QPtrList&lt;MainWindow&gt; *windows;</variable>
+    <variable>QMap&lt;QAction*,QString&gt; *goActionDocFiles;</variable>
+    <variable>QStringList pendingLinks;</variable>
+    <variable>QPtrList&lt;HelpWindow&gt; pendingBrowsers</variable>
+</variables>
+<slots>
+    <slot>init()</slot>
+    <slot>setup()</slot>
+    <slot>destroy()</slot>
+    <slot>about()</slot>
+    <slot>aboutApplication()</slot>
+    <slot>find()</slot>
+    <slot>findAgain()</slot>
+    <slot>findAgainPrev()</slot>
+    <slot>goHome()</slot>
+    <slot>print()</slot>
+    <slot>updateBookmarkMenu()</slot>
+    <slot>setupBookmarkMenu()</slot>
+    <slot>showBookmark( int id )</slot>
+    <slot>showLinkFromClient( const QString &amp; link )</slot>
+    <slot>showLink( const QString &amp; link )</slot>
+    <slot>showLinks( const QStringList &amp; links )</slot>
+    <slot>showQtHelp()</slot>
+    <slot>showSettingsDialog()</slot>
+    <slot>showWebBrowserSettings()</slot>
+    <slot>showSettingsDialog( int page )</slot>
+    <slot>hide()</slot>
+    <slot returnType="MainWindow *">newWindow()</slot>
+    <slot>saveSettings()</slot>
+    <slot>saveToolbarSettings()</slot>
+    <slot>showSearchLink( const QString &amp; link, const QStringList &amp; terms )</slot>
+    <slot>showGoActionLink()</slot>
+    <slot>showAssistantHelp()</slot>
+    <slot>updateProfileSettings()</slot>
+    <slot>backwardAvailable(bool)</slot>
+    <slot>forwardAvailable(bool)</slot>
+    <slot>browserTabChanged()</slot>
+</slots>
+<functions>
+    <function access="private">setupGoActions()</function>
+    <function access="private" returnType="bool">insertActionSeparator()</function>
+    <function returnType="bool">close( bool alsoDelete )</function>
+    <function specifier="non virtual" returnType="TabbedBrowser *">browsers()</function>
+    <function returnType="HelpDialog*">helpDialog()</function>
+    <function>timerEvent(QTimerEvent *)</function>
+</functions>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/mainwindow.ui.h
===================================================================
--- trunk/tools/assistant/mainwindow.ui.h	(revision 191)
+++ trunk/tools/assistant/mainwindow.ui.h	(revision 191)
@@ -0,0 +1,693 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "config.h"
+
+#include <qtabwidget.h>
+#include <qfileinfo.h>
+#include <qaccel.h>
+#include <qobjectlist.h>
+#include <qtimer.h>
+#include <qdragobject.h>
+#include <qfontinfo.h>
+#include <qaccel.h>
+#include <qmetaobject.h>
+#include <qeventloop.h>
+
+QPtrList<MainWindow> *MainWindow::windows = 0;
+
+#if defined(Q_WS_WIN)
+extern Q_EXPORT int qt_ntfs_permission_lookup;
+#endif
+
+void MainWindow::init()
+{
+#if defined(Q_WS_WIN)
+    // Workaround for QMimeSourceFactory failing in QFileInfo::isReadable() for
+    // certain user configs. See task: 34372
+    qt_ntfs_permission_lookup = 0;
+#endif
+    setupCompleted = FALSE;
+
+    goActions = new QPtrList<QAction>;
+    goActionDocFiles = new QMap<QAction*,QString>;
+    goActions->setAutoDelete( TRUE );
+
+    if ( !windows )
+	windows = new QPtrList<MainWindow>;
+    windows->append( this );
+    tabs = new TabbedBrowser( this, "qt_assistant_tabbedbrowser" );
+    setCentralWidget( tabs );
+    settingsDia = 0;
+
+    Config *config = Config::configuration();
+
+    updateProfileSettings();
+
+    dw = new QDockWindow( QDockWindow::InDock, this );
+    helpDock = new HelpDialog( dw, this );
+    dw->setResizeEnabled( TRUE );
+    dw->setCloseMode( QDockWindow::Always );
+    addDockWindow( dw, DockLeft );
+    dw->setWidget( helpDock );
+    dw->setCaption( "Sidebar" );
+    dw->setFixedExtentWidth( 320 );
+
+    // read geometry configuration
+    setupGoActions();
+
+    if ( !config->isMaximized() ) {
+	QRect geom = config->geometry();
+	if( geom.isValid() ) {
+	    resize(geom.size());
+	    move(geom.topLeft());
+	}
+    }
+
+    QString mainWindowLayout = config->mainWindowLayout();
+
+    QTextStream ts( &mainWindowLayout, IO_ReadOnly );
+    ts >> *this;
+
+    if ( config->sideBarHidden() )
+	dw->hide();
+
+    tabs->setup();
+    QTimer::singleShot( 0, this, SLOT( setup() ) );
+#if defined(Q_OS_MACX)
+    // Use the same forward and backward browser shortcuts as Safari and Internet Explorer do
+    // on the Mac. This means that if you have access to one of those cool Intellimice, the thing
+    // works just fine, since that's how Microsoft hacked it.
+    actionGoPrevious->setAccel(QKeySequence(Qt::CTRL|Qt::Key_Left));
+    actionGoNext->setAccel(QKeySequence(Qt::CTRL|Qt::Key_Right));
+#endif
+}
+
+void MainWindow::setup()
+{
+    if( setupCompleted )
+	return;
+
+    qApp->setOverrideCursor( QCursor( Qt::WaitCursor ) );
+    statusBar()->message( tr( "Initializing Qt Assistant..." ) );
+    setupCompleted = TRUE;
+    helpDock->initialize();
+    connect( actionGoPrevious, SIGNAL( activated() ), tabs, SLOT( backward() ) );
+    connect( actionGoNext, SIGNAL( activated() ), tabs, SLOT( forward() ) );
+    connect( actionEditCopy, SIGNAL( activated() ), tabs, SLOT( copy() ) );
+    connect( actionFileExit, SIGNAL( activated() ), qApp, SLOT( closeAllWindows() ) );
+    connect( actionAddBookmark, SIGNAL( activated() ),
+	     helpDock, SLOT( addBookmark() ) );
+    connect( helpDock, SIGNAL( showLink( const QString& ) ),
+	     this, SLOT( showLink( const QString& ) ) );
+    connect( helpDock, SIGNAL( showSearchLink( const QString&, const QStringList& ) ),
+	     this, SLOT( showSearchLink( const QString&, const QStringList&) ) );
+
+    connect( bookmarkMenu, SIGNAL( activated( int ) ),
+	     this, SLOT( showBookmark( int ) ) );
+    connect( actionZoomIn, SIGNAL( activated() ), tabs, SLOT( zoomIn() ) );
+    connect( actionZoomOut, SIGNAL( activated() ), tabs, SLOT( zoomOut() ) );
+
+    connect( actionOpenPage, SIGNAL( activated() ), tabs, SLOT( newTab() ) );
+    connect( actionClosePage, SIGNAL( activated() ), tabs, SLOT( closeTab() ) );
+    connect( actionNextPage, SIGNAL( activated() ), tabs, SLOT( nextTab() ) );
+    connect( actionPrevPage, SIGNAL( activated() ), tabs, SLOT( previousTab() ) );
+
+
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
+    QAccel *acc = new QAccel( this );
+//     acc->connectItem( acc->insertItem( Key_F5 ), browser, SLOT( reload() ) );
+    acc->connectItem( acc->insertItem( QKeySequence("SHIFT+CTRL+=") ), actionZoomIn, SIGNAL(activated()) );
+#endif
+
+    QAccel *a = new QAccel( this, dw );
+    a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+T") ) ),
+		    helpDock, SLOT( toggleContents() ) );
+    a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+I") ) ),
+		    helpDock, SLOT( toggleIndex() ) );
+    a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+B") ) ),
+		    helpDock, SLOT( toggleBookmarks() ) );
+    a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+S") ) ),
+		    helpDock, SLOT( toggleSearch() ) );
+
+    Config *config = Config::configuration();
+
+    setupBookmarkMenu();
+    PopupMenu->insertItem( tr( "Vie&ws" ), createDockWindowMenu() );
+    helpDock->tabWidget->setCurrentPage( config->sideBarPage() );
+
+    qApp->restoreOverrideCursor();
+    actionGoPrevious->setEnabled( FALSE );
+    actionGoNext->setEnabled( FALSE );
+}
+
+void MainWindow::setupGoActions()
+{
+    Config *config = Config::configuration();
+    QStringList titles = config->docTitles();
+    QAction *action = 0;
+
+    static bool separatorInserted = FALSE;
+
+    QAction *cur = goActions->first();
+    while( cur ) {
+	cur->removeFrom( goMenu );
+	cur->removeFrom( goActionToolbar );
+	cur = goActions->next();
+    }
+    goActions->clear();
+    goActionDocFiles->clear();
+
+    int addCount = 0;
+
+    QStringList::ConstIterator it = titles.begin();
+    for ( ; it != titles.end(); ++it ) {
+	QString title = *it;
+	QPixmap pix = config->docIcon( title );
+	if( !pix.isNull() ) {
+	    if( !separatorInserted ) {
+		goMenu->insertSeparator();
+		separatorInserted = TRUE;
+	    }
+	    action = new QAction( title, QIconSet( pix ), title, 0, 0 );
+	    action->addTo( goMenu );
+	    action->addTo( goActionToolbar );
+	    goActions->append( action );
+	    goActionDocFiles->insert( action, config->indexPage( title ) );
+	    connect( action, SIGNAL( activated() ),
+		     this, SLOT( showGoActionLink() ) );
+	    ++addCount;
+	}
+    }
+    if( !addCount )
+	goActionToolbar->hide();
+    else
+	goActionToolbar->show();
+
+}
+
+void MainWindow::browserTabChanged()
+{
+    if (tabs->currentBrowser()) {
+        actionGoPrevious->setEnabled(tabs->currentBrowser()->isBackwardAvailable());
+        actionGoNext->setEnabled(tabs->currentBrowser()->isForwardAvailable());
+    }
+}
+
+bool MainWindow::insertActionSeparator()
+{
+    goMenu->insertSeparator();
+    Toolbar->addSeparator();
+    return TRUE;
+}
+
+bool MainWindow::close( bool alsoDelete )
+{
+    saveSettings();
+    return QMainWindow::close( alsoDelete );
+}
+
+void MainWindow::destroy()
+{
+    windows->removeRef( this );
+    if ( windows->isEmpty() ) {
+	delete windows;
+	windows = 0;
+    }
+    delete goActions;
+    delete goActionDocFiles;
+}
+
+void MainWindow::about()
+{
+    QMessageBox box( this );
+    box.setText( "<center><img src=\"splash.png\">"
+		 "<p>Version " + QString(QT_VERSION_STR) + "</p>"
+		 "<p>Copyright (C) 2000-2007 Trolltech ASA. All rights reserved."
+		 "</p></center><p></p>"
+		 "<p>Qt Commercial Edition license holders: This program is"
+		 " licensed to you under the terms of the Qt Commercial License"
+		 " Agreement. For details, see the file LICENSE that came with"
+		 " this software distribution.</p><p></p>"
+		 "<p>Qt Open Source Edition users: This program is licensed to you"
+		 " under the terms of the GNU General Public License Version 2."
+		 " For details, see the file LICENSE.GPL that came with this"
+		 " software distribution.</p><p>The program is provided AS IS"
+		 " with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF"
+		 " DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE."
+		 "</p>" );
+    box.setCaption( tr( "Qt Assistant" ) );
+    box.setIcon( QMessageBox::NoIcon );
+    box.exec();
+}
+
+void MainWindow::aboutApplication()
+{
+    QString url = Config::configuration()->aboutURL();
+    if ( url == "about_qt" ) {
+	QMessageBox::aboutQt( this, "Qt Assistant" );
+	return;
+    }
+    QString text;
+    QFile file( url );
+    if( file.exists() && file.open( IO_ReadOnly ) )
+	text = QString( file.readAll() );
+    if( text.isNull() )
+	text = tr( "Failed to open about application contents in file: '%1'" ).arg( url );
+
+    QMessageBox box( this );
+    box.setText( text );
+    box.setCaption( Config::configuration()->aboutApplicationMenuText() );
+    box.setIcon( QMessageBox::NoIcon );
+    box.exec();
+}
+
+void MainWindow::find()
+{
+    if ( !findDialog )
+	findDialog = new FindDialog( this );
+    findDialog->comboFind->setFocus();
+    findDialog->comboFind->lineEdit()->setSelection(
+        0, findDialog->comboFind->lineEdit()->text().length() );
+    findDialog->show();
+}
+
+void MainWindow::findAgain()
+{
+    if (!findDialog || !findDialog->hasFindExpression()) {
+	find();
+	return;
+    }
+    findDialog->doFind(TRUE);
+}
+
+void MainWindow::findAgainPrev()
+{
+    if (!findDialog || !findDialog->hasFindExpression()) {
+	find();
+	return;
+    }
+    findDialog->doFind(FALSE);
+}
+
+void MainWindow::goHome()
+{
+    showLink( Config::configuration()->homePage() );
+}
+
+void MainWindow::print()
+{
+#ifndef	QT_NO_PRINTER
+    QPrinter printer( QPrinter::HighResolution );
+    printer.setFullPage( TRUE );
+    if ( printer.setup( this ) ) {
+	QPainter p;
+	if ( !p.begin( &printer ) )
+	    return;
+
+	qApp->setOverrideCursor( QCursor( Qt::WaitCursor ) );
+	qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
+
+	QPaintDeviceMetrics metrics(p.device());
+	QTextBrowser *browser = tabs->currentBrowser();
+	int dpiy = metrics.logicalDpiY();
+	int margin = (int) ( (2/2.54)*dpiy );
+	QRect view( margin,
+		    margin,
+		    metrics.width() - 2 * margin,
+		    metrics.height() - 2 * margin );
+	QSimpleRichText richText( browser->text(), browser->QWidget::font(), browser->context(),
+				  browser->styleSheet(), browser->mimeSourceFactory(),
+				  view.height(), Qt::black, FALSE );
+	richText.setWidth( &p, view.width() );
+	int page = 1;
+	do {
+	    qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
+
+	    richText.draw( &p, margin, margin, view, palette().active() );
+	    view.moveBy( 0, view.height() );
+	    p.translate( 0 , -view.height() );
+	    p.drawText( view.right() - p.fontMetrics().width( QString::number(page) ),
+			view.bottom() + p.fontMetrics().ascent() + 5, QString::number(page) );
+	    if ( view.top() - margin >= richText.height() )
+		break;
+	    printer.newPage();
+	    page++;
+	} while (TRUE);
+
+	qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
+	qApp->restoreOverrideCursor();
+    }
+#endif
+}
+
+void MainWindow::updateBookmarkMenu()
+{
+    for ( MainWindow *mw = windows->first(); mw; mw = windows->next() )
+	mw->setupBookmarkMenu();
+}
+
+void MainWindow::setupBookmarkMenu()
+{
+    bookmarkMenu->clear();
+    bookmarks.clear();
+    actionAddBookmark->addTo( bookmarkMenu );
+
+    QFile f( QDir::homeDirPath() + "/.assistant/bookmarks." +
+	Config::configuration()->profileName() );
+    if ( !f.open( IO_ReadOnly ) )
+	return;
+    QTextStream ts( &f );
+    bookmarkMenu->insertSeparator();
+    while ( !ts.atEnd() ) {
+	QString title = ts.readLine();
+	QString link = ts.readLine();
+	bookmarks.insert( bookmarkMenu->insertItem( title ), link );
+    }
+}
+
+void MainWindow::showBookmark( int id )
+{
+    if ( bookmarks.find( id ) != bookmarks.end() )
+	showLink( *bookmarks.find( id ) );
+}
+
+void MainWindow::showLinkFromClient( const QString &link )
+{
+    setWindowState(windowState() & ~WindowMinimized);
+    raise();
+    setActiveWindow();
+    showLink( link );
+}
+
+void MainWindow::showLink( const QString &link )
+{
+    if( link.isEmpty() ) {
+	qWarning( "The link is empty!" );
+    }
+
+    int find = link.find( '#' );
+    QString name = find >= 0 ? link.left( find ) : link;
+
+    QString absLink = link;
+    QFileInfo fi( name );
+    if ( fi.isRelative() ) {
+	if ( find >= 0 )
+	    absLink = fi.absFilePath() + link.right( link.length() - find );
+	else
+	    absLink = fi.absFilePath();
+    }
+    if( fi.exists() ) {
+	tabs->setSource( absLink );
+	tabs->currentBrowser()->setFocus();
+    } else {
+	// ### Default 404 site!
+	statusBar()->message( tr( "Failed to open link: '%1'" ).arg( link ), 5000 );
+	tabs->currentBrowser()->setText( tr( "<div align=\"center\"><h1>The page could not be found!</h1><br>"
+					     "<h3>'%1'</h3></div>").arg( link ) );
+	tabs->updateTitle( tr( "Error..." ) );
+    }
+}
+
+void MainWindow::showLinks( const QStringList &links )
+{
+    if ( links.size() == 0 ) {
+	qWarning( "MainWindow::showLinks() - Empty link" );
+	return;
+    }
+
+    if ( links.size() == 1 ) {
+	showLink( links.first() );
+	return;
+    }
+
+    pendingLinks = links;
+
+    QStringList::ConstIterator it = pendingLinks.begin();
+    // Initial showing, The tab is empty so update that without creating it first
+    if ( tabs->currentBrowser()->source().isEmpty() ) {
+	pendingBrowsers.append(tabs->currentBrowser());
+	tabs->setTitle(tabs->currentBrowser(), pendingLinks.first());
+    }
+    ++it;
+
+    while( it != pendingLinks.end() ) {
+	pendingBrowsers.append( tabs->newBackgroundTab(*it) );
+	++it;
+    }
+
+    startTimer(50);
+    return;
+}
+
+void MainWindow::timerEvent(QTimerEvent *e)
+{
+    QString link = pendingLinks.first();
+    HelpWindow *win = pendingBrowsers.first();
+    pendingLinks.pop_front();
+    pendingBrowsers.removeFirst();
+    if (pendingLinks.size() == 0)
+	killTimer(e->timerId());
+    win->setSource(link);
+}
+
+void MainWindow::showQtHelp()
+{
+    showLink( QString( qInstallPathDocs() ) + "/html/index.html" );
+}
+
+void MainWindow::showSettingsDialog()
+{
+    showSettingsDialog( -1 );
+}
+
+void MainWindow::showWebBrowserSettings()
+{
+    showSettingsDialog( 1 );
+}
+
+void MainWindow::showSettingsDialog( int page )
+{
+    if ( !settingsDia ){
+	settingsDia = new SettingsDialog( this );
+    }
+    QFontDatabase fonts;
+    settingsDia->fontCombo->clear();
+    settingsDia->fontCombo->insertStringList( fonts.families() );
+    settingsDia->fontCombo->lineEdit()->setText( tabs->browserFont().family() );
+    settingsDia->fixedfontCombo->clear();
+    settingsDia->fixedfontCombo->insertStringList( fonts.families() );
+    settingsDia->fixedfontCombo->lineEdit()->setText( tabs->styleSheet()->item( "pre" )->fontFamily() );
+    settingsDia->linkUnderlineCB->setChecked( tabs->linkUnderline() );
+    settingsDia->colorButton->setPaletteBackgroundColor( tabs->palette().color( QPalette::Active, QColorGroup::Link ) );
+    if ( page != -1 )
+	settingsDia->settingsTab->setCurrentPage( page );
+
+    int ret = settingsDia->exec();
+
+    if ( ret != QDialog::Accepted )
+	return;
+
+    QObjectList *lst = (QObjectList*)Toolbar->children();
+    QObject *obj;
+    for ( obj = lst->last(); obj; obj = lst->prev() ) {
+	if ( obj->isA( "QToolBarSeparator" ) ) {
+	    delete obj;
+	    obj = 0;
+	    break;
+	}
+    }
+
+    setupGoActions();
+
+    QFont fnt( tabs->browserFont() );
+    fnt.setFamily( settingsDia->fontCombo->currentText() );
+    tabs->setBrowserFont( fnt );
+    tabs->setLinkUnderline( settingsDia->linkUnderlineCB->isChecked() );
+
+    QPalette pal = tabs->palette();
+    QColor lc = settingsDia->colorButton->paletteBackgroundColor();
+    pal.setColor( QPalette::Active, QColorGroup::Link, lc );
+    pal.setColor( QPalette::Inactive, QColorGroup::Link, lc );
+    pal.setColor( QPalette::Disabled, QColorGroup::Link, lc );
+    tabs->setPalette( pal );
+
+    QString family = settingsDia->fixedfontCombo->currentText();
+
+    QStyleSheet *sh = tabs->styleSheet();
+    sh->item( "pre" )->setFontFamily( family );
+    sh->item( "code" )->setFontFamily( family );
+    sh->item( "tt" )->setFontFamily( family );
+    tabs->currentBrowser()->setText( tabs->currentBrowser()->text() );
+    showLink( tabs->currentBrowser()->source() );
+}
+
+void MainWindow::hide()
+{
+    saveToolbarSettings();
+    QMainWindow::hide();
+}
+
+MainWindow* MainWindow::newWindow()
+{
+    saveSettings();
+    saveToolbarSettings();
+    MainWindow *mw = new MainWindow;
+    mw->move( geometry().topLeft() );
+    if ( isMaximized() )
+	mw->showMaximized();
+    else
+	mw->show();
+    mw->goHome();
+    return mw;
+}
+
+void MainWindow::saveSettings()
+{
+    Config *config = Config::configuration();
+    config->setFontFamily( tabs->browserFont().family() );
+    config->setFontSize( tabs->currentBrowser()->font().pointSize() );
+    config->setFontFixedFamily( tabs->styleSheet()->item( "pre" )->fontFamily() );
+    config->setLinkUnderline( tabs->linkUnderline() );
+    config->setLinkColor( tabs->palette().color( QPalette::Active, QColorGroup::Link ).name() );
+    config->setSideBarPage( helpDock->tabWidget->currentPageIndex() );
+    config->setGeometry( QRect( x(), y(), width(), height() ) );
+    config->setMaximized( isMaximized() );
+
+    // Create list of the tab urls
+    QStringList lst;
+    QPtrList<HelpWindow> browsers = tabs->browsers();
+    HelpWindow *browser = browsers.first();
+    while (browser) {
+	lst << browser->source();
+	browser = browsers.next();
+    }
+    config->setSource(lst);
+    config->save();
+}
+
+void MainWindow::saveToolbarSettings()
+{
+    QString mainWindowLayout;
+    QTextStream ts( &mainWindowLayout, IO_WriteOnly );
+    ts << *this;
+    Config::configuration()->setMainWindowLayout( mainWindowLayout );
+}
+
+TabbedBrowser* MainWindow::browsers()
+{
+    return tabs;
+}
+
+void MainWindow::showSearchLink( const QString &link, const QStringList &terms )
+{
+    HelpWindow * hw = tabs->currentBrowser();
+    hw->blockScrolling( TRUE );
+    hw->setCursor( waitCursor );
+    if ( hw->source() == link )
+	hw->reload();
+    else
+	showLink( link );
+    hw->sync();
+    hw->setCursor( arrowCursor );
+
+    hw->viewport()->setUpdatesEnabled( FALSE );
+    int minPar = INT_MAX;
+    int minIndex = INT_MAX;
+    QStringList::ConstIterator it = terms.begin();
+    for ( ; it != terms.end(); ++it ) {
+	int para = 0;
+	int index = 0;
+	bool found = hw->find( *it, FALSE, TRUE, TRUE, &para, &index );
+	while ( found ) {
+	    if ( para < minPar ) {
+		minPar = para;
+		minIndex = index;
+	    }
+	    hw->setColor( red );
+	    found = hw->find( *it, FALSE, TRUE, TRUE );
+	}
+    }
+    hw->blockScrolling( FALSE );
+    hw->viewport()->setUpdatesEnabled( TRUE );
+    hw->setCursorPosition( minPar, minIndex );
+    hw->updateContents();
+}
+
+
+void MainWindow::showGoActionLink()
+{
+    const QObject *origin = sender();
+    if( !origin ||
+	origin->metaObject()->className() != QString( "QAction" ) )
+	return;
+
+    QAction *action = (QAction*) origin;
+    QString docfile = *( goActionDocFiles->find( action ) );
+    showLink( docfile );
+}
+
+void MainWindow::showAssistantHelp()
+{
+    showLink( Config::configuration()->assistantDocPath() + "/assistant.html" );
+}
+
+HelpDialog* MainWindow::helpDialog()
+{
+    return helpDock;
+}
+
+void MainWindow::backwardAvailable( bool enable )
+{
+    actionGoPrevious->setEnabled( enable );
+}
+
+void MainWindow::forwardAvailable( bool enable )
+{
+    actionGoNext->setEnabled( enable );
+}
+
+void MainWindow::updateProfileSettings()
+{
+    Config *config = Config::configuration();
+#ifndef Q_WS_MACX
+    setIcon( config->applicationIcon() );
+#endif
+    helpMenu->clear();
+    actionHelpAssistant->addTo( helpMenu );
+    helpMenu->insertSeparator();
+    helpAbout_Qt_AssistantAction->addTo( helpMenu );
+    if ( !config->aboutApplicationMenuText().isEmpty() )
+	actionAboutApplication->addTo( helpMenu );
+    helpMenu->insertSeparator();
+    actionHelpWhatsThis->addTo( helpMenu );
+
+    actionAboutApplication->setMenuText( config->aboutApplicationMenuText() );
+
+    if( !config->title().isNull() )
+	setCaption( config->title() );
+}
Index: trunk/tools/assistant/profile.cpp
===================================================================
--- trunk/tools/assistant/profile.cpp	(revision 191)
+++ trunk/tools/assistant/profile.cpp	(revision 191)
@@ -0,0 +1,117 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "profile.h"
+#include <qxml.h>
+#include <qtextcodec.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qdir.h>
+
+#define QT_TITLE "Qt Reference Documentation"
+#define DESIGNER_TITLE "Qt Designer Manual"
+#define ASSISTANT_TITLE  "Qt Assistant Manual"
+#define LINGUIST_TITLE "Guide to the Qt Translation Tools"
+#define QMAKE_TITLE "qmake User Guide"
+
+Profile *Profile::createDefaultProfile( const QString &docPath )
+{
+    QString path = qInstallPathDocs();
+    if ( !docPath.isEmpty() )
+        path = docPath;        
+    path = path + "/html/";
+    Profile *profile = new Profile;
+    profile->valid = TRUE;
+    profile->type = DefaultProfile;
+    profile->props["name"] = "default";
+    profile->props["applicationicon"] = "appicon.png";
+    profile->props["aboutmenutext"] = "About Qt";
+    profile->props["abouturl"] = "about_qt";
+    profile->props["title"] = "Qt Assistant";
+    profile->props["basepath"] = path;
+    profile->props["startpage"] = path + "index.html";
+
+    profile->addDCFTitle( path + "qt.dcf", QT_TITLE );
+    profile->addDCFTitle( path + "designer.dcf", DESIGNER_TITLE );
+    profile->addDCFTitle( path + "assistant.dcf", ASSISTANT_TITLE );
+    profile->addDCFTitle( path + "linguist.dcf", LINGUIST_TITLE );
+    profile->addDCFTitle( path + "qmake.dcf", QMAKE_TITLE );
+
+    profile->addDCFIcon( QT_TITLE, "qt.png" );
+    profile->addDCFIcon( DESIGNER_TITLE, "designer.png" );
+    profile->addDCFIcon( ASSISTANT_TITLE, "assistant.png" );
+    profile->addDCFIcon( LINGUIST_TITLE, "linguist.png" );
+
+    profile->addDCFIndexPage( QT_TITLE, path + "index.html" );
+    profile->addDCFIndexPage( DESIGNER_TITLE, path + "designer-manual.html" );
+    profile->addDCFIndexPage( ASSISTANT_TITLE, path + "assistant.html" );
+    profile->addDCFIndexPage( LINGUIST_TITLE, path + "linguist-manual.html" );
+    profile->addDCFIndexPage( QMAKE_TITLE, path + "qmake-manual.html" );
+
+    profile->addDCFImageDir( QT_TITLE, "../../gif/" );
+    profile->addDCFImageDir( DESIGNER_TITLE, "../../gif/" );
+    profile->addDCFImageDir( ASSISTANT_TITLE, "../../gif/" );
+    profile->addDCFImageDir( LINGUIST_TITLE, "../../gif/" );
+    profile->addDCFImageDir( QMAKE_TITLE, "../../gif/" );
+
+    return profile;
+}
+
+
+Profile::Profile()
+    : valid( TRUE ), dparser( 0 )
+{
+}
+
+
+void Profile::removeDocFileEntry( const QString &docfile )
+{
+    docs.remove( docfile );
+
+    QStringList titles;    
+    
+    for( QMap<QString,QString>::Iterator it = dcfTitles.begin();
+	 it != dcfTitles.end(); ++it ) {
+	if( (*it) == docfile ) {
+	    indexPages.remove( *it );
+	    icons.remove( *it );
+	    imageDirs.remove( *it );
+	    titles << it.key();
+	} 
+    }
+
+    for( QStringList::ConstIterator title = titles.begin();
+	 title != titles.end(); ++title ) {
+	
+	dcfTitles.remove( *title );
+    }
+
+#ifdef ASSISTANT_DEBUG   
+    qDebug( "docs:\n  - " + docs.join( "\n  - " ) );
+    qDebug( "titles:\n  - " + titles.join( "\n  - " ) );    
+    qDebug( "keys:\n  - " + ( (QStringList*) &(dcfTitles.keys()) )->join( "\n  - " ) );
+    qDebug( "values:\n  - " + ( (QStringList*) &(dcfTitles.values()) )->join( "\n  - " ) );
+#endif
+}
Index: trunk/tools/assistant/profile.h
===================================================================
--- trunk/tools/assistant/profile.h	(revision 191)
+++ trunk/tools/assistant/profile.h	(revision 191)
@@ -0,0 +1,123 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef PROFILE_H
+#define PROFILE_H
+
+#include <qfileinfo.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qmap.h>
+
+class DocuParser;
+
+class Profile
+{
+public:
+    enum ProfileType { DefaultProfile, UserProfile };
+    Profile();
+
+    inline bool isValid() const;
+
+    inline void addDCF( const QString &docfile );
+    inline void addDCFIcon( const QString title, const QString &icon );
+    inline void addDCFIndexPage( const QString title, const QString &indexPage );
+    inline void addDCFImageDir( const QString title, const QString &imgDir );
+    inline void addDCFTitle( const QString &dcf, const QString &title );
+    inline void addProperty( const QString &name, const QString &value );
+    inline bool hasDocFile( const QString &docFile );
+    void removeDocFileEntry( const QString &title );
+
+    inline ProfileType profileType() const { return type; }
+    inline void setProfileType( ProfileType t ) { type = t; }
+
+    inline DocuParser *docuParser() const { return dparser; }
+    inline void setDocuParser( DocuParser *dp ) { dparser = dp; }
+
+    static Profile* createDefaultProfile( const QString &docPath = QString::null );
+    static QString makeRelativePath( const QString &base, const QString &path );
+
+    int valid:1;
+    ProfileType type;
+    DocuParser *dparser;
+    QMap<QString,QString> props;
+    QMap<QString,QString> icons;
+    QMap<QString,QString> indexPages;
+    QMap<QString,QString> imageDirs;
+    QMap<QString,QString> dcfTitles;
+    QStringList docs;
+};
+
+
+inline bool Profile::isValid() const
+{
+    return valid;
+}
+
+inline void Profile::addDCFTitle(const QString &dcf, const QString &title)
+{
+    QString absdcf = QFileInfo(dcf).absFilePath();
+    dcfTitles[title] = absdcf;
+    if (docs.contains(absdcf) == 0)
+	docs << absdcf;
+}
+
+inline void Profile::addDCF( const QString &docfile )
+{
+    if( !docs.contains( docfile ) == 0 )
+	docs << docfile;
+}
+
+inline void Profile::addDCFIcon( const QString docfile,
+				     const QString &icon )
+{
+    icons[docfile] = icon;
+}
+
+inline void Profile::addDCFIndexPage( const QString title,
+				      const QString &indexPage )
+{
+    indexPages[title] = indexPage;
+}
+
+inline void Profile::addDCFImageDir( const QString docfile,
+				     const QString &imgDir )
+{
+    imageDirs[docfile] = imgDir;
+}
+
+inline void Profile::addProperty( const QString &name,
+				  const QString &value )
+{
+    props[name] = value;
+}
+
+inline bool Profile::hasDocFile( const QString &name )
+{
+    return docs.contains( name ) > 0;
+}
+
+#endif
Index: trunk/tools/assistant/settingsdialog.ui
===================================================================
--- trunk/tools/assistant/settingsdialog.ui	(revision 191)
+++ trunk/tools/assistant/settingsdialog.ui	(revision 191)
@@ -0,0 +1,509 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>SettingsDialogBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>SettingsDialogBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>389</width>
+            <height>253</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Qt Assistant - Settings</string>
+    </property>
+    <property name="sizeGripEnabled">
+        <bool>true</bool>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <widget class="QTabWidget">
+            <property name="name">
+                <cstring>settingsTab</cstring>
+            </property>
+            <property name="sizePolicy">
+                <sizepolicy>
+                    <hsizetype>5</hsizetype>
+                    <vsizetype>5</vsizetype>
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                </sizepolicy>
+            </property>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>tab</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;General</string>
+                </attribute>
+                <vbox>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <widget class="QLayoutWidget">
+                        <property name="name">
+                            <cstring>Layout2</cstring>
+                        </property>
+                        <grid>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QComboBox" row="1" column="1">
+                                <property name="name">
+                                    <cstring>fixedfontCombo</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>7</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="editable">
+                                    <bool>true</bool>
+                                </property>
+                            </widget>
+                            <widget class="QLabel" row="1" column="0">
+                                <property name="name">
+                                    <cstring>TextLabel1</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>Fix&amp;ed font:</string>
+                                </property>
+                                <property name="buddy" stdset="0">
+                                    <cstring>fixedfontCombo</cstring>
+                                </property>
+                            </widget>
+                            <widget class="QLabel" row="2" column="0">
+                                <property name="name">
+                                    <cstring>TextLabel2</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>Link color:</string>
+                                </property>
+                            </widget>
+                            <widget class="QComboBox" row="0" column="1">
+                                <property name="name">
+                                    <cstring>fontCombo</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>7</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="editable">
+                                    <bool>true</bool>
+                                </property>
+                            </widget>
+                            <widget class="QLabel" row="0" column="0">
+                                <property name="name">
+                                    <cstring>fontLabel</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>&amp;Font:</string>
+                                </property>
+                                <property name="buddy" stdset="0">
+                                    <cstring>fontCombo</cstring>
+                                </property>
+                            </widget>
+                            <widget class="QCheckBox" row="3" column="0">
+                                <property name="name">
+                                    <cstring>linkUnderlineCB</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>&amp;Underline links</string>
+                                </property>
+                                <property name="checked">
+                                    <bool>true</bool>
+                                </property>
+                            </widget>
+                            <widget class="QToolButton" row="2" column="1">
+                                <property name="name">
+                                    <cstring>colorButton</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>0</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="minimumSize">
+                                    <size>
+                                        <width>40</width>
+                                        <height>20</height>
+                                    </size>
+                                </property>
+                                <property name="paletteBackgroundColor">
+                                    <color>
+                                        <red>255</red>
+                                        <green>0</green>
+                                        <blue>0</blue>
+                                    </color>
+                                </property>
+                                <property name="focusPolicy">
+                                    <enum>TabFocus</enum>
+                                </property>
+                                <property name="text">
+                                    <string></string>
+                                </property>
+                            </widget>
+                        </grid>
+                    </widget>
+                </vbox>
+            </widget>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>tab</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;Web</string>
+                </attribute>
+                <grid>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <spacer row="4" column="0">
+                        <property name="name">
+                            <cstring>Spacer11</cstring>
+                        </property>
+                        <property name="orientation">
+                            <enum>Vertical</enum>
+                        </property>
+                        <property name="sizeType">
+                            <enum>Expanding</enum>
+                        </property>
+                        <property name="sizeHint">
+                            <size>
+                                <width>20</width>
+                                <height>30</height>
+                            </size>
+                        </property>
+                    </spacer>
+                    <widget class="QLabel" row="0" column="0">
+                        <property name="name">
+                            <cstring>TextLabel1_3</cstring>
+                        </property>
+                        <property name="text">
+                            <string>Web &amp;Browser Application:</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>browserApp</cstring>
+                        </property>
+                    </widget>
+                    <widget class="QLayoutWidget" row="1" column="0">
+                        <property name="name">
+                            <cstring>Layout9</cstring>
+                        </property>
+                        <hbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QLineEdit">
+                                <property name="name">
+                                    <cstring>browserApp</cstring>
+                                </property>
+                            </widget>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>buttonBrowse</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>1</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="maximumSize">
+                                    <size>
+                                        <width>30</width>
+                                        <height>32767</height>
+                                    </size>
+                                </property>
+                                <property name="text">
+                                    <string>...</string>
+                                </property>
+                            </widget>
+                        </hbox>
+                    </widget>
+                    <widget class="QLabel" row="2" column="0">
+                        <property name="name">
+                            <cstring>TextLabel1_3_3</cstring>
+                        </property>
+                        <property name="text">
+                            <string>&amp;Home page</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>homePage</cstring>
+                        </property>
+                    </widget>
+                    <widget class="QLayoutWidget" row="3" column="0">
+                        <property name="name">
+                            <cstring>layout8</cstring>
+                        </property>
+                        <hbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QLineEdit">
+                                <property name="name">
+                                    <cstring>homePage</cstring>
+                                </property>
+                            </widget>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>buttonHome</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>1</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="maximumSize">
+                                    <size>
+                                        <width>30</width>
+                                        <height>32767</height>
+                                    </size>
+                                </property>
+                                <property name="text">
+                                    <string>...</string>
+                                </property>
+                            </widget>
+                        </hbox>
+                    </widget>
+                </grid>
+            </widget>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>pdfTab</cstring>
+                </property>
+                <attribute name="title">
+                    <string>&amp;PDF</string>
+                </attribute>
+                <grid>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                    <widget class="QLabel" row="0" column="0">
+                        <property name="name">
+                            <cstring>TextLabel1_3_2</cstring>
+                        </property>
+                        <property name="text">
+                            <string>PDF &amp;Application</string>
+                        </property>
+                        <property name="buddy" stdset="0">
+                            <cstring>pdfApp</cstring>
+                        </property>
+                    </widget>
+                    <spacer row="2" column="0">
+                        <property name="name">
+                            <cstring>spacer10</cstring>
+                        </property>
+                        <property name="orientation">
+                            <enum>Vertical</enum>
+                        </property>
+                        <property name="sizeType">
+                            <enum>Expanding</enum>
+                        </property>
+                        <property name="sizeHint">
+                            <size>
+                                <width>20</width>
+                                <height>81</height>
+                            </size>
+                        </property>
+                    </spacer>
+                    <widget class="QLayoutWidget" row="1" column="0">
+                        <property name="name">
+                            <cstring>layout9</cstring>
+                        </property>
+                        <hbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QLineEdit">
+                                <property name="name">
+                                    <cstring>pdfApp</cstring>
+                                </property>
+                            </widget>
+                            <widget class="QPushButton">
+                                <property name="name">
+                                    <cstring>buttonPDF</cstring>
+                                </property>
+                                <property name="sizePolicy">
+                                    <sizepolicy>
+                                        <hsizetype>1</hsizetype>
+                                        <vsizetype>0</vsizetype>
+                                        <horstretch>0</horstretch>
+                                        <verstretch>0</verstretch>
+                                    </sizepolicy>
+                                </property>
+                                <property name="maximumSize">
+                                    <size>
+                                        <width>30</width>
+                                        <height>32767</height>
+                                    </size>
+                                </property>
+                                <property name="text">
+                                    <string>...</string>
+                                </property>
+                            </widget>
+                        </hbox>
+                    </widget>
+                </grid>
+            </widget>
+        </widget>
+        <widget class="QLayoutWidget">
+            <property name="name">
+                <cstring>Layout1</cstring>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <spacer>
+                    <property name="name">
+                        <cstring>Horizontal Spacing2</cstring>
+                    </property>
+                    <property name="orientation">
+                        <enum>Horizontal</enum>
+                    </property>
+                    <property name="sizeType">
+                        <enum>Expanding</enum>
+                    </property>
+                    <property name="sizeHint">
+                        <size>
+                            <width>0</width>
+                            <height>20</height>
+                        </size>
+                    </property>
+                </spacer>
+                <widget class="QPushButton">
+                    <property name="name">
+                        <cstring>buttonOk</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&amp;OK</string>
+                    </property>
+                    <property name="autoDefault">
+                        <bool>true</bool>
+                    </property>
+                    <property name="default">
+                        <bool>true</bool>
+                    </property>
+                </widget>
+                <widget class="QPushButton">
+                    <property name="name">
+                        <cstring>buttonCancel</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&amp;Cancel</string>
+                    </property>
+                    <property name="autoDefault">
+                        <bool>true</bool>
+                    </property>
+                </widget>
+            </hbox>
+        </widget>
+    </vbox>
+</widget>
+<connections>
+    <connection>
+        <sender>buttonOk</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>buttonCancel</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>reject()</slot>
+    </connection>
+    <connection>
+        <sender>colorButton</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>selectColor()</slot>
+    </connection>
+    <connection>
+        <sender>buttonBrowse</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>browseWebApp()</slot>
+    </connection>
+    <connection>
+        <sender>buttonHome</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>browseHomepage()</slot>
+    </connection>
+    <connection>
+        <sender>buttonPDF</sender>
+        <signal>clicked()</signal>
+        <receiver>SettingsDialogBase</receiver>
+        <slot>browsePDFApplication()</slot>
+    </connection>
+</connections>
+<tabstops>
+    <tabstop>settingsTab</tabstop>
+    <tabstop>fontCombo</tabstop>
+    <tabstop>fixedfontCombo</tabstop>
+    <tabstop>colorButton</tabstop>
+    <tabstop>linkUnderlineCB</tabstop>
+    <tabstop>browserApp</tabstop>
+    <tabstop>buttonBrowse</tabstop>
+    <tabstop>homePage</tabstop>
+    <tabstop>buttonHome</tabstop>
+    <tabstop>pdfApp</tabstop>
+    <tabstop>buttonPDF</tabstop>
+    <tabstop>buttonOk</tabstop>
+    <tabstop>buttonCancel</tabstop>
+</tabstops>
+<slots>
+    <slot>selectColor()</slot>
+    <slot>browseWebApp()</slot>
+    <slot>browsePDFApplication()</slot>
+    <slot>browseHomepage()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/settingsdialogimpl.cpp
===================================================================
--- trunk/tools/assistant/settingsdialogimpl.cpp	(revision 191)
+++ trunk/tools/assistant/settingsdialogimpl.cpp	(revision 191)
@@ -0,0 +1,115 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "settingsdialogimpl.h"
+#include "docuparser.h"
+#include "config.h"
+
+#include <qapplication.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcolordialog.h>
+#include <qdir.h>
+#include <qfiledialog.h>
+#include <qfileinfo.h>
+#include <qlineedit.h>
+#include <qlistbox.h>
+#include <qlistview.h>
+#include <qmessagebox.h>
+#include <qptrstack.h>
+#include <qsettings.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+#include <qtabwidget.h>
+#include <qmap.h>
+
+
+SettingsDialog::SettingsDialog( QWidget *parent, const char* name )
+    : SettingsDialogBase( parent, name )
+{
+    init();
+}
+
+void SettingsDialog::init()
+{
+    Config *config = Config::configuration();
+
+    browserApp->setText( config->webBrowser() );
+    homePage->setText( config->homePage() );
+    pdfApp->setText( config->pdfReader() );
+}
+
+void SettingsDialog::selectColor()
+{
+    QColor c = QColorDialog::getColor( colorButton->paletteBackgroundColor(), this );
+    colorButton->setPaletteBackgroundColor( c );
+}
+
+void SettingsDialog::browseWebApp()
+{
+    setFile( browserApp, tr( "Qt Assistant - Set Web Browser" ) );
+}
+
+void SettingsDialog::browsePDFApplication()
+{
+    setFile( pdfApp, tr( "Qt Assistant - Set PDF Browser" ) );
+}
+
+void SettingsDialog::browseHomepage()
+{
+    setFile( homePage, tr( "Qt Assistant - Set Homepage" ) );
+}
+
+void SettingsDialog::setFile( QLineEdit *le, const QString &caption )
+{
+    QFileDialog *fd = new QFileDialog( this );
+    fd->setCaption( caption );
+    fd->setMode( QFileDialog::AnyFile );
+    fd->setDir( QDir::homeDirPath() );
+
+    if ( fd->exec() == QDialog::Accepted ) {
+	if ( !fd->selectedFile().isEmpty() )
+	   le->setText( fd->selectedFile() );
+    }
+}
+
+void SettingsDialog::accept()
+{
+    Config *config = Config::configuration();
+
+    config->setWebBrowser( browserApp->text() );
+    config->setHomePage( homePage->text() );
+    config->setPdfReader( pdfApp->text() );
+
+    hide();
+    done( Accepted );
+}
+
+void SettingsDialog::reject()
+{
+    init();
+    done( Rejected );
+}
Index: trunk/tools/assistant/settingsdialogimpl.h
===================================================================
--- trunk/tools/assistant/settingsdialogimpl.h	(revision 191)
+++ trunk/tools/assistant/settingsdialogimpl.h	(revision 191)
@@ -0,0 +1,56 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef SETTINGSDIALOGIMPL_H
+#define SETTINGSDIALOGIMPL_H
+
+#include "settingsdialog.h"
+
+#include <qstringlist.h>
+#include <qptrlist.h>
+#include <qlistview.h>
+
+class SettingsDialog : public SettingsDialogBase
+{
+    Q_OBJECT
+
+public:
+    SettingsDialog( QWidget *parent, const char* name = 0 );
+
+protected slots:
+    void selectColor();
+    void browseWebApp();
+    void browsePDFApplication();
+    void browseHomepage();
+    void accept();
+    void reject();
+
+private:
+    void init();
+    void setFile( QLineEdit *le, const QString &caption );
+};
+
+#endif
Index: trunk/tools/assistant/tabbedbrowser.ui
===================================================================
--- trunk/tools/assistant/tabbedbrowser.ui	(revision 191)
+++ trunk/tools/assistant/tabbedbrowser.ui	(revision 191)
@@ -0,0 +1,134 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>TabbedBrowser</class>
+<comment>*********************************************************************
+** Copyright (C) 2003-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QWidget">
+    <property name="name">
+        <cstring>TabbedBrowser</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>710</width>
+            <height>681</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>TabbedBrowser</string>
+    </property>
+    <grid>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>0</number>
+        </property>
+        <property name="spacing">
+            <number>0</number>
+        </property>
+        <widget class="QTabWidget" row="0" column="0">
+            <property name="name">
+                <cstring>tab</cstring>
+            </property>
+            <widget class="QWidget">
+                <property name="name">
+                    <cstring>frontpage</cstring>
+                </property>
+                <attribute name="title">
+                    <string>Untitled</string>
+                </attribute>
+                <grid>
+                    <property name="name">
+                        <cstring>unnamed</cstring>
+                    </property>
+                </grid>
+            </widget>
+        </widget>
+    </grid>
+</widget>
+<includes>
+    <include location="global" impldecl="in declaration">qsettings.h</include>
+    <include location="local" impldecl="in implementation">helpwindow.h</include>
+    <include location="local" impldecl="in implementation">mainwindow.h</include>
+    <include location="global" impldecl="in implementation">qstylesheet.h</include>
+    <include location="global" impldecl="in implementation">qmime.h</include>
+    <include location="local" impldecl="in implementation">tabbedbrowser.ui.h</include>
+</includes>
+<forwards>
+    <forward>class HelpWindow;</forward>
+    <forward>class MainWindow;</forward>
+    <forward>class QStyleSheet;</forward>
+    <forward>class QMimeSourceFactory;</forward>
+</forwards>
+<variables>
+    <variable access="private">QStyleSheet *tabStyleSheet;</variable>
+    <variable access="private">bool tabLinkUnderline;</variable>
+    <variable access="private">QMimeSourceFactory *mimeSourceFactory;</variable>
+    <variable access="private">QWidget *lastCurrentTab;</variable>
+    <variable access="private">QFont tabFont;</variable>
+</variables>
+<slots>
+    <slot>forward()</slot>
+    <slot>backward()</slot>
+    <slot>setSource( const QString &amp; ref )</slot>
+    <slot>reload()</slot>
+    <slot>home()</slot>
+    <slot>nextTab()</slot>
+    <slot>previousTab()</slot>
+    <slot>newTab( const QString &amp; lnk )</slot>
+    <slot>zoomIn()</slot>
+    <slot>zoomOut()</slot>
+    <slot>updateTitle( const QString &amp; title )</slot>
+    <slot>newTab()</slot>
+    <slot>transferFocus()</slot>
+    <slot>initHelpWindow( HelpWindow * win )</slot>
+    <slot>setup()</slot>
+    <slot>setLinkUnderline( bool uline )</slot>
+    <slot>setPalette( const QPalette &amp; pal )</slot>
+    <slot>copy()</slot>
+    <slot>closeTab()</slot>
+    <slot>sourceChanged()</slot>
+</slots>
+<functions>
+    <function returnType="HelpWindow *">currentBrowser()</function>
+    <function access="private">init()</function>
+    <function returnType="MainWindow *">mainWindow()</function>
+    <function specifier="non virtual" returnType="QStyleSheet *">styleSheet()</function>
+    <function specifier="non virtual" returnType="bool">linkUnderline()</function>
+    <function specifier="non virtual" returnType="QStringList">sources()</function>
+    <function specifier="non virtual">setMimePath( QStringList lst )</function>
+    <function specifier="non virtual">setMimeExtension( const QString &amp; ext )</function>
+    <function specifier="non virtual">setBrowserFont( const QFont &amp; fnt )</function>
+    <function specifier="non virtual" returnType="QFont">browserFont()</function>
+    <function specifier="non virtual" returnType="QPtrList&lt;HelpWindow&gt;">browsers() const</function>
+    <function returnType="HelpWindow*">newBackgroundTab( const QString &amp; url )</function>
+    <function returnType="HelpWindow*" access="private">createHelpWindow(const QString &amp;)</function>	
+    <function>setTitle(HelpWindow*, const QString &amp;)</function>
+</functions>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/tabbedbrowser.ui.h
===================================================================
--- trunk/tools/assistant/tabbedbrowser.ui.h	(revision 191)
+++ trunk/tools/assistant/tabbedbrowser.ui.h	(revision 191)
@@ -0,0 +1,347 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+#include <qfileinfo.h>
+#include <qtoolbutton.h>
+#include <qpixmap.h>
+#include <qiconset.h>
+#include <qstyle.h>
+#include <qtimer.h>
+
+#include "config.h"
+
+static QString reduceLabelLength( const QString &s )
+{
+    uint maxLength = 16;
+    QString str = s;
+    if ( str.length() < maxLength )
+	return str;
+    str = str.left( maxLength - 3 );
+    str += "...";
+    return str;
+}
+
+void TabbedBrowser::forward()
+{
+    currentBrowser()->forward();
+}
+
+void TabbedBrowser::backward()
+{
+    currentBrowser()->backward();
+}
+
+void TabbedBrowser::setSource( const QString &ref )
+{
+    HelpWindow * win = currentBrowser();
+    win->setSource(ref);
+}
+
+void TabbedBrowser::reload()
+{
+    currentBrowser()->reload();
+}
+
+void TabbedBrowser::home()
+{
+    currentBrowser()->home();
+}
+
+HelpWindow * TabbedBrowser::currentBrowser()
+{
+    return (HelpWindow*) tab->currentPage();
+}
+
+void TabbedBrowser::nextTab()
+{
+    if( tab->currentPageIndex()<=tab->count()-1 )
+	tab->setCurrentPage( tab->currentPageIndex()+1 );
+}
+
+void TabbedBrowser::previousTab()
+{
+    int idx = tab->currentPageIndex()-1;
+    if( idx>=0 )
+	tab->setCurrentPage( idx );
+}
+
+HelpWindow *TabbedBrowser::createHelpWindow(const QString &title)
+{
+    MainWindow *mainWin = mainWindow();
+    HelpWindow *win = new HelpWindow( mainWin, this, "qt_assistant_helpwin" );
+    win->setFont( browserFont() );
+    win->setPalette( palette() );
+    win->setLinkUnderline( tabLinkUnderline );
+    win->setStyleSheet( tabStyleSheet );
+    win->setMimeSourceFactory( mimeSourceFactory );
+    tab->addTab(win, reduceLabelLength(title));
+    connect( win, SIGNAL( highlighted( const QString & ) ),
+	     (const QObject*) (mainWin->statusBar()), SLOT( message( const QString & ) ) );
+    connect( win, SIGNAL( chooseWebBrowser() ), mainWin, SLOT( showWebBrowserSettings() ) );
+    connect( win, SIGNAL( backwardAvailable(bool) ),
+	     mainWin, SLOT( backwardAvailable(bool) ) );
+    connect( win, SIGNAL( forwardAvailable(bool) ),
+	     mainWin, SLOT( forwardAvailable(bool) ) );
+    connect( win, SIGNAL( sourceChanged(const QString &) ), this, SLOT( sourceChanged() ));
+
+    tab->cornerWidget( Qt::TopRight )->setEnabled( tab->count() > 1 );
+    return win;
+}
+
+HelpWindow *TabbedBrowser::newBackgroundTab( const QString &url )
+{
+    HelpWindow *win = createHelpWindow(url);
+    return win;
+}
+
+void TabbedBrowser::newTab( const QString &lnk )
+{
+    QString link( lnk );
+    if( link.isNull() ) {
+	HelpWindow *w = currentBrowser();
+	if( w )
+	    link = w->source();
+    }
+    HelpWindow *win = createHelpWindow(link);
+    tab->showPage( win );
+    if( !link.isNull() ) {
+ 	win->setSource( link );
+    }
+}
+
+void TabbedBrowser::zoomIn()
+{
+    currentBrowser()->zoomIn();
+}
+
+void TabbedBrowser::zoomOut()
+{
+    currentBrowser()->zoomOut();
+}
+
+void TabbedBrowser::init()
+{
+    tabLinkUnderline = FALSE;
+    tabStyleSheet = new QStyleSheet( QStyleSheet::defaultSheet() );
+    lastCurrentTab = 0;
+    while( tab->count() )
+	tab->removePage( tab->page(0) );
+
+    mimeSourceFactory = new QMimeSourceFactory();
+    mimeSourceFactory->setExtensionType("html","text/html;charset=UTF-8");
+    mimeSourceFactory->setExtensionType("htm","text/html;charset=UTF-8");
+    mimeSourceFactory->setExtensionType("png", "image/png" );
+    mimeSourceFactory->setExtensionType("jpg", "image/jpeg" );
+    mimeSourceFactory->setExtensionType("jpeg", "image/jpeg" );
+    setMimePath( Config::configuration()->mimePaths() );
+
+    connect( tab, SIGNAL( currentChanged( QWidget* ) ),
+	     this, SLOT( transferFocus() ) );
+    connect( tab, SIGNAL( currentChanged( QWidget* ) ),
+        mainWindow(), SLOT( browserTabChanged() ) );
+
+    QTabBar *tabBar = (QTabBar*)tab->child( 0, "QTabBar", FALSE );
+    int m = ( tabBar ? style().pixelMetric( QStyle::PM_TabBarTabVSpace, (QWidget*)tabBar )
+	      + style().pixelMetric( QStyle::PM_TabBarBaseHeight, (QWidget*)tabBar ) : 0 );
+    int s = tab->height() - m;
+
+    // workaround for sgi style
+    QPalette pal = palette();
+    pal.setColor(QPalette::Active, QColorGroup::Button, pal.active().background());
+    pal.setColor(QPalette::Disabled, QColorGroup::Button, pal.disabled().background());
+    pal.setColor(QPalette::Inactive, QColorGroup::Button, pal.inactive().background());
+
+    QToolButton *newTabButton = new QToolButton( this );
+    newTabButton->setPalette(pal);
+    tab->setCornerWidget( newTabButton, Qt::TopLeft );
+    newTabButton->setCursor( arrowCursor );
+    newTabButton->setAutoRaise( TRUE );
+    newTabButton->setPixmap( QPixmap::fromMimeSource( "addtab.png" ) );
+    newTabButton->setFixedSize( s, s );
+    QObject::connect( newTabButton, SIGNAL( clicked() ), this, SLOT( newTab() ) );
+    QToolTip::add( newTabButton, tr( "Add page" ) );
+
+    QToolButton *closeTabButton = new QToolButton( this );
+    closeTabButton->setPalette(pal);
+    tab->setCornerWidget( closeTabButton, Qt::TopRight );
+    closeTabButton->setCursor( arrowCursor );
+    closeTabButton->setAutoRaise( TRUE );
+    QIconSet is( QPixmap::fromMimeSource( "closetab.png") );
+    QPixmap disabledPix = QPixmap::fromMimeSource( "d_closetab.png" );
+    is.setPixmap( disabledPix, QIconSet::Small, QIconSet::Disabled );
+    closeTabButton->setIconSet( is );
+    closeTabButton->setFixedSize( s, s );
+    QObject::connect( closeTabButton, SIGNAL( clicked() ), this, SLOT( closeTab() ) );
+    QToolTip::add( closeTabButton, tr( "Close page" ) );
+    closeTabButton->setEnabled( FALSE );
+}
+
+void TabbedBrowser::setMimePath( QStringList lst )
+{
+    mimeSourceFactory->setFilePath( lst );
+}
+
+void TabbedBrowser::setMimeExtension( const QString &ext )
+{
+    mimeSourceFactory->setExtensionType( "html", ext );
+    mimeSourceFactory->setExtensionType( "htm", ext );
+}
+
+void TabbedBrowser::updateTitle( const QString &title )
+{
+    tab->changeTab( currentBrowser(), title );
+}
+
+MainWindow* TabbedBrowser::mainWindow()
+{
+    return (MainWindow*) parent();
+}
+
+void TabbedBrowser::newTab()
+{
+    newTab( QString::null );
+}
+
+void TabbedBrowser::transferFocus()
+{
+    if( currentBrowser() ) {
+	currentBrowser()->setFocus();
+    }
+    mainWindow()->setCaption(Config::configuration()->title()
+			     + " - " + currentBrowser()->documentTitle());
+}
+
+void TabbedBrowser::initHelpWindow( HelpWindow * /*win*/ )
+{
+}
+
+void TabbedBrowser::setup()
+{
+    Config *config = Config::configuration();
+
+    QFont fnt( font() );
+    QFontInfo fntInfo( fnt );
+    fnt.setFamily( config->fontFamily() );
+    fnt.setPointSize( config->fontSize() );
+    setBrowserFont( fnt );
+
+    QPalette pal = palette();
+    QColor lc( config->linkColor() );
+    pal.setColor( QPalette::Active, QColorGroup::Link, lc );
+    pal.setColor( QPalette::Inactive, QColorGroup::Link, lc );
+    pal.setColor( QPalette::Disabled, QColorGroup::Link, lc );
+    setPalette( pal );
+
+    tabLinkUnderline = config->isLinkUnderline();
+
+    QString family = config->fontFixedFamily();
+    tabStyleSheet->item( "pre" )->setFontFamily( family );
+    tabStyleSheet->item( "code" )->setFontFamily( family );
+    tabStyleSheet->item( "tt" )->setFontFamily( family );
+
+    newTab( QString::null );
+}
+
+void TabbedBrowser::setLinkUnderline( bool uline )
+{
+    if( uline==tabLinkUnderline )
+	return;
+    tabLinkUnderline = uline;
+    int cnt = tab->count();
+    for( int i=0; i<cnt; i++ )
+	( (QTextBrowser*) tab->page( i ) )->setLinkUnderline( tabLinkUnderline );
+}
+
+QFont TabbedBrowser::browserFont()
+{
+    return tabFont;
+}
+
+void TabbedBrowser::setBrowserFont( const QFont &fnt )
+{
+    if( tabFont == fnt )
+	return;
+    tabFont = fnt;
+    int cnt = tab->count();
+    for( int i=0; i<cnt; i++ )
+	( (QTextBrowser*) tab->page( i ) )->setFont( fnt );
+}
+
+void TabbedBrowser::setPalette( const QPalette &pal )
+{
+    if( palette()==pal )
+	return;
+    QWidget::setPalette( pal );
+    int cnt = tab->count();
+    for( int i=0; i<cnt; i++ )
+	( (QTextBrowser*) tab->page( i ) )->setPalette( pal );
+}
+
+QStyleSheet* TabbedBrowser::styleSheet()
+{
+    return tabStyleSheet;
+}
+
+bool TabbedBrowser::linkUnderline()
+{
+    return tabLinkUnderline;
+}
+
+void TabbedBrowser::copy()
+{
+    currentBrowser()->copy();
+}
+
+void TabbedBrowser::closeTab()
+{
+    if( tab->count()==1 )
+	return;
+    HelpWindow *win = currentBrowser();
+    tab->removePage( win );
+    QTimer::singleShot(0, win, SLOT(deleteLater()));
+    tab->cornerWidget( Qt::TopRight )->setEnabled( tab->count() > 1 );
+}
+
+QStringList TabbedBrowser::sources()
+{
+    QStringList lst;
+    int cnt = tab->count();
+    for( int i=0; i<cnt; i++ ) {
+	lst.append( ( (QTextBrowser*) tab->page(i) )->source() );
+    }
+    return lst;
+}
+
+QPtrList<HelpWindow> TabbedBrowser::browsers() const
+{
+    QPtrList<HelpWindow> list;
+    for (int i=0; i<tab->count(); ++i) {
+	Q_ASSERT(::qt_cast<HelpWindow*>(tab->page(i)));
+	list.append(::qt_cast<HelpWindow*>(tab->page(i)));
+    }
+    return list;
+}
+
+void TabbedBrowser::sourceChanged()
+{
+    HelpWindow *win = ::qt_cast<HelpWindow *>( QObject::sender() );
+    Q_ASSERT( win );
+    QString docTitle(win->documentTitle());
+    if (docTitle.isEmpty())
+	docTitle = "...";
+    setTitle(win, docTitle);
+}
+
+void TabbedBrowser::setTitle(HelpWindow *win, const QString &title)
+{
+    tab->setTabLabel(win, reduceLabelLength(title));
+    if (win == currentBrowser())
+	mainWindow()->setCaption(Config::configuration()->title() + " - " + title);
+}
+
Index: trunk/tools/assistant/topicchooser.ui
===================================================================
--- trunk/tools/assistant/topicchooser.ui	(revision 191)
+++ trunk/tools/assistant/topicchooser.ui	(revision 191)
@@ -0,0 +1,175 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>TopicChooserBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>TopicChooserBase</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>391</width>
+            <height>223</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Choose Topic</string>
+    </property>
+    <property name="sizeGripEnabled">
+        <bool>true</bool>
+    </property>
+    <property name="whatsThis" stdset="0">
+        <string>Select a topic from the list and click the &lt;b&gt;Display&lt;/b&gt;-button to open the online help.</string>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>11</number>
+        </property>
+        <property name="spacing">
+            <number>6</number>
+        </property>
+        <widget class="QLabel">
+            <property name="name">
+                <cstring>label</cstring>
+            </property>
+            <property name="text">
+                <string>&amp;Topics</string>
+            </property>
+            <property name="buddy" stdset="0">
+                <cstring>listbox</cstring>
+            </property>
+        </widget>
+        <widget class="QListBox">
+            <property name="name">
+                <cstring>listbox</cstring>
+            </property>
+            <property name="whatsThis" stdset="0">
+                <string>Displays a list of available help topics for the keyword.</string>
+            </property>
+        </widget>
+        <widget class="QLayoutWidget">
+            <property name="name">
+                <cstring>Layout16</cstring>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <property name="margin">
+                    <number>0</number>
+                </property>
+                <property name="spacing">
+                    <number>6</number>
+                </property>
+                <spacer>
+                    <property name="name">
+                        <cstring>Horizontal Spacing2</cstring>
+                    </property>
+                    <property name="orientation">
+                        <enum>Horizontal</enum>
+                    </property>
+                    <property name="sizeType">
+                        <enum>Expanding</enum>
+                    </property>
+                    <property name="sizeHint">
+                        <size>
+                            <width>20</width>
+                            <height>20</height>
+                        </size>
+                    </property>
+                </spacer>
+                <widget class="QPushButton">
+                    <property name="name">
+                        <cstring>buttonDisplay</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&amp;Display</string>
+                    </property>
+                    <property name="autoDefault">
+                        <bool>true</bool>
+                    </property>
+                    <property name="default">
+                        <bool>true</bool>
+                    </property>
+                    <property name="whatsThis" stdset="0">
+                        <string>Open the topic selected in the list.</string>
+                    </property>
+                </widget>
+                <widget class="QPushButton">
+                    <property name="name">
+                        <cstring>buttonCancel</cstring>
+                    </property>
+                    <property name="text">
+                        <string>&amp;Close</string>
+                    </property>
+                    <property name="autoDefault">
+                        <bool>true</bool>
+                    </property>
+                    <property name="whatsThis" stdset="0">
+                        <string>Close the Dialog.</string>
+                    </property>
+                </widget>
+            </hbox>
+        </widget>
+    </vbox>
+</widget>
+<connections>
+    <connection>
+        <sender>buttonDisplay</sender>
+        <signal>clicked()</signal>
+        <receiver>TopicChooserBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>buttonCancel</sender>
+        <signal>clicked()</signal>
+        <receiver>TopicChooserBase</receiver>
+        <slot>reject()</slot>
+    </connection>
+    <connection>
+        <sender>listbox</sender>
+        <signal>doubleClicked(QListBoxItem*)</signal>
+        <receiver>TopicChooserBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>listbox</sender>
+        <signal>returnPressed(QListBoxItem*)</signal>
+        <receiver>TopicChooserBase</receiver>
+        <slot>accept()</slot>
+    </connection>
+</connections>
+<slots>
+    <slot access="protected">init()</slot>
+    <slot access="protected">destroy()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Index: trunk/tools/assistant/topicchooserimpl.cpp
===================================================================
--- trunk/tools/assistant/topicchooserimpl.cpp	(revision 191)
+++ trunk/tools/assistant/topicchooserimpl.cpp	(revision 191)
@@ -0,0 +1,63 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "topicchooserimpl.h"
+
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+
+TopicChooser::TopicChooser( QWidget *parent, const QStringList &lnkNames,
+			    const QStringList &lnks, const QString &title )
+    : TopicChooserBase( parent, 0, TRUE ), links( lnks ), linkNames( lnkNames )
+{
+    label->setText( tr( "Choose a topic for <b>%1</b>" ).arg( title ) );
+    listbox->insertStringList( linkNames );
+    listbox->setCurrentItem( listbox->firstItem() );
+    listbox->setFocus();
+}
+
+QString TopicChooser::link() const
+{
+    if ( listbox->currentItem() == -1 )
+	return QString::null;
+    QString s = listbox->currentText();
+    if ( s.isEmpty() )
+	return s;
+    int i = linkNames.findIndex( s );
+    return links[ i ];
+}
+
+QString TopicChooser::getLink( QWidget *parent, const QStringList &lnkNames,
+				      const QStringList &lnks, const QString &title )
+{
+    TopicChooser *dlg = new TopicChooser( parent, lnkNames, lnks, title );
+    QString lnk;
+    if ( dlg->exec() == QDialog::Accepted )
+	lnk = dlg->link();
+    delete dlg;
+    return lnk;
+}
Index: trunk/tools/assistant/topicchooserimpl.h
===================================================================
--- trunk/tools/assistant/topicchooserimpl.h	(revision 191)
+++ trunk/tools/assistant/topicchooserimpl.h	(revision 191)
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000-2007 Trolltech ASA.  All rights reserved.
+**
+** This file is part of Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef TOPICCHOOSERIMPL_H
+#define TOPICCHOOSERIMPL_H
+
+#include "topicchooser.h"
+
+#include <qstringlist.h>
+
+class TopicChooser : public TopicChooserBase
+{
+    Q_OBJECT
+    
+public:
+    TopicChooser( QWidget *parent, const QStringList &lnkNames,
+		  const QStringList &lnks, const QString &title );
+    
+    QString link() const;
+    
+    static QString getLink( QWidget *parent, const QStringList &lnkNames,
+			    const QStringList &lnks, const QString &title );
+    
+private:
+    QString theLink;
+    QStringList links, linkNames;
+
+};
+
+#endif
Index: trunk/tools/tools.pro
===================================================================
--- trunk/tools/tools.pro	(revision 28)
+++ trunk/tools/tools.pro	(revision 191)
@@ -8,6 +8,4 @@
 		      linguist
     unix:SUBDIRS	+= qtconfig
-    ## @todo (dmik) temporary, until everything can be compiled on OS/2
-    os2:SUBDIRS     -= assistant assistant/lib
 }
 
