summaryrefslogtreecommitdiffstats
path: root/tools/assistant/compat
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:34:13 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:34:13 (GMT)
commit67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch)
tree1dbf50b3dff8d5ca7e9344733968c72704eb15ff /tools/assistant/compat
downloadQt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2
Long live Qt!
Diffstat (limited to 'tools/assistant/compat')
-rw-r--r--tools/assistant/compat/Info_mac.plist18
-rw-r--r--tools/assistant/compat/LICENSE.GPL280
-rw-r--r--tools/assistant/compat/assistant.icnsbin0 -> 162568 bytes
-rw-r--r--tools/assistant/compat/assistant.icobin0 -> 355574 bytes
-rw-r--r--tools/assistant/compat/assistant.pro84
-rw-r--r--tools/assistant/compat/assistant.qrc37
-rw-r--r--tools/assistant/compat/assistant.rc1
-rw-r--r--tools/assistant/compat/compat.pro84
-rw-r--r--tools/assistant/compat/config.cpp438
-rw-r--r--tools/assistant/compat/config.h165
-rw-r--r--tools/assistant/compat/docuparser.cpp433
-rw-r--r--tools/assistant/compat/docuparser.h166
-rw-r--r--tools/assistant/compat/fontsettingsdialog.cpp137
-rw-r--r--tools/assistant/compat/fontsettingsdialog.h77
-rw-r--r--tools/assistant/compat/helpdialog.cpp1331
-rw-r--r--tools/assistant/compat/helpdialog.h184
-rw-r--r--tools/assistant/compat/helpdialog.ui404
-rw-r--r--tools/assistant/compat/helpwindow.cpp247
-rw-r--r--tools/assistant/compat/helpwindow.h100
-rw-r--r--tools/assistant/compat/images/assistant-128.pngbin0 -> 6448 bytes
-rw-r--r--tools/assistant/compat/images/assistant.pngbin0 -> 2034 bytes
-rw-r--r--tools/assistant/compat/images/close.pngbin0 -> 406 bytes
-rw-r--r--tools/assistant/compat/images/designer.pngbin0 -> 1282 bytes
-rw-r--r--tools/assistant/compat/images/linguist.pngbin0 -> 1382 bytes
-rw-r--r--tools/assistant/compat/images/mac/addtab.pngbin0 -> 469 bytes
-rw-r--r--tools/assistant/compat/images/mac/book.pngbin0 -> 1477 bytes
-rw-r--r--tools/assistant/compat/images/mac/closetab.pngbin0 -> 516 bytes
-rw-r--r--tools/assistant/compat/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--tools/assistant/compat/images/mac/find.pngbin0 -> 1836 bytes
-rw-r--r--tools/assistant/compat/images/mac/home.pngbin0 -> 1807 bytes
-rw-r--r--tools/assistant/compat/images/mac/next.pngbin0 -> 1310 bytes
-rw-r--r--tools/assistant/compat/images/mac/prev.pngbin0 -> 1080 bytes
-rw-r--r--tools/assistant/compat/images/mac/print.pngbin0 -> 2087 bytes
-rw-r--r--tools/assistant/compat/images/mac/synctoc.pngbin0 -> 1838 bytes
-rw-r--r--tools/assistant/compat/images/mac/whatsthis.pngbin0 -> 1586 bytes
-rw-r--r--tools/assistant/compat/images/mac/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--tools/assistant/compat/images/mac/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--tools/assistant/compat/images/qt.pngbin0 -> 1422 bytes
-rw-r--r--tools/assistant/compat/images/win/addtab.pngbin0 -> 314 bytes
-rw-r--r--tools/assistant/compat/images/win/book.pngbin0 -> 1109 bytes
-rw-r--r--tools/assistant/compat/images/win/closetab.pngbin0 -> 375 bytes
-rw-r--r--tools/assistant/compat/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--tools/assistant/compat/images/win/find.pngbin0 -> 1944 bytes
-rw-r--r--tools/assistant/compat/images/win/home.pngbin0 -> 1414 bytes
-rw-r--r--tools/assistant/compat/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--tools/assistant/compat/images/win/previous.pngbin0 -> 898 bytes
-rw-r--r--tools/assistant/compat/images/win/print.pngbin0 -> 1456 bytes
-rw-r--r--tools/assistant/compat/images/win/synctoc.pngbin0 -> 1235 bytes
-rw-r--r--tools/assistant/compat/images/win/whatsthis.pngbin0 -> 1040 bytes
-rw-r--r--tools/assistant/compat/images/win/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--tools/assistant/compat/images/win/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--tools/assistant/compat/images/wrap.pngbin0 -> 500 bytes
-rw-r--r--tools/assistant/compat/index.cpp581
-rw-r--r--tools/assistant/compat/index.h133
-rw-r--r--tools/assistant/compat/lib/lib.pro78
-rw-r--r--tools/assistant/compat/lib/qassistantclient.cpp447
-rw-r--r--tools/assistant/compat/lib/qassistantclient.h100
-rw-r--r--tools/assistant/compat/lib/qassistantclient_global.h63
-rw-r--r--tools/assistant/compat/main.cpp465
-rw-r--r--tools/assistant/compat/mainwindow.cpp901
-rw-r--r--tools/assistant/compat/mainwindow.h137
-rw-r--r--tools/assistant/compat/mainwindow.ui459
-rw-r--r--tools/assistant/compat/profile.cpp196
-rw-r--r--tools/assistant/compat/profile.h95
-rw-r--r--tools/assistant/compat/tabbedbrowser.cpp530
-rw-r--r--tools/assistant/compat/tabbedbrowser.h122
-rw-r--r--tools/assistant/compat/tabbedbrowser.ui233
-rw-r--r--tools/assistant/compat/topicchooser.cpp101
-rw-r--r--tools/assistant/compat/topicchooser.h77
-rw-r--r--tools/assistant/compat/topicchooser.ui162
-rw-r--r--tools/assistant/compat/translations/translations.pro34
71 files changed, 9100 insertions, 0 deletions
diff --git a/tools/assistant/compat/Info_mac.plist b/tools/assistant/compat/Info_mac.plist
new file mode 100644
index 0000000..b1e6336
--- /dev/null
+++ b/tools/assistant/compat/Info_mac.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.assistant-compat</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+</dict>
+</plist>
diff --git a/tools/assistant/compat/LICENSE.GPL b/tools/assistant/compat/LICENSE.GPL
new file mode 100644
index 0000000..b6e1c33
--- /dev/null
+++ b/tools/assistant/compat/LICENSE.GPL
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, 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
diff --git a/tools/assistant/compat/assistant.icns b/tools/assistant/compat/assistant.icns
new file mode 100644
index 0000000..6291dd3
--- /dev/null
+++ b/tools/assistant/compat/assistant.icns
Binary files differ
diff --git a/tools/assistant/compat/assistant.ico b/tools/assistant/compat/assistant.ico
new file mode 100644
index 0000000..9e1b83f
--- /dev/null
+++ b/tools/assistant/compat/assistant.ico
Binary files differ
diff --git a/tools/assistant/compat/assistant.pro b/tools/assistant/compat/assistant.pro
new file mode 100644
index 0000000..e865d6b
--- /dev/null
+++ b/tools/assistant/compat/assistant.pro
@@ -0,0 +1,84 @@
+include($$QT_SOURCE_TREE/tools/shared/fontpanel/fontpanel.pri)
+
+TEMPLATE = app
+LANGUAGE = C++
+TARGET = assistant_adp
+
+CONFIG += qt warn_on
+
+unix:contains(QT_CONFIG, dbus):QT += dbus
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+QT += xml network
+
+PROJECTNAME = Assistant
+DESTDIR = ../../../bin
+
+FORMS += helpdialog.ui \
+ mainwindow.ui \
+ tabbedbrowser.ui \
+ topicchooser.ui
+
+SOURCES += main.cpp \
+ helpwindow.cpp \
+ topicchooser.cpp \
+ docuparser.cpp \
+ index.cpp \
+ profile.cpp \
+ config.cpp \
+ helpdialog.cpp \
+ mainwindow.cpp \
+ tabbedbrowser.cpp \
+ fontsettingsdialog.cpp
+
+HEADERS += helpwindow.h \
+ topicchooser.h \
+ docuparser.h \
+ index.h \
+ profile.h \
+ helpdialog.h \
+ mainwindow.h \
+ tabbedbrowser.h \
+ config.h \
+ fontsettingsdialog.h
+
+RESOURCES += assistant.qrc
+
+contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
+DEFINES += QT_KEYWORDS
+#DEFINES += QT_PALMTOPCENTER_DOCS
+
+win32 {
+ !wince*:LIBS += -lshell32
+ RC_FILE = assistant.rc
+}
+
+mac {
+ ICON = assistant.icns
+ TARGET = Assistant_adp
+ QMAKE_INFO_PLIST = Info_mac.plist
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+TRANSLATIONS = assistant_de.ts
+
+unix:!contains(QT_CONFIG, zlib):LIBS += -lz
+
+contains(CONFIG, static): {
+ win32 {
+ exists($$[QT_INSTALL_PLUGINS]/imageformats/qjpeg.lib) {
+ QTPLUGIN += qjpeg
+ DEFINES += USE_STATIC_JPEG_PLUGIN
+ }
+ } else {
+ exists($$[QT_INSTALL_PLUGINS]/imageformats/qjpeg.a) {
+ QTPLUGIN += qjpeg
+ DEFINES += USE_STATIC_JPEG_PLUGIN
+ }
+ }
+}
diff --git a/tools/assistant/compat/assistant.qrc b/tools/assistant/compat/assistant.qrc
new file mode 100644
index 0000000..dae1f48
--- /dev/null
+++ b/tools/assistant/compat/assistant.qrc
@@ -0,0 +1,37 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>images/assistant-128.png</file>
+ <file>images/assistant.png</file>
+ <file>images/close.png</file>
+ <file>images/designer.png</file>
+ <file>images/linguist.png</file>
+ <file>images/mac/addtab.png</file>
+ <file>images/mac/book.png</file>
+ <file>images/mac/closetab.png</file>
+ <file>images/mac/editcopy.png</file>
+ <file>images/mac/find.png</file>
+ <file>images/mac/home.png</file>
+ <file>images/mac/next.png</file>
+ <file>images/mac/prev.png</file>
+ <file>images/mac/print.png</file>
+ <file>images/mac/synctoc.png</file>
+ <file>images/mac/whatsthis.png</file>
+ <file>images/mac/zoomin.png</file>
+ <file>images/mac/zoomout.png</file>
+ <file>images/qt.png</file>
+ <file>images/win/addtab.png</file>
+ <file>images/win/book.png</file>
+ <file>images/win/closetab.png</file>
+ <file>images/win/editcopy.png</file>
+ <file>images/win/find.png</file>
+ <file>images/win/home.png</file>
+ <file>images/win/next.png</file>
+ <file>images/win/previous.png</file>
+ <file>images/win/print.png</file>
+ <file>images/win/synctoc.png</file>
+ <file>images/win/whatsthis.png</file>
+ <file>images/win/zoomin.png</file>
+ <file>images/win/zoomout.png</file>
+ <file>images/wrap.png</file>
+ </qresource>
+</RCC>
diff --git a/tools/assistant/compat/assistant.rc b/tools/assistant/compat/assistant.rc
new file mode 100644
index 0000000..b4786ce
--- /dev/null
+++ b/tools/assistant/compat/assistant.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "assistant.ico"
diff --git a/tools/assistant/compat/compat.pro b/tools/assistant/compat/compat.pro
new file mode 100644
index 0000000..1086f4c
--- /dev/null
+++ b/tools/assistant/compat/compat.pro
@@ -0,0 +1,84 @@
+include($$QT_SOURCE_TREE/tools/shared/fontpanel/fontpanel.pri)
+
+TEMPLATE = app
+LANGUAGE = C++
+TARGET = assistant_adp
+
+CONFIG += qt warn_on
+
+unix:contains(QT_CONFIG, dbus):QT += dbus
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+QT += xml network
+
+PROJECTNAME = Assistant
+DESTDIR = ../../../bin
+
+FORMS += helpdialog.ui \
+ mainwindow.ui \
+ tabbedbrowser.ui \
+ topicchooser.ui
+
+SOURCES += main.cpp \
+ helpwindow.cpp \
+ topicchooser.cpp \
+ docuparser.cpp \
+ index.cpp \
+ profile.cpp \
+ config.cpp \
+ helpdialog.cpp \
+ mainwindow.cpp \
+ tabbedbrowser.cpp \
+ fontsettingsdialog.cpp
+
+HEADERS += helpwindow.h \
+ topicchooser.h \
+ docuparser.h \
+ index.h \
+ profile.h \
+ helpdialog.h \
+ mainwindow.h \
+ tabbedbrowser.h \
+ config.h \
+ fontsettingsdialog.h
+
+RESOURCES += assistant.qrc
+
+contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
+DEFINES += QT_KEYWORDS
+#DEFINES += QT_PALMTOPCENTER_DOCS
+
+win32 {
+ LIBS += -lshell32
+ RC_FILE = assistant.rc
+}
+
+mac {
+ ICON = assistant.icns
+ TARGET = Assistant_adp
+# QMAKE_INFO_PLIST = Info_mac.plist
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+TRANSLATIONS = assistant_de.ts
+
+unix:!contains(QT_CONFIG, zlib):LIBS += -lz
+
+contains(CONFIG, static): {
+ win32 {
+ exists($$[QT_INSTALL_PLUGINS]/imageformats/qjpeg.lib) {
+ QTPLUGIN += qjpeg
+ DEFINES += USE_STATIC_JPEG_PLUGIN
+ }
+ } else {
+ exists($$[QT_INSTALL_PLUGINS]/imageformats/qjpeg.a) {
+ QTPLUGIN += qjpeg
+ DEFINES += USE_STATIC_JPEG_PLUGIN
+ }
+ }
+}
diff --git a/tools/assistant/compat/config.cpp b/tools/assistant/compat/config.cpp
new file mode 100644
index 0000000..b2eba11
--- /dev/null
+++ b/tools/assistant/compat/config.cpp
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "config.h"
+#include "profile.h"
+#include "docuparser.h"
+
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QLibraryInfo>
+#include <QFont>
+#include <QFontInfo>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QSettings>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+static Config *static_configuration = 0;
+
+inline QString getVersionString()
+{
+ return QString::number( (QT_VERSION >> 16) & 0xff )
+ + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff );
+}
+
+Config::Config()
+ : profil( 0 ), hideSidebar( false ), rebuildDocs(true)
+{
+ 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
+ if (!config->defaultProfileExists()) {
+ config->profil = Profile::createDefaultProfile();
+ config->saveProfile(config->profil);
+ } else {
+ config->profil = new Profile();
+ }
+ config->loadDefaultProfile();
+ config->load();
+ return config;
+ }
+
+ QFile file(profileFileName);
+ if (!file.exists()) {
+ qWarning( "File does not exist: %s", qPrintable(profileFileName) );
+ return 0;
+ }
+ DocuParser *parser = DocuParser::createParser( profileFileName );
+ if (!parser) {
+ qWarning( "Failed to create parser for file: %s", qPrintable(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: %s", qPrintable(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 = getVersionString() + QLatin1String("/");
+
+ bool isDefaultProfile = profil->props[QLatin1String("name")] == QLatin1String("default");
+ const QString pKey = isDefaultProfile ? QString::fromLatin1(QT_VERSION_STR)
+ : getVersionString();
+
+ const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/");
+
+ QSettings settings;
+
+ home = profil->props[QLatin1String("startpage")];;
+ if (home.isEmpty() && isDefaultProfile)
+ home = QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html/index.html");
+ src = settings.value( profkey + QLatin1String("Source") ).toStringList();
+ sideBar = settings.value( key + QLatin1String("SideBarPage") ).toInt();
+ if (qApp->type() != QApplication::Tty)
+ winGeometry = settings.value(key + QLatin1String("windowGeometry")).toByteArray();
+
+ mainWinState = settings.value(key + QLatin1String("MainWindowState")).toByteArray();
+ pointFntSize = settings.value(key + QLatin1String("FontSize"), qApp->font().pointSizeF()).toDouble();
+ rebuildDocs = settings.value( key + QLatin1String("RebuildDocDB"), true ).toBool();
+
+ profileNames = settings.value( key + QLatin1String("Profile") ).toStringList();
+
+ m_fontSettings.windowFont = qVariantValue<QFont>(settings.value(key + QLatin1String("windowfont"), qApp->font()));
+ m_fontSettings.browserFont = qVariantValue<QFont>(settings.value(key + QLatin1String("browserfont"), qApp->font()));
+ m_fontSettings.useWindowFont = settings.value(key + QLatin1String("usewindowfont"), false).toBool();
+ m_fontSettings.useBrowserFont = settings.value(key + QLatin1String("usebrowserfont"), false).toBool();
+ m_fontSettings.windowWritingSystem = static_cast<QFontDatabase::WritingSystem>(
+ settings.value(key + QLatin1String("windowwritingsystem"), QFontDatabase::Latin).toInt());
+ m_fontSettings.browserWritingSystem = static_cast<QFontDatabase::WritingSystem>(
+ settings.value(key + QLatin1String("browserwritingsystem"), QFontDatabase::Latin).toInt());
+
+ m_fontSettings.browserFont.setPointSizeF(pointFntSize);
+}
+
+void Config::save()
+{
+ saveSettings();
+ saveProfile( profil );
+}
+
+void Config::saveSettings()
+{
+ const QString key = getVersionString() + QLatin1String("/");
+
+ const QString pKey = (profil->props[QLatin1String("name")] == QLatin1String("default"))
+ ? QString::fromLatin1(QT_VERSION_STR)
+ : getVersionString();
+
+ const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/");
+
+ QSettings settings;
+
+ settings.setValue( profkey + QLatin1String("Source"), src );
+ settings.setValue( key + QLatin1String("SideBarPage"), sideBarPage() );
+ if (qApp->type() != QApplication::Tty)
+ settings.setValue(key + QLatin1String("windowGeometry"), winGeometry);
+
+ settings.setValue( key + QLatin1String("MainWindowState"), mainWinState );
+ settings.setValue( key + QLatin1String("FontSize"), pointFntSize);
+ settings.setValue( key + QLatin1String("RebuildDocDB"), rebuildDocs );
+
+ settings.setValue(key + QLatin1String("windowfont"), m_fontSettings.windowFont);
+ settings.setValue(key + QLatin1String("browserfont"), m_fontSettings.browserFont);
+ settings.setValue(key + QLatin1String("usewindowfont"), m_fontSettings.useWindowFont);
+ settings.setValue(key + QLatin1String("usebrowserfont"), m_fontSettings.useBrowserFont);
+ settings.setValue(key + QLatin1String("windowwritingsystem"), m_fontSettings.windowWritingSystem);
+ settings.setValue(key + QLatin1String("browserwritingsystem"), m_fontSettings.browserWritingSystem);
+}
+
+#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
+
+bool Config::defaultProfileExists()
+{
+ QSettings settings;
+ const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/");
+
+ if (settings.contains(profKey + QLatin1String("DocFiles"))
+ && settings.contains(profKey + QLatin1String("Titles"))
+ && settings.contains(profKey + QLatin1String("ImageDirs"))) {
+ QStringList dcfs = settings.value(profKey + QLatin1String("DocFiles") ).toStringList();
+ foreach (QString file, dcfs) {
+ if (file == Profile::storableFilePath(file))
+ return true;
+ }
+ }
+ return false;
+}
+
+void Config::loadDefaultProfile()
+{
+ QSettings settings;
+ const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/");
+
+ if (!defaultProfileExists())
+ 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.value( profKey + QLatin1String("Titles") ).toStringList();
+ QStringList iconLst = settings.value( profKey + QLatin1String("DocIcons") ).toStringList();
+ QStringList indexLst = settings.value( profKey + QLatin1String("IndexPages") ).toStringList();
+ QStringList imgDirLst = settings.value( profKey + QLatin1String("ImageDirs") ).toStringList();
+ QStringList dcfs = settings.value( profKey + QLatin1String("DocFiles") ).toStringList();
+ profil->props[QLatin1String("name")] = QLatin1String("default");
+
+ QString filePath;
+ QStringList::ConstIterator it = titles.constBegin();
+ QStringList::ConstIterator iconIt = iconLst.constBegin();
+ QStringList::ConstIterator indexIt = indexLst.constBegin();
+ QStringList::ConstIterator imageIt = imgDirLst.constBegin();
+ QStringList::ConstIterator dcfIt = dcfs.constBegin();
+ while((it != titles.constEnd())
+ && (iconIt != iconLst.constEnd())
+ && (indexIt != indexLst.constEnd())
+ && (imageIt != imgDirLst.constEnd())
+ && (dcfIt != dcfs.constEnd())) {
+ profil->addDCFIcon( *it, *iconIt );
+ profil->addDCFIndexPage(*it, Profile::loadableFilePath(*indexIt));
+ profil->addDCFImageDir( *it, *imageIt );
+ profil->addDCFTitle(Profile::loadableFilePath(*dcfIt), *it);
+ ++it, ++iconIt, ++indexIt, ++imageIt, ++dcfIt;
+ }
+#if ASSISTANT_DEBUG
+ dumpmap( profil->icons, QLatin1String("Icons") );
+ dumpmap( profil->indexPages, QLatin1String("IndexPages") );
+ dumpmap( profil->imageDirs, QLatin1String("ImageDirs") );
+ dumpmap( profil->dcfTitles, QLatin1String("dcfTitles") );
+ qDebug( "Docfiles: \n " + profil->docs.join( "\n " ) );
+#endif
+}
+
+void Config::saveProfile( Profile *profile )
+{
+ if (profil->profileType() == Profile::UserProfile)
+ return;
+
+ const QString key = (profile->props[QLatin1String("name")] == QLatin1String("default"))
+ ? QString::fromLatin1(QT_VERSION_STR)
+ : getVersionString();
+
+ const QString profKey = key + QLatin1String("/Profile/") + profile->props[QLatin1String("name")] + QLatin1String("/");
+
+ QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath).replace(QLatin1String("\\"), QLatin1String("/"));
+ QStringList indexes, icons, imgDirs, dcfs;
+ QStringList titles = profile->dcfTitles.keys();
+ QStringList::ConstIterator it = titles.constBegin();
+ QString filePath;
+ for ( ; it != titles.constEnd(); ++it ) {
+
+ indexes << Profile::storableFilePath(profile->indexPages[*it]);
+ icons << profile->icons[*it];
+ imgDirs << profile->imageDirs[*it];
+ dcfs << Profile::storableFilePath(profile->dcfTitles[*it]);
+ }
+
+ QSettings settings;
+ settings.setValue( profKey + QLatin1String("Titles"), titles );
+ settings.setValue( profKey + QLatin1String("DocFiles"), dcfs );
+ settings.setValue( profKey + QLatin1String("IndexPages"), indexes );
+ settings.setValue( profKey + QLatin1String("DocIcons"), icons );
+ settings.setValue( profKey + QLatin1String("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.constBegin();
+ it != profil->dcfTitles.constEnd(); ++it ) {
+
+ // Mime source for .dcf file path
+ QFileInfo info( *it );
+ QString dcfPath = info.absolutePath();
+ if (!lst.contains(dcfPath))
+ lst << dcfPath;
+
+ // Image dir for .dcf
+ QString imgDir = QDir::toNativeSeparators( dcfPath + QDir::separator()
+ + profil->imageDirs[it.key()] );
+ if (!lst.contains(imgDir))
+ lst << imgDir;
+ }
+ return lst;
+}
+
+QStringList Config::profiles() const
+{
+ return profileNames;
+}
+
+QString Config::title() const
+{
+ QString s = profil->props[QLatin1String("title")];
+ if (s.isEmpty())
+ s = QObject::tr("Qt Assistant by Nokia");
+ return s;
+}
+
+QString Config::aboutApplicationMenuText() const
+{
+ return profil->props[QLatin1String("aboutmenutext")];
+}
+
+QString Config::aboutURL() const
+{
+ return profil->props[QLatin1String("abouturl")];
+}
+
+QString Config::homePage() const
+{
+ return home.isEmpty() ? profil->props[QLatin1String("startpage")] : home;
+}
+
+QStringList Config::source() const
+{
+ return src.size() == 0 ? QStringList(profil->props[QLatin1String("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
+ QString name = profil->icons[title];
+ QString resName = QLatin1String(":/trolltech/assistant/images/") + name;
+
+ if (QFile::exists(resName))
+ return QPixmap(resName);
+
+ if (name.startsWith(QLatin1String("file:")))
+ name = name.mid(5);
+ return QPixmap(name);
+}
+
+QPixmap Config::applicationIcon() const
+{
+ QString name = profil->props[QLatin1String("applicationicon")];
+ QString resName = QLatin1String(":/trolltech/assistant/images/") + name;
+
+ if (QFile::exists(resName))
+ return QPixmap(resName);
+
+ if (name.startsWith(QLatin1String("file:")))
+ name = name.mid(5);
+ return QPixmap(name);
+}
+
+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[QLatin1String("assistantdocs")].isEmpty()
+ ? QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html")
+ : profil->props[QLatin1String("assistantdocs")];
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/config.h b/tools/assistant/compat/config.h
new file mode 100644
index 0000000..0858ad8
--- /dev/null
+++ b/tools/assistant/compat/config.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "profile.h"
+
+#include <QString>
+#include <QStringList>
+#include <QPixmap>
+#include <QMap>
+
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+class Profile;
+
+struct FontSettings
+{
+ FontSettings() : useWindowFont(false), useBrowserFont(false),
+ windowWritingSystem(QFontDatabase::Latin), browserWritingSystem(QFontDatabase::Latin)
+ { }
+
+ QFont windowFont;
+ QFont browserFont;
+
+ bool useWindowFont;
+ bool useBrowserFont;
+
+ QFontDatabase::WritingSystem windowWritingSystem;
+ QFontDatabase::WritingSystem browserWritingSystem;
+};
+
+class Config
+{
+public:
+
+ Config();
+
+ void load();
+ void save();
+ Profile *profile() const { return profil; }
+ QString profileName() const { return profil->props[QLatin1String("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 homePage() const;
+ void setHomePage( const QString &hom ) { home = hom; }
+
+ QStringList source() const;
+ void setSource( const QStringList &s ) { src = s; }
+
+ int sideBarPage() const { return sideBar; }
+ void setSideBarPage( int sbp ) { sideBar = sbp; }
+
+ QByteArray windowGeometry() const { return winGeometry; }
+ void setWindowGeometry( const QByteArray &geometry ) { winGeometry = geometry; }
+
+ QByteArray mainWindowState() const { return mainWinState; }
+ void setMainWindowState( const QByteArray &state ) { mainWinState = state; }
+
+ qreal fontPointSize() const { return pointFntSize; }
+ void setFontPointSize(qreal size)
+ {
+ pointFntSize = size;
+ m_fontSettings.useBrowserFont = true;
+ m_fontSettings.browserFont.setPointSizeF(size);
+ }
+
+ FontSettings fontSettings() { return m_fontSettings; }
+ void setFontSettings(const FontSettings &settings) { m_fontSettings = settings; }
+
+ QString assistantDocPath() const;
+
+ bool docRebuild() const { return rebuildDocs; }
+ void setDocRebuild( bool rb ) { rebuildDocs = rb; }
+
+ void saveProfile( Profile *profile );
+ void loadDefaultProfile();
+ bool defaultProfileExists();
+
+ 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 home;
+ QStringList src;
+ QByteArray mainWinState;
+ QByteArray winGeometry;
+ qreal pointFntSize;
+ int sideBar;
+ bool hideSidebar;
+ bool rebuildDocs;
+ FontSettings m_fontSettings;
+};
+
+QT_END_NAMESPACE
+
+#endif // CONFIG_H
diff --git a/tools/assistant/compat/docuparser.cpp b/tools/assistant/compat/docuparser.cpp
new file mode 100644
index 0000000..31e1040
--- /dev/null
+++ b/tools/assistant/compat/docuparser.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "docuparser.h"
+#include "profile.h"
+
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QRegExp>
+#include <QString>
+#include <QDataStream>
+
+QT_BEGIN_NAMESPACE
+
+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 = QLatin1String("/Qt Assistant/") + QLatin1String(QT_VERSION_STR) + QLatin1String("/");
+
+DocuParser *DocuParser::createParser(const QString &fileName)
+{
+ QFile file(fileName);
+ if(!file.open(QFile::ReadOnly)) {
+ return 0;
+ }
+
+ QString str;
+ int maxlen = 1024;
+ int majVer = 0, minVer = 0, serVer = 0;
+ static QRegExp re(QLatin1String("assistantconfig +version=\"(\\d)\\.(\\d)\\.(\\d)\""), Qt::CaseInsensitive);
+ Q_ASSERT(re.isValid());
+ while(!(str = QLatin1String(file.readLine(maxlen))).isEmpty()) {
+ if(re.indexIn(str) >= 0) {
+ majVer = re.cap(1).toInt();
+ minVer = re.cap(2).toInt();
+ serVer = re.cap(3).toInt();
+ break;
+ }
+ }
+
+ if (majVer < 3 || (majVer == 3 && minVer < 2)) {
+ return new DocuParser310;
+ }
+
+ return new DocuParser320;
+}
+
+
+bool DocuParser::parse(QFile *file)
+{
+ QXmlInputSource source(file);
+ QXmlSimpleReader reader;
+ reader.setContentHandler(this);
+ reader.setErrorHandler(this);
+ setFileName(QFileInfo(*file).absoluteFilePath());
+ return reader.parse(source);
+}
+
+
+QString DocuParser::errorProtocol() const
+{
+ return errorProt;
+}
+
+
+QList<ContentItem> DocuParser::getContentItems()
+{
+ return contentList;
+}
+
+
+QList<IndexItem*> DocuParser::getIndexItems()
+{
+ return indexList;
+}
+
+QString DocuParser::absolutify(const QString &name, bool makeUrl) const
+{
+ if (!name.isEmpty()) {
+ QString s = name;
+ s.replace(QLatin1String("\\"), QLatin1String("/"));
+ QFileInfo orgPath(name);
+ if(orgPath.isRelative())
+ s = QFileInfo(fname).path() + QLatin1Char('/') + name;
+ if (makeUrl)
+ s.prepend(QLatin1String("file:"));
+ return s;
+ }
+ 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 = QLatin1String("");
+
+ contentRef = QLatin1String("");
+ indexRef = QLatin1String("");
+ depth = 0;
+
+ contentList.clear();
+ qDeleteAll(indexList);
+ indexList.clear();
+
+ return true;
+}
+
+
+bool DocuParser310::startElement(const QString &, const QString &,
+ const QString &qname,
+ const QXmlAttributes &attr)
+{
+ if (qname == QLatin1String("DCF") && state == StateInit) {
+ state = StateContent;
+ contentRef = absolutify(attr.value(QLatin1String("ref")), false);
+ conURL = contentRef;
+ docTitle = attr.value(QLatin1String("title"));
+ iconName = absolutify(attr.value(QLatin1String("icon")), false);
+ contentList.append(ContentItem(docTitle, absolutify(contentRef), depth));
+ } else if (qname == QLatin1String("section") && (state == StateContent || state == StateSect)) {
+ state = StateSect;
+ contentRef = absolutify(attr.value(QLatin1String("ref")));
+ title = attr.value(QLatin1String("title"));
+ depth++;
+ contentList.append(ContentItem(title, contentRef, depth));
+ } else if (qname == QLatin1String("keyword") && state == StateSect) {
+ state = StateKeyword;
+ indexRef = absolutify(attr.value(QLatin1String("ref")));
+ } else
+ return false;
+ return true;
+}
+
+bool DocuParser310::endElement(const QString &nameSpace, const QString &localName,
+ const QString &qName)
+{
+ Q_UNUSED(nameSpace);
+ Q_UNUSED(localName);
+ Q_UNUSED(qName);
+
+ switch(state) {
+ case StateInit:
+ break;
+ case StateContent:
+ state = StateInit;
+ break;
+ case StateSect:
+ state = --depth ? StateSect : StateContent;
+ break;
+ case StateKeyword:
+ state = StateSect;
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+
+bool DocuParser310::characters(const QString& ch)
+{
+ QString str = ch.simplified();
+ 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::fromLatin1("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.constBegin(); it != prof->dcfTitles.constEnd(); ++it)
+ p->dcfTitles[it.key()] = *it;
+
+ for (it = prof->icons.constBegin(); it != prof->icons.constEnd(); ++it)
+ p->icons[it.key()] = *it;
+
+ for (it = prof->indexPages.constBegin(); it != prof->indexPages.constEnd(); ++it)
+ p->indexPages[it.key()] = *it;
+}
+
+
+bool DocuParser320::startDocument()
+{
+ state = StateInit;
+ errorProt = QLatin1String("");
+
+ contentRef = QLatin1String("");
+ indexRef = QLatin1String("");
+ 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.toLower();
+
+ switch(state) {
+
+ case StateInit:
+ if(lower == QLatin1String("assistantconfig"))
+ state = StateDocRoot;
+ break;
+
+ case StateDocRoot:
+ if(lower == QLatin1String("dcf")) {
+ state = StateContent;
+ contentRef = absolutify(attr.value(QLatin1String("ref")));
+ conURL = contentRef;
+ docTitle = attr.value(QLatin1String("title"));
+ iconName = absolutify(attr.value(QLatin1String("icon")));
+ contentList.append(ContentItem(docTitle, contentRef, depth));
+ } else if(lower == QLatin1String("profile")) {
+ state = StateProfile;
+ }
+ break;
+
+ case StateSect:
+ if (lower == QLatin1String("keyword") && state == StateSect) {
+ state = StateKeyword;
+ indexRef = absolutify(attr.value(QLatin1String("ref")));
+ break;
+ } // else if (lower == "section")
+ case StateContent:
+ if(lower == QLatin1String("section")) {
+ state = StateSect;
+ contentRef = absolutify(attr.value(QLatin1String("ref")));
+ title = attr.value(QLatin1String("title"));
+ depth++;
+ contentList.append(ContentItem(title, contentRef, depth));
+ }
+ break;
+
+ case StateProfile:
+ if(lower == QLatin1String("property")) {
+ state = StateProperty;
+ propertyName = attr.value(QLatin1String("name"));
+ }
+ break;
+
+ case StateProperty:
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool DocuParser320::endElement(const QString &nameSpace,
+ const QString &localName,
+ const QString &qName)
+{
+ Q_UNUSED(nameSpace);
+ Q_UNUSED(localName);
+ Q_UNUSED(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()
+ << QLatin1String("startpage") << QLatin1String("abouturl")
+ << QLatin1String("applicationicon") << QLatin1String("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.simplified();
+ 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::fromLatin1("fatal parsing error: %1 in line %2, column %3\n")
+ .arg(exception.message())
+ .arg(exception.lineNumber())
+ .arg(exception.columnNumber());
+ return QXmlDefaultHandler::fatalError(exception);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/docuparser.h b/tools/assistant/compat/docuparser.h
new file mode 100644
index 0000000..181a8f1
--- /dev/null
+++ b/tools/assistant/compat/docuparser.h
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DOCUPARSER_H
+#define DOCUPARSER_H
+
+#include <QList>
+#include <QMap>
+#include <QXmlDefaultHandler>
+#include <QXmlAttributes>
+#include <QXmlParseException>
+
+QT_BEGIN_NAMESPACE
+
+class Profile;
+
+struct ContentItem {
+ ContentItem()
+ : title( QString() ), reference( QString() ), 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 );
+
+ QList<ContentItem> getContentItems();
+ QList<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, bool makeUrl = true ) const;
+
+ QString contentRef, indexRef, errorProt, conURL;
+ QString docTitle, title, iconName;
+ QList<ContentItem> contentList;
+ QList<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;
+};
+
+QT_END_NAMESPACE
+
+#endif // DOCUPARSER_H
diff --git a/tools/assistant/compat/fontsettingsdialog.cpp b/tools/assistant/compat/fontsettingsdialog.cpp
new file mode 100644
index 0000000..cd0cc06
--- /dev/null
+++ b/tools/assistant/compat/fontsettingsdialog.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fontsettingsdialog.h"
+#include "fontpanel.h"
+#include "config.h"
+
+#include <QtGui/QLabel>
+#include <QtGui/QComboBox>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QDialogButtonBox>
+
+QT_BEGIN_NAMESPACE
+
+FontSettingsDialog::FontSettingsDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_windowFontPanel(new FontPanel(this))
+ , m_browserFontPanel(new FontPanel(this))
+ , m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel))
+{
+ setModal(true);
+ setWindowTitle(tr("Font Settings"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QVBoxLayout *mainVLayout = new QVBoxLayout(this);
+ QHBoxLayout *hboxLayout = new QHBoxLayout;
+ mainVLayout->addLayout(hboxLayout);
+
+ QLabel *label = new QLabel(tr("Font settings for:"), this);
+ label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ hboxLayout->addWidget(label);
+ QComboBox *comboBox = new QComboBox(this);
+ comboBox->addItem(tr("Browser"));
+ comboBox->addItem(tr("Application"));
+ hboxLayout->addWidget(comboBox);
+
+ m_windowFontPanel->setCheckable(true);
+ m_browserFontPanel->setCheckable(true);
+
+ const QString customSettings(tr("Use custom settings"));
+ m_windowFontPanel->setTitle(customSettings);
+ m_browserFontPanel->setTitle(customSettings);
+
+ QStackedWidget *stackWidget = new QStackedWidget(this);
+ stackWidget->addWidget(m_browserFontPanel);
+ stackWidget->addWidget(m_windowFontPanel);
+
+ mainVLayout->addWidget(stackWidget);
+ mainVLayout->addWidget(m_dialogButtonBox);
+
+ connect(m_dialogButtonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_dialogButtonBox , SIGNAL(accepted()), this, SLOT(accept()));
+ connect(comboBox, SIGNAL(activated(int)), stackWidget, SLOT(setCurrentIndex(int)));
+}
+
+FontSettingsDialog::~FontSettingsDialog()
+{
+ // nothing todo
+}
+
+bool FontSettingsDialog::showDialog(FontSettings *settings)
+{
+ setupFontSettingsDialog(settings);
+
+ if (exec() != Accepted)
+ return false;
+
+ updateFontSettings(settings);
+ return true;
+}
+
+void FontSettingsDialog::updateFontSettings(FontSettings *settings)
+{
+ settings->useWindowFont = m_windowFontPanel->isChecked();
+ settings->useBrowserFont = m_browserFontPanel->isChecked();
+
+ settings->windowFont = settings->useWindowFont ? m_windowFontPanel->selectedFont() : qApp->font();
+ settings->browserFont = settings->useBrowserFont ? m_browserFontPanel->selectedFont() : qApp->font();
+
+ settings->windowWritingSystem = settings->useWindowFont ? m_windowFontPanel->writingSystem() : QFontDatabase::Latin;
+ settings->browserWritingSystem = settings->useBrowserFont ? m_browserFontPanel->writingSystem() : QFontDatabase::Latin;
+}
+
+void FontSettingsDialog::setupFontSettingsDialog(const FontSettings *settings)
+{
+ m_windowFontPanel->setSelectedFont(settings->windowFont);
+ m_browserFontPanel->setSelectedFont(settings->browserFont);
+
+ m_windowFontPanel->setWritingSystem(settings->windowWritingSystem);
+ m_browserFontPanel->setWritingSystem(settings->browserWritingSystem);
+
+ m_windowFontPanel->setChecked(settings->useWindowFont);
+ m_browserFontPanel->setChecked(settings->useBrowserFont);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/fontsettingsdialog.h b/tools/assistant/compat/fontsettingsdialog.h
new file mode 100644
index 0000000..e4607aa
--- /dev/null
+++ b/tools/assistant/compat/fontsettingsdialog.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _FONT_SETTINGS_DIALOG_H_
+#define _FONT_SETTINGS_DIALOG_H_
+
+#include <QtCore/QObject>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class FontPanel;
+struct FontSettings;
+class QDialogButtonBox;
+
+class FontSettingsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FontSettingsDialog(QWidget *parent = 0);
+ ~FontSettingsDialog();
+
+ bool showDialog(FontSettings *settings);
+
+private:
+ void updateFontSettings(FontSettings *settings);
+ void setupFontSettingsDialog(const FontSettings *settings);
+
+private:
+ FontPanel *m_windowFontPanel;
+ FontPanel *m_browserFontPanel;
+ QDialogButtonBox *m_dialogButtonBox;
+};
+
+#endif // _FONT_SETTINGS_DIALOG_H_
+
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/helpdialog.cpp b/tools/assistant/compat/helpdialog.cpp
new file mode 100644
index 0000000..4ea97d0
--- /dev/null
+++ b/tools/assistant/compat/helpdialog.cpp
@@ -0,0 +1,1331 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpdialog.h"
+#include "helpwindow.h"
+#include "topicchooser.h"
+#include "docuparser.h"
+#include "mainwindow.h"
+#include "config.h"
+#include "tabbedbrowser.h"
+
+#include <QtGui>
+#include <QtDebug>
+#include <QtCore/QVarLengthArray>
+
+#include <stdlib.h>
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+enum
+{
+ LinkRole = Qt::UserRole + 1000
+};
+
+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.toLatin1().constData());
+ return false;
+ }
+ return true;
+}
+
+struct IndexKeyword {
+ IndexKeyword(const QString &kw, const QString &l)
+ : keyword(kw), link(l) {}
+ IndexKeyword() : keyword(QString()), link(QString()) {}
+ bool operator<(const IndexKeyword &ik) const {
+ return keyword.toLower() < ik.keyword.toLower();
+ }
+ bool operator<=(const IndexKeyword &ik) const {
+ return keyword.toLower() <= ik.keyword.toLower();
+ }
+ bool operator>(const IndexKeyword &ik) const {
+ return keyword.toLower() > ik.keyword.toLower();
+ }
+ 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 != QLatin1Char('\'') && c != QLatin1Char('`')
+ && c != QLatin1Char('\"') && c != QLatin1Char(' ') && c != QLatin1Char('-') && c != QLatin1Char('_')
+ && c!= QLatin1Char('*'))
+ return QValidator::Invalid;
+ }
+ return QValidator::Acceptable;
+}
+
+class IndexListModel: public QStringListModel
+{
+public:
+ IndexListModel(QObject *parent = 0)
+ : QStringListModel(parent) {}
+
+ void clear() { contents.clear(); setStringList(QStringList()); }
+
+ QString description(int index) const { return stringList().at(index); }
+ QStringList links(int index) const { return contents.values(stringList().at(index)); }
+ void addLink(const QString &description, const QString &link) { contents.insert(description, link); }
+
+ void publish() { filter(QString(), QString()); }
+
+ QModelIndex filter(const QString &s, const QString &real);
+
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const
+ { return QStringListModel::flags(index) & ~Qt::ItemIsEditable; }
+
+private:
+ QMultiMap<QString, QString> contents;
+};
+
+bool caseInsensitiveLessThan(const QString &as, const QString &bs)
+{
+ const QChar *a = as.unicode();
+ const QChar *b = bs.unicode();
+ if (a == 0)
+ return true;
+ if (b == 0)
+ return false;
+ if (a == b)
+ return false;
+ int l=qMin(as.length(),bs.length());
+ while (l-- && QChar::toLower(a->unicode()) == QChar::toLower(b->unicode()))
+ a++,b++;
+ if (l==-1)
+ return (as.length() < bs.length());
+ return QChar::toLower(a->unicode()) < QChar::toLower(b->unicode());
+}
+
+/**
+ * \a real is kinda a hack for the smart search, need a way to match a regexp to an item
+ * How would you say the best match for Q.*Wiget is QWidget?
+ */
+QModelIndex IndexListModel::filter(const QString &s, const QString &real)
+{
+ QStringList list;
+
+ int goodMatch = -1;
+ int perfectMatch = -1;
+ if (s.isEmpty())
+ perfectMatch = 0;
+
+ const QRegExp regExp(s, Qt::CaseInsensitive);
+ QMultiMap<QString, QString>::iterator it = contents.begin();
+ QString lastKey;
+ for (; it != contents.end(); ++it) {
+ if (it.key() == lastKey)
+ continue;
+ lastKey = it.key();
+ const QString key = it.key();
+ if (key.contains(regExp) || key.contains(s, Qt::CaseInsensitive)) {
+ list.append(key);
+ if (perfectMatch == -1 && (key.startsWith(real, Qt::CaseInsensitive))) {
+ if (goodMatch == -1)
+ goodMatch = list.count() - 1;
+ if (real.length() == key.length()){
+ perfectMatch = list.count() - 1;
+ }
+ } else if (perfectMatch > -1 && s == key) {
+ perfectMatch = list.count() - 1;
+ }
+ }
+ }
+
+ int bestMatch = perfectMatch;
+ if (bestMatch == -1)
+ bestMatch = goodMatch;
+ bestMatch = qMax(0, bestMatch);
+
+ // sort the new list
+ QString match;
+ if (bestMatch >= 0 && list.count() > bestMatch)
+ match = list[bestMatch];
+ qSort(list.begin(), list.end(), caseInsensitiveLessThan);
+ setStringList(list);
+ for (int i = 0; i < list.size(); ++i) {
+ if (list.at(i) == match){
+ bestMatch = i;
+ break;
+ }
+ }
+ return index(bestMatch, 0, QModelIndex());
+}
+
+HelpNavigationListItem::HelpNavigationListItem(QListWidget *ls, const QString &txt)
+ : QListWidgetItem(txt, ls)
+{
+}
+
+void HelpNavigationListItem::addLink(const QString &link)
+{
+ QString lnk = HelpDialog::removeAnchorFromLink(link);
+ if (linkList.filter(lnk, Qt::CaseInsensitive).count() > 0)
+ return;
+ linkList << link;
+}
+
+HelpDialog::HelpDialog(QWidget *parent, MainWindow *h)
+ : QWidget(parent), lwClosed(false), help(h)
+{
+ ui.setupUi(this);
+ ui.listContents->setUniformRowHeights(true);
+ ui.listContents->header()->setStretchLastSection(false);
+ ui.listContents->header()->setResizeMode(QHeaderView::ResizeToContents);
+ ui.listBookmarks->setUniformRowHeights(true);
+ ui.listBookmarks->header()->setStretchLastSection(false);
+ ui.listBookmarks->header()->setResizeMode(QHeaderView::ResizeToContents);
+
+ indexModel = new IndexListModel(this);
+ ui.listIndex->setModel(indexModel);
+ ui.listIndex->setLayoutMode(QListView::Batched);
+ ui.listBookmarks->setItemHidden(ui.listBookmarks->headerItem(), true);
+ ui.listContents->setItemHidden(ui.listContents->headerItem(), true);
+ ui.searchButton->setShortcut(QKeySequence(Qt::ALT|Qt::SHIFT|Qt::Key_S));
+}
+
+void HelpDialog::initialize()
+{
+ connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
+
+ connect(ui.listContents, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(showTopic(QTreeWidgetItem*)));
+ connect(ui.listContents, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTreeItemMenu(QPoint)));
+ ui.listContents->viewport()->installEventFilter(this);
+
+ connect(ui.editIndex, SIGNAL(returnPressed()), this, SLOT(showTopic()));
+ connect(ui.editIndex, SIGNAL(textEdited(QString)), this, SLOT(searchInIndex(QString)));
+
+ connect(ui.listIndex, SIGNAL(activated(QModelIndex)), this, SLOT(showTopic()));
+ connect(ui.listIndex, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showIndexItemMenu(QPoint)));
+
+ connect(ui.listBookmarks, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(showTopic(QTreeWidgetItem*)));
+ connect(ui.listBookmarks, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTreeItemMenu(QPoint)));
+
+ connect(ui.termsEdit, SIGNAL(textChanged(const QString&)), this, SLOT(updateSearchButton(const QString&)));
+
+ connect(ui.resultBox, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showListItemMenu(QPoint)));
+
+ cacheFilesPath = QDir::homePath() + QLatin1String("/.assistant"); //### Find a better location for the dbs
+
+ ui.editIndex->installEventFilter(this);
+
+ ui.framePrepare->hide();
+ connect(qApp, SIGNAL(lastWindowClosed()), SLOT(lastWinClosed()));
+
+ ui.termsEdit->setValidator(new SearchValidator(ui.termsEdit));
+
+ actionOpenCurrentTab = new QAction(this);
+ actionOpenCurrentTab->setText(tr("Open Link in Current Tab"));
+
+ actionOpenLinkInNewWindow = new QAction(this);
+ actionOpenLinkInNewWindow->setText(tr("Open Link in New Window"));
+
+ actionOpenLinkInNewTab = new QAction(this);
+ actionOpenLinkInNewTab->setText(tr("Open Link in New Tab"));
+
+ itemPopup = new QMenu(this);
+ itemPopup->addAction(actionOpenCurrentTab);
+ itemPopup->addAction(actionOpenLinkInNewWindow);
+ itemPopup->addAction(actionOpenLinkInNewTab);
+
+ ui.tabWidget->setElideMode(Qt::ElideNone);
+
+ contentList.clear();
+
+ initDoneMsgShown = false;
+ fullTextIndex = 0;
+ indexDone = false;
+ titleMapDone = false;
+ contentsInserted = false;
+ bookmarksInserted = false;
+ setupTitleMap();
+
+}
+
+void HelpDialog::processEvents()
+{
+ qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+}
+
+
+void HelpDialog::lastWinClosed()
+{
+ lwClosed = true;
+}
+
+void HelpDialog::removeOldCacheFiles(bool onlyFulltextSearchIndex)
+{
+ if (!verifyDirectory(cacheFilesPath)) {
+ qWarning("Failed to created assistant directory");
+ return;
+ }
+ QString pname = QLatin1String(".") + Config::configuration()->profileName();
+
+ QStringList fileList;
+ fileList << QLatin1String("indexdb40.dict")
+ << QLatin1String("indexdb40.doc");
+
+ if (!onlyFulltextSearchIndex)
+ fileList << QLatin1String("indexdb40") << QLatin1String("contentdb40");
+
+ QStringList::iterator it = fileList.begin();
+ for (; it != fileList.end(); ++it) {
+ if (QFile::exists(cacheFilesPath + QDir::separator() + *it + pname)) {
+ QFile f(cacheFilesPath + QDir::separator() + *it + pname);
+ f.remove();
+ }
+ }
+}
+
+void HelpDialog::timerEvent(QTimerEvent *e)
+{
+ Q_UNUSED(e);
+ static int opacity = 255;
+ help->setWindowOpacity((opacity-=4)/255.0);
+ if (opacity<=0)
+ qApp->quit();
+}
+
+
+void HelpDialog::loadIndexFile()
+{
+ if (indexDone)
+ return;
+
+ setCursor(Qt::WaitCursor);
+ indexDone = true;
+ ui.labelPrepare->setText(tr("Prepare..."));
+ ui.framePrepare->show();
+ processEvents();
+
+ QProgressBar *bar = ui.progressPrepare;
+ bar->setMaximum(100);
+ bar->setValue(0);
+
+ keywordDocuments.clear();
+ QList<IndexKeyword> lst;
+ QFile indexFile(cacheFilesPath + QDir::separator() + QLatin1String("indexdb40.") +
+ Config::configuration()->profileName());
+ if (!indexFile.open(QFile::ReadOnly)) {
+ buildKeywordDB();
+ processEvents();
+ if (lwClosed)
+ return;
+ if (!indexFile.open(QFile::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;
+ }
+ }
+
+ QDataStream ds(&indexFile);
+ quint32 fileAges;
+ ds >> fileAges;
+ if (fileAges != getFileAges()) {
+ indexFile.close();
+ buildKeywordDB();
+ if (!indexFile.open(QFile::ReadOnly)) {
+ QMessageBox::warning(help, tr("Qt Assistant"),
+ tr("Cannot open the index file %1").arg(QFileInfo(indexFile).absoluteFilePath()));
+ return;
+ }
+ ds.setDevice(&indexFile);
+ ds >> fileAges;
+ }
+ ds >> lst;
+ indexFile.close();
+
+ bar->setValue(bar->maximum());
+ processEvents();
+
+ for (int i=0; i<lst.count(); ++i) {
+ const IndexKeyword &idx = lst.at(i);
+ indexModel->addLink(idx.keyword, idx.link);
+
+ keywordDocuments << HelpDialog::removeAnchorFromLink(idx.link);
+ }
+
+ indexModel->publish();
+
+ ui.framePrepare->hide();
+ showInitDoneMessage();
+ setCursor(Qt::ArrowCursor);
+}
+
+quint32 HelpDialog::getFileAges()
+{
+ QStringList addDocuFiles = Config::configuration()->docFiles();
+ QStringList::const_iterator i = addDocuFiles.constBegin();
+
+ quint32 fileAges = 0;
+ for (; i != addDocuFiles.constEnd(); ++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();
+
+ // Set up an indeterminate progress bar.
+ ui.labelPrepare->setText(tr("Prepare..."));
+ ui.progressPrepare->setMaximum(0);
+ ui.progressPrepare->setMinimum(0);
+ ui.progressPrepare->setValue(0);
+ processEvents();
+
+ QList<IndexKeyword> lst;
+ quint32 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).absoluteFilePath()));
+ continue;
+ }
+ fileAges += QFileInfo(file).lastModified().toTime_t();
+ DocuParser *handler = DocuParser::createParser(*i);
+ bool ok = handler->parse(&file);
+ file.close();
+ if (!ok){
+ QString msg = QString::fromLatin1("In file %1:\n%2")
+ .arg(QFileInfo(file).absoluteFilePath())
+ .arg(handler->errorProtocol());
+ QMessageBox::critical(this, tr("Parse Error"), tr(msg.toUtf8()));
+ delete handler;
+ continue;
+ }
+
+ QList<IndexItem*> indLst = handler->getIndexItems();
+ int counter = 0;
+ foreach (IndexItem *indItem, indLst) {
+ QFileInfo fi(indItem->reference);
+ lst.append(IndexKeyword(indItem->keyword, indItem->reference));
+
+ if (++counter%100 == 0) {
+ if (ui.progressPrepare)
+ ui.progressPrepare->setValue(counter);
+ processEvents();
+ if (lwClosed) {
+ return;
+ }
+ }
+ }
+ delete handler;
+ }
+ if (!lst.isEmpty())
+ qSort(lst);
+
+ QFile indexout(cacheFilesPath + QDir::separator() + QLatin1String("indexdb40.")
+ + Config::configuration()->profileName());
+ if (verifyDirectory(cacheFilesPath) && indexout.open(QFile::WriteOnly)) {
+ QDataStream s(&indexout);
+ s << fileAges;
+ s << lst;
+ indexout.close();
+ }
+}
+
+void HelpDialog::setupTitleMap()
+{
+ if (titleMapDone)
+ return;
+
+ bool needRebuild = false;
+ if (Config::configuration()->profileName() == QLatin1String("default")) {
+ const QStringList docuFiles = Config::configuration()->docFiles();
+ for (QStringList::ConstIterator it = docuFiles.begin(); it != docuFiles.end(); ++it) {
+ if (!QFile::exists(*it)) {
+ Config::configuration()->saveProfile(Profile::createDefaultProfile());
+ Config::configuration()->loadDefaultProfile();
+ needRebuild = true;
+ break;
+ }
+ }
+ }
+
+ if (Config::configuration()->docRebuild() || needRebuild) {
+ removeOldCacheFiles();
+ Config::configuration()->setDocRebuild(false);
+ Config::configuration()->saveProfile(Config::configuration()->profile());
+ }
+ if (contentList.isEmpty())
+ getAllContents();
+
+ titleMapDone = true;
+ titleMap.clear();
+ for (QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
+ ContentList lst = (*it).second;
+ foreach (ContentItem item, lst) {
+ titleMap[item.reference] = item.title.trimmed();
+ }
+ }
+ processEvents();
+}
+
+void HelpDialog::getAllContents()
+{
+ QFile contentFile(cacheFilesPath + QDir::separator() + QLatin1String("contentdb40.")
+ + Config::configuration()->profileName());
+ contentList.clear();
+ if (!contentFile.open(QFile::ReadOnly)) {
+ buildContentDict();
+ return;
+ }
+
+ QDataStream ds(&contentFile);
+ quint32 fileAges;
+ ds >> fileAges;
+ if (fileAges != getFileAges()) {
+ contentFile.close();
+ removeOldCacheFiles(true);
+ buildContentDict();
+ return;
+ }
+ QString key;
+ QList<ContentItem> lst;
+ while (!ds.atEnd()) {
+ ds >> key;
+ ds >> lst;
+ contentList += qMakePair(key, QList<ContentItem>(lst));
+ }
+ contentFile.close();
+ processEvents();
+
+}
+
+void HelpDialog::buildContentDict()
+{
+ QStringList docuFiles = Config::configuration()->docFiles();
+
+ quint32 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).absoluteFilePath()));
+ 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).absoluteFilePath()));
+ continue;
+ }
+ bool ok = handler->parse(&file);
+ file.close();
+ if (ok) {
+ contentList += qMakePair(*it, QList<ContentItem>(handler->getContentItems()));
+ delete handler;
+ } else {
+ QString msg = QString::fromLatin1("In file %1:\n%2")
+ .arg(QFileInfo(file).absoluteFilePath())
+ .arg(handler->errorProtocol());
+ QMessageBox::critical(this, tr("Parse Error"), tr(msg.toUtf8()));
+ continue;
+ }
+ }
+
+ QFile contentOut(cacheFilesPath + QDir::separator() + QLatin1String("contentdb40.")
+ + Config::configuration()->profileName());
+ if (contentOut.open(QFile::WriteOnly)) {
+ QDataStream s(&contentOut);
+ s << fileAges;
+ for (QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
+ s << *it;
+ }
+ contentOut.close();
+ }
+}
+
+void HelpDialog::currentTabChanged(int index)
+{
+ QString s = ui.tabWidget->widget(index)->objectName();
+ if (s == QLatin1String("indexPage"))
+ QTimer::singleShot(0, this, SLOT(loadIndexFile()));
+ else if (s == QLatin1String("bookmarkPage"))
+ insertBookmarks();
+ else if (s == QLatin1String("contentPage"))
+ QTimer::singleShot(0, this, SLOT(insertContents()));
+ else if (s == QLatin1String("searchPage"))
+ QTimer::singleShot(0, this, SLOT(setupFullTextIndex()));
+}
+
+void HelpDialog::showInitDoneMessage()
+{
+ if (initDoneMsgShown)
+ return;
+ initDoneMsgShown = true;
+ help->statusBar()->showMessage(tr("Done"), 3000);
+}
+
+void HelpDialog::showTopic(QTreeWidgetItem *item)
+{
+ if (item)
+ showTopic();
+}
+
+void HelpDialog::showTopic()
+{
+ QString tabName = ui.tabWidget->currentWidget()->objectName();
+
+ if (tabName == QLatin1String("indexPage"))
+ showIndexTopic();
+ else if (tabName == QLatin1String("bookmarkPage"))
+ showBookmarkTopic();
+ else if (tabName == QLatin1String("contentPage"))
+ showContentsTopic();
+}
+
+void HelpDialog::showIndexTopic()
+{
+ int row = ui.listIndex->currentIndex().row();
+ if (row == -1 || row >= indexModel->rowCount())
+ return;
+
+ QString description = indexModel->description(row);
+ QStringList links = indexModel->links(row);
+
+ bool blocked = ui.editIndex->blockSignals(true);
+ ui.editIndex->setText(description);
+ ui.editIndex->blockSignals(blocked);
+
+ if (links.count() == 1) {
+ emit showLink(links.first());
+ } else {
+ qSort(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, description);
+ if (!link.isEmpty())
+ emit showLink(link);
+ }
+
+ ui.listIndex->setCurrentIndex(indexModel->index(indexModel->stringList().indexOf(description)));
+ ui.listIndex->scrollTo(ui.listIndex->currentIndex(), QAbstractItemView::PositionAtTop);
+}
+
+void HelpDialog::searchInIndex(const QString &searchString)
+{
+ QRegExp atoz(QLatin1String("[A-Z]"));
+ int matches = searchString.count(atoz);
+ if (matches > 0 && !searchString.contains(QLatin1String(".*")))
+ {
+ int start = 0;
+ QString newSearch;
+ for (; matches > 0; --matches) {
+ int match = searchString.indexOf(atoz, start+1);
+ if (match <= start)
+ continue;
+ newSearch += searchString.mid(start, match-start);
+ newSearch += QLatin1String(".*");
+ start = match;
+ }
+ newSearch += searchString.mid(start);
+ ui.listIndex->setCurrentIndex(indexModel->filter(newSearch, searchString));
+ }
+ else
+ ui.listIndex->setCurrentIndex(indexModel->filter(searchString, searchString));
+}
+
+QString HelpDialog::titleOfLink(const QString &link)
+{
+ QString s = HelpDialog::removeAnchorFromLink(link);
+ s = titleMap[s];
+ if (s.isEmpty())
+ return link;
+ return s;
+}
+
+bool HelpDialog::eventFilter(QObject * o, QEvent * e)
+{
+ if (o == ui.editIndex && e->type() == QEvent::KeyPress) {
+ switch (static_cast<QKeyEvent*>(e)->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageDown:
+ case Qt::Key_PageUp:
+ QApplication::sendEvent(ui.listIndex, e);
+ break;
+
+ default:
+ break;
+ }
+ } else if (o == ui.listContents->viewport()) {
+ if (e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (me->button() == Qt::LeftButton) {
+ QTreeWidgetItem *item = ui.listContents->itemAt(me->pos());
+ QRect vRect = ui.listContents->visualItemRect(item);
+
+ // only show topic if we clicked an item
+ if (item && vRect.contains(me->pos()))
+ showTopic(item);
+ }
+ }
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void HelpDialog::addBookmark()
+{
+ if (!bookmarksInserted)
+ insertBookmarks();
+ QString link = help->browsers()->currentBrowser()->source().toString();
+ QString title = help->browsers()->currentBrowser()->documentTitle();
+ if (title.isEmpty())
+ title = titleOfLink(link);
+
+ QTreeWidgetItem *i = new QTreeWidgetItem(ui.listBookmarks, 0);
+ i->setText(0, title);
+ i->setData(0, LinkRole, link);
+ ui.buttonRemove->setEnabled(true);
+ saveBookmarks();
+ help->updateBookmarkMenu();
+}
+
+void HelpDialog::on_buttonAdd_clicked()
+{
+ addBookmark();
+}
+
+void HelpDialog::on_buttonRemove_clicked()
+{
+ if (!ui.listBookmarks->currentItem())
+ return;
+
+ delete ui.listBookmarks->currentItem();
+ saveBookmarks();
+ if (ui.listBookmarks->topLevelItemCount() != 0) {
+ ui.listBookmarks->setCurrentItem(ui.listBookmarks->topLevelItem(0));
+ }
+ ui.buttonRemove->setEnabled(ui.listBookmarks->topLevelItemCount() > 0);
+ help->updateBookmarkMenu();
+}
+
+void HelpDialog::insertBookmarks()
+{
+ if (bookmarksInserted)
+ return;
+ bookmarksInserted = true;
+ ui.listBookmarks->clear();
+ QFile f(cacheFilesPath + QDir::separator() + QLatin1String("bookmarks.")
+ + Config::configuration()->profileName());
+ if (!f.open(QFile::ReadOnly))
+ return;
+ QTextStream ts(&f);
+ while (!ts.atEnd()) {
+ QTreeWidgetItem *i = new QTreeWidgetItem(ui.listBookmarks, 0);
+ i->setText(0, ts.readLine());
+ i->setData(0, LinkRole, ts.readLine());
+ }
+ ui.buttonRemove->setEnabled(ui.listBookmarks->topLevelItemCount() > 0);
+ help->updateBookmarkMenu();
+ showInitDoneMessage();
+}
+
+void HelpDialog::showBookmarkTopic()
+{
+ if (!ui.listBookmarks->currentItem())
+ return;
+
+ QTreeWidgetItem *i = (QTreeWidgetItem*)ui.listBookmarks->currentItem();
+ emit showLink(i->data(0, LinkRole).toString());
+}
+
+static void store(QTreeWidgetItem *i, QTextStream &ts)
+{
+ ts << i->text(0) << endl;
+ ts << i->data(0, LinkRole).toString() << endl;
+
+ for (int index = 0; index < i->childCount(); ++index)
+ store(i->child(index), ts);
+}
+
+static void store(QTreeWidget *tw, QTextStream &ts)
+{
+ for (int index = 0; index < tw->topLevelItemCount(); ++index)
+ store(tw->topLevelItem(index), ts);
+}
+
+void HelpDialog::saveBookmarks()
+{
+ QFile f(cacheFilesPath + QDir::separator() + QLatin1String("bookmarks.")
+ + Config::configuration()->profileName());
+ if (!f.open(QFile::WriteOnly))
+ return;
+
+ QTextStream ts(&f);
+ store(ui.listBookmarks, ts);
+ f.close();
+}
+
+void HelpDialog::insertContents()
+{
+#ifdef Q_WS_MAC
+ static const QLatin1String IconPath(":/trolltech/assistant/images/mac/book.png");
+#else
+ static const QLatin1String IconPath(":/trolltech/assistant/images/win/book.png");
+#endif
+ if (contentsInserted)
+ return;
+
+ if (contentList.isEmpty())
+ getAllContents();
+
+ contentsInserted = true;
+ ui.listContents->clear();
+ setCursor(Qt::WaitCursor);
+ if (!titleMapDone)
+ setupTitleMap();
+
+#if 0 // ### port me
+ ui.listContents->setSorting(-1);
+#endif
+
+ for (QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
+ QTreeWidgetItem *newEntry = 0;
+
+ QTreeWidgetItem *contentEntry = 0;
+ QStack<QTreeWidgetItem*> stack;
+ stack.clear();
+ int depth = 0;
+ bool root = false;
+
+ const int depthSize = 32;
+ QVarLengthArray<QTreeWidgetItem*, depthSize> lastItem(depthSize);
+
+ ContentList lst = (*it).second;
+ for (ContentList::ConstIterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
+ ContentItem item = *it;
+ if (item.depth == 0) {
+ lastItem[0] = 0;
+ newEntry = new QTreeWidgetItem(ui.listContents, 0);
+ newEntry->setIcon(0, QIcon(IconPath));
+ newEntry->setText(0, item.title);
+ newEntry->setData(0, LinkRole, 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) {
+ if (lastItem.capacity() == depth)
+ lastItem.resize(depth + depthSize);
+ contentEntry = new QTreeWidgetItem(stack.top(), lastItem[ depth ]);
+ lastItem[ depth ] = contentEntry;
+ contentEntry->setText(0, item.title);
+ contentEntry->setData(0, LinkRole, item.reference);
+ }
+ else if (item.depth < depth) {
+ stack.pop();
+ depth--;
+ item = *(--it);
+ }
+ }
+ }
+ processEvents();
+ }
+ setCursor(Qt::ArrowCursor);
+ showInitDoneMessage();
+}
+
+void HelpDialog::showContentsTopic()
+{
+ QTreeWidgetItem *i = (QTreeWidgetItem*)ui.listContents->currentItem();
+ if (!i)
+ return;
+ emit showLink(i->data(0, LinkRole).toString());
+}
+
+QTreeWidgetItem * HelpDialog::locateLink(QTreeWidgetItem *item, const QString &link)
+{
+ QTreeWidgetItem *child = 0;
+#ifdef Q_OS_WIN
+ Qt::CaseSensitivity checkCase = Qt::CaseInsensitive;
+#else
+ Qt::CaseSensitivity checkCase = Qt::CaseSensitive;
+#endif
+ for (int i = 0, childCount = item->childCount(); i<childCount; i++) {
+ child = item->child(i);
+ ///check whether it is this item
+ if (link.startsWith(child->data(0, LinkRole).toString(), checkCase))
+ break;
+ //check if the link is a child of this item
+ else if (child->childCount()) {
+ child = locateLink(child, link);
+ if (child)
+ break;
+ }
+ child = 0;
+ }
+ return child;
+}
+
+void HelpDialog::locateContents(const QString &link)
+{
+ //ensure the TOC is filled
+ if (!contentsInserted)
+ insertContents();
+#ifdef Q_OS_WIN
+ Qt::CaseSensitivity checkCase = Qt::CaseInsensitive;
+#else
+ Qt::CaseSensitivity checkCase = Qt::CaseSensitive;
+#endif
+ QString findLink(link);
+ //Installations on a windows local drive will give the 'link' as <file:///C:/xxx>
+ //and the contents in the TOC will be <file:C:/xxx>.
+ //But on others the 'link' of format <file:///root/xxx>
+ //and the contents in the TOC will be <file:/root/xxx>.
+ if (findLink.contains(QLatin1String("file:///"))) {
+ if (findLink[9] == QLatin1Char(':')) //on windows drives
+ findLink.replace(0, 8, QLatin1String("file:"));
+ else
+ findLink.replace(0, 8, QLatin1String("file:/"));
+ }
+
+ bool topLevel = false;
+ QTreeWidgetItem *item = 0;
+ int totalItems = ui.listContents->topLevelItemCount();
+
+ for (int i = 0; i < totalItems; i++ ) {
+ // first see if we are one of the top level items
+ item = (QTreeWidgetItem*)ui.listContents->topLevelItem(i);
+ if (findLink.startsWith(item->data(0, LinkRole).toString(), checkCase)) {
+ topLevel = true;
+ break;
+ }
+ }
+
+ if (!topLevel) {
+ // now try to find it in the sublevel items
+ for (int n = 0; n < totalItems; ++n) {
+ item = (QTreeWidgetItem*)ui.listContents->topLevelItem(n);
+ item = locateLink(item, findLink);
+ if (item)
+ break;
+ }
+ }
+
+ //remove the old selection
+ QList<QTreeWidgetItem *> selected = ui.listContents->selectedItems();
+ foreach(QTreeWidgetItem *sel, selected)
+ ui.listContents->setItemSelected(sel, false);
+
+ //set the TOC item and show
+ ui.listContents->setCurrentItem(item);
+ ui.listContents->setItemSelected(item, true);
+ ui.listContents->scrollToItem(item);
+}
+
+void HelpDialog::toggleContents()
+{
+ if (!isVisible() || ui.tabWidget->currentIndex() != 0) {
+ ui.tabWidget->setCurrentIndex(0);
+ parentWidget()->show();
+ }
+ else
+ parentWidget()->hide();
+}
+
+void HelpDialog::toggleIndex()
+{
+ if (!isVisible() || ui.tabWidget->currentIndex() != 1 || !ui.editIndex->hasFocus()) {
+ ui.tabWidget->setCurrentIndex(1);
+ parentWidget()->show();
+ ui.editIndex->setFocus();
+ }
+ else
+ parentWidget()->hide();
+}
+
+void HelpDialog::toggleBookmarks()
+{
+ if (!isVisible() || ui.tabWidget->currentIndex() != 2) {
+ ui.tabWidget->setCurrentIndex(2);
+ parentWidget()->show();
+ }
+ else
+ parentWidget()->hide();
+}
+
+void HelpDialog::toggleSearch()
+{
+ if (!isVisible() || ui.tabWidget->currentIndex() != 3) {
+ ui.tabWidget->setCurrentIndex(3);
+ parentWidget()->show();
+ }
+ else
+ parentWidget()->hide();
+}
+
+void HelpDialog::setupFullTextIndex()
+{
+ if (fullTextIndex)
+ return;
+
+ QString pname = Config::configuration()->profileName();
+ fullTextIndex = new Index(QStringList(), QDir::homePath()); // ### 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;
+ }
+ fullTextIndex->setDictionaryFile(cacheFilesPath + QDir::separator() + QLatin1String("indexdb40.dict.") + pname);
+ fullTextIndex->setDocListFile(cacheFilesPath + QDir::separator() + QLatin1String("indexdb40.doc.") + pname);
+ processEvents();
+
+ connect(fullTextIndex, SIGNAL(indexingProgress(int)),
+ this, SLOT(setIndexingProgress(int)));
+ QFile f(cacheFilesPath + QDir::separator() + QLatin1String("indexdb40.dict.") + pname);
+ if (!f.exists()) {
+ QString doc;
+ QSet<QString> documentSet;
+ QMap<QString, QString>::ConstIterator it = titleMap.constBegin();
+ for (; it != titleMap.constEnd(); ++it) {
+ doc = HelpDialog::removeAnchorFromLink(it.key());
+ if (!doc.isEmpty())
+ documentSet.insert(doc);
+ }
+ loadIndexFile();
+ for ( QStringList::Iterator it = keywordDocuments.begin(); it != keywordDocuments.end(); ++it ) {
+ if (!(*it).isEmpty())
+ documentSet.insert(*it);
+ }
+ fullTextIndex->setDocList( documentSet.toList() );
+
+ help->statusBar()->clearMessage();
+ setCursor(Qt::WaitCursor);
+ ui.labelPrepare->setText(tr("Indexing files..."));
+ ui.progressPrepare->setMaximum(100);
+ ui.progressPrepare->reset();
+ ui.progressPrepare->show();
+ ui.framePrepare->show();
+ processEvents();
+ if (fullTextIndex->makeIndex() == -1)
+ return;
+ fullTextIndex->writeDict();
+ ui.progressPrepare->setValue(100);
+ ui.framePrepare->hide();
+ setCursor(Qt::ArrowCursor);
+ showInitDoneMessage();
+ } else {
+ setCursor(Qt::WaitCursor);
+ help->statusBar()->showMessage(tr("Reading dictionary..."));
+ processEvents();
+ fullTextIndex->readDict();
+ help->statusBar()->showMessage(tr("Done"), 3000);
+ setCursor(Qt::ArrowCursor);
+ }
+ keywordDocuments.clear();
+}
+
+void HelpDialog::setIndexingProgress(int prog)
+{
+ ui.progressPrepare->setValue(prog);
+ processEvents();
+}
+
+void HelpDialog::startSearch()
+{
+ QString str = ui.termsEdit->text();
+ str = str.simplified();
+ str = str.replace(QLatin1String("\'"), QLatin1String("\""));
+ str = str.replace(QLatin1String("`"), QLatin1String("\""));
+ QString buf = str;
+ str = str.replace(QLatin1String("-"), QLatin1String(" "));
+ str = str.replace(QRegExp(QLatin1String("\\s[\\S]?\\s")), QLatin1String(" "));
+ terms = str.split(QLatin1Char(' '));
+ QStringList termSeq;
+ QStringList seqWords;
+ QStringList::iterator it = terms.begin();
+ for (; it != terms.end(); ++it) {
+ (*it) = (*it).simplified();
+ (*it) = (*it).toLower();
+ (*it) = (*it).replace(QLatin1String("\""), QLatin1String(""));
+ }
+ if (str.contains(QLatin1Char('\"'))) {
+ if ((str.count(QLatin1Char('\"')))%2 == 0) {
+ int beg = 0;
+ int end = 0;
+ QString s;
+ beg = str.indexOf(QLatin1Char('\"'), beg);
+ while (beg != -1) {
+ beg++;
+ end = str.indexOf(QLatin1Char('\"'), beg);
+ s = str.mid(beg, end - beg);
+ s = s.toLower();
+ s = s.simplified();
+ if (s.contains(QLatin1Char('*'))) {
+ QMessageBox::warning(this, tr("Full Text Search"),
+ tr("Using a wildcard within phrases is not allowed."));
+ return;
+ }
+ seqWords += s.split(QLatin1Char(' '));
+ termSeq << s;
+ beg = str.indexOf(QLatin1Char('\"'), end + 1);
+ }
+ } else {
+ QMessageBox::warning(this, tr("Full Text Search"),
+ tr("The closing quotation mark is missing."));
+ return;
+ }
+ }
+ setCursor(Qt::WaitCursor);
+ foundDocs.clear();
+ foundDocs = fullTextIndex->query(terms, termSeq, seqWords);
+ QString msg = tr("%n document(s) found.", "", foundDocs.count());
+ help->statusBar()->showMessage(tr(msg.toUtf8()), 3000);
+ ui.resultBox->clear();
+ for (it = foundDocs.begin(); it != foundDocs.end(); ++it)
+ ui.resultBox->addItem(fullTextIndex->getDocumentTitle(*it));
+
+ terms.clear();
+ bool isPhrase = false;
+ QString s;
+ for (int i = 0; i < (int)buf.length(); ++i) {
+ if (buf[i] == QLatin1Char('\"')) {
+ isPhrase = !isPhrase;
+ s = s.simplified();
+ if (!s.isEmpty())
+ terms << s;
+ s = QLatin1String("");
+ } else if (buf[i] == QLatin1Char(' ') && !isPhrase) {
+ s = s.simplified();
+ if (!s.isEmpty())
+ terms << s;
+ s = QLatin1String("");
+ } else
+ s += buf[i];
+ }
+ if (!s.isEmpty())
+ terms << s;
+
+ setCursor(Qt::ArrowCursor);
+}
+
+void HelpDialog::on_helpButton_clicked()
+{
+ emit showLink(MainWindow::urlifyFileName(
+ Config::configuration()->assistantDocPath() +
+ QLatin1String("/assistant-manual.html#full-text-searching")));
+}
+
+void HelpDialog::on_resultBox_itemActivated(QListWidgetItem *item)
+{
+ showResultPage(item);
+}
+
+void HelpDialog::showResultPage(QListWidgetItem *item)
+{
+ if (item)
+ emit showSearchLink(foundDocs[ui.resultBox->row(item)], terms);
+}
+
+void HelpDialog::showIndexItemMenu(const QPoint &pos)
+{
+ QListView *listView = qobject_cast<QListView*>(sender());
+ if (!listView)
+ return;
+
+ QModelIndex idx = listView->indexAt(pos);
+ if (!idx.isValid())
+ return;
+
+ QAction *action = itemPopup->exec(listView->viewport()->mapToGlobal(pos));
+ if (action == actionOpenCurrentTab) {
+ showTopic();
+ } else if (action) {
+ HelpWindow *hw = help->browsers()->currentBrowser();
+ QString itemName = idx.data().toString();
+ ui.editIndex->setText(itemName);
+ QStringList links = indexModel->links(idx.row());
+ if (links.count() == 1) {
+ if (action == actionOpenLinkInNewWindow)
+ 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, itemName);
+ if (!link.isEmpty()) {
+ if (action == actionOpenLinkInNewWindow)
+ hw->openLinkInNewWindow(link);
+ else
+ hw->openLinkInNewPage(link);
+ }
+ }
+ }
+}
+
+void HelpDialog::showListItemMenu(const QPoint &pos)
+{
+ QListWidget *listWidget = qobject_cast<QListWidget*>(sender());
+ if (!listWidget)
+ return;
+ QListWidgetItem *item = listWidget->itemAt(pos);
+ if (!item)
+ return;
+
+ QAction *action = itemPopup->exec(listWidget->viewport()->mapToGlobal(pos));
+ if (action == actionOpenCurrentTab) {
+ showResultPage(item);
+ } else if (action) {
+ HelpWindow *hw = help->browsers()->currentBrowser();
+ QString link = foundDocs[ui.resultBox->row(item)];
+ if (action == actionOpenLinkInNewWindow)
+ hw->openLinkInNewWindow(link);
+ else
+ hw->openLinkInNewPage(link);
+ }
+}
+
+void HelpDialog::showTreeItemMenu(const QPoint &pos)
+{
+ QTreeWidget *treeWidget = qobject_cast<QTreeWidget*>(sender());
+
+ if (!treeWidget)
+ return;
+
+ QTreeWidgetItem *item = treeWidget->itemAt(pos);
+
+ if (!item)
+ return;
+
+ QAction *action = itemPopup->exec(treeWidget->viewport()->mapToGlobal(pos));
+ if (action == actionOpenCurrentTab) {
+ if (ui.tabWidget->currentWidget()->objectName() == QLatin1String("contentPage"))
+ showContentsTopic();
+ else
+ showBookmarkTopic();
+ } else if (action) {
+ QTreeWidgetItem *i = (QTreeWidgetItem*)item;
+ if (action == actionOpenLinkInNewWindow)
+ help->browsers()->currentBrowser()->openLinkInNewWindow(i->data(0, LinkRole).toString());
+ else
+ help->browsers()->currentBrowser()->openLinkInNewPage(i->data(0, LinkRole).toString());
+ }
+}
+
+void HelpDialog::on_termsEdit_returnPressed()
+{
+ startSearch();
+}
+
+void HelpDialog::updateSearchButton(const QString &txt)
+{
+ ui.searchButton->setDisabled(txt.isEmpty());
+}
+
+void HelpDialog::on_searchButton_clicked()
+{
+ startSearch();
+}
+
+QString HelpDialog::removeAnchorFromLink(const QString &link)
+{
+ int i = link.length();
+ int j = link.lastIndexOf(QLatin1Char('/'));
+ int l = link.lastIndexOf(QDir::separator());
+ if (l > j)
+ j = l;
+ if (j > -1) {
+ QString fileName = link.mid(j+1);
+ int k = fileName.lastIndexOf(QLatin1Char('#'));
+ if (k > -1)
+ i = j + k + 1;
+ }
+ return link.left(i);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/helpdialog.h b/tools/assistant/compat/helpdialog.h
new file mode 100644
index 0000000..29d77d9
--- /dev/null
+++ b/tools/assistant/compat/helpdialog.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPDIALOG_H
+#define HELPDIALOG_H
+
+#include "ui_helpdialog.h"
+#include "index.h"
+#include "helpwindow.h"
+#include "docuparser.h"
+
+#include <QList>
+#include <QPair>
+#include <QListWidget>
+#include <QTreeWidget>
+#include <QMap>
+#include <QStringList>
+#include <QValidator>
+#include <qmenu.h>
+#include <QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QProgressBar;
+class MainWindow;
+class QTextBrowser;
+class IndexListModel;
+
+class HelpNavigationListItem : public QListWidgetItem
+{
+public:
+ HelpNavigationListItem(QListWidget *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)
+ : QValidator(parent) {}
+ ~SearchValidator() {}
+ QValidator::State validate(QString &str, int &) const;
+};
+
+class HelpDialog : public QWidget
+{
+ Q_OBJECT
+public:
+ HelpDialog(QWidget *parent, MainWindow *h);
+
+ inline QTabWidget *tabWidget() const
+ { return ui.tabWidget; }
+
+ QString titleOfLink(const QString &link);
+ bool eventFilter(QObject *, QEvent *);
+ bool lastWindowClosed() { return lwClosed; }
+
+ void timerEvent(QTimerEvent *e);
+ static QString removeAnchorFromLink(const QString &link);
+
+signals:
+ void showLink(const QString &s);
+ void showSearchLink(const QString &s, const QStringList &terms);
+
+public slots:
+ void initialize();
+ void startSearch();
+ void addBookmark();
+ void currentTabChanged(int index);
+ void locateContents(const QString &link);
+
+private slots:
+ void on_buttonAdd_clicked();
+ void on_buttonRemove_clicked();
+ void on_termsEdit_returnPressed();
+ void on_helpButton_clicked();
+ void on_searchButton_clicked();
+ void on_resultBox_itemActivated(QListWidgetItem*);
+ void updateSearchButton(const QString &txt);
+
+ void showResultPage(QListWidgetItem *);
+
+ void showTopic(QTreeWidgetItem *);
+ void loadIndexFile();
+ void insertContents();
+ void setupFullTextIndex();
+ void showTopic();
+ void searchInIndex(const QString &s);
+ void toggleContents();
+ void toggleIndex();
+ void toggleBookmarks();
+ void toggleSearch();
+ void lastWinClosed();
+ void setIndexingProgress(int prog);
+ void showListItemMenu(const QPoint &pos);
+ void showIndexItemMenu(const QPoint &pos);
+ void showTreeItemMenu(const QPoint &pos);
+ void insertBookmarks();
+ void processEvents();
+
+private:
+ typedef QList<ContentItem> ContentList;
+ void removeOldCacheFiles(bool onlyFulltextSearchIndex = false);
+ void buildKeywordDB();
+ quint32 getFileAges();
+ void showIndexTopic();
+ void showBookmarkTopic();
+ void setupTitleMap();
+ void saveBookmarks();
+ void showContentsTopic();
+ void showInitDoneMessage();
+ void buildContentDict();
+ QTreeWidgetItem * locateLink(QTreeWidgetItem *item, const QString &link);
+
+private:
+ Ui::HelpDialog ui;
+
+ IndexListModel *indexModel;
+ QMap<QString, QString> titleMap;
+ bool indexDone, bookmarksInserted, titleMapDone, contentsInserted;
+ bool lwClosed;
+ MainWindow *help;
+ QString documentationPath;
+ Index *fullTextIndex;
+ QStringList terms, foundDocs;
+ bool initDoneMsgShown;
+ void getAllContents();
+ QList<QPair<QString, ContentList> > contentList;
+ QMenu *itemPopup;
+ QString cacheFilesPath;
+ QStringList keywordDocuments;
+
+ QAction *actionOpenCurrentTab;
+ QAction *actionOpenLinkInNewWindow;
+ QAction *actionOpenLinkInNewTab;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPDIALOG_H
diff --git a/tools/assistant/compat/helpdialog.ui b/tools/assistant/compat/helpdialog.ui
new file mode 100644
index 0000000..acd1372
--- /dev/null
+++ b/tools/assistant/compat/helpdialog.ui
@@ -0,0 +1,404 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>HelpDialog</class>
+ <widget class="QWidget" name="HelpDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>274</width>
+ <height>417</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Help</string>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>Help&lt;/b>&lt;p>Choose the topic you want help on from the contents list, or search the index for keywords.&lt;/p></string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="whatsThis" >
+ <string>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</string>
+ </property>
+ <widget class="QWidget" name="contentPage" >
+ <attribute name="title" >
+ <string>Con&amp;tents</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>5</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="listContents" >
+ <property name="contextMenuPolicy" >
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>Help topics organized by category.&lt;/b>&lt;p>Double-click an item to see the topics in that category. To view a topic, just double-click it.&lt;/p></string>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>true</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>column 1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="indexPage" >
+ <attribute name="title" >
+ <string>&amp;Index</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>5</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>&amp;Look For:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>editIndex</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="editIndex" >
+ <property name="toolTip" >
+ <string>Enter keyword</string>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>Enter a keyword.&lt;/b>&lt;p>The list will select an item that matches the entered string best.&lt;/p></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="listIndex" >
+ <property name="contextMenuPolicy" >
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>List of available help topics.&lt;/b>&lt;p>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></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="bookmarkPage" >
+ <attribute name="title" >
+ <string>&amp;Bookmarks</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>5</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="listBookmarks" >
+ <property name="contextMenuPolicy" >
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="whatsThis" >
+ <string>Displays the list of bookmarks.</string>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>column 1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonAdd" >
+ <property name="toolTip" >
+ <string>Add new bookmark</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Add the currently displayed page as a new bookmark.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonRemove" >
+ <property name="toolTip" >
+ <string>Delete bookmark</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Delete the selected bookmark.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="searchPage" >
+ <attribute name="title" >
+ <string>&amp;Search</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>5</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1_2" >
+ <property name="text" >
+ <string>Searching f&amp;or:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>termsEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLineEdit" name="termsEdit" >
+ <property name="toolTip" >
+ <string>Enter searchword(s).</string>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>Enter search word(s).&lt;/b>&lt;p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.&lt;/p></string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QListWidget" name="resultBox" >
+ <property name="contextMenuPolicy" >
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="whatsThis" >
+ <string>&lt;b>Found documents&lt;/b>&lt;p>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></string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Found &amp;Documents:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>resultBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="helpButton" >
+ <property name="toolTip" >
+ <string>Display the help page.</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Display the help page for the full text search.</string>
+ </property>
+ <property name="text" >
+ <string>He&amp;lp</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>61</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="searchButton" >
+ <property name="toolTip" >
+ <string>Start searching.</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Pressing this button starts the search.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Search</string>
+ </property>
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="framePrepare" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>3</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelPrepare" >
+ <property name="text" >
+ <string>Preparing...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressPrepare" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <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>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/compat/helpwindow.cpp b/tools/assistant/compat/helpwindow.cpp
new file mode 100644
index 0000000..d3ddc29
--- /dev/null
+++ b/tools/assistant/compat/helpwindow.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpwindow.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpdialog.h"
+#include "config.h"
+
+#include <QApplication>
+#include <QClipboard>
+#include <QUrl>
+#include <QMessageBox>
+#include <QDir>
+#include <QFile>
+#include <QProcess>
+#include <QAction>
+#include <QFileInfo>
+#include <QFont>
+#include <QtEvents>
+#include <QTextStream>
+#include <QTextCodec>
+#include <QStatusBar>
+#include <QTextCursor>
+#include <QTextObject>
+#include <QTextLayout>
+#include <QtDebug>
+#include <qdesktopservices.h>
+
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+
+#if defined(Q_OS_WIN32)
+# include <windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+HelpWindow::HelpWindow(MainWindow *w, QWidget *parent)
+ : QTextBrowser(parent)
+ , mw(w)
+ , blockScroll(false)
+ , shiftPressed(false)
+ , newWindow(false)
+{
+ FontSettings settings = Config::configuration()->fontSettings();
+ setFont(settings.browserFont);
+
+ connect(this, SIGNAL(copyAvailable(bool)), w, SLOT(copyAvailable(bool)));
+}
+
+void HelpWindow::setSource(const QUrl &name)
+{
+ if (name.isValid()) {
+ if (name.scheme() == QLatin1String("http") || name.scheme() == QLatin1String("ftp")
+ || name.scheme() == QLatin1String("mailto") || name.path().endsWith(QLatin1String("pdf"))) {
+ bool launched = QDesktopServices::openUrl(name);
+ if (!launched) {
+ QMessageBox::information(mw, tr("Help"),
+ tr("Unable to launch web browser.\n"),
+ tr("OK"));
+ }
+ return;
+ }
+
+ QFileInfo fi(name.toLocalFile());
+ if (name.scheme() == QLatin1String("file") && fi.exists()) {
+ if (newWindow || (shiftPressed && hasFocus())) {
+ shiftPressed = false;
+ mw->saveSettings();
+ MainWindow *nmw = new MainWindow;
+ nmw->move(mw->geometry().topLeft());
+ nmw->show();
+
+ if (mw->isMaximized())
+ nmw->showMaximized();
+
+ nmw->setup();
+ nmw->showLink(name.toString());
+ } else {
+ QTextBrowser::setSource(name);
+ QTextBrowser::scrollToAnchor(name.fragment());
+ }
+ return;
+ }
+ }
+
+ mw->statusBar()->showMessage(tr("Failed to open link: '%1'").arg(name.toString()), 5000);
+ setHtml(tr("<div align=\"center\"><h1>The page could not be found</h1><br>"
+ "<h3>'%1'</h3></div>").arg(name.toString()));
+ mw->browsers()->updateTitle(tr("Error..."));
+}
+
+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.clear();
+}
+
+void HelpWindow::openLinkInNewPage(const QString &link)
+{
+ lastAnchor = link;
+ openLinkInNewPage();
+}
+
+bool HelpWindow::hasAnchorAt(const QPoint& pos)
+{
+ lastAnchor = anchorAt(pos);
+ if (lastAnchor.isEmpty())
+ return false;
+ lastAnchor = source().resolved(lastAnchor).toString();
+ if (lastAnchor.at(0) == QLatin1Char('#')) {
+ QString src = source().toString();
+ int hsh = src.indexOf(QLatin1Char('#'));
+ lastAnchor = (hsh>=0 ? src.left(hsh) : src) + lastAnchor;
+ }
+ return true;
+}
+
+void HelpWindow::contextMenuEvent(QContextMenuEvent *e)
+{
+ QMenu menu(QLatin1String(""), 0);
+
+ QUrl link;
+ QAction *copyAnchorAction = 0;
+ if (hasAnchorAt(e->pos())) {
+ link = anchorAt(e->pos());
+ if (link.isRelative())
+ link = source().resolved(link);
+ copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
+ copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
+
+ menu.addAction(tr("Open Link in New Tab"),
+ this, SLOT(openLinkInNewPage()));
+ menu.addAction(tr("Open Link in New Window\tShift+LMB"),
+ this, SLOT(openLinkInNewWindow()));
+ }
+ mw->setupPopupMenu(&menu);
+ QAction *action = menu.exec(e->globalPos());
+ if (action == copyAnchorAction)
+ QApplication::clipboard()->setText(link.toString());
+}
+
+void HelpWindow::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() == Qt::XButton1) {
+ QTextBrowser::backward();
+ return;
+ }
+
+ if (e->button() == Qt::XButton2) {
+ QTextBrowser::forward();
+ return;
+ }
+
+ if (e->button() == Qt::MidButton && hasAnchorAt(e->pos())) {
+ openLinkInNewPage();
+ return;
+ }
+ QTextBrowser::mouseReleaseEvent(e);
+}
+
+void HelpWindow::blockScrolling(bool b)
+{
+ blockScroll = b;
+}
+
+void HelpWindow::ensureCursorVisible()
+{
+ if (!blockScroll)
+ QTextBrowser::ensureCursorVisible();
+}
+
+void HelpWindow::mousePressEvent(QMouseEvent *e)
+{
+ shiftPressed = e->modifiers() & Qt::ShiftModifier;
+ if (!(shiftPressed && hasAnchorAt(e->pos())))
+ QTextBrowser::mousePressEvent(e);
+}
+
+void HelpWindow::keyPressEvent(QKeyEvent *e)
+{
+ shiftPressed = e->modifiers() & Qt::ShiftModifier;
+ QTextBrowser::keyPressEvent(e);
+}
+
+bool HelpWindow::isKDERunning() const
+{
+ return !qgetenv("KDE_FULL_SESSION").isEmpty();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/helpwindow.h b/tools/assistant/compat/helpwindow.h
new file mode 100644
index 0000000..f1327b5
--- /dev/null
+++ b/tools/assistant/compat/helpwindow.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPWINDOW_H
+#define HELPWINDOW_H
+
+#include <QTextBrowser>
+
+QT_BEGIN_NAMESPACE
+
+class MainWindow;
+class QKeyEvent;
+class QMime;
+class QMouseEvent;
+class QMenu;
+
+class HelpWindow : public QTextBrowser
+{
+ Q_OBJECT
+public:
+ HelpWindow( MainWindow *m, QWidget *parent = 0);
+ void setSource( const QUrl &name );
+ void blockScrolling( bool b );
+ void openLinkInNewWindow( const QString &link );
+ void openLinkInNewPage( const QString &link );
+ void addMimePath( const QString &path );
+
+ void mousePressEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *);
+
+signals:
+ void chooseWebBrowser();
+ void choosePDFReader();
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+
+protected slots:
+ void ensureCursorVisible();
+
+private slots:
+ void openLinkInNewWindow();
+ void openLinkInNewPage();
+
+ bool isKDERunning() const;
+
+private:
+ bool hasAnchorAt(const QPoint& pos);
+
+ MainWindow *mw;
+ QString lastAnchor;
+ bool blockScroll;
+ bool shiftPressed;
+ bool newWindow;
+ bool fwdAvail;
+ bool backAvail;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPWINDOW_H
diff --git a/tools/assistant/compat/images/assistant-128.png b/tools/assistant/compat/images/assistant-128.png
new file mode 100644
index 0000000..f05949f
--- /dev/null
+++ b/tools/assistant/compat/images/assistant-128.png
Binary files differ
diff --git a/tools/assistant/compat/images/assistant.png b/tools/assistant/compat/images/assistant.png
new file mode 100644
index 0000000..ea4d1e7
--- /dev/null
+++ b/tools/assistant/compat/images/assistant.png
Binary files differ
diff --git a/tools/assistant/compat/images/close.png b/tools/assistant/compat/images/close.png
new file mode 100644
index 0000000..540694e
--- /dev/null
+++ b/tools/assistant/compat/images/close.png
Binary files differ
diff --git a/tools/assistant/compat/images/designer.png b/tools/assistant/compat/images/designer.png
new file mode 100644
index 0000000..72c42e7
--- /dev/null
+++ b/tools/assistant/compat/images/designer.png
Binary files differ
diff --git a/tools/assistant/compat/images/linguist.png b/tools/assistant/compat/images/linguist.png
new file mode 100644
index 0000000..d388cbd
--- /dev/null
+++ b/tools/assistant/compat/images/linguist.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/addtab.png b/tools/assistant/compat/images/mac/addtab.png
new file mode 100644
index 0000000..20928fb
--- /dev/null
+++ b/tools/assistant/compat/images/mac/addtab.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/book.png b/tools/assistant/compat/images/mac/book.png
new file mode 100644
index 0000000..7a3204c
--- /dev/null
+++ b/tools/assistant/compat/images/mac/book.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/closetab.png b/tools/assistant/compat/images/mac/closetab.png
new file mode 100644
index 0000000..ab9d669
--- /dev/null
+++ b/tools/assistant/compat/images/mac/closetab.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/editcopy.png b/tools/assistant/compat/images/mac/editcopy.png
new file mode 100644
index 0000000..f551364
--- /dev/null
+++ b/tools/assistant/compat/images/mac/editcopy.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/find.png b/tools/assistant/compat/images/mac/find.png
new file mode 100644
index 0000000..3561745
--- /dev/null
+++ b/tools/assistant/compat/images/mac/find.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/home.png b/tools/assistant/compat/images/mac/home.png
new file mode 100644
index 0000000..78d94da
--- /dev/null
+++ b/tools/assistant/compat/images/mac/home.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/next.png b/tools/assistant/compat/images/mac/next.png
new file mode 100644
index 0000000..a585cab
--- /dev/null
+++ b/tools/assistant/compat/images/mac/next.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/prev.png b/tools/assistant/compat/images/mac/prev.png
new file mode 100644
index 0000000..612fb34
--- /dev/null
+++ b/tools/assistant/compat/images/mac/prev.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/print.png b/tools/assistant/compat/images/mac/print.png
new file mode 100644
index 0000000..10ca56c
--- /dev/null
+++ b/tools/assistant/compat/images/mac/print.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/synctoc.png b/tools/assistant/compat/images/mac/synctoc.png
new file mode 100644
index 0000000..067fa94
--- /dev/null
+++ b/tools/assistant/compat/images/mac/synctoc.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/whatsthis.png b/tools/assistant/compat/images/mac/whatsthis.png
new file mode 100644
index 0000000..5b7078f
--- /dev/null
+++ b/tools/assistant/compat/images/mac/whatsthis.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/zoomin.png b/tools/assistant/compat/images/mac/zoomin.png
new file mode 100644
index 0000000..d46f5af
--- /dev/null
+++ b/tools/assistant/compat/images/mac/zoomin.png
Binary files differ
diff --git a/tools/assistant/compat/images/mac/zoomout.png b/tools/assistant/compat/images/mac/zoomout.png
new file mode 100644
index 0000000..4632656
--- /dev/null
+++ b/tools/assistant/compat/images/mac/zoomout.png
Binary files differ
diff --git a/tools/assistant/compat/images/qt.png b/tools/assistant/compat/images/qt.png
new file mode 100644
index 0000000..2dc6716
--- /dev/null
+++ b/tools/assistant/compat/images/qt.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/addtab.png b/tools/assistant/compat/images/win/addtab.png
new file mode 100644
index 0000000..4bb0feb
--- /dev/null
+++ b/tools/assistant/compat/images/win/addtab.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/book.png b/tools/assistant/compat/images/win/book.png
new file mode 100644
index 0000000..09ec4d3
--- /dev/null
+++ b/tools/assistant/compat/images/win/book.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/closetab.png b/tools/assistant/compat/images/win/closetab.png
new file mode 100644
index 0000000..ef9e020
--- /dev/null
+++ b/tools/assistant/compat/images/win/closetab.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/editcopy.png b/tools/assistant/compat/images/win/editcopy.png
new file mode 100644
index 0000000..1121b47
--- /dev/null
+++ b/tools/assistant/compat/images/win/editcopy.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/find.png b/tools/assistant/compat/images/win/find.png
new file mode 100644
index 0000000..6ea35e9
--- /dev/null
+++ b/tools/assistant/compat/images/win/find.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/home.png b/tools/assistant/compat/images/win/home.png
new file mode 100644
index 0000000..b1c6ae1
--- /dev/null
+++ b/tools/assistant/compat/images/win/home.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/next.png b/tools/assistant/compat/images/win/next.png
new file mode 100644
index 0000000..8df4127
--- /dev/null
+++ b/tools/assistant/compat/images/win/next.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/previous.png b/tools/assistant/compat/images/win/previous.png
new file mode 100644
index 0000000..0780bc2
--- /dev/null
+++ b/tools/assistant/compat/images/win/previous.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/print.png b/tools/assistant/compat/images/win/print.png
new file mode 100644
index 0000000..ba7c02d
--- /dev/null
+++ b/tools/assistant/compat/images/win/print.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/synctoc.png b/tools/assistant/compat/images/win/synctoc.png
new file mode 100644
index 0000000..da301bc
--- /dev/null
+++ b/tools/assistant/compat/images/win/synctoc.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/whatsthis.png b/tools/assistant/compat/images/win/whatsthis.png
new file mode 100644
index 0000000..623cad6
--- /dev/null
+++ b/tools/assistant/compat/images/win/whatsthis.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/zoomin.png b/tools/assistant/compat/images/win/zoomin.png
new file mode 100644
index 0000000..2e586fc
--- /dev/null
+++ b/tools/assistant/compat/images/win/zoomin.png
Binary files differ
diff --git a/tools/assistant/compat/images/win/zoomout.png b/tools/assistant/compat/images/win/zoomout.png
new file mode 100644
index 0000000..a736d39
--- /dev/null
+++ b/tools/assistant/compat/images/win/zoomout.png
Binary files differ
diff --git a/tools/assistant/compat/images/wrap.png b/tools/assistant/compat/images/wrap.png
new file mode 100644
index 0000000..90f18d9
--- /dev/null
+++ b/tools/assistant/compat/images/wrap.png
Binary files differ
diff --git a/tools/assistant/compat/index.cpp b/tools/assistant/compat/index.cpp
new file mode 100644
index 0000000..e98b00b
--- /dev/null
+++ b/tools/assistant/compat/index.cpp
@@ -0,0 +1,581 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "index.h"
+
+#include <QFile>
+#include <QDir>
+#include <QStringList>
+#include <QApplication>
+#include <QByteArray>
+#include <QTextStream>
+#include <QtAlgorithms>
+#include <QUrl>
+#include <QTextCodec>
+#include <ctype.h>
+#include <QTextDocument>
+
+QT_BEGIN_NAMESPACE
+
+struct Term {
+ Term() : frequency(-1) {}
+ Term( const QString &t, int f, QVector<Document> l ) : term( t ), frequency( f ), documents( l ) {}
+ QString term;
+ int frequency;
+ QVector<Document>documents;
+ bool operator<( const Term &i2 ) const { return frequency < i2.frequency; }
+};
+
+QDataStream &operator>>( QDataStream &s, Document &l )
+{
+ s >> l.docNumber;
+ s >> l.frequency;
+ return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const Document &l )
+{
+ s << (qint16)l.docNumber;
+ s << (qint16)l.frequency;
+ return s;
+}
+
+Index::Index( const QString &dp, const QString &hp )
+ : QObject( 0 ), docPath( dp )
+{
+ Q_UNUSED(hp);
+
+ alreadyHaveDocList = false;
+ lastWindowClosed = false;
+ connect( qApp, SIGNAL(lastWindowClosed()),
+ this, SLOT(setLastWinClosed()) );
+}
+
+Index::Index( const QStringList &dl, const QString &hp )
+ : QObject( 0 )
+{
+ Q_UNUSED(hp);
+ 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;
+ }
+ QUrl url(*it);
+ parseDocument( url.toLocalFile(), i );
+ if ( i%steps == 0 ) {
+ prog++;
+ emit indexingProgress( prog );
+ }
+ }
+ return 0;
+}
+
+void Index::setupDocumentList()
+{
+ QDir d( docPath );
+ QStringList filters;
+ filters.append(QLatin1String("*.html"));
+ QStringList lst = d.entryList(filters);
+ QStringList::ConstIterator it = lst.constBegin();
+ for ( ; it != lst.constEnd(); ++it )
+ docList.append( QLatin1String("file:") + docPath + QLatin1String("/") + *it );
+}
+
+void Index::insertInDict( const QString &str, int docNum )
+{
+ if ( str == QLatin1String("amp") || str == QLatin1String("nbsp"))
+ return;
+ Entry *e = 0;
+ if ( dict.count() )
+ e = dict[ str ];
+
+ if ( e ) {
+ if ( e->documents.last().docNumber != docNum )
+ e->documents.append( Document(docNum, 1 ) );
+ else
+ e->documents.last().frequency++;
+ } else {
+ dict.insert( str, new Entry( docNum ) );
+ }
+}
+
+QString Index::getCharsetForDocument(QFile *file)
+{
+ QTextStream s(file);
+ QString contents = s.readAll();
+
+ QString encoding;
+ int start = contents.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
+ if (start > 0) {
+ int end = contents.indexOf(QLatin1String(">"), start);
+ QString meta = contents.mid(start+5, end-start);
+ meta = meta.toLower();
+ QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
+ if (r.indexIn(meta) != -1) {
+ encoding = r.cap(1);
+ }
+ }
+
+ file->seek(0);
+ if (encoding.isEmpty())
+ return QLatin1String("utf-8");
+ return encoding;
+}
+
+void Index::parseDocument( const QString &filename, int docNum )
+{
+ QFile file( filename );
+ if ( !file.open(QFile::ReadOnly) ) {
+ qWarning( "can not open file %s", qPrintable(filename) );
+ return;
+ }
+
+ QTextStream s(&file);
+ QString en = getCharsetForDocument(&file);
+ s.setCodec(QTextCodec::codecForName(en.toLatin1().constData()));
+
+ QString text = s.readAll();
+ 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 ( j < text.length() ) {
+ if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
+ valid = false;
+ if ( i > 1 )
+ insertInDict( QString(str,i), docNum );
+ i = 0;
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
+ valid = true;
+ c = buf[++j];
+ continue;
+ }
+ if ( !valid ) {
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
+ str[i] = c.toLower();
+ ++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()
+{
+ QFile f( dictFile );
+ if ( !f.open(QFile::WriteOnly ) )
+ return;
+ QDataStream s( &f );
+ for(QHash<QString, Entry *>::Iterator it = dict.begin(); it != dict.end(); ++it) {
+ s << it.key();
+ s << it.value()->documents.count();
+ s << it.value()->documents;
+ }
+ f.close();
+ writeDocumentList();
+}
+
+void Index::writeDocumentList()
+{
+ QFile f( docListFile );
+ if ( !f.open(QFile::WriteOnly ) )
+ return;
+ QDataStream s( &f );
+ s << docList;
+}
+
+void Index::readDict()
+{
+ QFile f( dictFile );
+ if ( !f.open(QFile::ReadOnly ) )
+ return;
+
+ dict.clear();
+ QDataStream s( &f );
+ QString key;
+ int numOfDocs;
+ QVector<Document> docs;
+ while ( !s.atEnd() ) {
+ s >> key;
+ s >> numOfDocs;
+ docs.resize(numOfDocs);
+ s >> docs;
+ dict.insert( key, new Entry( docs ) );
+ }
+ f.close();
+ readDocumentList();
+}
+
+void Index::readDocumentList()
+{
+ QFile f( docListFile );
+ if ( !f.open(QFile::ReadOnly ) )
+ return;
+ QDataStream s( &f );
+ s >> docList;
+}
+
+QStringList Index::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords )
+{
+ QList<Term> termList;
+ for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it ) {
+ Entry *e = 0;
+ if ( (*it).contains(QLatin1Char('*')) ) {
+ QVector<Document> wcts = setupDummyTerm( getWildcardTerms( *it ) );
+ termList.append( Term(QLatin1String("dummy"), wcts.count(), wcts ) );
+ } else if ( dict[ *it ] ) {
+ e = dict[ *it ];
+ termList.append( Term( *it, e->documents.count(), e->documents ) );
+ } else {
+ return QStringList();
+ }
+ }
+ if ( !termList.count() )
+ return QStringList();
+ qSort(termList);
+
+ QVector<Document> minDocs = termList.takeFirst().documents;
+ for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) {
+ Term *t = &(*it);
+ QVector<Document> docs = t->documents;
+ for(QVector<Document>::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) {
+ bool found = false;
+ for (QVector<Document>::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) {
+ if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) {
+ (*minDoc_it).frequency += (*doc_it).frequency;
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ minDoc_it = minDocs.erase( minDoc_it );
+ else
+ ++minDoc_it;
+ }
+ }
+
+ QStringList results;
+ qSort( minDocs );
+ if ( termSeq.isEmpty() ) {
+ for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it)
+ results << docList.at((int)(*it).docNumber);
+ return results;
+ }
+
+ QString fileName;
+ for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) {
+ fileName = docList[ (int)(*it).docNumber ];
+ if ( searchForPattern( termSeq, seqWords, fileName ) )
+ results << fileName;
+ }
+ return results;
+}
+
+QString Index::getDocumentTitle( const QString &fullFileName )
+{
+ QUrl url(fullFileName);
+ QString fileName = url.toLocalFile();
+
+ if (documentTitleCache.contains(fileName))
+ return documentTitleCache.value(fileName);
+
+ QFile file( fileName );
+ if ( !file.open( QFile::ReadOnly ) ) {
+ qWarning( "cannot open file %s", qPrintable(fileName) );
+ return fileName;
+ }
+ QTextStream s( &file );
+ QString text = s.readAll();
+
+ int start = text.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
+ int end = text.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
+
+ QString title = tr("Untitled");
+ if (end - start > 0) {
+ title = text.mid(start, end - start);
+ if (Qt::mightBeRichText(title)) {
+ QTextDocument doc;
+ doc.setHtml(title);
+ title = doc.toPlainText();
+ }
+ }
+ documentTitleCache.insert(fileName, title);
+ return title;
+}
+
+QStringList Index::getWildcardTerms( const QString &term )
+{
+ QStringList lst;
+ QStringList terms = split( term );
+ QStringList::Iterator iter;
+
+ for(QHash<QString, Entry*>::Iterator it = dict.begin(); it != dict.end(); ++it) {
+ int index = 0;
+ bool found = false;
+ QString text( it.key() );
+ for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
+ if ( *iter == QLatin1String("*") ) {
+ found = true;
+ continue;
+ }
+ if ( iter == terms.begin() && (*iter)[0] != text[0] ) {
+ found = false;
+ break;
+ }
+ index = text.indexOf( *iter, index );
+ if ( *iter == terms.last() && index != (int)text.length()-1 ) {
+ index = text.lastIndexOf( *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.indexOf(QLatin1Char('*'), j );
+
+ if (str.startsWith(QLatin1String("*")))
+ lst << QLatin1String("*");
+
+ while ( i != -1 ) {
+ if ( i > j && i <= (int)str.length() ) {
+ lst << str.mid( j, i - j );
+ lst << QLatin1String("*");
+ }
+ j = i + 1;
+ i = str.indexOf(QLatin1Char('*'), j );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+
+ return lst;
+}
+
+QVector<Document> Index::setupDummyTerm( const QStringList &terms )
+{
+ QList<Term> termList;
+ for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) {
+ Entry *e = 0;
+ if ( dict[ *it ] ) {
+ e = dict[ *it ];
+ termList.append( Term( *it, e->documents.count(), e->documents ) );
+ }
+ }
+ QVector<Document> maxList(0);
+ if ( !termList.count() )
+ return maxList;
+ qSort(termList);
+
+ maxList = termList.takeLast().documents;
+ for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) {
+ Term *t = &(*it);
+ QVector<Document> docs = t->documents;
+ for (QVector<Document>::iterator docIt = docs.begin(); docIt != docs.end(); ++docIt ) {
+ if ( maxList.indexOf( *docIt ) == -1 )
+ maxList.append( *docIt );
+ }
+ }
+ 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 )
+{
+ QUrl url(fileName);
+ QString fName = url.toLocalFile();
+ QFile file( fName );
+ if ( !file.open( QFile::ReadOnly ) ) {
+ qWarning( "cannot open file %s", qPrintable(fName) );
+ 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.readAll();
+ bool valid = true;
+ const QChar *buf = text.unicode();
+ QChar str[64];
+ QChar c = buf[0];
+ int j = 0;
+ int i = 0;
+ while ( j < text.length() ) {
+ if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
+ valid = false;
+ if ( i > 1 )
+ buildMiniDict( QString(str,i) );
+ i = 0;
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
+ valid = true;
+ c = buf[++j];
+ continue;
+ }
+ if ( !valid ) {
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
+ str[i] = c.toLower();
+ ++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;
+ QList<uint> a, b;
+ QList<uint>::iterator aIt;
+ for ( ; patIt != patterns.end(); ++patIt ) {
+ wordLst = (*patIt).split(QLatin1Char(' '));
+ 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.contains( *aIt + 1 )) {
+ (*aIt)++;
+ ++aIt;
+ } else {
+ aIt = a.erase( aIt );
+ }
+ }
+ }
+ }
+ if ( a.count() )
+ return true;
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/index.h b/tools/assistant/compat/index.h
new file mode 100644
index 0000000..9fc30af
--- /dev/null
+++ b/tools/assistant/compat/index.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INDEX_H
+#define INDEX_H
+
+#include <QStringList>
+#include <QHash>
+#include <QDataStream>
+#include <QObject>
+#include <QList>
+#include <QFile>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+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;
+ }
+ qint16 docNumber;
+ qint16 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( QVector<Document> l ) : documents( l ) {}
+ QVector<Document> documents;
+ };
+ struct PosEntry {
+ PosEntry( int p ) { positions.append( p ); }
+ QList<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& );
+ QVector<Document> setupDummyTerm( const QStringList& );
+ bool searchForPattern( const QStringList&, const QStringList&, const QString& );
+ void buildMiniDict( const QString& );
+ QString getCharsetForDocument(QFile *);
+ QStringList docList;
+ QHash<QString, Entry*> dict;
+ QHash<QString, PosEntry*> miniDict;
+ uint wordNum;
+ QString docPath;
+ QString dictFile, docListFile;
+ bool alreadyHaveDocList;
+ bool lastWindowClosed;
+ QHash<QString, QString> documentTitleCache;
+};
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/lib/lib.pro b/tools/assistant/compat/lib/lib.pro
new file mode 100644
index 0000000..d4b5a47
--- /dev/null
+++ b/tools/assistant/compat/lib/lib.pro
@@ -0,0 +1,78 @@
+TEMPLATE = lib
+QT += network
+TARGET = QtAssistantClient
+isEmpty(QT_MAJOR_VERSION) {
+ VERSION=4.3.0
+} else {
+ VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
+}
+
+CONFIG += qt warn_on
+mac|win32:CONFIG += debug_and_release
+mac:unix:CONFIG += explicitlib
+CONFIG -= dll
+
+HEADERS = qassistantclient.h \
+ qassistantclient_global.h
+SOURCES = qassistantclient.cpp
+
+DESTDIR = ../../../../lib
+DLLDESTDIR = ../../../../bin
+
+unix {
+ QMAKE_CFLAGS += $$QMAKE_CFLAGS_SHLIB
+ QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SHLIB
+}
+
+DEFINES += QT_ASSISTANT_CLIENT_LIBRARY
+contains(CONFIG, static) {
+ DEFINES += QT_ASSISTANT_CLIENT_STATIC
+}
+
+#load up the headers info
+CONFIG += qt_install_headers
+HEADERS_PRI = $$QT_BUILD_TREE/include/QtAssistant/headers.pri
+include($$HEADERS_PRI)|clear(HEADERS_PRI)
+
+#mac frameworks
+mac:!static:contains(QT_CONFIG, qt_framework) {
+ TARGET = QtAssistant # Change the name to match the headers
+ QMAKE_FRAMEWORK_BUNDLE_NAME = $$TARGET
+ CONFIG += lib_bundle qt_no_framework_direct_includes qt_framework
+ CONFIG(debug, debug|release) {
+ !build_pass:CONFIG += build_all
+ } else { #release
+ !debug_and_release|build_pass {
+ CONFIG -= qt_install_headers #no need to install these as well
+ FRAMEWORK_HEADERS.version = Versions
+ FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
+ FRAMEWORK_HEADERS.path = Headers
+ }
+ QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+ }
+}
+
+TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #done towards the end
+
+target.path=$$[QT_INSTALL_LIBS]
+INSTALLS += target
+win32 {
+ dlltarget.path=$$[QT_INSTALL_BINS]
+ INSTALLS += dlltarget
+}
+
+qt_install_headers {
+ assistant_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
+ assistant_headers.path = $$[QT_INSTALL_HEADERS]/QtAssistant
+ INSTALLS += assistant_headers
+}
+
+unix {
+ CONFIG += create_pc
+ QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS]
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS]/QtAssistant
+ QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_INSTALL_HEADERS]
+ QMAKE_PKGCONFIG_DESTDIR = pkgconfig
+ QMAKE_PKGCONFIG_REQUIRES += QtNetwork
+}
+
diff --git a/tools/assistant/compat/lib/qassistantclient.cpp b/tools/assistant/compat/lib/qassistantclient.cpp
new file mode 100644
index 0000000..25fbd6c
--- /dev/null
+++ b/tools/assistant/compat/lib/qassistantclient.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qassistantclient.h"
+
+#include <qtcpsocket.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+#include <qmap.h>
+
+QT_BEGIN_NAMESPACE
+
+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
+ \obsolete
+ \brief The QAssistantClient class provides a means of using Qt
+ Assistant as an application's help tool.
+
+ \inmodule QtAssistant
+ \ingroup helpsystem
+
+ \bold{Note:} \e{This class is obsolete and only required when using
+ the old Qt Assistant, now called assistant_adp. If you want to use
+ the new Qt Assistant as a remote help viewer, simple create a
+ QProcess instance and specify \tt{assistant} as its executable.
+ The following code shows how to start Qt Assistant and request a
+ certain page to be shown:}
+
+ \snippet doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp 0
+
+ \e{For a complete example using the Qt Assistant remotely, see the \l
+ {help/remotecontrol}{Remote Control} example.}
+
+ In order to make Qt Assistant act as a customized help tool for
+ your application, you must provide your application with a
+ QAssistantClient object in addition to a \l
+ {assistant-manual.html} {Qt Assistant Document Profile} (\c .adp
+ file) and the associated documentation.
+
+ Note that the QAssistantClient class is not included in the Qt
+ library. To use it you must add the following line to your pro
+ file:
+
+ \snippet doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp 1
+
+ A QAssistantClient instance can open or close Qt Assistant
+ whenever it is required.
+
+ Once you have created a QAssistantClient instance, specifying the
+ path to the Qt Assistant executable, using Qt Assistant is
+ simple: You can either call the openAssistant() slot to show the
+ defined start page of the documentation, or you can call the
+ showPage() slot to show a particular help page. When you call
+ openAssistant() and showPage(), Qt Assistant will be launched if
+ it isn't already running. When Qt Assistant is running, the
+ isOpen() function returns true.
+
+ When calling showPage() the Qt Assistant instance will also be
+ brought to the foreground if its hidden. The showPage() slot can
+ be called multiple times, while calling openAssistant() several
+ times without closing the application in between, will have no
+ effect.
+
+ You can close Qt Assistant at any time using the closeAssistant()
+ slot. When you call openAssistant(), or you call showPage()
+ without a previous call to openAssistant(), the assistantOpened()
+ signal is emitted. Similarly when closeAssistant() is called,
+ assistantClosed() is emitted. In either case, if an error occurs,
+ error() is emitted.
+
+ 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.
+
+ Qt Assistant's documentation set can be altered using the command
+ line arguments that are passed to the application when it is
+ launched. When started without any options, Qt Assistant displays
+ a default set of documentation. When Qt is installed, the default
+ documentation set in Qt Assistant contains the Qt reference
+ documentation as well as the tools that come with Qt, such as \QD
+ and \c qmake.
+
+ Use the setArguments() function to specify the command line
+ arguments. You can add or remove documentation from Qt Assistant
+ by adding and removing the relevant content files: The command
+ line arguments are \c {-addContentFile file.dcf} and \c
+ {-removeContentFile file.dcf} respectively. You can make Qt
+ Assistant run customized documentation sets that are separate from
+ the Qt documentation, by specifying a profile: \c {-profile
+ myapplication.adp}. The profile format can also be used to alter
+ several of Qt Assistant's properties such as its title and
+ startpage.
+
+ The Documentation Content File (\c .dcf) and Qt Assistant
+ Documentation Profile (\c .adp) formats are documented in the \l
+ {assistant-manual.html}{Qt Assistant Manual}.
+
+ For a complete example using the QAssistantClient class, see the
+ \e{Simple Text Viewer} example. The example shows how you can make
+ Qt Assistant act as a customized help tool for your application
+ using the QAssistantClient class combined with a Qt Assistant
+ Document Profile.
+
+ \sa {Qt Assistant Manual}, {Simple Text Viewer Example}
+*/
+
+/*!
+ \fn void QAssistantClient::assistantOpened()
+
+ This signal is emitted when Qt Assistant is opened and the
+ client-server communication is set up.
+
+ \sa openAssistant(), showPage()
+*/
+
+/*!
+ \fn void QAssistantClient::assistantClosed()
+
+ This signal is emitted when the connection to Qt Assistant is
+ closed. This happens when the user exits Qt Assistant, if an
+ error in the server or client occurs, or if closeAssistant() is
+ called.
+
+ \sa closeAssistant()
+*/
+
+/*!
+ \fn void QAssistantClient::error( const QString &message )
+
+ 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 message provides an
+ explanation of the error.
+*/
+
+/*!
+ Constructs an assistant client with the specified \a parent. For
+ systems other than Mac OS, \a path specifies the path to the Qt
+ Assistant executable. For Mac OS, \a path specifies a directory
+ containing a valid assistant.app bundle. If \a path is the empty
+ string, the system path (\c{%PATH%} or \c $PATH) is used.
+*/
+QAssistantClient::QAssistantClient( const QString &path, QObject *parent )
+ : QObject( parent ), host ( QLatin1String("localhost") )
+{
+#if defined(Q_OS_MAC)
+ const QString assistant = QLatin1String("Assistant_adp");
+#else
+ const QString assistant = QLatin1String("assistant_adp");
+#endif
+
+ if ( path.isEmpty() )
+ assistantCommand = assistant;
+ else {
+ QFileInfo fi( path );
+ if ( fi.isDir() )
+ assistantCommand = path + QLatin1String("/") + assistant;
+ else
+ assistantCommand = path;
+ }
+
+#if defined(Q_OS_MAC)
+ assistantCommand += QLatin1String(".app/Contents/MacOS/Assistant_adp");
+#endif
+
+ socket = new QTcpSocket( this );
+ connect( socket, SIGNAL(connected()),
+ SLOT(socketConnected()) );
+ connect( socket, SIGNAL(disconnected()),
+ SLOT(socketConnectionClosed()) );
+ connect( socket, SIGNAL(error(QAbstractSocket::SocketError)),
+ SLOT(socketError()) );
+ opened = false;
+ proc = new QProcess( this );
+ port = 0;
+ pageBuffer = QLatin1String("");
+ connect( proc, SIGNAL(readyReadStandardError()),
+ this, SLOT(readStdError()) );
+ connect( proc, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(procError(QProcess::ProcessError)) );
+}
+
+/*!
+ Destroys the assistant client object.
+*/
+QAssistantClient::~QAssistantClient()
+{
+ if ( proc->state() == QProcess::Running )
+ proc->terminate();
+
+ if( dpointers ) {
+ QAssistantClientPrivate *d = (*dpointers)[ this ];
+ if ( d ) {
+ dpointers->remove(this);
+ delete d;
+ if( dpointers->isEmpty() ) {
+ delete dpointers;
+ dpointers = 0;
+ }
+ }
+ }
+}
+
+/*!
+ Opens Qt Assistant, i.e. sets up the client-server communication
+ between the application and Qt Assistant, and shows the start page
+ specified by the current \l {assistant-manual.html}
+ {Qt Assistant Document Profile}. If there is no specfied profile,
+ and Qt is installed, the default start page is the Qt Reference
+ Documentation's index page.
+
+ If the connection is already established, this function does
+ nothing. Use the showPage() function to show another page. If an
+ error occurs, the error() signal is emitted.
+
+ \sa showPage(), assistantOpened()
+*/
+void QAssistantClient::openAssistant()
+{
+ if ( proc->state() == QProcess::Running )
+ return;
+
+ QStringList args;
+ args.append(QLatin1String("-server"));
+ if( !pageBuffer.isEmpty() ) {
+ args.append( QLatin1String("-file") );
+ args.append( pageBuffer );
+ }
+
+ QAssistantClientPrivate *d = data( this );
+ if( d ) {
+ QStringList::ConstIterator it = d->arguments.constBegin();
+ while( it!=d->arguments.constEnd() ) {
+ args.append( *it );
+ ++it;
+ }
+ }
+
+ connect( proc, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(readPort()) );
+
+ proc->start(assistantCommand, args);
+}
+
+void QAssistantClient::procError(QProcess::ProcessError err)
+{
+ switch (err)
+ {
+ case QProcess::FailedToStart:
+ emit error( tr( "Failed to start Qt Assistant." ) );
+ break;
+ case QProcess::Crashed:
+ emit error( tr( "Qt Assistant crashed." ) );
+ break;
+ default:
+ emit error( tr( "Error while running Qt Assistant." ) );
+ }
+}
+
+void QAssistantClient::readPort()
+{
+ QString p(QString::fromLatin1(proc->readAllStandardOutput()));
+ quint16 port = p.toUShort();
+ if ( port == 0 ) {
+ emit error( tr( "Cannot connect to Qt Assistant." ) );
+ return;
+ }
+ socket->connectToHost( host, port );
+ disconnect( proc, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(readPort()) );
+}
+
+/*!
+ Closes the Qt Assistant instance.
+
+ \sa openAssistant(), assistantClosed()
+*/
+void QAssistantClient::closeAssistant()
+{
+ if ( !opened )
+ return;
+
+ bool blocked = proc->blockSignals(true);
+ proc->terminate();
+ if (!proc->waitForFinished(2000)) {
+ // If the process hasn't died after 2 seconds,
+ // we kill it, causing it to exit immediately.
+ proc->kill();
+ }
+ proc->blockSignals(blocked);
+}
+
+/*!
+ Brings Qt Assistant to the foreground showing the given \a page.
+ The \a page parameter is a path to an HTML file
+ (e.g., QLatin1String("/home/pasquale/superproduct/docs/html/intro.html")).
+
+ If Qt Assistant hasn't been opened yet, this function will call
+ the openAssistant() slot with the specified page as the start
+ page.
+
+ \note The first time Qt Assistant is started, its window will open
+ in front of the application's windows. Subsequent calls to this function
+ will only load the specified pages in Qt Assistant and will not display
+ its window in front of the application's windows.
+
+ \sa openAssistant()
+*/
+void QAssistantClient::showPage( const QString &page )
+{
+ if (opened) {
+ QTextStream os( socket );
+ os << page << QLatin1String("\n");
+ } else {
+ pageBuffer = page;
+
+ if (proc->state() == QProcess::NotRunning) {
+ openAssistant();
+ pageBuffer.clear();
+ return;
+ }
+ }
+}
+
+/*!
+ \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()
+{
+ QAbstractSocket::SocketError err = socket->error();
+ if (err == QTcpSocket::ConnectionRefusedError)
+ emit error( tr( "Could not connect to Assistant: Connection refused" ) );
+ else if (err == QTcpSocket::HostNotFoundError)
+ emit error( tr( "Could not connect to Assistant: Host not found" ) );
+ else if (err != QTcpSocket::RemoteHostClosedError)
+ emit error( tr( "Communication error" ) );
+}
+
+void QAssistantClient::readStdError()
+{
+ QString errmsg = QString::fromLatin1(proc->readAllStandardError());
+
+ if (!errmsg.isEmpty())
+ emit error( errmsg.simplified() );
+}
+
+/*!
+ \fn void QAssistantClient::setArguments(const QStringList &arguments)
+
+ Sets the command line \a arguments that are passed to Qt Assistant
+ when it is launched.
+
+ The command line arguments can be used to alter Qt Assistant's
+ documentation set. When started without any options, Qt Assistant
+ displays a default set of documentation. When Qt is installed, the
+ default documentation set in Qt Assistant contains the Qt
+ reference documentation as well as the tools that come with Qt,
+ such as Qt Designer and qmake.
+*/
+void QAssistantClient::setArguments( const QStringList &args )
+{
+ QAssistantClientPrivate *d = data( this, true );
+ d->arguments = args;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/lib/qassistantclient.h b/tools/assistant/compat/lib/qassistantclient.h
new file mode 100644
index 0000000..d76246f
--- /dev/null
+++ b/tools/assistant/compat/lib/qassistantclient.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QASSISTANTCLIENT_H
+#define QASSISTANTCLIENT_H
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QProcess>
+#include <QtCore/qglobal.h>
+#include <QtAssistant/qassistantclient_global.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QTcpSocket;
+
+class QT_ASSISTANT_CLIENT_EXPORT QAssistantClient : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( bool open READ isOpen )
+
+public:
+ QAssistantClient( const QString &path, QObject *parent = 0);
+ ~QAssistantClient();
+
+ bool isOpen() const;
+
+ void setArguments( const QStringList &args );
+
+public Q_SLOTS:
+ virtual void openAssistant();
+ virtual void closeAssistant();
+ virtual void showPage( const QString &page );
+
+Q_SIGNALS:
+ void assistantOpened();
+ void assistantClosed();
+ void error( const QString &msg );
+
+private Q_SLOTS:
+ void socketConnected();
+ void socketConnectionClosed();
+ void readPort();
+ void procError(QProcess::ProcessError err);
+ void socketError();
+ void readStdError();
+
+private:
+ QTcpSocket *socket;
+ QProcess *proc;
+ quint16 port;
+ QString host, assistantCommand, pageBuffer;
+ bool opened;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/compat/lib/qassistantclient_global.h b/tools/assistant/compat/lib/qassistantclient_global.h
new file mode 100644
index 0000000..3ae8bb2
--- /dev/null
+++ b/tools/assistant/compat/lib/qassistantclient_global.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QASSISTANTCLIENT_GLOBAL_H
+#define QASSISTANTCLIENT_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_ASSISTANT_CLIENT_STATIC) || (!defined(QT_SHARED) && !defined(QT_DLL))
+# define QT_ASSISTANT_CLIENT_EXPORT
+#elif defined(QT_ASSISTANT_CLIENT_LIBRARY)
+# define QT_ASSISTANT_CLIENT_EXPORT Q_DECL_EXPORT
+#else
+# define QT_ASSISTANT_CLIENT_EXPORT Q_DECL_IMPORT
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/compat/main.cpp b/tools/assistant/compat/main.cpp
new file mode 100644
index 0000000..6609572
--- /dev/null
+++ b/tools/assistant/compat/main.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "helpdialog.h"
+#include "config.h"
+
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QApplication>
+#include <QPixmap>
+#include <QStringList>
+#include <QDir>
+#include <QMessageBox>
+#include <QPointer>
+#include <QTranslator>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined(USE_STATIC_JPEG_PLUGIN)
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN(qjpeg)
+#endif
+
+#define INDEX_CHECK( text ) if( i+1 >= argc ) { fprintf(stderr, "%s\n", text); return 1; }
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtDBus/QDBusObjectPath>
+#include "tabbedbrowser.h"
+QT_END_INCLUDE_NAMESPACE
+
+class HelpWindowAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "com.trolltech.Assistant.HelpWindow")
+
+ Q_PROPERTY(QString source READ source WRITE setSource)
+
+public:
+ HelpWindowAdaptor(HelpWindow *w) : QDBusAbstractAdaptor(w), helpWindow(w)
+ {
+ setAutoRelaySignals(true);
+ }
+
+public Q_SLOTS:
+ inline QString source() const { return helpWindow->source().toString(); }
+ inline void setSource(const QString &src) { helpWindow->setSource(src); }
+
+ inline void clearHistory() { helpWindow->clearHistory(); }
+ inline void backward() { helpWindow->backward(); }
+ inline void forward() { helpWindow->forward(); }
+ inline void reload() { helpWindow->reload(); }
+ inline void home() { helpWindow->home(); }
+
+private:
+ HelpWindow *helpWindow;
+};
+
+class AssistantAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "com.trolltech.Assistant.HelpViewer")
+
+public:
+ AssistantAdaptor(MainWindow *mw) : QDBusAbstractAdaptor(mw), mw(mw)
+ {
+ QDBusConnection connection = QDBusConnection::sessionBus();
+ connection.registerService(QLatin1String("com.trolltech.Assistant"));
+ connection.registerObject(QLatin1String("/Assistant"), mw);
+ }
+
+public slots:
+ void showLink(const QString &link) { mw->showLink(link); }
+ QDBusObjectPath createNewTab();
+ QDBusObjectPath currentTab();
+
+private:
+ QDBusObjectPath pathForBrowser(HelpWindow *window);
+ MainWindow *mw;
+};
+
+QDBusObjectPath AssistantAdaptor::createNewTab()
+{
+ HelpWindow *window = mw->browsers()->newBackgroundTab();
+ return pathForBrowser(window);
+}
+
+QDBusObjectPath AssistantAdaptor::currentTab()
+{
+ HelpWindow *window = mw->browsers()->currentBrowser();
+ return pathForBrowser(window);
+}
+
+QDBusObjectPath AssistantAdaptor::pathForBrowser(HelpWindow *window)
+{
+ int index = mw->browsers()->browsers().indexOf(window);
+ if (index == -1)
+ return QDBusObjectPath();
+
+ QString name(QLatin1String("/Assistant/Tabs/"));
+ name += QString::number(index);
+ QDBusObjectPath path(name);
+
+ if (!window->findChild<HelpWindowAdaptor *>()) {
+ (void)new HelpWindowAdaptor(window);
+ QDBusConnection::sessionBus().registerObject(name, window);
+ }
+
+ return path;
+}
+
+#endif // QT_NO_DBUS
+
+class AssistantSocket : public QTcpSocket
+{
+ Q_OBJECT
+public:
+ AssistantSocket( int sock, QObject *parent = 0 );
+ ~AssistantSocket() {}
+
+signals:
+ void showLinkRequest( const QString& );
+
+private slots:
+ void readClient();
+ void connectionClosed();
+};
+
+
+class AssistantServer : public QTcpServer
+{
+ Q_OBJECT
+public:
+ AssistantServer( QObject* parent = 0 );
+ quint16 getPort() const;
+
+signals:
+ void showLinkRequest( const QString& );
+ void newConnect();
+
+public slots:
+ virtual void incomingConnection( int socket );
+
+private:
+ quint16 p;
+};
+
+AssistantSocket::AssistantSocket( int sock, QObject *parent )
+ : QTcpSocket( parent )
+{
+ connect( this, SIGNAL(readyRead()), SLOT(readClient()) );
+ connect( this, SIGNAL(disconnected()), SLOT(connectionClosed()) );
+ setSocketDescriptor( sock );
+}
+
+void AssistantSocket::readClient()
+{
+ QString link = QString();
+ while ( canReadLine() )
+ link = QLatin1String(readLine());
+ if ( !link.isNull() ) {
+ link = link.replace(QLatin1String("\n"), QLatin1String(""));
+ link = link.replace(QLatin1String("\r"), QLatin1String(""));
+ QFileInfo fi(link);
+ link = fi.absoluteFilePath();
+ emit showLinkRequest( link );
+ }
+}
+
+void AssistantSocket::connectionClosed()
+{
+ deleteLater();
+}
+
+AssistantServer::AssistantServer( QObject *parent )
+ : QTcpServer( parent )
+{
+ listen(QHostAddress::LocalHost, 0);
+ if ( !isListening() ) {
+ QMessageBox::critical( 0, tr( "Qt Assistant" ),
+ tr( "Failed to bind to port %1" ).arg( serverPort() ) );
+ exit( 1 );
+ }
+ p = serverPort();
+}
+
+quint16 AssistantServer::getPort() const
+{
+ return p;
+}
+
+void AssistantServer::incomingConnection( int socket )
+{
+ AssistantSocket *as = new AssistantSocket( socket, this );
+ connect( as, SIGNAL(showLinkRequest(QString)),
+ this, SIGNAL(showLinkRequest(QString)) );
+ emit newConnect();
+}
+
+int runAssistant( int argc, char ** argv )
+{
+ bool withGUI = true;
+#ifndef Q_WS_WIN
+ if ( argc > 1 ) {
+ QString arg = QString::fromLocal8Bit(argv[1]);
+ arg = arg.toLower();
+ if ( arg == QLatin1String("-addcontentfile")
+ || arg == QLatin1String("-removecontentfile")
+ || arg == QLatin1String("-help")
+ || arg == QLatin1String("/?")
+ )
+ withGUI = false;
+ }
+#endif
+ QApplication a(argc, argv, withGUI);
+ a.setOrganizationName(QLatin1String("Trolltech"));
+ a.setApplicationName(QLatin1String("Assistant"));
+
+ QString resourceDir;
+ AssistantServer *as = 0;
+ QStringList catlist;
+ QString file, profileName, aDocPath;
+ bool server = false;
+ bool hideSidebar = false;
+ bool configLoaded = false;
+ if ( argc == 2 ) {
+ file = QString::fromLocal8Bit(argv[1]);
+ if (file.startsWith(QLatin1String("-")) || file == QLatin1String("/?")) {
+ file.clear();
+ } else {
+ QFileInfo fi(file);
+ file = fi.absoluteFilePath();
+ file = MainWindow::urlifyFileName(file);
+ }
+ }
+ if ( file.isEmpty() ) {
+ for ( int i = 1; i < argc; i++ ) {
+ QString opt = QString::fromLocal8Bit(argv[i]).toLower();
+ if ( opt == QLatin1String("-file") ) {
+ INDEX_CHECK( "Missing file argument!" );
+ i++;
+ file = QFile::decodeName(argv[i]);
+ } else if ( opt == QLatin1String("-server") ) {
+ server = true;
+ } else if ( opt == QLatin1String("-profile") ) {
+ INDEX_CHECK( "Missing profile argument!" );
+ profileName = QFile::decodeName(argv[++i]);
+ } else if ( opt == QLatin1String("-addcontentfile") ) {
+ INDEX_CHECK( "Missing content file!" );
+ Config *c = Config::loadConfig(QString());
+ QFileInfo file( QFile::decodeName(argv[i+1]) );
+ if( !file.exists() ) {
+ fprintf(stderr, "Could not locate content file: %s\n", qPrintable(file.absoluteFilePath()));
+ return 1;
+ }
+ DocuParser *parser = DocuParser::createParser( file.absoluteFilePath() );
+ if( parser ) {
+ QFile f( QFile::decodeName(argv[i+1]) );
+ if( !parser->parse( &f ) ) {
+ fprintf(stderr, "Failed to parse file: %s\n", qPrintable(file.absoluteFilePath()));
+ return 1;
+ }
+ parser->addTo( c->profile() );
+ c->setDocRebuild( true );
+ c->save();
+ }
+ return 0;
+ } else if ( opt == QLatin1String("-removecontentfile") ) {
+ INDEX_CHECK("Missing content file!");
+ Config *c = Config::loadConfig(QString());
+ Profile *profile = c->profile();
+ QString contentFile = QString::fromLocal8Bit(argv[i+i]);
+ QStringList entries;
+#ifdef Q_WS_WIN
+ contentFile.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ entries = profile->docs.filter(contentFile, Qt::CaseInsensitive);
+#else
+ entries = profile->docs.filter(contentFile);
+#endif
+ if (entries.count() == 0) {
+ fprintf(stderr, "Could not locate content file: %s\n", qPrintable(contentFile));
+ return 1;
+ } else if (entries.count() > 1) {
+ fprintf(stderr, "More than one entry matching file name found, "
+ "please specify full path to file");
+ return 1;
+ } else {
+ QFileInfo file(entries[0]);
+ if( !file.exists() ) {
+ fprintf(stderr, "Could not locate content file: %s\n", qPrintable(file.absoluteFilePath()));
+ return 1;
+ }
+ profile->removeDocFileEntry( file.absoluteFilePath() );
+ c->setDocRebuild( true );
+ c->save();
+ }
+ return 0;
+ } else if ( QString( QLatin1String(argv[i]) ).toLower() == QLatin1String("-docpath") ) {
+ INDEX_CHECK( "Missing path!" );
+ QDir dir(QString::fromLocal8Bit(argv[i+1]));
+ if ( dir.exists() ) {
+ Config *c = Config::loadConfig(QString());
+ c->saveProfile(Profile::createDefaultProfile(dir.absolutePath()));
+ c->loadDefaultProfile();
+ c->setDocRebuild(true);
+ c->save();
+ configLoaded = true;
+ ++i;
+ } else {
+ fprintf(stderr, "The specified path does not exist!\n");
+ return 1;
+ }
+ } else if ( opt == QLatin1String("-hidesidebar") ) {
+ hideSidebar = true;
+ } else if ( opt == QLatin1String("-help") || opt == QLatin1String("/?") ) {
+ QString helpText = QLatin1String( "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.");
+#ifdef Q_WS_WIN
+ QMessageBox::information( 0, QLatin1String("Qt Assistant"),
+ QLatin1String("<pre>") + helpText + QLatin1String("</pre>") );
+#else
+ fprintf(stdout, "%s\n", qPrintable(helpText));
+#endif
+ exit( 0 );
+ } else if ( opt == QLatin1String("-resourcedir") ) {
+ INDEX_CHECK( "Missing resource directory argument!" );
+ resourceDir = QFile::decodeName( argv[++i] );
+ } else {
+ fprintf(stderr, "Unrecognized option %s. Try -help to get help.\n", qPrintable(opt));
+ return 1;
+ }
+ }
+ }
+
+ if( resourceDir.isNull() )
+ resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+
+ QTranslator translator( 0 );
+ translator.load( QLatin1String("assistant_adp_") + QLocale::system().name(), resourceDir );
+ a.installTranslator( &translator );
+
+ QTranslator qtTranslator( 0 );
+ qtTranslator.load( QLatin1String("qt_") + QLocale::system().name(), 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.toLatin1().constData() );
+ fflush( stderr );
+ return -1;
+ }
+
+ QStringList links = conf->source();
+ conf->hideSideBar( hideSidebar );
+
+ QPointer<MainWindow> mw = new MainWindow();
+ mw->setObjectName(QLatin1String("Assistant"));
+
+ if ( server ) {
+ as = new AssistantServer();
+ printf("%d\n", as->serverPort() );
+ fflush( stdout );
+ as->connect( as, SIGNAL(showLinkRequest(QString)),
+ mw, SLOT(showLinkFromClient(QString)) );
+ }
+
+#if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)
+ new AssistantAdaptor(mw);
+#endif // QT_NO_DBUS
+
+ FontSettings settings = conf->fontSettings();
+ if (mw->font() != settings.windowFont)
+ a.setFont(settings.windowFont, "QWidget");
+
+#ifdef Q_WS_MAC
+ // Make sure AssitantClient shows the window in front.
+ mw->raise();
+#endif
+ mw->show();
+
+ if (!file.isEmpty())
+ mw->showLink( MainWindow::urlifyFileName(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;
+}
+
+QT_END_NAMESPACE
+
+int main( int argc, char ** argv )
+{
+ Q_INIT_RESOURCE(assistant);
+ return QT_PREPEND_NAMESPACE(runAssistant)(argc, argv);
+}
+
+#include "main.moc"
diff --git a/tools/assistant/compat/mainwindow.cpp b/tools/assistant/compat/mainwindow.cpp
new file mode 100644
index 0000000..65759ad
--- /dev/null
+++ b/tools/assistant/compat/mainwindow.cpp
@@ -0,0 +1,901 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpdialog.h"
+#include "config.h"
+#include "fontsettingsdialog.h"
+
+#include <QDockWidget>
+#include <QDir>
+#include <QTimer>
+#include <QStatusBar>
+#include <QShortcut>
+#include <QMessageBox>
+#include <QPainter>
+#include <QEventLoop>
+#include <QtEvents>
+#include <QFontDatabase>
+#include <QWhatsThis>
+#include <QTextDocumentFragment>
+#include <QLibraryInfo>
+#include <QPrinter>
+#include <QPrintDialog>
+#include <QAbstractTextDocumentLayout>
+#include <QTextDocument>
+#include <QTextObject>
+#include <QFileDialog>
+#include <QThread>
+
+QT_BEGIN_NAMESPACE
+
+QList<MainWindow*> MainWindow::windows;
+
+#if defined(Q_WS_WIN)
+extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
+#endif
+
+MainWindow::MainWindow()
+{
+ setUnifiedTitleAndToolBarOnMac(true);
+ ui.setupUi(this);
+
+#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 = QList<QAction*>();
+ goActionDocFiles = new QMap<QAction*,QString>;
+
+ windows.append(this);
+ tabs = new TabbedBrowser(this);
+ connect(tabs, SIGNAL(tabCountChanged(int)), this, SLOT(updateTabActions(int)));
+ setCentralWidget(tabs);
+
+ Config *config = Config::configuration();
+
+ updateProfileSettings();
+
+ dw = new QDockWidget(this);
+ dw->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ dw->setWindowTitle(tr("Sidebar"));
+ dw->setObjectName(QLatin1String("sidebar"));
+ helpDock = new HelpDialog(dw, this);
+ dw->setWidget(helpDock);
+
+ addDockWidget(Qt::LeftDockWidgetArea, dw);
+
+ // read geometry configuration
+ setupGoActions();
+
+ restoreGeometry(config->windowGeometry());
+ restoreState(config->mainWindowState());
+ if (config->sideBarHidden())
+ dw->hide();
+
+ tabs->setup();
+ QTimer::singleShot(0, this, SLOT(setup()));
+#if defined(Q_WS_MAC)
+ QMenu *windowMenu = new QMenu(tr("&Window"), this);
+ menuBar()->insertMenu(ui.helpMenu->menuAction(), windowMenu);
+ windowMenu->addAction(tr("Minimize"), this,
+ SLOT(showMinimized()), QKeySequence(tr("Ctrl+M")));
+ // 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.
+ ui.actionGoPrevious->setShortcut(QKeySequence(Qt::CTRL|Qt::Key_Left));
+ ui.actionGoNext->setShortcut(QKeySequence(Qt::CTRL|Qt::Key_Right));
+
+ static const QLatin1String MacIconPath(":/trolltech/assistant/images/mac");
+ ui.actionGoNext->setIcon(QIcon(MacIconPath + QLatin1String("/next.png")));
+ ui.actionGoPrevious->setIcon(QIcon(MacIconPath + QLatin1String("/prev.png")));
+ ui.actionGoHome->setIcon(QIcon(MacIconPath + QLatin1String("/home.png")));
+ ui.actionEditCopy->setIcon(QIcon(MacIconPath + QLatin1String("/editcopy.png")));
+ ui.actionEditCopy->setIcon(QIcon(MacIconPath + QLatin1String("/editcopy.png")));
+ ui.actionEditFind->setIcon(QIcon(MacIconPath + QLatin1String("/find.png")));
+ ui.actionFilePrint->setIcon(QIcon(MacIconPath + QLatin1String("/print.png")));
+ ui.actionZoomOut->setIcon(QIcon(MacIconPath + QLatin1String("/zoomout.png")));
+ ui.actionZoomIn->setIcon(QIcon(MacIconPath + QLatin1String("/zoomin.png")));
+ ui.actionSyncToc->setIcon(QIcon(MacIconPath + QLatin1String("/synctoc.png")));
+ ui.actionHelpWhatsThis->setIcon(QIcon(MacIconPath + QLatin1String("/whatsthis.png")));
+#endif
+}
+
+MainWindow::~MainWindow()
+{
+ windows.removeAll(this);
+ delete goActionDocFiles;
+}
+
+void MainWindow::setup()
+{
+ if(setupCompleted)
+ return;
+
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+ statusBar()->showMessage(tr("Initializing Qt Assistant..."));
+ setupCompleted = true;
+ helpDock->initialize();
+ connect(ui.actionGoPrevious, SIGNAL(triggered()), tabs, SLOT(backward()));
+ connect(ui.actionGoNext, SIGNAL(triggered()), tabs, SLOT(forward()));
+ connect(ui.actionEditCopy, SIGNAL(triggered()), tabs, SLOT(copy()));
+ connect(ui.actionFileExit, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
+ connect(ui.actionAddBookmark, SIGNAL(triggered()),
+ helpDock, SLOT(addBookmark()));
+ connect(helpDock, SIGNAL(showLink(QString)),
+ this, SLOT(showLink(QString)));
+ connect(helpDock, SIGNAL(showSearchLink(QString,QStringList)),
+ this, SLOT(showSearchLink(QString,QStringList)));
+
+ connect(ui.bookmarkMenu, SIGNAL(triggered(QAction*)),
+ this, SLOT(showBookmark(QAction*)));
+ connect(ui.actionZoomIn, SIGNAL(triggered()), tabs, SLOT(zoomIn()));
+ connect(ui.actionZoomOut, SIGNAL(triggered()), tabs, SLOT(zoomOut()));
+
+ connect(ui.actionOpenPage, SIGNAL(triggered()), tabs, SLOT(newTab()));
+ connect(ui.actionClosePage, SIGNAL(triggered()), tabs, SLOT(closeTab()));
+ connect(ui.actionNextPage, SIGNAL(triggered()), tabs, SLOT(nextTab()));
+ connect(ui.actionPrevPage, SIGNAL(triggered()), tabs, SLOT(previousTab()));
+
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
+ QShortcut *acc = new QShortcut(tr("SHIFT+CTRL+="), this);
+ connect(acc, SIGNAL(activated()), ui.actionZoomIn, SIGNAL(triggered()));
+#endif
+
+ connect(new QShortcut(tr("Ctrl+T"), this), SIGNAL(activated()), helpDock, SLOT(toggleContents()));
+ connect(new QShortcut(tr("Ctrl+I"), this), SIGNAL(activated()), helpDock, SLOT(toggleIndex()));
+ connect(new QShortcut(tr("Ctrl+B"), this), SIGNAL(activated()), helpDock, SLOT(toggleBookmarks()));
+ connect(new QShortcut(tr("Ctrl+S"), this), SIGNAL(activated()), helpDock, SLOT(toggleSearch()));
+ connect(new QShortcut(tr("Ctrl+]"), this), SIGNAL(activated()), tabs, SLOT(nextTab()));
+ connect(new QShortcut(tr("Ctrl+["), this), SIGNAL(activated()), tabs, SLOT(previousTab()));
+
+ Config *config = Config::configuration();
+
+ setupBookmarkMenu();
+
+ QAction *viewsAction = createPopupMenu()->menuAction();
+ viewsAction->setText(tr("Views"));
+ ui.viewMenu->addAction(viewsAction);
+
+ const int tabIndex = config->sideBarPage();
+ helpDock->tabWidget()->setCurrentIndex(tabIndex);
+ // The tab index is 0 by default, so we need to force an upate
+ // to poulate the contents in this case.
+ if (tabIndex == 0)
+ helpDock->currentTabChanged(tabIndex);
+
+ ui.actionEditFind->setShortcut(QKeySequence::Find);
+ ui.actionEditFindNext->setShortcut(QKeySequence::FindNext);
+ ui.actionEditFindPrev->setShortcut(QKeySequence::FindPrevious);
+
+ QObject::connect(ui.actionEditFind, SIGNAL(triggered()), tabs, SLOT(find()));
+ QObject::connect(ui.actionEditFindNext, SIGNAL(triggered()), tabs, SLOT(findNext()));
+ QObject::connect(ui.actionEditFindPrev, SIGNAL(triggered()), tabs, SLOT(findPrevious()));
+ connect(ui.actionEditFont_Settings, SIGNAL(triggered()), this, SLOT(showFontSettingsDialog()));
+
+ qApp->restoreOverrideCursor();
+ ui.actionGoPrevious->setEnabled(false);
+ ui.actionGoNext->setEnabled(false);
+ ui.actionEditCopy->setEnabled(false);
+
+ // set the current selected item in the treeview
+ helpDialog()->locateContents(tabs->currentBrowser()->source().toString());
+ connect(tabs, SIGNAL(browserUrlChanged(QString)), helpDock, SLOT(locateContents(QString)));
+}
+
+void MainWindow::browserTabChanged()
+{
+ HelpWindow *win = tabs->currentBrowser();
+ if (win) {
+ QTextCursor cursor(win->textCursor());
+ ui.actionEditCopy->setEnabled(cursor.hasSelection());
+ ui.actionGoPrevious->setEnabled(win->isBackwardAvailable());
+ ui.actionGoNext->setEnabled(win->isForwardAvailable());
+ }
+}
+
+void MainWindow::copyAvailable(bool yes)
+{
+ ui.actionEditCopy->setEnabled(yes);
+}
+
+void MainWindow::updateTabActions(int index)
+{
+ bool enabled = (index > 1) ? true : false;
+ ui.actionPrevPage->setEnabled(enabled);
+ ui.actionNextPage->setEnabled(enabled);
+ ui.actionClosePage->setEnabled(enabled);
+}
+
+void MainWindow::setupGoActions()
+{
+ Config *config = Config::configuration();
+ QStringList titles = config->docTitles();
+ QAction *action = 0;
+
+ static bool separatorInserted = false;
+
+ foreach (QAction *a, goActions) {
+ ui.goMenu->removeAction(a);
+ ui.goActionToolbar->removeAction(a);
+ }
+ qDeleteAll(goActions);
+ goActions.clear();
+ goActionDocFiles->clear();
+
+ int addCount = 0;
+
+ foreach (QString title, titles) {
+ QPixmap pix = config->docIcon(title);
+ if(!pix.isNull()) {
+ if(!separatorInserted) {
+ ui.goMenu->addSeparator();
+ separatorInserted = true;
+ }
+ action = new QAction(this);
+ action->setText(title);
+ action->setWhatsThis(tr("Displays the main page of a specific documentation set."));
+ action->setIcon(QIcon(pix));
+ ui.goMenu->addAction(action);
+ ui.goActionToolbar->addAction(action);
+ goActions.append(action);
+ goActionDocFiles->insert(action, config->indexPage(title));
+ connect(action, SIGNAL(triggered()),
+ this, SLOT(showGoActionLink()));
+ ++addCount;
+ }
+ }
+ if(!addCount)
+ ui.goActionToolbar->hide();
+ else
+ ui.goActionToolbar->show();
+
+}
+
+bool MainWindow::insertActionSeparator()
+{
+ ui.goMenu->addSeparator();
+ ui.Toolbar->addSeparator();
+ return true;
+}
+
+void MainWindow::closeEvent(QCloseEvent *e)
+{
+ saveSettings();
+ e->accept();
+}
+
+void MainWindow::about()
+{
+ QMessageBox box(this);
+#if QT_EDITION == QT_EDITION_OPENSOURCE
+ QString edition = tr("Open Source Edition");
+ QString info = tr("This version of Qt Assistant is part of the Qt Open Source Edition, for use "
+ "in the development of Open Source applications. "
+ "Qt is a comprehensive C++ framework for cross-platform application "
+ "development.");
+ QString moreInfo = tr("You need a commercial Qt license for development of proprietary (closed "
+ "source) applications. Please see <a href=\"http://qtsoftware.com/company/model"
+ "\">qtsoftware.com/company/model</a> for an overview of Qt licensing.");
+#elif defined(QT_PRODUCT_LICENSE)
+ QString edition;
+ QString info;
+ QString moreInfo(tr("This program is licensed to you under the terms of the "
+ "Qt %1 License Agreement. For details, see the license file "
+ "that came with this software distribution.").arg(QLatin1String(QT_PRODUCT_LICENSE)));
+#else
+ QString edition;
+ QString info;
+ QString moreInfo(tr("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."));
+
+#endif
+
+ box.setText(QString::fromLatin1("<center><img src=\":/trolltech/assistant/images/assistant-128.png\">"
+ "<h3>%1</h3>"
+ "<p>Version %2 %3</p></center>"
+ "<p>%4</p>"
+ "<p>%5</p>"
+ "<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</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/>")
+ .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)).arg(edition).arg(info).arg(moreInfo));
+ box.setWindowTitle(tr("Qt Assistant"));
+ box.setIcon(QMessageBox::NoIcon);
+ box.exec();
+}
+
+void MainWindow::on_actionAboutApplication_triggered()
+{
+ QString url = Config::configuration()->aboutURL();
+ if (url == QLatin1String("about_qt")) {
+ QMessageBox::aboutQt(this, QLatin1String("Qt Assistant"));
+ return;
+ }
+ QString text;
+ if (url.startsWith(QLatin1String("file:")))
+ url = url.mid(5);
+ QFile file(url);
+ if(file.exists() && file.open(QFile::ReadOnly))
+ text = QString::fromUtf8(file.readAll());
+ if(text.isNull())
+ text = tr("Failed to open about application contents in file: '%1'").arg(url);
+
+ QFileInfo fi(file);
+ QString path = QDir::cleanPath(fi.absolutePath());
+ if (!QDir::searchPaths(QLatin1String("aboutImages")).contains(path))
+ QDir::addSearchPath(QLatin1String("aboutImages"), path);
+
+ QMessageBox box(this);
+ box.setText(text);
+ box.setWindowTitle(Config::configuration()->aboutApplicationMenuText());
+ box.setIcon(QMessageBox::NoIcon);
+ box.exec();
+}
+
+void MainWindow::on_actionAboutAssistant_triggered()
+{
+ about();
+}
+
+void MainWindow::on_actionGoHome_triggered()
+{
+ QString home = MainWindow::urlifyFileName(Config::configuration()->homePage());
+ showLink(home);
+}
+
+QString MainWindow::urlifyFileName(const QString &fileName)
+{
+ QString name = fileName;
+ QUrl url(name);
+
+#if defined(Q_OS_WIN32)
+ if (!url.isValid() || url.scheme().isEmpty() || url.scheme().toLower() != QLatin1String("file:")) {
+ int i = name.indexOf(QLatin1Char('#'));
+ QString anchor = name.mid(i);
+ name = name.toLower();
+ if (i > -1)
+ name.replace(i, anchor.length(), anchor);
+ name.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ foreach (QFileInfo drive, QDir::drives()) {
+ if (name.startsWith(drive.absolutePath().toLower())) {
+ name = QLatin1String("file:") + name;
+ break;
+ }
+ }
+ }
+#else
+ if (!url.isValid() || url.scheme().isEmpty())
+ name.prepend(QLatin1String("file:"));
+#endif
+ return name;
+}
+
+class PrintThread : public QThread
+{
+ QPrinter _printer;
+ QTextDocument *_document;
+
+public:
+ PrintThread(QObject *parent)
+ : QThread(parent), _printer(QPrinter::HighResolution), _document(0)
+ {
+ }
+ ~PrintThread()
+ {
+ wait();
+ }
+
+ QPrinter *printer()
+ {
+ return &_printer;
+ }
+
+ void start(QTextDocument *document)
+ {
+ _document = document->clone();
+ _document->moveToThread(this);
+ QThread::start();
+ }
+
+protected:
+ void run()
+ {
+ _document->print(printer());
+ delete _document;
+ _document = 0;
+ }
+};
+
+void MainWindow::on_actionFilePrint_triggered()
+{
+#ifndef QT_NO_PRINTER
+ if (!QFontDatabase::supportsThreadedFontRendering()) {
+ QPrinter printer(QPrinter::HighResolution);
+
+ QPrintDialog dlg(&printer, this);
+ if (dlg.exec() == QDialog::Accepted) {
+ qApp->setOverrideCursor(Qt::WaitCursor);
+ tabs->currentBrowser()->document()->print(&printer);
+ qApp->restoreOverrideCursor();
+ }
+ return;
+ }
+
+ PrintThread *thread = new PrintThread(this);
+
+ QPrintDialog dlg(thread->printer(), this);
+ if (dlg.exec() == QDialog::Accepted) {
+ connect(thread, SIGNAL(finished()), SLOT(printingFinished()));
+ connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+
+ qApp->setOverrideCursor(Qt::BusyCursor);
+ thread->start(tabs->currentBrowser()->document());
+ } else {
+ delete thread;
+ }
+#else
+ Q_ASSERT("No printing support");
+#endif
+}
+
+void MainWindow::printingFinished()
+{
+ qApp->restoreOverrideCursor();
+}
+
+void MainWindow::updateBookmarkMenu()
+{
+ for(QList<MainWindow*>::Iterator it = windows.begin(); it != windows.end(); ++it)
+ (*it)->setupBookmarkMenu();
+}
+
+void MainWindow::setupBookmarkMenu()
+{
+ ui.bookmarkMenu->clear();
+ bookmarks.clear();
+ ui.bookmarkMenu->addAction(ui.actionAddBookmark);
+
+ QFile f(QDir::homePath() + QLatin1String("/.assistant/bookmarks.") +
+ Config::configuration()->profileName());
+ if (!f.open(QFile::ReadOnly))
+ return;
+ QTextStream ts(&f);
+ ui.bookmarkMenu->addSeparator();
+ while (!ts.atEnd()) {
+ QString title = ts.readLine();
+ QString link = ts.readLine();
+ bookmarks.insert(ui.bookmarkMenu->addAction(title), link);
+ }
+}
+
+void MainWindow::showBookmark(QAction *action)
+{
+ if (bookmarks.contains(action))
+ showLink(bookmarks.value(action));
+}
+
+void MainWindow::showLinkFromClient(const QString &link)
+{
+ setWindowState(windowState() & ~Qt::WindowMinimized);
+ raise();
+ activateWindow();
+ QString l = MainWindow::urlifyFileName(link);
+ showLink(l);
+ if (isMinimized())
+ showNormal();
+}
+
+void MainWindow::showLink(const QString &link)
+{
+ if(link.isEmpty())
+ qWarning("The link is empty!");
+
+ // don't fill the history with the same url more then once
+ if (link == tabs->currentBrowser()->source().toString())
+ return;
+
+ QUrl url(link);
+ QFileInfo fi(url.toLocalFile());
+ tabs->setSource(url.toString());
+ tabs->currentBrowser()->setFocus();
+}
+
+void MainWindow::showLinks(const QStringList &links)
+{
+ if (links.size() == 0) {
+ qWarning("MainWindow::showLinks() - Empty link");
+ return;
+ }
+
+ if (links.size() == 1) {
+ showLink(MainWindow::urlifyFileName(links.first()));
+ return;
+ }
+
+ QStringList::ConstIterator it = links.begin();
+ // Initial showing, The tab is empty so update that without creating it first
+ if (!tabs->currentBrowser()->source().isValid()) {
+ QPair<HelpWindow*, QString> browser;
+ browser.first = tabs->currentBrowser();
+ browser.second = links.first();
+ pendingBrowsers.append(browser);
+ tabs->setTitle(tabs->currentBrowser(), tr("..."));
+ }
+ ++it;
+
+ while(it != links.end()) {
+ QPair<HelpWindow*, QString> browser;
+ browser.first = tabs->newBackgroundTab();
+ browser.second = *it;
+ pendingBrowsers.append(browser);
+ ++it;
+ }
+
+ startTimer(50);
+ return;
+}
+
+void MainWindow::removePendingBrowser(HelpWindow *win)
+{
+ if (!pendingBrowsers.count())
+ return;
+
+ QMutableListIterator<QPair<HelpWindow*, QString> > it(pendingBrowsers);
+ while (it.hasNext()) {
+ QPair<HelpWindow*, QString> browser = it.next();
+ if (browser.first == win) {
+ it.remove();
+ break;
+ }
+ }
+}
+
+void MainWindow::timerEvent(QTimerEvent *e)
+{
+ QPair<HelpWindow*, QString> browser = pendingBrowsers.first();
+ pendingBrowsers.pop_front();
+
+ if (pendingBrowsers.size() == 0)
+ killTimer(e->timerId());
+
+ browser.first->setSource(MainWindow::urlifyFileName(browser.second));
+}
+
+void MainWindow::showQtHelp()
+{
+ showLink(QLibraryInfo::location(QLibraryInfo::DocumentationPath) +
+ QLatin1String("/html/index.html"));
+}
+
+MainWindow* MainWindow::newWindow()
+{
+ saveSettings();
+ MainWindow *mw = new MainWindow;
+ mw->move(geometry().topLeft());
+ if (isMaximized())
+ mw->showMaximized();
+ else
+ mw->show();
+ mw->on_actionGoHome_triggered();
+ return mw;
+}
+
+void MainWindow::saveSettings()
+{
+ Config *config = Config::configuration();
+
+ config->setSideBarPage(helpDock->tabWidget()->currentIndex());
+ config->setWindowGeometry(saveGeometry());
+ config->setMainWindowState(saveState());
+
+ // Create list of the tab urls
+ QStringList lst;
+ QList<HelpWindow*> browsers = tabs->browsers();
+ foreach (HelpWindow *browser, browsers)
+ lst << browser->source().toString();
+ config->setSource(lst);
+ config->save();
+}
+
+TabbedBrowser* MainWindow::browsers() const
+{
+ return tabs;
+}
+
+void MainWindow::showSearchLink(const QString &link, const QStringList &terms)
+{
+ HelpWindow * hw = tabs->currentBrowser();
+ hw->blockScrolling(true);
+ hw->setCursor(Qt::WaitCursor);
+ if (hw->source() == link)
+ hw->reload();
+ else
+ showLink(link);
+ hw->setCursor(Qt::ArrowCursor);
+
+ hw->viewport()->setUpdatesEnabled(false);
+
+ QTextCharFormat marker;
+ marker.setForeground(Qt::red);
+
+ QTextCursor firstHit;
+
+ QTextCursor c = hw->textCursor();
+ c.beginEditBlock();
+ foreach (QString term, terms) {
+ c.movePosition(QTextCursor::Start);
+ hw->setTextCursor(c);
+
+ bool found = hw->find(term, QTextDocument::FindWholeWords);
+ while (found) {
+ QTextCursor hit = hw->textCursor();
+ if (firstHit.isNull() || hit.position() < firstHit.position())
+ firstHit = hit;
+
+ hit.mergeCharFormat(marker);
+ found = hw->find(term, QTextDocument::FindWholeWords);
+ }
+ }
+
+ if (firstHit.isNull()) {
+ firstHit = hw->textCursor();
+ firstHit.movePosition(QTextCursor::Start);
+ }
+ firstHit.clearSelection();
+ c.endEditBlock();
+ hw->setTextCursor(firstHit);
+
+ hw->blockScrolling(false);
+ hw->viewport()->setUpdatesEnabled(true);
+}
+
+
+void MainWindow::showGoActionLink()
+{
+ const QObject *origin = sender();
+ if(!origin ||
+ QString::fromLatin1(origin->metaObject()->className()) != QString::fromLatin1("QAction"))
+ return;
+
+ QAction *action = (QAction*) origin;
+ QString docfile = *(goActionDocFiles->find(action));
+ showLink(MainWindow::urlifyFileName(docfile));
+}
+
+void MainWindow::on_actionHelpAssistant_triggered()
+{
+ showLink(Config::configuration()->assistantDocPath() + QLatin1String("/assistant-manual.html"));
+}
+
+HelpDialog* MainWindow::helpDialog() const
+{
+ return helpDock;
+}
+
+void MainWindow::backwardAvailable(bool enable)
+{
+ ui.actionGoPrevious->setEnabled(enable);
+}
+
+void MainWindow::forwardAvailable(bool enable)
+{
+ ui.actionGoNext->setEnabled(enable);
+}
+
+void MainWindow::updateProfileSettings()
+{
+ Config *config = Config::configuration();
+#ifndef Q_WS_MAC
+ setWindowIcon(config->applicationIcon());
+#endif
+ ui.helpMenu->clear();
+ //ui.helpMenu->addAction(ui.actionHelpAssistant);
+ //ui.helpMenu->addSeparator();
+ ui.helpMenu->addAction(ui.actionAboutAssistant);
+ if (!config->aboutApplicationMenuText().isEmpty())
+ ui.helpMenu->addAction(ui.actionAboutApplication);
+ ui.helpMenu->addSeparator();
+ ui.helpMenu->addAction(ui.actionHelpWhatsThis);
+
+ ui.actionAboutApplication->setText(config->aboutApplicationMenuText());
+
+ if(!config->title().isNull())
+ setWindowTitle(config->title());
+}
+
+void MainWindow::setupPopupMenu(QMenu *m)
+{
+ m->addAction(ui.actionNewWindow);
+ m->addAction(ui.actionOpenPage);
+ m->addAction(ui.actionClosePage);
+ m->addSeparator();
+ m->addAction(ui.actionSaveAs);
+ m->addSeparator();
+ m->addAction(ui.actionGoPrevious);
+ m->addAction(ui.actionGoNext);
+ m->addAction(ui.actionGoHome);
+ m->addSeparator();
+ m->addAction(ui.actionZoomIn);
+ m->addAction(ui.actionZoomOut);
+ m->addSeparator();
+ m->addAction(ui.actionEditCopy);
+ m->addAction(ui.actionEditFind);
+}
+
+void MainWindow::on_actionSyncToc_triggered()
+{
+ HelpWindow *w = tabs->currentBrowser();
+ if(w) {
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+ QString link = w->source().toString();
+ helpDock->locateContents(link);
+ helpDock->tabWidget()->setCurrentIndex(0);
+ qApp->restoreOverrideCursor();
+ }
+}
+
+void MainWindow::on_actionNewWindow_triggered()
+{
+ newWindow()->show();
+}
+
+void MainWindow::on_actionClose_triggered()
+{
+ close();
+}
+
+void MainWindow::on_actionHelpWhatsThis_triggered()
+{
+ QWhatsThis::enterWhatsThisMode();
+}
+
+void MainWindow::on_actionSaveAs_triggered()
+{
+ QString fileName;
+ QUrl url = tabs->currentBrowser()->source();
+ if (url.isValid()) {
+ QFileInfo fi(url.toLocalFile());
+ fileName = fi.fileName();
+ }
+ fileName = QFileDialog::getSaveFileName(this, tr("Save Page"), fileName);
+ if (fileName.isEmpty())
+ return;
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ QMessageBox::critical(this, tr("Save Page"), tr("Cannot open file for writing!"));
+ return;
+ }
+
+ QFileInfo fi(fileName);
+ QString fn = fi.fileName();
+ int i = fn.lastIndexOf(QLatin1Char('.'));
+ if (i > -1)
+ fn = fn.left(i);
+ QString relativeDestPath = fn + QLatin1String("_images");
+ QDir destDir(fi.absolutePath() + QDir::separator() + relativeDestPath);
+ bool imgDirAvailable = destDir.exists();
+ if (!imgDirAvailable)
+ imgDirAvailable = destDir.mkdir(destDir.absolutePath());
+
+ // save images
+ QTextDocument *doc = tabs->currentBrowser()->document()->clone();
+ if (url.isValid() && imgDirAvailable) {
+ QTextBlock::iterator it;
+ for (QTextBlock block = doc->begin(); block != doc->end(); block = block.next()) {
+ for (it = block.begin(); !(it.atEnd()); ++it) {
+ QTextFragment fragment = it.fragment();
+ if (fragment.isValid()) {
+ QTextImageFormat fm = fragment.charFormat().toImageFormat();
+ if (fm.isValid() && !fm.name().isEmpty()) {
+ QUrl imagePath = tabs->currentBrowser()->source().resolved(fm.name());
+ if (!imagePath.isValid())
+ continue;
+ QString from = imagePath.toLocalFile();
+ QString destName = fm.name();
+ int j = destName.lastIndexOf(QLatin1Char('/'));
+ if (j > -1)
+ destName = destName.mid(j+1);
+ QFileInfo info(from);
+ if (info.exists()) {
+ if (!QFile::copy(from, destDir.absolutePath()
+ + QDir::separator() + destName))
+ continue;
+ fm.setName(QLatin1String("./") + relativeDestPath + QLatin1String("/") + destName);
+ QTextCursor cursor(doc);
+ cursor.setPosition(fragment.position());
+ cursor.setPosition(fragment.position() + fragment.length(),
+ QTextCursor::KeepAnchor);
+ cursor.setCharFormat(fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ QString src = doc->toHtml(QByteArray("utf-8"));
+ QTextStream s(&file);
+ s.setCodec("utf-8");
+ s << src;
+ s.flush();
+ file.close();
+}
+
+void MainWindow::showFontSettingsDialog()
+{
+ Config *config = Config::configuration();
+ FontSettings settings = config->fontSettings();
+
+ { // It is important that the dialog be deleted before UI mode changes.
+ FontSettingsDialog dialog;
+ if (!dialog.showDialog(&settings))
+ return;
+ }
+
+ config->setFontPointSize(settings.browserFont.pointSizeF());
+ config->setFontSettings(settings);
+
+ updateApplicationFontSettings(settings);
+}
+
+void MainWindow::updateApplicationFontSettings(FontSettings &settings)
+{
+ QFont font = settings.windowFont;
+ if (this->font() != font)
+ qApp->setFont(font, "QWidget");
+
+ font = settings.browserFont;
+ QList<HelpWindow*> browsers = tabs->browsers();
+ foreach (HelpWindow *browser, browsers) {
+ if (browser->font() != font)
+ browser->setFont(font);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/mainwindow.h b/tools/assistant/compat/mainwindow.h
new file mode 100644
index 0000000..2073f0d
--- /dev/null
+++ b/tools/assistant/compat/mainwindow.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "ui_mainwindow.h"
+#include "config.h"
+
+#include <QPointer>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+class TabbedBrowser;
+class HelpDialog;
+class HelpWindow;
+class QMenu;
+class QDockWidget;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ MainWindow();
+ virtual ~MainWindow();
+
+ TabbedBrowser *browsers() const;
+ HelpDialog *helpDialog() const;
+
+ void setupPopupMenu(QMenu *menu);
+ static QString urlifyFileName(const QString &fileName);
+
+ void removePendingBrowser(HelpWindow *win);
+
+public slots:
+ MainWindow *newWindow();
+
+ void setup();
+ void showLink(const QString &link);
+ void showLinks(const QStringList &links);
+ void saveSettings();
+ void updateBookmarkMenu();
+ void printingFinished();
+
+private slots:
+ void on_actionNewWindow_triggered();
+ void on_actionGoHome_triggered();
+ void on_actionFilePrint_triggered();
+ void on_actionClose_triggered();
+ void on_actionHelpWhatsThis_triggered();
+ void on_actionHelpAssistant_triggered();
+ void on_actionAboutApplication_triggered();
+ void on_actionAboutAssistant_triggered();
+ void on_actionSaveAs_triggered();
+ void on_actionSyncToc_triggered();
+
+ void about();
+ void setupBookmarkMenu();
+ void showBookmark(QAction *action);
+ void showLinkFromClient(const QString &link);
+ void showQtHelp();
+ void showSearchLink(const QString &link, const QStringList &terms);
+ void showGoActionLink();
+ void updateProfileSettings();
+ void backwardAvailable(bool);
+ void forwardAvailable(bool);
+
+ void browserTabChanged();
+ void copyAvailable(bool yes);
+ void updateTabActions(int index);
+ void showFontSettingsDialog();
+
+protected:
+ void closeEvent(QCloseEvent *);
+ void timerEvent(QTimerEvent *);
+
+private:
+ void setupGoActions();
+ bool insertActionSeparator();
+ void updateApplicationFontSettings(FontSettings &settings);
+
+private:
+ Ui::MainWindow ui;
+
+ QList<QAction*> goActions;
+ uint setupCompleted:1;
+ TabbedBrowser *tabs;
+ QMap<QAction*, QString> bookmarks;
+ HelpDialog *helpDock;
+ QDockWidget *dw;
+ static QList<MainWindow*> windows;
+ QMap<QAction*,QString> *goActionDocFiles;
+ QList<QPair<HelpWindow*,QString> > pendingBrowsers;
+};
+
+#endif // MAINWINDOW_H
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/mainwindow.ui b/tools/assistant/compat/mainwindow.ui
new file mode 100644
index 0000000..803a4dc
--- /dev/null
+++ b/tools/assistant/compat/mainwindow.ui
@@ -0,0 +1,459 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+*********************************************************************</comment>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>949</width>
+ <height>670</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant by Nokia</string>
+ </property>
+ <widget class="QWidget" name="__qt_central_widget" />
+ <widget class="QToolBar" name="Toolbar" >
+ <property name="windowTitle" >
+ <string>Toolbar</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <attribute name="toolBarArea" >
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak" >
+ <bool>false</bool>
+ </attribute>
+ <addaction name="actionGoPrevious" />
+ <addaction name="actionGoNext" />
+ <addaction name="actionGoHome" />
+ <addaction name="actionSyncToc" />
+ <addaction name="separator" />
+ <addaction name="actionEditCopy" />
+ <addaction name="actionEditFind" />
+ <addaction name="actionFilePrint" />
+ <addaction name="separator" />
+ <addaction name="actionZoomIn" />
+ <addaction name="actionZoomOut" />
+ <addaction name="separator" />
+ <addaction name="actionHelpWhatsThis" />
+ </widget>
+ <widget class="QToolBar" name="goActionToolbar" >
+ <property name="windowTitle" >
+ <string>Go</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <attribute name="toolBarArea" >
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak" >
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>949</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="helpMenu" >
+ <property name="title" >
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="actionHelpAssistant" />
+ <addaction name="separator" />
+ <addaction name="actionAboutAssistant" />
+ <addaction name="actionAboutApplication" />
+ <addaction name="separator" />
+ <addaction name="actionHelpWhatsThis" />
+ </widget>
+ <widget class="QMenu" name="fileMenu" >
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="actionNewWindow" />
+ <addaction name="actionOpenPage" />
+ <addaction name="actionClosePage" />
+ <addaction name="separator" />
+ <addaction name="actionSaveAs" />
+ <addaction name="separator" />
+ <addaction name="actionFilePrint" />
+ <addaction name="separator" />
+ <addaction name="actionClose" />
+ <addaction name="actionFileExit" />
+ </widget>
+ <widget class="QMenu" name="bookmarkMenu" >
+ <property name="title" >
+ <string>Boo&amp;kmarks</string>
+ </property>
+ </widget>
+ <widget class="QMenu" name="goMenu" >
+ <property name="title" >
+ <string>&amp;Go</string>
+ </property>
+ <addaction name="actionGoPrevious" />
+ <addaction name="actionGoNext" />
+ <addaction name="actionGoHome" />
+ <addaction name="actionSyncToc" />
+ <addaction name="separator" />
+ <addaction name="actionNextPage" />
+ <addaction name="actionPrevPage" />
+ </widget>
+ <widget class="QMenu" name="viewMenu" >
+ <property name="title" >
+ <string>&amp;View</string>
+ </property>
+ <addaction name="actionZoomIn" />
+ <addaction name="actionZoomOut" />
+ </widget>
+ <widget class="QMenu" name="editMenu" >
+ <property name="title" >
+ <string>&amp;Edit</string>
+ </property>
+ <addaction name="actionEditCopy" />
+ <addaction name="actionEditFind" />
+ <addaction name="actionEditFindNext" />
+ <addaction name="actionEditFindPrev" />
+ <addaction name="separator" />
+ <addaction name="actionEditFont_Settings" />
+ </widget>
+ <addaction name="fileMenu" />
+ <addaction name="editMenu" />
+ <addaction name="viewMenu" />
+ <addaction name="goMenu" />
+ <addaction name="bookmarkMenu" />
+ <addaction name="helpMenu" />
+ </widget>
+ <action name="actionFilePrint" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/print.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Print...</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Print the currently displayed page.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+P</string>
+ </property>
+ </action>
+ <action name="actionFileExit" >
+ <property name="text" >
+ <string>E&amp;xit</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Quit Qt Assistant.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Q</string>
+ </property>
+ <property name="menuRole" >
+ <enum>QAction::QuitRole</enum>
+ </property>
+ </action>
+ <action name="actionEditCopy" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/editcopy.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Copy</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Copy the selected text to the clipboard.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionEditFind" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/find.png</iconset>
+ </property>
+ <property name="text" >
+ <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="shortcut" >
+ <string>Ctrl+F</string>
+ </property>
+ </action>
+ <action name="actionEditFindNext" >
+ <property name="text" >
+ <string>Find &amp;Next</string>
+ </property>
+ <property name="shortcut" >
+ <string>F3</string>
+ </property>
+ </action>
+ <action name="actionEditFindPrev" >
+ <property name="text" >
+ <string>Find &amp;Previous</string>
+ </property>
+ <property name="shortcut" >
+ <string>Shift+F3</string>
+ </property>
+ </action>
+ <action name="actionGoHome" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/home.png</iconset>
+ </property>
+ <property name="text" >
+ <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="shortcut" >
+ <string>Ctrl+Home</string>
+ </property>
+ </action>
+ <action name="actionGoPrevious" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/previous.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Previous</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Go to the previous page.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+Left</string>
+ </property>
+ </action>
+ <action name="actionGoNext" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/next.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Next</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Go to the next page.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+Right</string>
+ </property>
+ </action>
+ <action name="actionAboutAssistant" >
+ <property name="text" >
+ <string>About Qt Assistant</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Display further information about Qt Assistant.</string>
+ </property>
+ <property name="menuRole" >
+ <enum>QAction::AboutRole</enum>
+ </property>
+ </action>
+ <action name="actionAboutApplication" >
+ <property name="text" >
+ <string>About Qt</string>
+ </property>
+ <property name="menuRole" >
+ <enum>QAction::AboutQtRole</enum>
+ </property>
+ </action>
+ <action name="actionZoomIn" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/zoomin.png</iconset>
+ </property>
+ <property name="text" >
+ <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="shortcut" >
+ <string>Ctrl++</string>
+ </property>
+ </action>
+ <action name="actionZoomOut" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/zoomout.png</iconset>
+ </property>
+ <property name="text" >
+ <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="shortcut" >
+ <string>Ctrl+-</string>
+ </property>
+ </action>
+ <action name="actionNewWindow" >
+ <property name="text" >
+ <string>New Window</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Open a new window.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="actionClose" >
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Close the current window.</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+W</string>
+ </property>
+ </action>
+ <action name="actionAddBookmark" >
+ <property name="text" >
+ <string>&amp;Add Bookmark</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Add the currently displayed page as a new bookmark.</string>
+ </property>
+ </action>
+ <action name="actionHelpWhatsThis" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/whatsthis.png</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="shortcut" >
+ <string>Shift+F1</string>
+ </property>
+ </action>
+ <action name="actionOpenPage" >
+ <property name="text" >
+ <string>Add Tab</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Alt+N</string>
+ </property>
+ </action>
+ <action name="actionNextPage" >
+ <property name="text" >
+ <string>Next Tab</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Alt+Right</string>
+ </property>
+ </action>
+ <action name="actionPrevPage" >
+ <property name="text" >
+ <string>Previous Tab</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Alt+Left</string>
+ </property>
+ </action>
+ <action name="actionClosePage" >
+ <property name="text" >
+ <string>Close Tab</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Alt+Q</string>
+ </property>
+ </action>
+ <action name="actionHelpAssistant" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/assistant.png</iconset>
+ </property>
+ <property name="text" >
+ <string>Qt Assistant Manual</string>
+ </property>
+ <property name="shortcut" >
+ <string>F1</string>
+ </property>
+ </action>
+ <action name="actionSaveAs" >
+ <property name="text" >
+ <string>Save Page As...</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Alt+S</string>
+ </property>
+ </action>
+ <action name="actionSyncToc" >
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/synctoc.png</iconset>
+ </property>
+ <property name="text" >
+ <string>Sync with Table of Contents</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Select the page in contents tab.</string>
+ </property>
+ </action>
+ <action name="actionEditFont_Settings" >
+ <property name="text" >
+ <string>Font Settings...</string>
+ </property>
+ <property name="menuRole" >
+ <enum>QAction::PreferencesRole</enum>
+ </property>
+ </action>
+ </widget>
+ <resources>
+ <include location="assistant.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/assistant/compat/profile.cpp b/tools/assistant/compat/profile.cpp
new file mode 100644
index 0000000..10b1737
--- /dev/null
+++ b/tools/assistant/compat/profile.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "profile.h"
+#include <QTextCodec>
+#include <QFileInfo>
+#include <QRegExp>
+#include <QDir>
+#include <QList>
+#include <QLibraryInfo>
+
+QT_BEGIN_NAMESPACE
+
+#define QT_TITLE QLatin1String("Qt Reference Documentation")
+#define DESIGNER_TITLE QLatin1String("Qt Designer Manual")
+#define ASSISTANT_TITLE QLatin1String("Qt Assistant Manual")
+#define LINGUIST_TITLE QLatin1String("Qt Linguist Manual")
+#define QMAKE_TITLE QLatin1String("qmake Manual")
+
+Profile *Profile::createDefaultProfile(const QString &docPath)
+{
+ QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath);
+ if (!docPath.isEmpty())
+ path = docPath;
+ path = QDir::cleanPath(path) + QLatin1String("/html/");
+
+ Profile *profile = new Profile;
+ profile->valid = true;
+ profile->type = DefaultProfile;
+ profile->props[QLatin1String("name")] = QLatin1String("default");
+ profile->props[QLatin1String("applicationicon")] = QLatin1String("assistant.png");
+ profile->props[QLatin1String("aboutmenutext")] = QLatin1String("About Qt");
+ profile->props[QLatin1String("abouturl")] = QLatin1String("about_qt");
+ profile->props[QLatin1String("basepath")] = path;
+ profile->props[QLatin1String("startpage")] = path + QLatin1String("index.html");
+
+ profile->addDCFTitle( path + QLatin1String("qt.dcf"), QT_TITLE );
+ profile->addDCFTitle( path + QLatin1String("designer.dcf"), DESIGNER_TITLE );
+ profile->addDCFTitle( path + QLatin1String("assistant.dcf"), ASSISTANT_TITLE );
+ profile->addDCFTitle( path + QLatin1String("linguist.dcf"), LINGUIST_TITLE );
+ profile->addDCFTitle( path + QLatin1String("qmake.dcf"), QMAKE_TITLE );
+
+ profile->addDCFIcon( QT_TITLE, QLatin1String("qt.png") );
+ profile->addDCFIcon( DESIGNER_TITLE, QLatin1String("designer.png") );
+ profile->addDCFIcon( ASSISTANT_TITLE, QLatin1String("assistant.png") );
+ profile->addDCFIcon( LINGUIST_TITLE, QLatin1String("linguist.png") );
+
+ profile->addDCFIndexPage( QT_TITLE, path + QLatin1String("index.html") );
+ profile->addDCFIndexPage( DESIGNER_TITLE, path + QLatin1String("designer-manual.html") );
+ profile->addDCFIndexPage( ASSISTANT_TITLE, path + QLatin1String("assistant-manual.html") );
+ profile->addDCFIndexPage( LINGUIST_TITLE, path + QLatin1String("linguist-manual.html") );
+ profile->addDCFIndexPage( QMAKE_TITLE, path + QLatin1String("qmake-manual.html") );
+
+ profile->addDCFImageDir( QT_TITLE, QLatin1String("../../gif/") );
+ profile->addDCFImageDir( DESIGNER_TITLE, QLatin1String("../../gif/") );
+ profile->addDCFImageDir( ASSISTANT_TITLE, QLatin1String("../../gif/") );
+ profile->addDCFImageDir( LINGUIST_TITLE, QLatin1String("../../gif/") );
+ profile->addDCFImageDir( QMAKE_TITLE, QLatin1String("../../gif/") );
+
+ return profile;
+}
+
+Profile::Profile()
+ : valid( true ), dparser( 0 )
+{
+ type = DefaultProfile;
+}
+
+bool Profile::isValid() const
+{
+ return valid;
+}
+
+void Profile::addDCFTitle(const QString &dcf, const QString &title)
+{
+ QString absdcf = QFileInfo(dcf).absoluteFilePath();
+ dcfTitles[title] = absdcf;
+ if (!docs.contains(absdcf))
+ docs << absdcf;
+}
+
+void Profile::addDCF(const QString &docfile)
+{
+ if( !docs.contains( docfile ) == 0 )
+ docs << docfile;
+}
+
+void Profile::addDCFIcon(const QString docfile, const QString &icon)
+{
+ icons[docfile] = icon;
+}
+
+void Profile::addDCFIndexPage(const QString title, const QString &indexPage)
+{
+ indexPages[title] = indexPage;
+}
+
+void Profile::addDCFImageDir(const QString docfile, const QString &imgDir)
+{
+ imageDirs[docfile] = imgDir;
+}
+
+void Profile::addProperty(const QString &name, const QString &value)
+{
+ props[name] = value;
+}
+
+bool Profile::hasDocFile(const QString &name)
+{
+ return docs.contains( name );
+}
+
+void Profile::removeDocFileEntry(const QString &docfile)
+{
+ docs.removeAll(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.constBegin();
+ title != titles.constEnd(); ++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
+}
+
+QString Profile::storableFilePath(const QString &fileName)
+{
+ QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath).replace(QLatin1String("\\"), QLatin1String("/"));
+ QString fName = fileName;
+ if (fName.startsWith(path))
+ fName.replace(0, path.length(), QLatin1String("$DOCPATH$"));
+ return fName;
+}
+
+QString Profile::loadableFilePath(const QString &fileName)
+{
+ QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath).replace(QLatin1String("\\"), QLatin1String("/"));
+ QString fName = fileName;
+ if (fName.startsWith(QLatin1String("$DOCPATH$")))
+ fName.replace(0, 9, path);
+ return fName;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/profile.h b/tools/assistant/compat/profile.h
new file mode 100644
index 0000000..24aef3e
--- /dev/null
+++ b/tools/assistant/compat/profile.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROFILE_H
+#define PROFILE_H
+
+#include <QFileInfo>
+#include <QString>
+#include <QStringList>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+class DocuParser;
+
+class Profile
+{
+public:
+ enum ProfileType { DefaultProfile, UserProfile };
+ Profile();
+
+ bool isValid() const;
+
+ void addDCF( const QString &docfile );
+ void addDCFIcon( const QString title, const QString &icon );
+ void addDCFIndexPage( const QString title, const QString &indexPage );
+ void addDCFImageDir( const QString title, const QString &imgDir );
+ void addDCFTitle( const QString &dcf, const QString &title );
+ void addProperty( const QString &name, const QString &value );
+ bool hasDocFile( const QString &docFile );
+ void removeDocFileEntry( const QString &title );
+
+ ProfileType profileType() const { return type; }
+ void setProfileType( ProfileType t ) { type = t; }
+
+ DocuParser *docuParser() const { return dparser; }
+ void setDocuParser( DocuParser *dp ) { dparser = dp; }
+
+ static Profile* createDefaultProfile(const QString &docPath = QString());
+ static QString makeRelativePath(const QString &base, const QString &path);
+ static QString storableFilePath(const QString &fileName);
+ static QString loadableFilePath(const QString &fileName);
+
+ uint 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;
+};
+
+QT_END_NAMESPACE
+
+#endif // PROFILE_H
diff --git a/tools/assistant/compat/tabbedbrowser.cpp b/tools/assistant/compat/tabbedbrowser.cpp
new file mode 100644
index 0000000..198be4a
--- /dev/null
+++ b/tools/assistant/compat/tabbedbrowser.cpp
@@ -0,0 +1,530 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tabbedbrowser.h"
+#include "mainwindow.h"
+#include "helpwindow.h"
+#include "config.h"
+
+#include <QStyleOptionTab>
+#include <QToolTip>
+#include <QFileInfo>
+#include <QToolButton>
+#include <QPixmap>
+#include <QIcon>
+#include <QStyle>
+#include <QTimer>
+#include <QStackedWidget>
+#include <QTimer>
+#include <QTextBlock>
+#include <QKeyEvent>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_MAC
+const QLatin1String ImageLocation(":trolltech/assistant/images/mac/");
+#else
+const QLatin1String ImageLocation(":trolltech/assistant/images/win/");
+#endif
+
+TabbedBrowser::TabbedBrowser(MainWindow *parent)
+ : QWidget(parent)
+{
+ ui.setupUi(this);
+ init();
+
+ QStackedWidget *stack = qFindChild<QStackedWidget*>(ui.tab);
+ Q_ASSERT(stack);
+ stack->setContentsMargins(0, 0, 0, 0);
+ connect(stack, SIGNAL(currentChanged(int)), parent, SLOT(browserTabChanged()));
+
+ QPalette p = palette();
+ p.setColor(QPalette::Inactive, QPalette::Highlight,
+ p.color(QPalette::Active, QPalette::Highlight));
+ p.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ p.color(QPalette::Active, QPalette::HighlightedText));
+ setPalette(p);
+}
+
+TabbedBrowser::~TabbedBrowser()
+{
+}
+
+MainWindow *TabbedBrowser::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void TabbedBrowser::forward()
+{
+ currentBrowser()->forward();
+ emit browserUrlChanged(currentBrowser()->source().toString());
+}
+
+void TabbedBrowser::backward()
+{
+ currentBrowser()->backward();
+ emit browserUrlChanged(currentBrowser()->source().toString());
+}
+
+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() const
+{
+ return static_cast<HelpWindow*>(ui.tab->currentWidget());
+}
+
+void TabbedBrowser::nextTab()
+{
+ if(ui.tab->currentIndex()<=ui.tab->count()-1)
+ ui.tab->setCurrentIndex(ui.tab->currentIndex()+1);
+}
+
+void TabbedBrowser::previousTab()
+{
+ int idx = ui.tab->currentIndex()-1;
+ if(idx>=0)
+ ui.tab->setCurrentIndex(idx);
+}
+
+HelpWindow *TabbedBrowser::createHelpWindow()
+{
+ MainWindow *mainWin = mainWindow();
+ HelpWindow *win = new HelpWindow(mainWin, 0);
+ win->setFrameStyle(QFrame::NoFrame);
+ win->setPalette(palette());
+ win->setSearchPaths(Config::configuration()->mimePaths());
+ ui.tab->addTab(win, tr("..."));
+ connect(win, SIGNAL(highlighted(QString)),
+ (const QObject*) (mainWin->statusBar()), SLOT(showMessage(QString)));
+ connect(win, SIGNAL(backwardAvailable(bool)),
+ mainWin, SLOT(backwardAvailable(bool)));
+ connect(win, SIGNAL(forwardAvailable(bool)),
+ mainWin, SLOT(forwardAvailable(bool)));
+ connect(win, SIGNAL(sourceChanged(QUrl)), this, SLOT(sourceChanged()));
+
+ ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
+ win->installEventFilter(this);
+ win->viewport()->installEventFilter(this);
+ ui.editFind->installEventFilter(this);
+ return win;
+}
+
+HelpWindow *TabbedBrowser::newBackgroundTab()
+{
+ HelpWindow *win = createHelpWindow();
+ emit tabCountChanged(ui.tab->count());
+ return win;
+}
+
+void TabbedBrowser::newTab(const QString &lnk)
+{
+ QString link(lnk);
+ if(link.isNull()) {
+ HelpWindow *w = currentBrowser();
+ if(w)
+ link = w->source().toString();
+ }
+ HelpWindow *win = createHelpWindow();
+ ui.tab->setCurrentIndex(ui.tab->indexOf(win));
+ if(!link.isNull()) {
+ win->setSource(link);
+ }
+
+ emit tabCountChanged(ui.tab->count());
+}
+
+void TabbedBrowser::zoomIn()
+{
+ currentBrowser()->zoomIn();
+ Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
+}
+
+void TabbedBrowser::zoomOut()
+{
+ currentBrowser()->zoomOut();
+ Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
+}
+
+void TabbedBrowser::init()
+{
+
+ lastCurrentTab = 0;
+ while(ui.tab->count()) {
+ QWidget *page = ui.tab->widget(0);
+ ui.tab->removeTab(0);
+ delete page;
+ }
+
+ connect(ui.tab, SIGNAL(currentChanged(int)),
+ this, SLOT(transferFocus()));
+
+ QTabBar *tabBar = qFindChild<QTabBar*>(ui.tab);
+ QStyleOptionTab opt;
+ if (tabBar) {
+ opt.init(tabBar);
+ opt.shape = tabBar->shape();
+ tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(tabBar, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(openTabMenu(const QPoint&)));
+ }
+
+ // workaround for sgi style
+ QPalette pal = palette();
+ pal.setColor(QPalette::Active, QPalette::Button, pal.color(QPalette::Active, QPalette::Window));
+ pal.setColor(QPalette::Disabled, QPalette::Button, pal.color(QPalette::Disabled, QPalette::Window));
+ pal.setColor(QPalette::Inactive, QPalette::Button, pal.color(QPalette::Inactive, QPalette::Window));
+
+ QToolButton *newTabButton = new QToolButton(this);
+ ui.tab->setCornerWidget(newTabButton, Qt::TopLeftCorner);
+ newTabButton->setCursor(Qt::ArrowCursor);
+ newTabButton->setAutoRaise(true);
+ newTabButton->setIcon(QIcon(ImageLocation + QLatin1String("addtab.png")));
+ QObject::connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));
+ newTabButton->setToolTip(tr("Add page"));
+
+ QToolButton *closeTabButton = new QToolButton(this);
+ closeTabButton->setPalette(pal);
+ ui.tab->setCornerWidget(closeTabButton, Qt::TopRightCorner);
+ closeTabButton->setCursor(Qt::ArrowCursor);
+ closeTabButton->setAutoRaise(true);
+ closeTabButton->setIcon(QIcon(ImageLocation + QLatin1String("closetab.png")));
+ QObject::connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeTab()));
+ closeTabButton->setToolTip(tr("Close page"));
+ closeTabButton->setEnabled(false);
+
+ QObject::connect(ui.toolClose, SIGNAL(clicked()), ui.frameFind, SLOT(hide()));
+ QObject::connect(ui.toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
+ QObject::connect(ui.toolNext, SIGNAL(clicked()), this, SLOT(findNext()));
+ QObject::connect(ui.editFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
+ QObject::connect(ui.editFind, SIGNAL(textEdited(const QString&)),
+ this, SLOT(find(QString)));
+ ui.frameFind->setVisible(false);
+ ui.labelWrapped->setVisible(false);
+ autoHideTimer = new QTimer(this);
+ autoHideTimer->setInterval(5000);
+ autoHideTimer->setSingleShot(true);
+ QObject::connect(autoHideTimer, SIGNAL(timeout()), ui.frameFind, SLOT(hide()));
+}
+
+void TabbedBrowser::updateTitle(const QString &title)
+{
+ ui.tab->setTabText(ui.tab->indexOf(currentBrowser()), title.trimmed());
+}
+
+void TabbedBrowser::newTab()
+{
+ newTab(QString());
+}
+
+void TabbedBrowser::transferFocus()
+{
+ if(currentBrowser()) {
+ currentBrowser()->setFocus();
+ }
+ mainWindow()->setWindowTitle(Config::configuration()->title()
+ + QLatin1String(" - ")
+ + currentBrowser()->documentTitle());
+}
+
+void TabbedBrowser::initHelpWindow(HelpWindow * /*win*/)
+{
+}
+
+void TabbedBrowser::setup()
+{
+ newTab(QString());
+}
+
+void TabbedBrowser::copy()
+{
+ currentBrowser()->copy();
+}
+
+void TabbedBrowser::closeTab()
+{
+ if(ui.tab->count()==1)
+ return;
+ HelpWindow *win = currentBrowser();
+ mainWindow()->removePendingBrowser(win);
+ ui.tab->removeTab(ui.tab->indexOf(win));
+ QTimer::singleShot(0, win, SLOT(deleteLater()));
+ ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
+ emit tabCountChanged(ui.tab->count());
+}
+
+QStringList TabbedBrowser::sources() const
+{
+ QStringList lst;
+ int cnt = ui.tab->count();
+ for(int i=0; i<cnt; i++) {
+ lst.append(((QTextBrowser*) ui.tab->widget(i))->source().toString());
+ }
+ return lst;
+}
+
+QList<HelpWindow*> TabbedBrowser::browsers() const
+{
+ QList<HelpWindow*> list;
+ for (int i=0; i<ui.tab->count(); ++i) {
+ Q_ASSERT(qobject_cast<HelpWindow*>(ui.tab->widget(i)));
+ list.append(static_cast<HelpWindow*>(ui.tab->widget(i)));
+ }
+ return list;
+}
+
+void TabbedBrowser::sourceChanged()
+{
+ HelpWindow *win = qobject_cast<HelpWindow *>(QObject::sender());
+ Q_ASSERT(win);
+ QString docTitle(win->documentTitle());
+ if (docTitle.isEmpty())
+ docTitle = QLatin1String("...");
+ // Make the classname in the title a bit more visible (otherwise
+ // we just see the "Qt 4.0 : Q..." which isn't really helpful ;-)
+ QString qtTitle = QLatin1String("Qt ") + QString::number( (QT_VERSION >> 16) & 0xff )
+ + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff )
+ + QLatin1String(": ");
+ if (docTitle.startsWith(qtTitle))
+ docTitle = docTitle.mid(qtTitle.length());
+ setTitle(win, docTitle);
+ ui.frameFind->hide();
+ ui.labelWrapped->hide();
+ win->setTextCursor(win->cursorForPosition(QPoint(0, 0)));
+}
+
+void TabbedBrowser::setTitle(HelpWindow *win, const QString &title)
+{
+ const QString tt = title.trimmed();
+ ui.tab->setTabText(ui.tab->indexOf(win), tt);
+ if (win == currentBrowser())
+ mainWindow()->setWindowTitle(Config::configuration()->title() + QLatin1String(" - ") + tt);
+}
+
+void TabbedBrowser::keyPressEvent(QKeyEvent *e)
+{
+ int key = e->key();
+ QString ttf = ui.editFind->text();
+ QString text = e->text();
+
+ if (ui.frameFind->isVisible()) {
+ switch (key) {
+ case Qt::Key_Escape:
+ ui.frameFind->hide();
+ ui.labelWrapped->hide();
+ return;
+ case Qt::Key_Backspace:
+ ttf.chop(1);
+ break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ // Return/Enter key events are not accepted by QLineEdit
+ return;
+ default:
+ if (text.isEmpty()) {
+ QWidget::keyPressEvent(e);
+ return;
+ }
+ ttf += text;
+ }
+ } else {
+ if (text.isEmpty() || text[0].isSpace() || !text[0].isPrint()) {
+ QWidget::keyPressEvent(e);
+ return;
+ }
+ if (text.startsWith(QLatin1Char('/'))) {
+ ui.editFind->clear();
+ find();
+ return;
+ }
+ ttf = text;
+ ui.frameFind->show();
+ }
+
+ ui.editFind->setText(ttf);
+ find(ttf, false, false);
+}
+
+void TabbedBrowser::findNext()
+{
+ find(ui.editFind->text(), true, false);
+}
+
+void TabbedBrowser::findPrevious()
+{
+ find(ui.editFind->text(), false, true);
+}
+
+void TabbedBrowser::find()
+{
+ ui.frameFind->show();
+ ui.editFind->setFocus(Qt::ShortcutFocusReason);
+ ui.editFind->selectAll();
+ autoHideTimer->stop();
+}
+
+void TabbedBrowser::find(QString ttf, bool forward, bool backward)
+{
+ HelpWindow *browser = currentBrowser();
+ QTextDocument *doc = browser->document();
+ QString oldText = ui.editFind->text();
+ QTextCursor c = browser->textCursor();
+ QTextDocument::FindFlags options;
+ QPalette p = ui.editFind->palette();
+ p.setColor(QPalette::Active, QPalette::Base, Qt::white);
+
+ if (c.hasSelection())
+ c.setPosition(forward ? c.position() : c.anchor(), QTextCursor::MoveAnchor);
+
+ QTextCursor newCursor = c;
+
+ if (!ttf.isEmpty()) {
+ if (backward)
+ options |= QTextDocument::FindBackward;
+
+ if (ui.checkCase->isChecked())
+ options |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWholeWords->isChecked())
+ options |= QTextDocument::FindWholeWords;
+
+ newCursor = doc->find(ttf, c, options);
+ ui.labelWrapped->hide();
+
+ if (newCursor.isNull()) {
+ QTextCursor ac(doc);
+ ac.movePosition(options & QTextDocument::FindBackward
+ ? QTextCursor::End : QTextCursor::Start);
+ newCursor = doc->find(ttf, ac, options);
+ if (newCursor.isNull()) {
+ p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
+ newCursor = c;
+ } else
+ ui.labelWrapped->show();
+ }
+ }
+
+ if (!ui.frameFind->isVisible())
+ ui.frameFind->show();
+ browser->setTextCursor(newCursor);
+ ui.editFind->setPalette(p);
+ if (!ui.editFind->hasFocus())
+ autoHideTimer->start();
+}
+
+bool TabbedBrowser::eventFilter(QObject *o, QEvent *e)
+{
+ if (o == ui.editFind) {
+ if (e->type() == QEvent::FocusIn && autoHideTimer->isActive())
+ autoHideTimer->stop();
+ } else if (e->type() == QEvent::KeyPress && ui.frameFind->isVisible()) { // assume textbrowser
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (ke->key() == Qt::Key_Space) {
+ keyPressEvent(ke);
+ return true;
+ }
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void TabbedBrowser::openTabMenu(const QPoint& pos)
+{
+ QTabBar *tabBar = qFindChild<QTabBar*>(ui.tab);
+
+ QMenu m(QLatin1String(""), tabBar);
+ QAction *new_action = m.addAction(tr("New Tab"));
+ QAction *close_action = m.addAction(tr("Close Tab"));
+ QAction *close_others_action = m.addAction(tr("Close Other Tabs"));
+
+ if (tabBar->count() == 1) {
+ close_action->setEnabled(false);
+ close_others_action->setEnabled(false);
+ }
+
+ QAction *action_picked = m.exec(tabBar->mapToGlobal(pos));
+ if (!action_picked)
+ return;
+
+ if (action_picked == new_action) {
+ newTab();
+ return;
+ }
+
+ QList<HelpWindow*> windowList = browsers();
+ for (int i = 0; i < tabBar->count(); ++i) {
+ if (tabBar->tabRect(i).contains(pos)) {
+ HelpWindow *win = static_cast<HelpWindow*>(ui.tab->widget(i));
+ if (action_picked == close_action) {
+ mainWindow()->removePendingBrowser(win);
+ QTimer::singleShot(0, win, SLOT(deleteLater()));
+ }
+ windowList.removeOne(win);
+ break;
+ }
+ }
+
+ if (action_picked == close_others_action) {
+ foreach (HelpWindow* win, windowList) {
+ mainWindow()->removePendingBrowser(win);
+ QTimer::singleShot(0, win, SLOT(deleteLater()));
+ windowList.removeOne(win);
+ }
+ }
+
+ ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(windowList.count() > 1);
+ emit tabCountChanged(windowList.count());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/tabbedbrowser.h b/tools/assistant/compat/tabbedbrowser.h
new file mode 100644
index 0000000..0e26bed
--- /dev/null
+++ b/tools/assistant/compat/tabbedbrowser.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABBEDBROWSER_H
+#define TABBEDBROWSER_H
+
+#include "ui_tabbedbrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class MainWindow;
+class HelpWindow;
+class QStyleSheet;
+class QMimeSourceFactory;
+class QTimer;
+
+class TabbedBrowser : public QWidget
+{
+ Q_OBJECT
+public:
+ TabbedBrowser(MainWindow *parent);
+ virtual ~TabbedBrowser();
+
+ MainWindow *mainWindow() const;
+ HelpWindow *currentBrowser() const;
+ QStringList sources() const;
+ QList<HelpWindow*> browsers() const;
+
+ HelpWindow* newBackgroundTab();
+ HelpWindow* createHelpWindow();
+
+ void setTitle(HelpWindow*, const QString &);
+
+signals:
+ void tabCountChanged(int count);
+ void browserUrlChanged(const QString &link);
+
+protected:
+ void keyPressEvent(QKeyEvent *);
+ bool eventFilter(QObject *o, QEvent *e);
+
+public slots:
+ void init();
+ void forward();
+ void backward();
+ void setSource(const QString &ref);
+ void reload();
+ void home();
+ void nextTab();
+ void previousTab();
+ void newTab(const QString &lnk);
+ void zoomIn();
+ void zoomOut();
+ void updateTitle(const QString &title);
+ void newTab();
+ void transferFocus();
+ void initHelpWindow(HelpWindow *win);
+ void setup();
+ void copy();
+ void closeTab();
+ void sourceChanged();
+
+ void find();
+ void findNext();
+ void findPrevious();
+
+private slots:
+ void find(QString, bool forward = false, bool backward = false);
+ void openTabMenu(const QPoint& pos);
+
+private:
+ Ui::TabbedBrowser ui;
+ QWidget *lastCurrentTab;
+ QFont tabFont;
+
+ QString fixedFontFam;
+ QColor lnkColor;
+ bool underlineLnk;
+ QTimer *autoHideTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // TABBEDBROWSER_H
diff --git a/tools/assistant/compat/tabbedbrowser.ui b/tools/assistant/compat/tabbedbrowser.ui
new file mode 100644
index 0000000..acb38f3
--- /dev/null
+++ b/tools/assistant/compat/tabbedbrowser.ui
@@ -0,0 +1,233 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>TabbedBrowser</class>
+ <widget class="QWidget" name="TabbedBrowser" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>710</width>
+ <height>664</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>TabbedBrowser</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tab" >
+ <widget class="QWidget" name="frontpage" >
+ <attribute name="title" >
+ <string>Untitled</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frameFind" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="toolClose" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/close.png</iconset>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="editFind" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolPrevious" >
+ <property name="text" >
+ <string>Previous</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/previous.png</iconset>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolNext" >
+ <property name="minimumSize" >
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Next</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/next.png</iconset>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ <property name="arrowType" >
+ <enum>Qt::NoArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkCase" >
+ <property name="text" >
+ <string>Case Sensitive</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkWholeWords" >
+ <property name="text" >
+ <string>Whole words</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelWrapped" >
+ <property name="minimumSize" >
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>105</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>&lt;img src=":/trolltech/assistant/images/wrap.png">&amp;nbsp;Search wrapped</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="scaledContents" >
+ <bool>true</bool>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>81</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="assistant.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/assistant/compat/topicchooser.cpp b/tools/assistant/compat/topicchooser.cpp
new file mode 100644
index 0000000..7333cb3
--- /dev/null
+++ b/tools/assistant/compat/topicchooser.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "topicchooser.h"
+
+#include <QLabel>
+#include <QListWidget>
+#include <QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+TopicChooser::TopicChooser(QWidget *parent, const QStringList &lnkNames,
+ const QStringList &lnks, const QString &title)
+ : QDialog(parent), links(lnks), linkNames(lnkNames)
+{
+ ui.setupUi(this);
+
+ ui.label->setText(tr("Choose a topic for <b>%1</b>").arg(title));
+ ui.listbox->addItems(linkNames);
+ if (ui.listbox->count() != 0)
+ ui.listbox->setCurrentRow(0);
+ ui.listbox->setFocus();
+}
+
+QString TopicChooser::link() const
+{
+ if (ui.listbox->currentRow() == -1)
+ return QString();
+ QString s = ui.listbox->item(ui.listbox->currentRow())->text();
+ if (s.isEmpty())
+ return s;
+ int i = linkNames.indexOf(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;
+}
+
+void TopicChooser::on_buttonDisplay_clicked()
+{
+ accept();
+}
+
+void TopicChooser::on_buttonCancel_clicked()
+{
+ reject();
+}
+
+void TopicChooser::on_listbox_itemActivated(QListWidgetItem *item)
+{
+ Q_UNUSED(item);
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/topicchooser.h b/tools/assistant/compat/topicchooser.h
new file mode 100644
index 0000000..122a233
--- /dev/null
+++ b/tools/assistant/compat/topicchooser.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOPICCHOOSER_H
+#define TOPICCHOOSER_H
+
+#include "ui_topicchooser.h"
+
+#include <QDialog>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class TopicChooser : public QDialog
+{
+ 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 slots:
+ void on_buttonDisplay_clicked();
+ void on_buttonCancel_clicked();
+ void on_listbox_itemActivated(QListWidgetItem *item);
+
+private:
+ Ui::TopicChooser ui;
+ QString theLink;
+ QStringList links, linkNames;
+};
+
+#endif // TOPICCHOOSER_H
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/topicchooser.ui b/tools/assistant/compat/topicchooser.ui
new file mode 100644
index 0000000..a26eeb8
--- /dev/null
+++ b/tools/assistant/compat/topicchooser.ui
@@ -0,0 +1,162 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>TopicChooser</class>
+ <widget class="QDialog" name="TopicChooser" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>391</width>
+ <height>223</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Choose Topic</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Select a topic from the list and click the &lt;b>Display&lt;/b>-button to open the online help.</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&amp;Topics</string>
+ </property>
+ <property name="buddy" >
+ <cstring>listbox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listbox" >
+ <property name="whatsThis" >
+ <string>Displays a list of available help topics for the keyword.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDisplay" >
+ <property name="whatsThis" >
+ <string>Open the topic selected in the list.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Display</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="whatsThis" >
+ <string>Close the Dialog.</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/compat/translations/translations.pro b/tools/assistant/compat/translations/translations.pro
new file mode 100644
index 0000000..19fcc06
--- /dev/null
+++ b/tools/assistant/compat/translations/translations.pro
@@ -0,0 +1,34 @@
+# Include those manually as they do not contain any directory specification
+
+FORMS += ../helpdialog.ui \
+ ../mainwindow.ui \
+ ../tabbedbrowser.ui \
+ ../topicchooser.ui
+
+SOURCES += ../main.cpp \
+ ../helpwindow.cpp \
+ ../topicchooser.cpp \
+ ../docuparser.cpp \
+ ../index.cpp \
+ ../profile.cpp \
+ ../config.cpp \
+ ../helpdialog.cpp \
+ ../mainwindow.cpp \
+ ../tabbedbrowser.cpp \
+ ../fontsettingsdialog.cpp
+
+SOURCES += ../../../shared/fontpanel/fontpanel.cpp
+
+HEADERS += ../helpwindow.h \
+ ../topicchooser.h \
+ ../docuparser.h \
+ ../index.h \
+ ../profile.h \
+ ../helpdialog.h \
+ ../mainwindow.h \
+ ../tabbedbrowser.h \
+ ../config.h \
+ ../fontsettingsdialog.h
+
+
+TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_de.ts $$[QT_INSTALL_TRANSLATIONS]/assistant_untranslated.ts