summaryrefslogtreecommitdiffstats
path: root/tools/assistant
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 10:18:55 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 10:18:55 +0100
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tools/assistant
Long live Qt 4.5!
Diffstat (limited to 'tools/assistant')
-rw-r--r--tools/assistant/assistant.pro8
-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
-rw-r--r--tools/assistant/lib/fulltextsearch/fulltextsearch.pri161
-rw-r--r--tools/assistant/lib/fulltextsearch/fulltextsearch.pro50
-rw-r--r--tools/assistant/lib/fulltextsearch/license.txt503
-rw-r--r--tools/assistant/lib/fulltextsearch/qanalyzer.cpp201
-rw-r--r--tools/assistant/lib/fulltextsearch/qanalyzer_p.h145
-rw-r--r--tools/assistant/lib/fulltextsearch/qclucene-config_p.h552
-rw-r--r--tools/assistant/lib/fulltextsearch/qclucene_global_p.h127
-rw-r--r--tools/assistant/lib/fulltextsearch/qdocument.cpp172
-rw-r--r--tools/assistant/lib/fulltextsearch/qdocument_p.h93
-rw-r--r--tools/assistant/lib/fulltextsearch/qfield.cpp163
-rw-r--r--tools/assistant/lib/fulltextsearch/qfield_p.h112
-rw-r--r--tools/assistant/lib/fulltextsearch/qfilter.cpp49
-rw-r--r--tools/assistant/lib/fulltextsearch/qfilter_p.h68
-rw-r--r--tools/assistant/lib/fulltextsearch/qhits.cpp86
-rw-r--r--tools/assistant/lib/fulltextsearch/qhits_p.h79
-rw-r--r--tools/assistant/lib/fulltextsearch/qindexreader.cpp161
-rw-r--r--tools/assistant/lib/fulltextsearch/qindexreader_p.h108
-rw-r--r--tools/assistant/lib/fulltextsearch/qindexwriter.cpp183
-rw-r--r--tools/assistant/lib/fulltextsearch/qindexwriter_p.h117
-rw-r--r--tools/assistant/lib/fulltextsearch/qquery.cpp350
-rw-r--r--tools/assistant/lib/fulltextsearch/qquery_p.h181
-rw-r--r--tools/assistant/lib/fulltextsearch/qqueryparser.cpp168
-rw-r--r--tools/assistant/lib/fulltextsearch/qqueryparser_p.h102
-rw-r--r--tools/assistant/lib/fulltextsearch/qreader.cpp94
-rw-r--r--tools/assistant/lib/fulltextsearch/qreader_p.h97
-rw-r--r--tools/assistant/lib/fulltextsearch/qsearchable.cpp195
-rw-r--r--tools/assistant/lib/fulltextsearch/qsearchable_p.h128
-rw-r--r--tools/assistant/lib/fulltextsearch/qsort.cpp89
-rw-r--r--tools/assistant/lib/fulltextsearch/qsort_p.h77
-rw-r--r--tools/assistant/lib/fulltextsearch/qterm.cpp126
-rw-r--r--tools/assistant/lib/fulltextsearch/qterm_p.h93
-rw-r--r--tools/assistant/lib/fulltextsearch/qtoken.cpp142
-rw-r--r--tools/assistant/lib/fulltextsearch/qtoken_p.h105
-rw-r--r--tools/assistant/lib/fulltextsearch/qtokenizer.cpp110
-rw-r--r--tools/assistant/lib/fulltextsearch/qtokenizer_p.h90
-rw-r--r--tools/assistant/lib/fulltextsearch/qtokenstream.cpp59
-rw-r--r--tools/assistant/lib/fulltextsearch/qtokenstream_p.h88
-rw-r--r--tools/assistant/lib/helpsystem.qrc8
-rw-r--r--tools/assistant/lib/images/1leftarrow.pngbin0 -> 669 bytes
-rw-r--r--tools/assistant/lib/images/1rightarrow.pngbin0 -> 706 bytes
-rw-r--r--tools/assistant/lib/images/3leftarrow.pngbin0 -> 832 bytes
-rw-r--r--tools/assistant/lib/images/3rightarrow.pngbin0 -> 820 bytes
-rw-r--r--tools/assistant/lib/lib.pro65
-rw-r--r--tools/assistant/lib/qhelp_global.h124
-rw-r--r--tools/assistant/lib/qhelpcollectionhandler.cpp595
-rw-r--r--tools/assistant/lib/qhelpcollectionhandler_p.h123
-rw-r--r--tools/assistant/lib/qhelpcontentwidget.cpp585
-rw-r--r--tools/assistant/lib/qhelpcontentwidget.h146
-rw-r--r--tools/assistant/lib/qhelpdatainterface.cpp273
-rw-r--r--tools/assistant/lib/qhelpdatainterface_p.h155
-rw-r--r--tools/assistant/lib/qhelpdbreader.cpp580
-rw-r--r--tools/assistant/lib/qhelpdbreader_p.h128
-rw-r--r--tools/assistant/lib/qhelpengine.cpp212
-rw-r--r--tools/assistant/lib/qhelpengine.h84
-rw-r--r--tools/assistant/lib/qhelpengine_p.h144
-rw-r--r--tools/assistant/lib/qhelpenginecore.cpp727
-rw-r--r--tools/assistant/lib/qhelpenginecore.h136
-rw-r--r--tools/assistant/lib/qhelpgenerator.cpp823
-rw-r--r--tools/assistant/lib/qhelpgenerator_p.h117
-rw-r--r--tools/assistant/lib/qhelpindexwidget.cpp445
-rw-r--r--tools/assistant/lib/qhelpindexwidget.h114
-rw-r--r--tools/assistant/lib/qhelpprojectdata.cpp374
-rw-r--r--tools/assistant/lib/qhelpprojectdata_p.h89
-rw-r--r--tools/assistant/lib/qhelpsearchengine.cpp445
-rw-r--r--tools/assistant/lib/qhelpsearchengine.h121
-rw-r--r--tools/assistant/lib/qhelpsearchindex_default.cpp60
-rw-r--r--tools/assistant/lib/qhelpsearchindex_default_p.h149
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene.cpp392
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene_p.h121
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_default.cpp653
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_default_p.h165
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp481
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h123
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_default.cpp385
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_default_p.h132
-rw-r--r--tools/assistant/lib/qhelpsearchquerywidget.cpp353
-rw-r--r--tools/assistant/lib/qhelpsearchquerywidget.h87
-rw-r--r--tools/assistant/lib/qhelpsearchresultwidget.cpp439
-rw-r--r--tools/assistant/lib/qhelpsearchresultwidget.h84
-rw-r--r--tools/assistant/tools/assistant/Info_mac.plist18
-rw-r--r--tools/assistant/tools/assistant/aboutdialog.cpp171
-rw-r--r--tools/assistant/tools/assistant/aboutdialog.h91
-rw-r--r--tools/assistant/tools/assistant/assistant.icnsbin0 -> 162568 bytes
-rw-r--r--tools/assistant/tools/assistant/assistant.icobin0 -> 355574 bytes
-rw-r--r--tools/assistant/tools/assistant/assistant.pro89
-rw-r--r--tools/assistant/tools/assistant/assistant.qchbin0 -> 366592 bytes
-rw-r--r--tools/assistant/tools/assistant/assistant.qrc5
-rw-r--r--tools/assistant/tools/assistant/assistant.rc1
-rw-r--r--tools/assistant/tools/assistant/assistant_images.qrc36
-rw-r--r--tools/assistant/tools/assistant/bookmarkdialog.ui146
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanager.cpp874
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanager.h205
-rw-r--r--tools/assistant/tools/assistant/centralwidget.cpp1080
-rw-r--r--tools/assistant/tools/assistant/centralwidget.h194
-rw-r--r--tools/assistant/tools/assistant/cmdlineparser.cpp320
-rw-r--r--tools/assistant/tools/assistant/cmdlineparser.h99
-rw-r--r--tools/assistant/tools/assistant/contentwindow.cpp173
-rw-r--r--tools/assistant/tools/assistant/contentwindow.h86
-rw-r--r--tools/assistant/tools/assistant/doc/HOWTO17
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qdoc434
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qdocconf17
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qhp22
-rw-r--r--tools/assistant/tools/assistant/doc/classic.css92
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-address-toolbar.pngbin0 -> 2899 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-assistant.pngbin0 -> 105954 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-dockwidgets.pngbin0 -> 50554 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-docwindow.pngbin0 -> 55582 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-examples.pngbin0 -> 9799 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-filter-toolbar.pngbin0 -> 1767 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-preferences-documentation.pngbin0 -> 13417 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-preferences-filters.pngbin0 -> 15561 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-preferences-fonts.pngbin0 -> 13139 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-preferences-options.pngbin0 -> 14255 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-search.pngbin0 -> 59254 bytes
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-toolbar.pngbin0 -> 6532 bytes
-rw-r--r--tools/assistant/tools/assistant/filternamedialog.cpp73
-rw-r--r--tools/assistant/tools/assistant/filternamedialog.h67
-rw-r--r--tools/assistant/tools/assistant/filternamedialog.ui67
-rw-r--r--tools/assistant/tools/assistant/helpviewer.cpp556
-rw-r--r--tools/assistant/tools/assistant/helpviewer.h169
-rw-r--r--tools/assistant/tools/assistant/images/assistant-128.pngbin0 -> 6448 bytes
-rw-r--r--tools/assistant/tools/assistant/images/assistant.pngbin0 -> 2034 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/addtab.pngbin0 -> 469 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/book.pngbin0 -> 1477 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/closetab.pngbin0 -> 516 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/find.pngbin0 -> 1836 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/home.pngbin0 -> 1807 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/next.pngbin0 -> 1310 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/previous.pngbin0 -> 1080 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/print.pngbin0 -> 2087 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/resetzoom.pngbin0 -> 1567 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/synctoc.pngbin0 -> 1838 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--tools/assistant/tools/assistant/images/mac/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--tools/assistant/tools/assistant/images/trolltech-logo.pngbin0 -> 10096 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/addtab.pngbin0 -> 314 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/book.pngbin0 -> 1109 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/closetab.pngbin0 -> 375 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/find.pngbin0 -> 1944 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/home.pngbin0 -> 1414 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/previous.pngbin0 -> 898 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/print.pngbin0 -> 1456 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/resetzoom.pngbin0 -> 1134 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/synctoc.pngbin0 -> 1235 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--tools/assistant/tools/assistant/images/win/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--tools/assistant/tools/assistant/images/wrap.pngbin0 -> 500 bytes
-rw-r--r--tools/assistant/tools/assistant/indexwindow.cpp216
-rw-r--r--tools/assistant/tools/assistant/indexwindow.h90
-rw-r--r--tools/assistant/tools/assistant/installdialog.cpp338
-rw-r--r--tools/assistant/tools/assistant/installdialog.h101
-rw-r--r--tools/assistant/tools/assistant/installdialog.ui118
-rw-r--r--tools/assistant/tools/assistant/main.cpp318
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp1008
-rw-r--r--tools/assistant/tools/assistant/mainwindow.h172
-rw-r--r--tools/assistant/tools/assistant/preferencesdialog.cpp453
-rw-r--r--tools/assistant/tools/assistant/preferencesdialog.h106
-rw-r--r--tools/assistant/tools/assistant/preferencesdialog.ui310
-rw-r--r--tools/assistant/tools/assistant/qtdocinstaller.cpp151
-rw-r--r--tools/assistant/tools/assistant/qtdocinstaller.h77
-rw-r--r--tools/assistant/tools/assistant/remotecontrol.cpp283
-rw-r--r--tools/assistant/tools/assistant/remotecontrol.h84
-rw-r--r--tools/assistant/tools/assistant/remotecontrol_win.h68
-rw-r--r--tools/assistant/tools/assistant/searchwidget.cpp246
-rw-r--r--tools/assistant/tools/assistant/searchwidget.h90
-rw-r--r--tools/assistant/tools/assistant/topicchooser.cpp86
-rw-r--r--tools/assistant/tools/assistant/topicchooser.h72
-rw-r--r--tools/assistant/tools/assistant/topicchooser.ui116
-rw-r--r--tools/assistant/tools/qcollectiongenerator/main.cpp559
-rw-r--r--tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro14
-rw-r--r--tools/assistant/tools/qhelpconverter/adpreader.cpp171
-rw-r--r--tools/assistant/tools/qhelpconverter/adpreader.h90
-rw-r--r--tools/assistant/tools/qhelpconverter/assistant-128.pngbin0 -> 6448 bytes
-rw-r--r--tools/assistant/tools/qhelpconverter/assistant.pngbin0 -> 2034 bytes
-rw-r--r--tools/assistant/tools/qhelpconverter/conversionwizard.cpp265
-rw-r--r--tools/assistant/tools/qhelpconverter/conversionwizard.h96
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/filespage.html8
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/filterpage.html13
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/generalpage.html10
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/identifierpage.html17
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/inputpage.html7
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/outputpage.html7
-rw-r--r--tools/assistant/tools/qhelpconverter/doc/pathpage.html8
-rw-r--r--tools/assistant/tools/qhelpconverter/filespage.cpp112
-rw-r--r--tools/assistant/tools/qhelpconverter/filespage.h73
-rw-r--r--tools/assistant/tools/qhelpconverter/filespage.ui79
-rw-r--r--tools/assistant/tools/qhelpconverter/filterpage.cpp147
-rw-r--r--tools/assistant/tools/qhelpconverter/filterpage.h79
-rw-r--r--tools/assistant/tools/qhelpconverter/filterpage.ui125
-rw-r--r--tools/assistant/tools/qhelpconverter/finishpage.cpp76
-rw-r--r--tools/assistant/tools/qhelpconverter/finishpage.h65
-rw-r--r--tools/assistant/tools/qhelpconverter/generalpage.cpp92
-rw-r--r--tools/assistant/tools/qhelpconverter/generalpage.h66
-rw-r--r--tools/assistant/tools/qhelpconverter/generalpage.ui69
-rw-r--r--tools/assistant/tools/qhelpconverter/helpwindow.cpp84
-rw-r--r--tools/assistant/tools/qhelpconverter/helpwindow.h65
-rw-r--r--tools/assistant/tools/qhelpconverter/identifierpage.cpp71
-rw-r--r--tools/assistant/tools/qhelpconverter/identifierpage.h66
-rw-r--r--tools/assistant/tools/qhelpconverter/identifierpage.ui132
-rw-r--r--tools/assistant/tools/qhelpconverter/inputpage.cpp103
-rw-r--r--tools/assistant/tools/qhelpconverter/inputpage.h71
-rw-r--r--tools/assistant/tools/qhelpconverter/inputpage.ui79
-rw-r--r--tools/assistant/tools/qhelpconverter/main.cpp62
-rw-r--r--tools/assistant/tools/qhelpconverter/outputpage.cpp110
-rw-r--r--tools/assistant/tools/qhelpconverter/outputpage.h71
-rw-r--r--tools/assistant/tools/qhelpconverter/outputpage.ui95
-rw-r--r--tools/assistant/tools/qhelpconverter/pathpage.cpp112
-rw-r--r--tools/assistant/tools/qhelpconverter/pathpage.h71
-rw-r--r--tools/assistant/tools/qhelpconverter/pathpage.ui114
-rw-r--r--tools/assistant/tools/qhelpconverter/qhcpwriter.cpp145
-rw-r--r--tools/assistant/tools/qhelpconverter/qhcpwriter.h70
-rw-r--r--tools/assistant/tools/qhelpconverter/qhelpconverter.pro47
-rw-r--r--tools/assistant/tools/qhelpconverter/qhelpconverter.qrc13
-rw-r--r--tools/assistant/tools/qhelpconverter/qhpwriter.cpp184
-rw-r--r--tools/assistant/tools/qhelpconverter/qhpwriter.h85
-rw-r--r--tools/assistant/tools/qhelpgenerator/main.cpp144
-rw-r--r--tools/assistant/tools/qhelpgenerator/qhelpgenerator.pro14
-rw-r--r--tools/assistant/tools/shared/helpgenerator.cpp79
-rw-r--r--tools/assistant/tools/shared/helpgenerator.h72
-rw-r--r--tools/assistant/tools/tools.pro8
-rw-r--r--tools/assistant/translations/qt_help.pro49
-rw-r--r--tools/assistant/translations/translations.pro49
-rw-r--r--tools/assistant/translations/translations_adp.pro41
298 files changed, 38928 insertions, 0 deletions
diff --git a/tools/assistant/assistant.pro b/tools/assistant/assistant.pro
new file mode 100644
index 0000000000..08d0d4b8f1
--- /dev/null
+++ b/tools/assistant/assistant.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += lib/fulltextsearch \
+ lib \
+ tools \
+ compat \
+ compat/lib \ \ No newline at end of file
diff --git a/tools/assistant/compat/Info_mac.plist b/tools/assistant/compat/Info_mac.plist
new file mode 100644
index 0000000000..b1e6336fb0
--- /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 0000000000..b6e1c33e04
--- /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 0000000000..6291dd3975
--- /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 0000000000..9e1b83f1b6
--- /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 0000000000..e865d6b7a6
--- /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 0000000000..dae1f48ad0
--- /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 0000000000..b4786ceaaf
--- /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 0000000000..1086f4c825
--- /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 0000000000..b2eba11570
--- /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 0000000000..0858ad88a6
--- /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 0000000000..31e10407fd
--- /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 0000000000..181a8f1e70
--- /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 0000000000..cd0cc06328
--- /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 0000000000..e4607aa786
--- /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 0000000000..4ea97d0ec8
--- /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 0000000000..29d77d9cb7
--- /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 0000000000..acd1372f0c
--- /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 0000000000..d3ddc29bd1
--- /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 0000000000..f1327b5c07
--- /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 0000000000..f05949f6d8
--- /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 0000000000..ea4d1e70c1
--- /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 0000000000..540694eae3
--- /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 0000000000..72c42e73e4
--- /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 0000000000..d388cbd0ba
--- /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 0000000000..20928fb402
--- /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 0000000000..7a3204c870
--- /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 0000000000..ab9d669eee
--- /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 0000000000..f551364464
--- /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 0000000000..3561745f01
--- /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 0000000000..78d94da18d
--- /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 0000000000..a585cab80c
--- /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 0000000000..612fb34dce
--- /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 0000000000..10ca56c82a
--- /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 0000000000..067fa941b5
--- /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 0000000000..5b7078fffd
--- /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 0000000000..d46f5aff0d
--- /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 0000000000..46326566d1
--- /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 0000000000..2dc67161c1
--- /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 0000000000..4bb0feb92d
--- /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 0000000000..09ec4d33f7
--- /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 0000000000..ef9e02086c
--- /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 0000000000..1121b47d8b
--- /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 0000000000..6ea35e930d
--- /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 0000000000..b1c6ae1913
--- /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 0000000000..8df4127a00
--- /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 0000000000..0780bc23dd
--- /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 0000000000..ba7c02dc18
--- /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 0000000000..da301bc599
--- /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 0000000000..623cad6876
--- /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 0000000000..2e586fc7bf
--- /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 0000000000..a736d39343
--- /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 0000000000..90f18d9f77
--- /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 0000000000..e98b00bacf
--- /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 0000000000..9fc30afa7d
--- /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 0000000000..d4b5a47b2a
--- /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 0000000000..25fbd6c399
--- /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 0000000000..d76246f0b6
--- /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 0000000000..3ae8bb29c8
--- /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 0000000000..66095729c6
--- /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 0000000000..65759ade6c
--- /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 0000000000..2073f0d210
--- /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 0000000000..803a4dc04d
--- /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 0000000000..10b1737c94
--- /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 0000000000..24aef3e878
--- /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 0000000000..198be4a3e4
--- /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 0000000000..0e26bede07
--- /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 0000000000..acb38f3bf0
--- /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 0000000000..7333cb38c5
--- /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 0000000000..122a233308
--- /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 0000000000..a26eeb8d63
--- /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 0000000000..19fcc06a6d
--- /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
diff --git a/tools/assistant/lib/fulltextsearch/fulltextsearch.pri b/tools/assistant/lib/fulltextsearch/fulltextsearch.pri
new file mode 100644
index 0000000000..134678feb6
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/fulltextsearch.pri
@@ -0,0 +1,161 @@
+DEFINES += _BUILD_FOR_QT_ LUCENE_DISABLE_MEMTRACKING
+win32:DEFINES += _CRT_SECURE_NO_DEPRECATE _MT
+
+CLUCENEDIR = ../../../../src/3rdparty/clucene/src/CLucene
+
+INCLUDEPATH += . .. \
+ $$CLUCENEDIR \
+ $$CLUCENEDIR/../ \
+ $$CLUCENEDIR/analysis \
+ $$CLUCENEDIR/analysis/standard \
+ $$CLUCENEDIR/config \
+ $$CLUCENEDIR/debug \
+ $$CLUCENEDIR/document \
+ $$CLUCENEDIR/index \
+ $$CLUCENEDIR/queryParser \
+ $$CLUCENEDIR/search \
+ $$CLUCENEDIR/store \
+ $$CLUCENEDIR/util
+
+
+SOURCES += $$CLUCENEDIR/StdHeader.cpp \
+ $$CLUCENEDIR/analysis/AnalysisHeader.cpp \
+ $$CLUCENEDIR/analysis/Analyzers.cpp \
+ $$CLUCENEDIR/config/gunichartables.cpp \
+ $$CLUCENEDIR/config/repl_lltot.cpp \
+ $$CLUCENEDIR/config/repl_tcscasecmp.cpp \
+ $$CLUCENEDIR/config/repl_tcslwr.cpp \
+ $$CLUCENEDIR/config/repl_tcstod.cpp \
+ $$CLUCENEDIR/config/repl_tcstoll.cpp \
+ $$CLUCENEDIR/config/repl_tprintf.cpp \
+ $$CLUCENEDIR/config/threads.cpp \
+ $$CLUCENEDIR/config/utf8.cpp \
+ $$CLUCENEDIR/debug/condition.cpp \
+ $$CLUCENEDIR/debug/error.cpp \
+ $$CLUCENEDIR/debug/memtracking.cpp \
+ $$CLUCENEDIR/document/DateField.cpp \
+ $$CLUCENEDIR/document/Document.cpp \
+ $$CLUCENEDIR/document/Field.cpp \
+ $$CLUCENEDIR/index/CompoundFile.cpp \
+ $$CLUCENEDIR/index/DocumentWriter.cpp \
+ $$CLUCENEDIR/index/FieldInfos.cpp \
+ $$CLUCENEDIR/index/FieldsReader.cpp \
+ $$CLUCENEDIR/index/FieldsWriter.cpp \
+ $$CLUCENEDIR/index/IndexModifier.cpp \
+ $$CLUCENEDIR/index/IndexReader.cpp \
+ $$CLUCENEDIR/index/IndexWriter.cpp \
+ $$CLUCENEDIR/index/MultiReader.cpp \
+ $$CLUCENEDIR/index/SegmentInfos.cpp \
+ $$CLUCENEDIR/index/SegmentMergeInfo.cpp \
+ $$CLUCENEDIR/index/SegmentMergeQueue.cpp \
+ $$CLUCENEDIR/index/SegmentMerger.cpp \
+ $$CLUCENEDIR/index/SegmentReader.cpp \
+ $$CLUCENEDIR/index/SegmentTermDocs.cpp \
+ $$CLUCENEDIR/index/SegmentTermEnum.cpp \
+ $$CLUCENEDIR/index/SegmentTermPositions.cpp \
+ $$CLUCENEDIR/index/SegmentTermVector.cpp \
+ $$CLUCENEDIR/index/Term.cpp \
+ $$CLUCENEDIR/index/TermInfo.cpp \
+ $$CLUCENEDIR/index/TermInfosReader.cpp \
+ $$CLUCENEDIR/index/TermInfosWriter.cpp \
+ $$CLUCENEDIR/index/TermVectorReader.cpp \
+ $$CLUCENEDIR/index/TermVectorWriter.cpp \
+ $$CLUCENEDIR/queryParser/Lexer.cpp \
+ $$CLUCENEDIR/queryParser/MultiFieldQueryParser.cpp \
+ $$CLUCENEDIR/queryParser/QueryParser.cpp \
+ $$CLUCENEDIR/queryParser/QueryParserBase.cpp \
+ $$CLUCENEDIR/queryParser/QueryToken.cpp \
+ $$CLUCENEDIR/queryParser/TokenList.cpp \
+ $$CLUCENEDIR/search/BooleanQuery.cpp \
+ $$CLUCENEDIR/search/BooleanScorer.cpp \
+ $$CLUCENEDIR/search/CachingWrapperFilter.cpp \
+ $$CLUCENEDIR/search/ChainedFilter.cpp \
+ $$CLUCENEDIR/search/ConjunctionScorer.cpp \
+ $$CLUCENEDIR/search/DateFilter.cpp \
+ $$CLUCENEDIR/search/ExactPhraseScorer.cpp \
+ $$CLUCENEDIR/search/Explanation.cpp \
+ $$CLUCENEDIR/search/FieldCache.cpp \
+ $$CLUCENEDIR/search/FieldCacheImpl.cpp \
+ $$CLUCENEDIR/search/FieldDocSortedHitQueue.cpp \
+ $$CLUCENEDIR/search/FieldSortedHitQueue.cpp \
+ $$CLUCENEDIR/search/FilteredTermEnum.cpp \
+ $$CLUCENEDIR/search/FuzzyQuery.cpp \
+ $$CLUCENEDIR/search/HitQueue.cpp \
+ $$CLUCENEDIR/search/Hits.cpp \
+ $$CLUCENEDIR/search/IndexSearcher.cpp \
+ $$CLUCENEDIR/search/MultiSearcher.cpp \
+ $$CLUCENEDIR/search/MultiTermQuery.cpp \
+ $$CLUCENEDIR/search/PhrasePositions.cpp \
+ $$CLUCENEDIR/search/PhraseQuery.cpp \
+ $$CLUCENEDIR/search/PhraseScorer.cpp \
+ $$CLUCENEDIR/search/PrefixQuery.cpp \
+ $$CLUCENEDIR/search/QueryFilter.cpp \
+ $$CLUCENEDIR/search/RangeFilter.cpp \
+ $$CLUCENEDIR/search/RangeQuery.cpp \
+ $$CLUCENEDIR/search/SearchHeader.cpp \
+ $$CLUCENEDIR/search/Similarity.cpp \
+ $$CLUCENEDIR/search/SloppyPhraseScorer.cpp \
+ $$CLUCENEDIR/search/Sort.cpp \
+ $$CLUCENEDIR/search/TermQuery.cpp \
+ $$CLUCENEDIR/search/TermScorer.cpp \
+ $$CLUCENEDIR/search/WildcardQuery.cpp \
+ $$CLUCENEDIR/search/WildcardTermEnum.cpp \
+ $$CLUCENEDIR/store/FSDirectory.cpp \
+ $$CLUCENEDIR/store/IndexInput.cpp \
+ $$CLUCENEDIR/store/IndexOutput.cpp \
+ $$CLUCENEDIR/store/Lock.cpp \
+ $$CLUCENEDIR/store/MMapInput.cpp \
+ $$CLUCENEDIR/store/RAMDirectory.cpp \
+ $$CLUCENEDIR/store/TransactionalRAMDirectory.cpp \
+ $$CLUCENEDIR/util/BitSet.cpp \
+ $$CLUCENEDIR/util/Equators.cpp \
+ $$CLUCENEDIR/util/FastCharStream.cpp \
+ $$CLUCENEDIR/util/fileinputstream.cpp \
+ $$CLUCENEDIR/util/Misc.cpp \
+ $$CLUCENEDIR/util/Reader.cpp \
+ $$CLUCENEDIR/util/StringBuffer.cpp \
+ $$CLUCENEDIR/util/StringIntern.cpp \
+ $$CLUCENEDIR/util/ThreadLocal.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardAnalyzer.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardFilter.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardTokenizer.cpp
+
+
+#Header files
+HEADERS += qclucene_global_p.h \
+ qclucene-config_p.h \
+ qanalyzer_p.h \
+ qtokenizer_p.h \
+ qtoken_p.h \
+ qtokenstream_p.h \
+ qdocument_p.h \
+ qfield_p.h \
+ qindexreader_p.h \
+ qindexwriter_p.h \
+ qterm_p.h \
+ qqueryparser_p.h \
+ qfilter_p.h \
+ qhits_p.h \
+ qsearchable_p.h \
+ qsort_p.h \
+ qquery_p.h \
+ qreader_p.h
+
+
+#Source files
+SOURCES += qanalyzer.cpp \
+ qtokenizer.cpp \
+ qtoken.cpp \
+ qtokenstream.cpp \
+ qdocument.cpp \
+ qfield.cpp \
+ qindexreader.cpp \
+ qindexwriter.cpp \
+ qterm.cpp \
+ qqueryparser.cpp \
+ qfilter.cpp \
+ qhits.cpp \
+ qsearchable.cpp \
+ qsort.cpp \
+ qquery.cpp \
+ qreader.cpp
diff --git a/tools/assistant/lib/fulltextsearch/fulltextsearch.pro b/tools/assistant/lib/fulltextsearch/fulltextsearch.pro
new file mode 100644
index 0000000000..e0cd13a821
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/fulltextsearch.pro
@@ -0,0 +1,50 @@
+
+QMAKE_TARGET_PRODUCT = QtCLucene
+QMAKE_TARGET_DESCRIPTION = QtCLucene full text search library wrapper.
+#if qt is built with frameworks in debug, we must build QtCLucene in debug and release
+#that's a similar logic as in qbase.pri
+mac:!static:contains(QT_CONFIG, qt_framework) {
+ CONFIG(debug, debug|release) {
+ !build_pass:CONFIG += build_all
+ }
+}
+QT_CONFIG -= qt_framework
+QT -= gui
+TEMPLATE = lib
+TARGET = QtCLucene
+DEFINES += QHELP_LIB
+include(../../../../src/qbase.pri)
+include(fulltextsearch.pri)
+
+CONFIG += qt warn_off
+contains(QT_CONFIG, reduce_exports) {
+ CONFIG += hide_symbols
+ # workaround for compiler errors on Ubuntu
+ linux*-g++*:DEFINES += _GLIBCXX_EXTERN_TEMPLATE=0
+}
+
+unix:QMAKE_PKGCONFIG_REQUIRES = QtCore
+
+# impossible to disable exceptions in clucene atm
+CONFIG(exceptions_off) {
+ CONFIG -= exceptions_off
+ CONFIG += exceptions
+ !win32|win32-g++ {
+ QMAKE_CFLAGS -= -fno-exceptions
+ QMAKE_CXXFLAGS -= -fno-exceptions
+ QMAKE_LFLAGS -= -fno-exceptions
+ QMAKE_CFLAGS += -fexceptions
+ QMAKE_CXXFLAGS += -fexceptions
+ QMAKE_LFLAGS += -fexceptions
+ }
+}
+
+win32-msvc.net | win32-msvc2* {
+ QMAKE_CFLAGS_RELEASE -= -O2
+ QMAKE_CXXFLAGS_RELEASE -= -O2
+}
+
+# the following define could be set globally in case we need it elsewhere
+solaris* {
+ DEFINES += Q_SOLARIS_VERSION=$$system(uname -r | sed -e 's/5\.//')
+}
diff --git a/tools/assistant/lib/fulltextsearch/license.txt b/tools/assistant/lib/fulltextsearch/license.txt
new file mode 100644
index 0000000000..9ef3d701d1
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/license.txt
@@ -0,0 +1,503 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp
new file mode 100644
index 0000000000..e19a0758f0
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qanalyzer_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneAnalyzerPrivate::QCLuceneAnalyzerPrivate()
+ : QSharedData()
+{
+ analyzer = 0;
+ deleteCLuceneAnalyzer = true;
+}
+
+QCLuceneAnalyzerPrivate::QCLuceneAnalyzerPrivate(const QCLuceneAnalyzerPrivate &other)
+ : QSharedData()
+{
+ analyzer = _CL_POINTER(other.analyzer);
+}
+
+QCLuceneAnalyzerPrivate::~QCLuceneAnalyzerPrivate()
+{
+ if (deleteCLuceneAnalyzer)
+ _CLDECDELETE(analyzer);
+}
+
+
+QCLuceneAnalyzer::QCLuceneAnalyzer()
+ : d(new QCLuceneAnalyzerPrivate())
+{
+ //nothing todo, private
+}
+
+QCLuceneAnalyzer::~QCLuceneAnalyzer()
+{
+ // nothing todo
+}
+
+qint32 QCLuceneAnalyzer::positionIncrementGap(const QString &fieldName) const
+{
+ Q_UNUSED(fieldName);
+ return 0;
+}
+
+QCLuceneTokenStream QCLuceneAnalyzer::tokenStream(const QString &fieldName,
+ const QCLuceneReader &reader) const
+{
+ TCHAR *fName = QStringToTChar(fieldName);
+ QCLuceneTokenStream tokenStream;
+ tokenStream.d->tokenStream = d->analyzer->tokenStream(fName, reader.d->reader);
+ delete [] fName;
+
+ return tokenStream;
+}
+
+
+QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::standard::StandardAnalyzer();
+}
+
+QCLuceneStandardAnalyzer::~QCLuceneStandardAnalyzer()
+{
+ // nothing todo
+}
+
+QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer(const QStringList &stopWords)
+{
+ const TCHAR **tArray = new const TCHAR*[stopWords.count() +1];
+
+ for(int i = 0; i < stopWords.count(); ++i) {
+ TCHAR *stopWord = QStringToTChar(stopWords.at(i));
+ tArray[i] = STRDUP_TtoT(stopWord);
+ delete [] stopWord;
+ }
+ tArray[stopWords.count()] = 0;
+
+ d->analyzer = new lucene::analysis::standard::StandardAnalyzer(tArray);
+}
+
+
+QCLuceneWhitespaceAnalyzer::QCLuceneWhitespaceAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::WhitespaceAnalyzer();
+}
+
+QCLuceneWhitespaceAnalyzer::~QCLuceneWhitespaceAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLuceneSimpleAnalyzer::QCLuceneSimpleAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::SimpleAnalyzer();
+}
+
+QCLuceneSimpleAnalyzer::~QCLuceneSimpleAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLuceneStopAnalyzer::QCLuceneStopAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::StopAnalyzer();
+}
+
+QCLuceneStopAnalyzer::~QCLuceneStopAnalyzer()
+{
+ // nothing todo
+}
+
+QCLuceneStopAnalyzer::QCLuceneStopAnalyzer(const QStringList &stopWords)
+ : QCLuceneAnalyzer()
+{
+ const TCHAR **tArray = new const TCHAR*[stopWords.count() +1];
+
+ for(int i = 0; i < stopWords.count(); ++i) {
+ TCHAR *stopWord = QStringToTChar(stopWords.at(i));
+ tArray[i] = STRDUP_TtoT(stopWord);
+ delete [] stopWord;
+ }
+ tArray[stopWords.count()] = 0;
+
+ d->analyzer = new lucene::analysis::StopAnalyzer(tArray);
+}
+
+QStringList QCLuceneStopAnalyzer::englishStopWords() const
+{
+ QStringList stopWordList;
+
+ const TCHAR** stopWords = lucene::analysis::StopAnalyzer::ENGLISH_STOP_WORDS;
+ for (qint32 i = 0; stopWords[i] != 0; ++i)
+ stopWordList.append(TCharToQString(stopWords[i]));
+
+ return stopWordList;
+}
+
+
+QCLuceneKeywordAnalyzer::QCLuceneKeywordAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::KeywordAnalyzer();
+}
+
+QCLuceneKeywordAnalyzer::~QCLuceneKeywordAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLucenePerFieldAnalyzerWrapper::QCLucenePerFieldAnalyzerWrapper(
+ QCLuceneAnalyzer *defaultAnalyzer)
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new
+ lucene::analysis::PerFieldAnalyzerWrapper(defaultAnalyzer->d->analyzer);
+
+ analyzers.append(defaultAnalyzer);
+ defaultAnalyzer->d->deleteCLuceneAnalyzer = false;
+}
+
+QCLucenePerFieldAnalyzerWrapper::~QCLucenePerFieldAnalyzerWrapper()
+{
+ qDeleteAll(analyzers);
+}
+
+void QCLucenePerFieldAnalyzerWrapper::addAnalyzer(const QString &fieldName,
+ QCLuceneAnalyzer *analyzer)
+{
+ lucene::analysis::PerFieldAnalyzerWrapper *analyzerWrapper =
+ static_cast<lucene::analysis::PerFieldAnalyzerWrapper*> (d->analyzer);
+
+ if (analyzerWrapper == 0)
+ return;
+
+ analyzers.append(analyzer);
+ analyzer->d->deleteCLuceneAnalyzer = false;
+
+ TCHAR *fName = QStringToTChar(fieldName);
+ analyzerWrapper->addAnalyzer(fName, analyzer->d->analyzer);
+ delete [] fName;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer_p.h b/tools/assistant/lib/fulltextsearch/qanalyzer_p.h
new file mode 100644
index 0000000000..c0b94f4069
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qanalyzer_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QANALYZER_P_H
+#define QANALYZER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qreader_p.h"
+#include "qtokenstream_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class Analyzer;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+class QCLuceneQueryParser;
+class QCLuceneStopAnalyzer;
+class QCLuceneSimpleAnalyzer;
+class QCLuceneKeywordAnalyzer;
+class QCLuceneStandardAnalyzer;
+class QCLuceneWhitespaceAnalyzer;
+class QCLucenePerFieldAnalyzerWrapper;
+
+class QHELP_EXPORT QCLuceneAnalyzerPrivate : public QSharedData
+{
+public:
+ QCLuceneAnalyzerPrivate();
+ QCLuceneAnalyzerPrivate(const QCLuceneAnalyzerPrivate &other);
+
+ ~QCLuceneAnalyzerPrivate();
+
+ Analyzer *analyzer;
+ bool deleteCLuceneAnalyzer;
+
+private:
+ QCLuceneAnalyzerPrivate &operator=(const QCLuceneAnalyzerPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneAnalyzer
+{
+public:
+ virtual ~QCLuceneAnalyzer();
+
+ qint32 positionIncrementGap(const QString &fieldName) const;
+ QCLuceneTokenStream tokenStream(const QString &fieldName,
+ const QCLuceneReader &reader) const;
+
+protected:
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneStopAnalyzer;
+ friend class QCLuceneSimpleAnalyzer;
+ friend class QCLuceneKeywordAnalyzer;
+ friend class QCLuceneStandardAnalyzer;
+ friend class QCLuceneWhitespaceAnalyzer;
+ friend class QCLucenePerFieldAnalyzerWrapper;
+ QSharedDataPointer<QCLuceneAnalyzerPrivate> d;
+
+private:
+ QCLuceneAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneStandardAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneStandardAnalyzer();
+ QCLuceneStandardAnalyzer(const QStringList &stopWords);
+
+ ~QCLuceneStandardAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneWhitespaceAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneWhitespaceAnalyzer();
+ ~QCLuceneWhitespaceAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneSimpleAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneSimpleAnalyzer();
+ ~QCLuceneSimpleAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneStopAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneStopAnalyzer();
+ QCLuceneStopAnalyzer(const QStringList &stopWords);
+
+ ~QCLuceneStopAnalyzer();
+
+ QStringList englishStopWords() const;
+};
+
+class QHELP_EXPORT QCLuceneKeywordAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneKeywordAnalyzer();
+ ~QCLuceneKeywordAnalyzer();
+};
+
+class QHELP_EXPORT QCLucenePerFieldAnalyzerWrapper : public QCLuceneAnalyzer
+{
+public:
+ QCLucenePerFieldAnalyzerWrapper(QCLuceneAnalyzer *defaultAnalyzer);
+ ~QCLucenePerFieldAnalyzerWrapper();
+
+ void addAnalyzer(const QString &fieldName, QCLuceneAnalyzer *analyzer);
+
+private:
+ QList<QCLuceneAnalyzer*> analyzers;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANALYZER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qclucene-config_p.h b/tools/assistant/lib/fulltextsearch/qclucene-config_p.h
new file mode 100644
index 0000000000..b3befbec5e
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qclucene-config_p.h
@@ -0,0 +1,552 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QCLUCENE_CONFIG_P_H
+#define QCLUCENE_CONFIG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1
+
+/*
+src/CLucene/clucene-config.h.
+Generated
+automatically
+at
+end
+of
+configure.
+*/
+/* config.h.tmp. Generated by configure. */
+/* config.h.tmp.in. Generated from configure.ac by autoheader. */
+
+/* Disable multithreading */
+/* #undef _CL_DISABLE_MULTITHREADING */
+
+/* Define to 1 if you have the <algorithm> header file. */
+#ifndef _CL_HAVE_ALGORITHM
+#define _CL_HAVE_ALGORITHM 1
+#endif
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#ifndef _CL_HAVE_CTYPE_H
+#define _CL_HAVE_CTYPE_H 1
+#endif
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#ifndef _CL_HAVE_DIRENT_H
+#define _CL_HAVE_DIRENT_H 1
+#endif
+
+#if !defined (__MINGW32__)
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+# ifndef _CL_HAVE_DLFCN_H
+# define _CL_HAVE_DLFCN_H 1
+# endif
+#endif
+
+/* Define to 1 if you have the <errno.h> header file. */
+#ifndef _CL_HAVE_ERRNO_H
+#define _CL_HAVE_ERRNO_H 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C)
+ /* Define to 1 if you have the <ext/hash_map> header file. */
+# ifndef _CL_HAVE_EXT_HASH_MAP
+# define _CL_HAVE_EXT_HASH_MAP 1
+# endif
+
+ /* Define to 1 if you have the <ext/hash_set> header file. */
+# ifndef _CL_HAVE_EXT_HASH_SET
+# define _CL_HAVE_EXT_HASH_SET 1
+# endif
+#endif
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#ifndef _CL_HAVE_FCNTL_H
+#define _CL_HAVE_FCNTL_H 1
+#endif
+
+#if !defined(__xlC__) && !defined(__xlc__) && !defined (__MINGW32__) && \
+ !defined(__HP_aCC) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC) || \
+ defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x550) || (defined(__HP_aCC) && defined(__ia64))
+ /* Define to 1 if the system has the type `float_t'. */
+# ifndef _CL_HAVE_FLOAT_T
+# define _CL_HAVE_FLOAT_T 1
+# endif
+#endif
+
+/* Define to 1 if you have the <functional> header file. */
+#ifndef _CL_HAVE_FUNCTIONAL
+#define _CL_HAVE_FUNCTIONAL 1
+#endif
+
+/* Does not support new float byte<->float conversions */
+#ifndef _CL_HAVE_FUNCTIONING_FLOAT_BYTE
+#define _CL_HAVE_FUNCTIONING_FLOAT_BYTE
+#endif
+
+/* Define to 1 if you have the `getpagesize' function. */
+#ifndef _CL_HAVE_GETPAGESIZE
+#define _CL_HAVE_GETPAGESIZE 1
+#endif
+
+/* Define to 1 if you have the <hash_map> header file. */
+/* #undef _CL_HAVE_HASH_MAP */
+
+/* Define to 1 if you have the <hash_set> header file. */
+/* #undef _CL_HAVE_HASH_SET */
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#ifndef _CL_HAVE_INTPTR_T
+#define _CL_HAVE_INTPTR_T 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifndef _CL_HAVE_INTTYPES_H
+#define _CL_HAVE_INTTYPES_H 1
+#endif
+
+/* Define to 1 if you have the <list> header file. */
+#ifndef _CL_HAVE_LIST
+#define _CL_HAVE_LIST 1
+#endif
+
+/* Define to 1 if you have the `lltoa' function. */
+/* #undef _CL_HAVE_LLTOA */
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `lltow' function. */
+# ifndef _CL_HAVE_LLTOW
+# define _CL_HAVE_LLTOW 1
+# endif
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if long double works and has more range or precision than double. */
+# ifndef _CL_HAVE_LONG_DOUBLE
+# define _CL_HAVE_LONG_DOUBLE 1
+# endif
+#endif
+
+/* Define to 1 if you have the <map> header file. */
+#ifndef _CL_HAVE_MAP
+#define _CL_HAVE_MAP 1
+#endif
+
+/* Define to 1 if you have the <math.h> header file. */
+#ifndef _CL_HAVE_MATH_H
+#define _CL_HAVE_MATH_H 1
+#endif
+
+/* Define to 1 if you have the <memory.h> header file. */
+#ifndef _CL_HAVE_MEMORY_H
+#define _CL_HAVE_MEMORY_H 1
+#endif
+
+#if !defined(__MINGW32__) && !defined(__HP_aCC) && !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if you have a working `mmap' system call. */
+# ifndef _CL_HAVE_MMAP
+# define _CL_HAVE_MMAP 1
+# endif
+#endif
+
+/* define if the compiler implements namespaces */
+#ifndef _CL_HAVE_NAMESPACES
+#define _CL_HAVE_NAMESPACES
+#endif
+
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) || defined(__HP_aCC) || defined(__xlC__) || defined(__xlc__)
+ /* Define if you have the nanosleep function */
+# ifndef _CL_HAVE_NANOSLEEP
+# define _CL_HAVE_NANOSLEEP 1
+# endif
+#endif
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef _CL_HAVE_NDIR_H */
+
+/* Does not support new float byte<->float conversions */
+/* #undef _CL_HAVE_NO_FLOAT_BYTE */
+
+/* Does not support try/catch blocks */
+/* #undef _CL_HAVE_NO_FUNCTION_TRY_BLOCKS */
+
+/* Define to 1 if you have the `printf' function. */
+#ifndef _CL_HAVE_PRINTF
+#define _CL_HAVE_PRINTF 1
+#endif
+
+#if !defined(__MINGW32__)
+ /* Define if you have POSIX threads libraries and header files. */
+# ifndef _CL_HAVE_PTHREAD
+# define _CL_HAVE_PTHREAD 1
+# endif
+#endif
+
+/* Define if recursive pthread mutexes are available */
+/* #undef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE */
+
+/* Define to 1 if you have the <set> header file. */
+#ifndef _CL_HAVE_SET
+#define _CL_HAVE_SET 1
+#endif
+
+/* Define to 1 if you have the `snprintf' function. */
+#ifndef _CL_HAVE_SNPRINTF
+#define _CL_HAVE_SNPRINTF 1
+#endif
+
+/* Defined if the snprintf overflow test fails */
+/* #undef _CL_HAVE_SNPRINTF_BUG */
+
+/* Define to 1 if you have the `snwprintf' function. */
+/* #undef _CL_HAVE_SNWPRINTF */
+
+#if !defined(__HP_aCC) && !defined(__SUNPRO_CC) && !defined(__SUNPRO_C)
+ /* define if the compiler supports ISO C++ standard library */
+# ifndef _CL_HAVE_STD
+# define _CL_HAVE_STD
+# endif
+#endif
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#ifndef _CL_HAVE_STDARG_H
+#define _CL_HAVE_STDARG_H 1
+#endif
+
+/* x */
+#ifndef _CL_HAVE_STDEXCEPT
+#define _CL_HAVE_STDEXCEPT
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__HP_aCC) && \
+ !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if you have the <stdint.h> header file. */
+# ifndef _CL_HAVE_STDINT_H
+# define _CL_HAVE_STDINT_H 1
+# endif
+#endif
+
+#if !defined(__HP_aCC)
+ /* Define to 1 if you have the <stdlib.h> header file. */
+# ifndef _CL_HAVE_STDLIB_H
+# define _CL_HAVE_STDLIB_H 1
+# endif
+
+ /* define if the compiler supports Standard Template Library */
+# ifndef _CL_HAVE_STL
+# define _CL_HAVE_STL
+# endif
+#endif
+
+/* Define to 1 if you have the <strings.h> header file. */
+#ifndef _CL_HAVE_STRINGS_H
+#define _CL_HAVE_STRINGS_H 1
+#endif
+
+/* Define to 1 if you have the <string.h> header file. */
+#ifndef _CL_HAVE_STRING_H
+#define _CL_HAVE_STRING_H 1
+#endif
+
+/* Define to 1 if you have the `strlwr' function. */
+/* #undef _CL_HAVE_STRLWR */
+
+/* Define to 1 if you have the `strtoll' function. */
+/* #undef _CL_HAVE_STRTOLL */
+
+/* Define to 1 if you have the `strupr' function. */
+/* #undef _CL_HAVE_STRUPR */
+
+/* Defined if the swprintf test fails */
+#ifndef _CL_HAVE_SWPRINTF_BUG
+#define _CL_HAVE_SWPRINTF_BUG
+#endif
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef _CL_HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef _CL_HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#ifndef _CL_HAVE_SYS_STAT_H
+#define _CL_HAVE_SYS_STAT_H 1
+#endif
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#ifndef _CL_HAVE_SYS_TIMEB_H
+#define _CL_HAVE_SYS_TIMEB_H 1
+#endif
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#ifndef _CL_HAVE_SYS_TYPES_H
+#define _CL_HAVE_SYS_TYPES_H 1
+#endif
+
+// Do not use the tchar.h that ships with mingw, this causes the qt build to
+// fail (211547, 211401, etc...), reuse the replacement as with any other compiler
+// #if defined(__MINGW32__)
+// /* Define to 1 if you have the <tchar.h> header file. */
+// # ifndef _CL_HAVE_TCHAR_H
+// # define _CL_HAVE_TCHAR_H 1
+// # endif
+// #endif
+
+#if defined(__MINGW32__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+ /* Define to 1 if you have the `tell' function. */
+# ifndef _CL_HAVE_TELL
+# define _CL_HAVE_TELL 1
+# endif
+#endif
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#ifndef _CL_HAVE_UNISTD_H
+#define _CL_HAVE_UNISTD_H 1
+#endif
+
+/* Define to 1 if you have the <vector> header file. */
+#ifndef _CL_HAVE_VECTOR
+#define _CL_HAVE_VECTOR 1
+#endif
+
+/* Define to 1 if you have the `vsnwprintf' function. */
+/* #undef _CL_HAVE_VSNWPRINTF */
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#ifndef _CL_HAVE_WCHAR_H
+#define _CL_HAVE_WCHAR_H 1
+#endif
+
+/* Define to 1 if the system has the type `wchar_t'. */
+#ifndef _CL_HAVE_WCHAR_T
+#define _CL_HAVE_WCHAR_T 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__MINGW32__) && \
+ !defined(Q_OS_MAC) && !defined(__HP_aCC)
+ /* Define to 1 if you have the `wcscasecmp' function. */
+# ifndef _CL_HAVE_WCSCASECMP
+# define _CL_HAVE_WCSCASECMP 1
+# endif
+#endif
+
+/* Define to 1 if you have the `wcscat' function. */
+#ifndef _CL_HAVE_WCSCAT
+#define _CL_HAVE_WCSCAT 1
+#endif
+
+/* Define to 1 if you have the `wcschr' function. */
+#ifndef _CL_HAVE_WCSCHR
+#define _CL_HAVE_WCSCHR 1
+#endif
+
+/* Define to 1 if you have the `wcscmp' function. */
+#ifndef _CL_HAVE_WCSCMP
+#define _CL_HAVE_WCSCMP 1
+#endif
+
+/* Define to 1 if you have the `wcscpy' function. */
+#ifndef _CL_HAVE_WCSCPY
+#define _CL_HAVE_WCSCPY 1
+#endif
+
+/* Define to 1 if you have the `wcscspn' function. */
+#ifndef _CL_HAVE_WCSCSPN
+#define _CL_HAVE_WCSCSPN 1
+#endif
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `wcsicmp' function. */
+# ifndef _CL_HAVE_WCSICMP
+# define _CL_HAVE_WCSICMP 1
+# endif
+#endif
+
+/* Define to 1 if you have the `wcslen' function. */
+#ifndef _CL_HAVE_WCSLEN
+#define _CL_HAVE_WCSLEN 1
+#endif
+
+/* Define to 1 if you have the `wcsncmp' function. */
+#ifndef _CL_HAVE_WCSNCMP
+#define _CL_HAVE_WCSNCMP 1
+#endif
+
+/* Define to 1 if you have the `wcsncpy' function. */
+#ifndef _CL_HAVE_WCSNCPY
+#define _CL_HAVE_WCSNCPY 1
+#endif
+
+/* Define to 1 if you have the `wcsstr' function. */
+#ifndef _CL_HAVE_WCSSTR
+#define _CL_HAVE_WCSSTR 1
+#endif
+
+/* Define to 1 if you have the `wcstod' function. */
+#ifndef _CL_HAVE_WCSTOD
+#define _CL_HAVE_WCSTOD 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__HP_aCC)
+ /* Define to 1 if you have the `wcstoll' function. */
+# ifndef _CL_HAVE_WCSTOLL
+# define _CL_HAVE_WCSTOLL 1
+# endif
+#endif
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `wcsupr' function. */
+# ifndef _CL_HAVE_WCSUPR
+# define _CL_HAVE_WCSUPR 1
+# endif
+#endif
+
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) || defined(__HP_aCC)
+ /* Define to 1 if you have a functioning <wchar.h> header file. */
+# ifndef _CL_HAVE_WCTYPE_H
+# define _CL_HAVE_WCTYPE_H
+# endif
+#endif
+
+/* Define to 1 if you have the `wprintf' function. */
+/* #undef _CL_HAVE_WPRINTF */
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `_filelength' function. */
+# ifndef _CL_HAVE__FILELENGTH
+# define _CL_HAVE__FILELENGTH 1
+# endif
+#endif
+
+/* How to define a static const in a class */
+#ifndef LUCENE_STATIC_CONSTANT_SYNTAX
+#define LUCENE_STATIC_CONSTANT_SYNTAX 1
+#endif
+
+/* Name of package */
+#ifndef _CL_PACKAGE
+#define _CL_PACKAGE "clucene-core"
+#endif
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef _CL_PACKAGE_BUGREPORT
+#define _CL_PACKAGE_BUGREPORT ""
+#endif
+
+/* Define to the full name of this package. */
+#ifndef _CL_PACKAGE_NAME
+#define _CL_PACKAGE_NAME ""
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef _CL_PACKAGE_STRING
+#define _CL_PACKAGE_STRING ""
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef _CL_PACKAGE_TARNAME
+#define _CL_PACKAGE_TARNAME ""
+#endif
+
+/* Define to the version of this package. */
+#ifndef _CL_PACKAGE_VERSION
+#define _CL_PACKAGE_VERSION ""
+#endif
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef _CL_PTHREAD_CREATE_JOINABLE */
+
+/* The size of a `unsigned char', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_CHAR */
+
+/* The size of a `unsigned int', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_INT */
+
+/* The size of a `unsigned long', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_LONG */
+
+/* The size of a `unsigned long long', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_LONG_LONG */
+
+/* The size of a `unsigned __int64', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED___INT64 */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef _CL_STAT_MACROS_BROKEN */
+
+#if !defined(__HP_aCC)
+ /* Define to 1 if you have the ANSI C header files. */
+# ifndef _CL_STDC_HEADERS
+# define _CL_STDC_HEADERS 1
+# endif
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+# ifndef _CL_TIME_WITH_SYS_TIME
+# define _CL_TIME_WITH_SYS_TIME 1
+# endif
+#endif
+
+/* Version number of package */
+#ifndef _CL_VERSION
+#define _CL_VERSION "0.9.17"
+#endif
+
+/* Forces into Ascii mode */
+/* #undef _ASCII */
+
+/* Conditional Debugging */
+/* #undef _CL__CND_DEBUG */
+
+/* debuging option */
+/* #undef _DEBUG */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* If not already defined, then define as a datatype of *exactly* 32 bits. */
+/* #undef uint32_t */
+
+/* If not already defined, then define as a datatype of *exactly* 64 bits. */
+/* #undef uint64_t */
+
+/* If not already defined, then define as a datatype of *exactly* 8 bits. */
+/* #undef uint8_t */
+
+/* once:
+_SRC_CLUCENE_CLUCENE_CONFIG_H
+*/
+#endif
+
+
+#if defined Q_CC_MSVC && _MSC_VER < 1300
+# define LUCENE_NO_STDC_NAMESPACE
+#endif
+
+
+#endif // QCLUCENE_CONFIG_P_H
+
diff --git a/tools/assistant/lib/fulltextsearch/qclucene_global_p.h b/tools/assistant/lib/fulltextsearch/qclucene_global_p.h
new file mode 100644
index 0000000000..2a9d146848
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qclucene_global_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QCLUCENE_GLOBAL_P_H
+#define QCLUCENE_GLOBAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#if !defined(_MSC_VER)
+# include "qclucene-config_p.h"
+#endif
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_SHARED) && !defined(QT_DLL)
+# define QHELP_EXPORT
+#elif defined(QHELP_LIB)
+# define QHELP_EXPORT Q_DECL_EXPORT
+#else
+# define QHELP_EXPORT Q_DECL_IMPORT
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// adjustments here, need to be done in
+// QTDIR/src/3rdparty/clucene/src/CLucene/StdHeader.h as well
+//
+#if defined(_LUCENE_DONTIMPLEMENT_NS_MACROS)
+
+#elif !defined(DISABLE_NAMESPACE)
+# ifdef QT_NAMESPACE
+# define CL_NS_DEF(sub) namespace QT_NAMESPACE { namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace QT_NAMESPACE { namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}}
+# define CL_NS_END2 }}}}
+
+# define CL_NS_USE(sub) using namespace QT_NAMESPACE::lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace QT_NAMESPACE::lucene::sub::sub2;
+
+# define CL_NS(sub) QT_NAMESPACE::lucene::sub
+# define CL_NS2(sub,sub2) QT_NAMESPACE::lucene::sub::sub2
+# else
+# define CL_NS_DEF(sub) namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}
+# define CL_NS_END2 }}}
+
+# define CL_NS_USE(sub) using namespace lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace lucene::sub::sub2;
+
+# define CL_NS(sub) lucene::sub
+# define CL_NS2(sub,sub2) lucene::sub::sub2
+# endif
+#else
+# define CL_NS_DEF(sub)
+# define CL_NS_DEF2(sub, sub2)
+# define CL_NS_END
+# define CL_NS_END2
+# define CL_NS_USE(sub)
+# define CL_NS_USE2(sub,sub2)
+# define CL_NS(sub)
+# define CL_NS2(sub,sub2)
+#endif
+
+#if !defined(_MSC_VER) && defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+# if !defined(TCHAR)
+# define TCHAR wchar_t
+# endif
+#else
+# include <windows.h>
+#endif
+
+namespace {
+ TCHAR* QStringToTChar(const QString &str)
+ {
+ TCHAR *string = new TCHAR[(str.length() +1) * sizeof(TCHAR)];
+ memset(string, 0, (str.length() +1) * sizeof(TCHAR));
+ #if defined(UNICODE) || defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+ str.toWCharArray(string);
+ #else
+ const QByteArray ba = str.toAscii();
+ strcpy(string, ba.constData());
+ #endif
+ return string;
+ }
+
+ QString TCharToQString(const TCHAR *string)
+ {
+ #if defined(UNICODE) || defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+ QString retValue = QString::fromWCharArray(string);
+ return retValue;
+ #else
+ return QString(QLatin1String(string));
+ #endif
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCLUCENE_GLOBAL_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qdocument.cpp b/tools/assistant/lib/fulltextsearch/qdocument.cpp
new file mode 100644
index 0000000000..7e0f6d9b35
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qdocument.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qdocument_p.h"
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/util/Reader.h>
+#include <CLucene/document/Document.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneDocumentPrivate::QCLuceneDocumentPrivate()
+ : QSharedData()
+{
+ document = 0;
+ deleteCLuceneDocument = true;
+}
+
+QCLuceneDocumentPrivate::QCLuceneDocumentPrivate(const QCLuceneDocumentPrivate &other)
+ : QSharedData()
+{
+ document = _CL_POINTER(other.document);
+}
+
+QCLuceneDocumentPrivate::~QCLuceneDocumentPrivate()
+{
+ if (deleteCLuceneDocument)
+ _CLDECDELETE(document);
+}
+
+
+QCLuceneDocument::QCLuceneDocument()
+ : d(new QCLuceneDocumentPrivate())
+{
+ // nothing todo
+ d->document = new lucene::document::Document();
+}
+
+QCLuceneDocument::~QCLuceneDocument()
+{
+ qDeleteAll(fieldList);
+ fieldList.clear();
+}
+
+void QCLuceneDocument::add(QCLuceneField *field)
+{
+ field->d->deleteCLuceneField = false;
+ d->document->add(*field->d->field);
+ fieldList.append(field);
+}
+
+QCLuceneField* QCLuceneDocument::getField(const QString &name) const
+{
+ QCLuceneField* field = 0;
+ foreach (field, fieldList) {
+ if (field->name() == name && field->d->field != 0)
+ return field;
+ }
+
+ field = 0;
+ TCHAR *fieldName = QStringToTChar(name);
+ lucene::document::Field *f = d->document->getField(fieldName);
+ if (f) {
+ field = new QCLuceneField();
+ field->d->field = f;
+ fieldList.append(field);
+ field->d->deleteCLuceneField = false;
+
+ lucene::util::Reader *r = f->readerValue();
+ if (r) {
+ field->reader->d->reader = r;
+ field->reader->d->deleteCLuceneReader = false;
+ }
+ }
+ delete [] fieldName;
+
+ return field;
+}
+
+QString QCLuceneDocument::get(const QString &name) const
+{
+ QCLuceneField* field = getField(name);
+ if (field)
+ return field->stringValue();
+
+ return QString();
+}
+
+QString QCLuceneDocument::toString() const
+{
+ return TCharToQString(d->document->toString());
+}
+
+void QCLuceneDocument::setBoost(qreal boost)
+{
+ d->document->setBoost(qreal(boost));
+}
+
+qreal QCLuceneDocument::getBoost() const
+{
+ return qreal(d->document->getBoost());
+}
+
+void QCLuceneDocument::removeField(const QString &name)
+{
+ TCHAR *fieldName = QStringToTChar(name);
+ d->document->removeField(fieldName);
+ delete [] fieldName;
+
+ QList<QCLuceneField*> tmp;
+ lucene::document::DocumentFieldEnumeration *dfe = d->document->fields();
+ while (dfe->hasMoreElements()) {
+ const lucene::document::Field* f = dfe->nextElement();
+ foreach (QCLuceneField* field, fieldList) {
+ if (f == field->d->field) {
+ tmp.append(field);
+ break;
+ }
+ }
+ }
+ _CLDELETE(dfe);
+ fieldList = tmp;
+}
+
+void QCLuceneDocument::removeFields(const QString &name)
+{
+ for (qint32 i = fieldList.count() -1; i >= 0; --i) {
+ QCLuceneField* field = fieldList.at(i);
+ if (field->name() == name)
+ delete fieldList.takeAt(i);
+ }
+
+ TCHAR *fieldName = QStringToTChar(name);
+ d->document->removeFields(fieldName);
+ delete [] fieldName;
+}
+
+QStringList QCLuceneDocument::getValues(const QString &name) const
+{
+ TCHAR *fieldName = QStringToTChar(name);
+ TCHAR **values = d->document->getValues(fieldName);
+
+ QStringList retValue;
+ if (values) {
+ for (qint32 i = 0; 0 != values[i]; ++i) {
+ retValue.append(TCharToQString((const TCHAR*)values[i]));
+ delete [] values[i]; values[i] = 0;
+ }
+ delete values;
+ }
+
+ delete [] fieldName;
+ return retValue;
+}
+
+void QCLuceneDocument::clear()
+{
+ d->document->clear();
+ qDeleteAll(fieldList);
+ fieldList.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qdocument_p.h b/tools/assistant/lib/fulltextsearch/qdocument_p.h
new file mode 100644
index 0000000000..45f3d00cb1
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qdocument_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QDOCUMENT_P_H
+#define QDOCUMENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qfield_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(document)
+ class Document;
+CL_NS_END
+CL_NS_USE(document)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneIndexReader;
+class QCLuceneIndexWriter;
+class QCLuceneIndexSearcher;
+class QCLuceneMultiSearcher;
+
+class QHELP_EXPORT QCLuceneDocumentPrivate : public QSharedData
+{
+public:
+ QCLuceneDocumentPrivate();
+ QCLuceneDocumentPrivate(const QCLuceneDocumentPrivate &other);
+
+ ~QCLuceneDocumentPrivate();
+
+ Document *document;
+ bool deleteCLuceneDocument;
+
+private:
+ QCLuceneDocumentPrivate &operator=(const QCLuceneDocumentPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneDocument
+{
+public:
+ QCLuceneDocument();
+ ~QCLuceneDocument();
+
+ void add(QCLuceneField *field);
+ QCLuceneField* getField(const QString &name) const;
+ QString get(const QString &name) const;
+ QString toString() const;
+ void setBoost(qreal boost);
+ qreal getBoost() const;
+ void removeField(const QString &name);
+ void removeFields(const QString &name);
+ QStringList getValues(const QString &name) const;
+ void clear();
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneIndexReader;
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneIndexSearcher;
+ friend class QCLuceneMultiSearcher;
+ QSharedDataPointer<QCLuceneDocumentPrivate> d;
+
+private:
+ mutable QList<QCLuceneField*> fieldList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDOCUMENT_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qfield.cpp b/tools/assistant/lib/fulltextsearch/qfield.cpp
new file mode 100644
index 0000000000..0c64fa8c7d
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qfield.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qfield_p.h"
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/document/Field.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneFieldPrivate::QCLuceneFieldPrivate()
+ : QSharedData()
+{
+ field = 0;
+ deleteCLuceneField = true;
+}
+
+QCLuceneFieldPrivate::QCLuceneFieldPrivate(const QCLuceneFieldPrivate &other)
+ : QSharedData()
+{
+ field = _CL_POINTER(other.field);
+}
+
+QCLuceneFieldPrivate::~QCLuceneFieldPrivate()
+{
+ if (deleteCLuceneField)
+ _CLDECDELETE(field);
+}
+
+
+QCLuceneField::QCLuceneField()
+ : d(new QCLuceneFieldPrivate())
+ , reader(0)
+{
+ // nothing todo
+}
+
+QCLuceneField::QCLuceneField(const QString &name, const QString &value, int configs)
+ : d(new QCLuceneFieldPrivate())
+ , reader(0)
+{
+ TCHAR* fieldName = QStringToTChar(name);
+ TCHAR* fieldValue = QStringToTChar(value);
+
+ d->field = new lucene::document::Field(fieldName, fieldValue, configs);
+
+ delete [] fieldName;
+ delete [] fieldValue;
+}
+
+QCLuceneField::QCLuceneField(const QString &name, QCLuceneReader *reader,
+ int configs)
+ : d(new QCLuceneFieldPrivate())
+ , reader(reader)
+{
+ TCHAR* fieldName = QStringToTChar(name);
+
+ reader->d->deleteCLuceneReader = false; // clucene takes ownership
+ d->field = new lucene::document::Field(fieldName, reader->d->reader, configs);
+
+ delete [] fieldName;
+}
+
+QCLuceneField::~QCLuceneField()
+{
+ delete reader;
+}
+
+QString QCLuceneField::name() const
+{
+ return TCharToQString(d->field->name());
+}
+
+QString QCLuceneField::stringValue() const
+{
+ return TCharToQString((const TCHAR*)d->field->stringValue());
+}
+
+QCLuceneReader* QCLuceneField::readerValue() const
+{
+ return reader;
+}
+
+bool QCLuceneField::isStored() const
+{
+ return d->field->isStored();
+}
+
+bool QCLuceneField::isIndexed() const
+{
+ return d->field->isIndexed();
+}
+
+bool QCLuceneField::isTokenized() const
+{
+ return d->field->isTokenized();
+}
+
+bool QCLuceneField::isCompressed() const
+{
+ return d->field->isCompressed();
+}
+
+void QCLuceneField::setConfig(int termVector)
+{
+ d->field->setConfig(termVector);
+}
+
+bool QCLuceneField::isTermVectorStored() const
+{
+ return d->field->isTermVectorStored();
+}
+
+bool QCLuceneField::isStoreOffsetWithTermVector() const
+{
+ return d->field->isStoreOffsetWithTermVector();
+}
+
+bool QCLuceneField::isStorePositionWithTermVector() const
+{
+ return d->field->isStorePositionWithTermVector();
+}
+
+qreal QCLuceneField::getBoost() const
+{
+ return qreal(d->field->getBoost());
+}
+
+void QCLuceneField::setBoost(qreal value)
+{
+ d->field->setBoost(qreal(value));
+}
+
+bool QCLuceneField::isBinary() const
+{
+ return d->field->isBinary();
+}
+
+bool QCLuceneField::getOmitNorms() const
+{
+ return d->field->getOmitNorms();
+}
+
+void QCLuceneField::setOmitNorms(bool omitNorms)
+{
+ d->field->setOmitNorms(omitNorms);
+}
+
+QString QCLuceneField::toString() const
+{
+ return TCharToQString(d->field->toString());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qfield_p.h b/tools/assistant/lib/fulltextsearch/qfield_p.h
new file mode 100644
index 0000000000..86b6440ff4
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qfield_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QFIELD_P_H
+#define QFIELD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(document)
+ class Field;
+CL_NS_END
+CL_NS_USE(document)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneReader;
+class QCLuceneDocument;
+
+class QHELP_EXPORT QCLuceneFieldPrivate : public QSharedData
+{
+public:
+ QCLuceneFieldPrivate();
+ QCLuceneFieldPrivate(const QCLuceneFieldPrivate &other);
+
+ ~QCLuceneFieldPrivate();
+
+ Field *field;
+ bool deleteCLuceneField;
+
+private:
+ QCLuceneFieldPrivate &operator=(const QCLuceneFieldPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneField
+{
+public:
+ enum Store {
+ STORE_YES = 1,
+ STORE_NO = 2,
+ STORE_COMPRESS = 4
+ };
+
+ enum Index {
+ INDEX_NO = 16,
+ INDEX_TOKENIZED = 32,
+ INDEX_UNTOKENIZED = 64,
+ INDEX_NONORMS = 128
+ };
+
+ enum TermVector {
+ TERMVECTOR_NO = 256,
+ TERMVECTOR_YES = 512,
+ TERMVECTOR_WITH_POSITIONS = 1024,
+ TERMVECTOR_WITH_OFFSETS = 2048
+ };
+
+ QCLuceneField(const QString &name, const QString &value, int configs);
+ QCLuceneField(const QString &name, QCLuceneReader *reader, int configs);
+ ~QCLuceneField();
+
+ QString name() const;
+ QString stringValue() const;
+ QCLuceneReader* readerValue() const;
+ bool isStored() const;
+ bool isIndexed() const;
+ bool isTokenized() const;
+ bool isCompressed() const;
+ void setConfig(int termVector);
+ bool isTermVectorStored() const;
+ bool isStoreOffsetWithTermVector() const;
+ bool isStorePositionWithTermVector() const;
+ qreal getBoost() const;
+ void setBoost(qreal value);
+ bool isBinary() const;
+ bool getOmitNorms() const;
+ void setOmitNorms(bool omitNorms);
+ QString toString() const;
+
+protected:
+ QCLuceneField();
+ friend class QCLuceneDocument;
+ QSharedDataPointer<QCLuceneFieldPrivate> d;
+
+private:
+ QCLuceneReader* reader;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFIELD_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qfilter.cpp b/tools/assistant/lib/fulltextsearch/qfilter.cpp
new file mode 100644
index 0000000000..24373399fb
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qfilter.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qfilter_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/Filter.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneFilterPrivate::QCLuceneFilterPrivate()
+ : QSharedData()
+{
+ filter = 0;
+ deleteCLuceneFilter = true;
+}
+
+QCLuceneFilterPrivate::QCLuceneFilterPrivate(const QCLuceneFilterPrivate &other)
+ : QSharedData()
+{
+ filter = _CL_POINTER(other.filter);
+}
+
+QCLuceneFilterPrivate::~QCLuceneFilterPrivate ()
+{
+ if (deleteCLuceneFilter)
+ _CLDECDELETE(filter);
+}
+
+
+QCLuceneFilter::QCLuceneFilter()
+ : d(new QCLuceneFilterPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneFilter::~QCLuceneFilter()
+{
+ // nothing todo
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qfilter_p.h b/tools/assistant/lib/fulltextsearch/qfilter_p.h
new file mode 100644
index 0000000000..fcc0674485
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qfilter_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QFilter_P_H
+#define QFilter_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QSharedDataPointer>
+
+CL_NS_DEF(search)
+ class Filter;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneSearcher;
+
+class QHELP_EXPORT QCLuceneFilterPrivate : public QSharedData
+{
+public:
+ QCLuceneFilterPrivate();
+ QCLuceneFilterPrivate(const QCLuceneFilterPrivate &other);
+
+ ~QCLuceneFilterPrivate ();
+
+ Filter *filter;
+ bool deleteCLuceneFilter;
+
+private:
+ QCLuceneFilterPrivate &operator=(const QCLuceneFilterPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneFilter
+{
+ QCLuceneFilter();
+ virtual ~QCLuceneFilter();
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneSearcher;
+ QSharedDataPointer<QCLuceneFilterPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFilter_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qhits.cpp b/tools/assistant/lib/fulltextsearch/qhits.cpp
new file mode 100644
index 0000000000..b3dbea7b67
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qhits.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qhits_p.h"
+#include "qsearchable_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneHitsPrivate::QCLuceneHitsPrivate()
+ : QSharedData()
+{
+ hits = 0;
+ deleteCLuceneHits = true;
+}
+
+QCLuceneHitsPrivate::QCLuceneHitsPrivate(const QCLuceneHitsPrivate &other)
+ : QSharedData()
+{
+ hits = _CL_POINTER(other.hits);
+}
+
+QCLuceneHitsPrivate::~QCLuceneHitsPrivate()
+{
+ if (deleteCLuceneHits)
+ _CLDECDELETE(hits);
+}
+
+
+QCLuceneHits::QCLuceneHits(const QCLuceneSearcher &searcher,
+ const QCLuceneQuery &query, const QCLuceneFilter &filter)
+ : d(new QCLuceneHitsPrivate())
+{
+ d->hits = new lucene::search::Hits(searcher.d->searchable, query.d->query,
+ filter.d->filter);
+}
+
+QCLuceneHits::QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter, const QCLuceneSort &sort)
+ : d(new QCLuceneHitsPrivate())
+{
+ d->hits = new lucene::search::Hits(searcher.d->searchable, query.d->query,
+ filter.d->filter, sort.d->sort);
+}
+
+QCLuceneHits::~QCLuceneHits()
+{
+ // nothing todo
+}
+
+QCLuceneDocument QCLuceneHits::document(const qint32 index)
+{
+ // TODO: check this
+ QCLuceneDocument document;
+ document.d->deleteCLuceneDocument = false;
+ lucene::document::Document &doc = d->hits->doc(int32_t(index));
+ document.d->document = &doc;
+
+ return document;
+}
+
+qint32 QCLuceneHits::length() const
+{
+ return qint32(d->hits->length());
+}
+
+qint32 QCLuceneHits::id(const qint32 index)
+{
+ return qint32(d->hits->id(int32_t(index)));
+}
+
+qreal QCLuceneHits::score(const qint32 index)
+{
+ return qreal(d->hits->score(int32_t(index)));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qhits_p.h b/tools/assistant/lib/fulltextsearch/qhits_p.h
new file mode 100644
index 0000000000..fb6666b22e
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qhits_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QHITS_P_H
+#define QHITS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsort_p.h"
+#include "qquery_p.h"
+#include "qfilter_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Hits;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneSearcher;
+
+class QHELP_EXPORT QCLuceneHitsPrivate : public QSharedData
+{
+public:
+ QCLuceneHitsPrivate();
+ QCLuceneHitsPrivate(const QCLuceneHitsPrivate &other);
+
+ ~QCLuceneHitsPrivate();
+
+ Hits *hits;
+ bool deleteCLuceneHits;
+
+private:
+ QCLuceneHitsPrivate &operator=(const QCLuceneHitsPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneHits
+{
+public:
+ QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter);
+ QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter, const QCLuceneSort &sort);
+ virtual ~QCLuceneHits();
+
+ QCLuceneDocument document(const qint32 index);
+ qint32 length() const;
+ qint32 id (const qint32 index);
+ qreal score(const qint32 index);
+
+protected:
+ friend class QCLuceneSearcher;
+ QSharedDataPointer<QCLuceneHitsPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHITS_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qindexreader.cpp b/tools/assistant/lib/fulltextsearch/qindexreader.cpp
new file mode 100644
index 0000000000..5f967cce68
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qindexreader.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qindexreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexReader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneIndexReaderPrivate::QCLuceneIndexReaderPrivate()
+ : QSharedData()
+{
+ reader = 0;
+ deleteCLuceneIndexReader = true;
+}
+
+QCLuceneIndexReaderPrivate::QCLuceneIndexReaderPrivate(const QCLuceneIndexReaderPrivate &other)
+ : QSharedData()
+{
+ reader = _CL_POINTER(other.reader);
+}
+
+QCLuceneIndexReaderPrivate::~QCLuceneIndexReaderPrivate()
+{
+ if (deleteCLuceneIndexReader)
+ _CLDECDELETE(reader);
+}
+
+
+QCLuceneIndexReader::QCLuceneIndexReader()
+ : d(new QCLuceneIndexReaderPrivate())
+{
+ // nothing todo, private
+}
+
+QCLuceneIndexReader::~QCLuceneIndexReader()
+{
+ // nothing todo
+}
+
+bool QCLuceneIndexReader::isLuceneFile(const QString &filename)
+{
+ using namespace lucene::index;
+
+ return IndexReader::isLuceneFile(filename);
+}
+
+bool QCLuceneIndexReader::indexExists(const QString &directory)
+{
+ using namespace lucene::index;
+ return IndexReader::indexExists(directory);
+}
+
+QCLuceneIndexReader QCLuceneIndexReader::open(const QString &path)
+{
+ using namespace lucene::index;
+
+ QCLuceneIndexReader indexReader;
+ indexReader.d->reader = IndexReader::open(path);
+
+ return indexReader;
+}
+
+void QCLuceneIndexReader::unlock(const QString &path)
+{
+ using namespace lucene::index;
+ IndexReader::unlock(path);
+}
+
+bool QCLuceneIndexReader::isLocked(const QString &directory)
+{
+ using namespace lucene::index;
+ return IndexReader::isLocked(directory);
+}
+
+quint64 QCLuceneIndexReader::lastModified(const QString &directory)
+{
+ using namespace lucene::index;
+ return quint64(IndexReader::lastModified(directory));
+}
+
+qint64 QCLuceneIndexReader::getCurrentVersion(const QString &directory)
+{
+ using namespace lucene::index;
+ return qint64(IndexReader::getCurrentVersion(directory));
+}
+
+void QCLuceneIndexReader::close()
+{
+ d->reader->close();
+}
+
+bool QCLuceneIndexReader::isCurrent()
+{
+ return d->reader->isCurrent();
+}
+
+void QCLuceneIndexReader::undeleteAll()
+{
+ d->reader->undeleteAll();
+}
+
+qint64 QCLuceneIndexReader::getVersion()
+{
+ return qint64(d->reader->getVersion());
+}
+
+void QCLuceneIndexReader::deleteDocument(qint32 docNum)
+{
+ d->reader->deleteDocument(int32_t(docNum));
+}
+
+bool QCLuceneIndexReader::hasNorms(const QString &field)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ bool retValue = d->reader->hasNorms(fieldName);
+ delete [] fieldName;
+
+ return retValue;
+}
+
+qint32 QCLuceneIndexReader::deleteDocuments(const QCLuceneTerm &term)
+{
+ return d->reader->deleteDocuments(term.d->term);
+}
+
+bool QCLuceneIndexReader::document(qint32 index, QCLuceneDocument &document)
+{
+ if (!document.d->document)
+ document.d->document = new lucene::document::Document();
+
+ if (d->reader->document(int32_t(index), document.d->document))
+ return true;
+
+ return false;
+}
+
+void QCLuceneIndexReader::setNorm(qint32 doc, const QString &field, qreal value)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ d->reader->setNorm(int32_t(doc), fieldName, qreal(value));
+ delete [] fieldName;
+}
+
+void QCLuceneIndexReader::setNorm(qint32 doc, const QString &field, quint8 value)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ d->reader->setNorm(int32_t(doc), fieldName, uint8_t(value));
+ delete [] fieldName;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qindexreader_p.h b/tools/assistant/lib/fulltextsearch/qindexreader_p.h
new file mode 100644
index 0000000000..4a7330def3
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qindexreader_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QINDEXREADER_P_H
+#define QINDEXREADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qterm_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(index)
+ class IndexReader;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+class QCLuceneIndexSearcher;
+
+class QHELP_EXPORT QCLuceneIndexReaderPrivate : public QSharedData
+{
+public:
+ QCLuceneIndexReaderPrivate();
+ QCLuceneIndexReaderPrivate(const QCLuceneIndexReaderPrivate &other);
+
+ ~QCLuceneIndexReaderPrivate();
+
+ IndexReader *reader;
+ bool deleteCLuceneIndexReader;
+
+private:
+ QCLuceneIndexReaderPrivate &operator=(const QCLuceneIndexReaderPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneIndexReader
+{
+public:
+ enum FieldOption {
+ ALL = 1,
+ INDEXED = 2,
+ UNINDEXED = 4,
+ INDEXED_WITH_TERMVECTOR = 8,
+ INDEXED_NO_TERMVECTOR = 16,
+ TERMVECTOR = 32,
+ TERMVECTOR_WITH_POSITION = 64,
+ TERMVECTOR_WITH_OFFSET = 128,
+ TERMVECTOR_WITH_POSITION_OFFSET = 256
+ };
+
+ virtual ~QCLuceneIndexReader();
+
+ static bool isLuceneFile(const QString &filename);
+ static bool indexExists(const QString &directory);
+ static QCLuceneIndexReader open(const QString &path);
+
+ static void unlock(const QString &path);
+ static bool isLocked(const QString &directory);
+
+ static quint64 lastModified(const QString &directory);
+ static qint64 getCurrentVersion(const QString &directory);
+
+ void close();
+ bool isCurrent();
+ void undeleteAll();
+ qint64 getVersion();
+ void deleteDocument(qint32 docNum);
+ bool hasNorms(const QString &field);
+ qint32 deleteDocuments(const QCLuceneTerm &term);
+ bool document(qint32 index, QCLuceneDocument &document);
+ void setNorm(qint32 doc, const QString &field, qreal value);
+ void setNorm(qint32 doc, const QString &field, quint8 value);
+
+protected:
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneIndexSearcher;
+ QSharedDataPointer<QCLuceneIndexReaderPrivate> d;
+
+private:
+ QCLuceneIndexReader();
+};
+
+QT_END_NAMESPACE
+
+#endif // QINDEXREADER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qindexwriter.cpp b/tools/assistant/lib/fulltextsearch/qindexwriter.cpp
new file mode 100644
index 0000000000..890cc67c8d
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qindexwriter.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qindexwriter_p.h"
+#include "qindexreader_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexWriter.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneIndexWriterPrivate::QCLuceneIndexWriterPrivate()
+ : QSharedData()
+{
+ writer = 0;
+ deleteCLuceneIndexWriter = true;
+}
+
+QCLuceneIndexWriterPrivate::QCLuceneIndexWriterPrivate(const QCLuceneIndexWriterPrivate &other)
+ : QSharedData()
+{
+ writer = _CL_POINTER(other.writer);
+}
+
+QCLuceneIndexWriterPrivate::~QCLuceneIndexWriterPrivate()
+{
+ if (deleteCLuceneIndexWriter)
+ _CLDECDELETE(writer);
+}
+
+
+QCLuceneIndexWriter::QCLuceneIndexWriter(const QString &path,
+ QCLuceneAnalyzer &analyzer,
+ bool create, bool closeDir)
+ : d(new QCLuceneIndexWriterPrivate())
+ , analyzer(analyzer)
+{
+ d->writer = new lucene::index::IndexWriter(path,
+ analyzer.d->analyzer, create, closeDir);
+}
+
+QCLuceneIndexWriter::~QCLuceneIndexWriter()
+{
+ // nothing todo
+}
+
+void QCLuceneIndexWriter::close()
+{
+ d->writer->close();
+}
+
+void QCLuceneIndexWriter::optimize()
+{
+ d->writer->optimize();
+}
+
+qint32 QCLuceneIndexWriter::docCount()
+{
+ return qint32(d->writer->docCount());
+}
+
+QCLuceneAnalyzer QCLuceneIndexWriter::getAnalyzer()
+{
+ return analyzer;
+}
+
+void QCLuceneIndexWriter::addIndexes(const QList<QCLuceneIndexReader*> &readers)
+{
+ using namespace lucene::index;
+ IndexReader** readerArray = new IndexReader*[readers.count()];
+
+ for (int i = 0; i < readers.count(); ++i)
+ readerArray[i] = (readers.at(i))->d->reader;
+
+ d->writer->addIndexes(readerArray);
+ delete readerArray;
+}
+
+void QCLuceneIndexWriter::addDocument(QCLuceneDocument &doc,
+ QCLuceneAnalyzer &analyzer)
+{
+ if (doc.d->document)
+ d->writer->addDocument(doc.d->document, analyzer.d->analyzer);
+}
+
+qint32 QCLuceneIndexWriter::getMaxFieldLength() const
+{
+ return qint32(d->writer->getMaxFieldLength());
+}
+
+void QCLuceneIndexWriter::setMaxFieldLength(qint32 value)
+{
+ d->writer->setMaxFieldLength(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getMaxBufferedDocs() const
+{
+ return qint32(d->writer->getMaxBufferedDocs());
+}
+
+void QCLuceneIndexWriter::setMaxBufferedDocs(qint32 value)
+{
+ d->writer->setMaxBufferedDocs(int32_t(value));
+}
+
+qint64 QCLuceneIndexWriter::getWriteLockTimeout() const
+{
+ return qint64(d->writer->getWriteLockTimeout());
+}
+
+void QCLuceneIndexWriter::setWriteLockTimeout(qint64 writeLockTimeout)
+{
+ d->writer->setWriteLockTimeout(int64_t(writeLockTimeout));
+}
+
+qint64 QCLuceneIndexWriter::getCommitLockTimeout() const
+{
+ return qint64(d->writer->getCommitLockTimeout());
+}
+
+void QCLuceneIndexWriter::setCommitLockTimeout(qint64 commitLockTimeout)
+{
+ d->writer->setCommitLockTimeout(int64_t(commitLockTimeout));
+}
+
+qint32 QCLuceneIndexWriter::getMergeFactor() const
+{
+ return qint32(d->writer->getMergeFactor());
+}
+
+void QCLuceneIndexWriter::setMergeFactor(qint32 value)
+{
+ d->writer->setMergeFactor(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getTermIndexInterval() const
+{
+ return qint32(d->writer->getTermIndexInterval());
+}
+
+void QCLuceneIndexWriter::setTermIndexInterval(qint32 interval)
+{
+ d->writer->setTermIndexInterval(int32_t(interval));
+}
+
+qint32 QCLuceneIndexWriter::getMinMergeDocs() const
+{
+ return qint32(d->writer->getMinMergeDocs());
+}
+
+void QCLuceneIndexWriter::setMinMergeDocs(qint32 value)
+{
+ d->writer->setMinMergeDocs(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getMaxMergeDocs() const
+{
+ return qint32(d->writer->getMaxMergeDocs());
+}
+
+void QCLuceneIndexWriter::setMaxMergeDocs(qint32 value)
+{
+ d->writer->setMaxMergeDocs(int32_t(value));
+}
+
+bool QCLuceneIndexWriter::getUseCompoundFile() const
+{
+ return d->writer->getUseCompoundFile();
+}
+
+void QCLuceneIndexWriter::setUseCompoundFile(bool value)
+{
+ d->writer->setUseCompoundFile(value);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qindexwriter_p.h b/tools/assistant/lib/fulltextsearch/qindexwriter_p.h
new file mode 100644
index 0000000000..e793494d95
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qindexwriter_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QINDEXWRITER_P_H
+#define QINDEXWRITER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qanalyzer_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(index)
+ class IndexWriter;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexReader;
+
+class QHELP_EXPORT QCLuceneIndexWriterPrivate : public QSharedData
+{
+public:
+ QCLuceneIndexWriterPrivate();
+ QCLuceneIndexWriterPrivate(const QCLuceneIndexWriterPrivate &other);
+
+ ~QCLuceneIndexWriterPrivate();
+
+ IndexWriter *writer;
+ bool deleteCLuceneIndexWriter;
+
+private:
+ QCLuceneIndexWriterPrivate &operator=(const QCLuceneIndexWriterPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneIndexWriter
+{
+public:
+ enum {
+ DEFAULT_MERGE_FACTOR = 10,
+ COMMIT_LOCK_TIMEOUT = 10000,
+ DEFAULT_MAX_BUFFERED_DOCS = 10,
+ DEFAULT_MAX_FIELD_LENGTH = 10000,
+ DEFAULT_TERM_INDEX_INTERVAL = 128,
+ DEFAULT_MAX_MERGE_DOCS = 0x7FFFFFFFL
+ };
+
+ QCLuceneIndexWriter(const QString &path, QCLuceneAnalyzer &analyzer,
+ bool create, bool closeDir = true);
+ virtual ~QCLuceneIndexWriter();
+
+ void close();
+ void optimize();
+ qint32 docCount();
+ QCLuceneAnalyzer getAnalyzer();
+
+ void addIndexes(const QList<QCLuceneIndexReader*> &readers);
+ void addDocument(QCLuceneDocument &doc, QCLuceneAnalyzer &analyzer);
+
+ qint32 getMaxFieldLength() const;
+ void setMaxFieldLength(qint32 value);
+
+ qint32 getMaxBufferedDocs() const;
+ void setMaxBufferedDocs(qint32 value);
+
+ qint64 getWriteLockTimeout() const;
+ void setWriteLockTimeout(qint64 writeLockTimeout);
+
+ qint64 getCommitLockTimeout() const;
+ void setCommitLockTimeout(qint64 commitLockTimeout);
+
+ qint32 getMergeFactor() const;
+ void setMergeFactor(qint32 value);
+
+ qint32 getTermIndexInterval() const;
+ void setTermIndexInterval(qint32 interval);
+
+ qint32 getMinMergeDocs() const;
+ void setMinMergeDocs(qint32 value);
+
+ qint32 getMaxMergeDocs() const;
+ void setMaxMergeDocs(qint32 value);
+
+ bool getUseCompoundFile() const;
+ void setUseCompoundFile(bool value);
+
+protected:
+ QSharedDataPointer<QCLuceneIndexWriterPrivate> d;
+
+private:
+ QCLuceneAnalyzer analyzer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QINDEXWRITER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qquery.cpp b/tools/assistant/lib/fulltextsearch/qquery.cpp
new file mode 100644
index 0000000000..2210220978
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qquery.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qquery_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/PhraseQuery.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneQueryPrivate::QCLuceneQueryPrivate()
+ : QSharedData()
+{
+ query = 0;
+ deleteCLuceneQuery = true;
+}
+
+QCLuceneQueryPrivate::QCLuceneQueryPrivate(const QCLuceneQueryPrivate &other)
+ : QSharedData()
+{
+ query = _CL_POINTER(other.query);
+}
+
+QCLuceneQueryPrivate::~QCLuceneQueryPrivate()
+{
+ if (deleteCLuceneQuery)
+ _CLDECDELETE(query);
+}
+
+
+QCLuceneQuery::QCLuceneQuery()
+ : d(new QCLuceneQueryPrivate())
+{
+ // nothing todo, private
+}
+
+QCLuceneQuery::~QCLuceneQuery()
+{
+ // nothing todo
+}
+
+void QCLuceneQuery::setBoost(qreal boost)
+{
+ d->query->setBoost(qreal(boost));
+}
+
+qreal QCLuceneQuery::getBoost() const
+{
+ return qreal(d->query->getBoost());
+}
+
+QString QCLuceneQuery::getQueryName() const
+{
+ return TCharToQString(d->query->getQueryName());
+}
+
+bool QCLuceneQuery::instanceOf(const QString &other) const
+{
+ if (other == getQueryName())
+ return true;
+
+ return false;
+}
+
+QString QCLuceneQuery::toString(const QString &field) const
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ QString retValue = TCharToQString(d->query->toString(fieldName));
+ delete [] fieldName;
+
+ return retValue;
+}
+
+quint32 QCLuceneQuery::hashCode() const
+{
+ return quint32(d->query->hashCode());
+}
+
+QString QCLuceneQuery::toString() const
+{
+ return TCharToQString(d->query->toString());
+}
+
+bool QCLuceneQuery::equals(const QCLuceneQuery &other) const
+{
+ return d->query->equals(other.d->query);
+}
+
+
+QCLucenePrefixQuery::QCLucenePrefixQuery(const QCLuceneTerm &prefix)
+ : QCLuceneQuery()
+ , prefix(prefix)
+{
+ d->query = new lucene::search::PrefixQuery(prefix.d->term);
+}
+
+QCLucenePrefixQuery::~QCLucenePrefixQuery()
+{
+ // nothing todo
+}
+
+QString QCLucenePrefixQuery::getClassName()
+{
+ return TCharToQString(lucene::search::PrefixQuery::getClassName());
+}
+
+QCLuceneTerm QCLucenePrefixQuery::getPrefix() const
+{
+ return prefix;
+}
+
+
+QCLuceneRangeQuery::QCLuceneRangeQuery(const QCLuceneTerm &lowerTerm,
+ const QCLuceneTerm &upperTerm,
+ bool inclusive)
+ : QCLuceneQuery()
+ , lowerTerm(lowerTerm)
+ , upperTerm(upperTerm)
+{
+ d->query = new lucene::search::RangeQuery(lowerTerm.d->term,
+ upperTerm.d->term, inclusive);
+}
+
+QCLuceneRangeQuery::~QCLuceneRangeQuery()
+{
+ // nothing todo
+}
+
+QString QCLuceneRangeQuery::getClassName()
+{
+ return TCharToQString(lucene::search::RangeQuery::getClassName());
+}
+
+QCLuceneTerm QCLuceneRangeQuery::getLowerTerm() const
+{
+ return lowerTerm;
+}
+
+QCLuceneTerm QCLuceneRangeQuery::getUpperTerm() const
+{
+ return upperTerm;
+}
+
+bool QCLuceneRangeQuery::isInclusive() const
+{
+ lucene::search::RangeQuery *query =
+ static_cast<lucene::search::RangeQuery*> (d->query);
+
+ if (query == 0)
+ return false;
+
+ return query->isInclusive();
+}
+
+QString QCLuceneRangeQuery::getField() const
+{
+ lucene::search::RangeQuery *query =
+ static_cast<lucene::search::RangeQuery*> (d->query);
+
+ if (query == 0)
+ return QString();
+
+ return TCharToQString(query->getField());
+}
+
+
+QCLuceneTermQuery::QCLuceneTermQuery(const QCLuceneTerm &term)
+ : QCLuceneQuery()
+ , term(term)
+{
+ d->query = new lucene::search::TermQuery(term.d->term);
+}
+
+QCLuceneTermQuery::~QCLuceneTermQuery()
+{
+ // nothing todo
+}
+
+QString QCLuceneTermQuery::getClassName()
+{
+ return TCharToQString(lucene::search::TermQuery::getClassName());
+}
+
+QCLuceneTerm QCLuceneTermQuery::getTerm() const
+{
+ return term;
+}
+
+
+QCLuceneBooleanQuery::QCLuceneBooleanQuery()
+ : QCLuceneQuery()
+{
+ d->query = new lucene::search::BooleanQuery();
+}
+
+QCLuceneBooleanQuery::~QCLuceneBooleanQuery()
+{
+ qDeleteAll(queries);
+}
+
+QString QCLuceneBooleanQuery::getClassName()
+{
+ return TCharToQString(lucene::search::BooleanQuery::getClassName());
+}
+
+quint32 QCLuceneBooleanQuery::getClauseCount() const
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return 1024;
+
+ return quint32(query->getClauseCount());
+}
+
+quint32 QCLuceneBooleanQuery::getMaxClauseCount() const
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return 1024;
+
+ return quint32(query->getMaxClauseCount());
+}
+
+void QCLuceneBooleanQuery::setMaxClauseCount(quint32 maxClauseCount)
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return;
+
+ query->setMaxClauseCount(size_t(maxClauseCount));
+}
+
+void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool required, bool prohibited)
+{
+ add(query, false, required, prohibited);
+}
+
+void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool delQuery,
+ bool required, bool prohibited)
+{
+ lucene::search::BooleanQuery *booleanQuery =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (booleanQuery == 0)
+ return;
+
+ booleanQuery->add(query->d->query, delQuery, required, prohibited);
+
+ if (delQuery) {
+ queries.append(query);
+ query->d->deleteCLuceneQuery = false;
+ }
+}
+
+
+QCLucenePhraseQuery::QCLucenePhraseQuery()
+ : QCLuceneQuery()
+{
+ d->query = new lucene::search::PhraseQuery();
+}
+
+QCLucenePhraseQuery::~QCLucenePhraseQuery()
+{
+ termList.clear();
+}
+
+QString QCLucenePhraseQuery::getClassName()
+{
+ return TCharToQString(lucene::search::RangeQuery::getClassName());
+}
+
+qint32 QCLucenePhraseQuery::getSlop() const
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return 0;
+
+ return qint32(phraseQuery->getSlop());
+}
+
+void QCLucenePhraseQuery::setSlop(const qint32 slop)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ phraseQuery->setSlop(int32_t(slop));
+}
+
+void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ termList.append(term);
+ phraseQuery->add(term.d->term);
+}
+
+void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term, qint32 position)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ termList.insert(position, term);
+ phraseQuery->add(term.d->term, int32_t(position));
+
+}
+
+QString QCLucenePhraseQuery::getFieldName() const
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return QString();
+
+ return TCharToQString(phraseQuery->getFieldName());
+}
+
+QList<QCLuceneTerm> QCLucenePhraseQuery::getTerms() const
+{
+ return termList;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qquery_p.h b/tools/assistant/lib/fulltextsearch/qquery_p.h
new file mode 100644
index 0000000000..42eaf07b0d
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qquery_p.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QQUERY_P_H
+#define QQUERY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qterm_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Query;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneTermQuery;
+class QCLuceneRangeQuery;
+class QCLuceneQueryParser;
+class QCLucenePrefixQuery;
+class QCLuceneBooleanQuery;
+class QCLucenePhraseQuery;
+
+class QHELP_EXPORT QCLuceneQueryPrivate : public QSharedData
+{
+public:
+ QCLuceneQueryPrivate();
+ QCLuceneQueryPrivate(const QCLuceneQueryPrivate &other);
+
+ ~QCLuceneQueryPrivate();
+
+ Query *query;
+ bool deleteCLuceneQuery;
+
+private:
+ QCLuceneQueryPrivate &operator=(const QCLuceneQueryPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneQuery
+{
+public:
+ virtual ~QCLuceneQuery();
+
+ void setBoost(qreal boost);
+ qreal getBoost() const;
+ QString getQueryName() const;
+ bool instanceOf(const QString &other) const;
+ QString toString(const QString &field) const;
+ quint32 hashCode() const;
+ QString toString() const;
+ bool equals(const QCLuceneQuery &other) const;
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneTermQuery;
+ friend class QCLuceneRangeQuery;
+ friend class QCLucenePrefixQuery;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneBooleanQuery;
+ friend class QCLucenePhraseQuery;
+ QSharedDataPointer<QCLuceneQueryPrivate> d;
+
+private:
+ QCLuceneQuery();
+};
+
+class QHELP_EXPORT QCLucenePrefixQuery : public QCLuceneQuery
+{
+public:
+ QCLucenePrefixQuery(const QCLuceneTerm &prefix);
+ ~QCLucenePrefixQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getPrefix() const;
+
+private:
+ QCLuceneTerm prefix;
+};
+
+class QHELP_EXPORT QCLuceneRangeQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneRangeQuery(const QCLuceneTerm &lowerTerm,
+ const QCLuceneTerm &upperTerm, bool inclusive);
+ ~QCLuceneRangeQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getLowerTerm() const;
+ QCLuceneTerm getUpperTerm() const;
+
+ bool isInclusive() const;
+ QString getField() const;
+
+private:
+ QCLuceneTerm lowerTerm;
+ QCLuceneTerm upperTerm;
+};
+
+class QHELP_EXPORT QCLuceneTermQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneTermQuery(const QCLuceneTerm &term);
+ ~QCLuceneTermQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getTerm() const;
+
+private:
+ QCLuceneTerm term;
+};
+
+class QHELP_EXPORT QCLuceneBooleanQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneBooleanQuery();
+ ~QCLuceneBooleanQuery();
+
+ static QString getClassName();
+
+ quint32 getClauseCount() const;
+ quint32 getMaxClauseCount() const;
+ void setMaxClauseCount(quint32 maxClauseCount);
+
+ void add(QCLuceneQuery *query, bool required, bool prohibited);
+ void add(QCLuceneQuery *query, bool delQuery, bool required, bool prohibited);
+
+private:
+ QList<QCLuceneQuery*> queries;
+};
+
+class QHELP_EXPORT QCLucenePhraseQuery : public QCLuceneQuery
+{
+public:
+ QCLucenePhraseQuery();
+ ~QCLucenePhraseQuery();
+
+ static QString getClassName();
+
+ qint32 getSlop() const;
+ void setSlop(const qint32 slop);
+
+ void addTerm(const QCLuceneTerm &term);
+ void addTerm(const QCLuceneTerm &term, qint32 position);
+
+ QString getFieldName() const;
+ QList<QCLuceneTerm> getTerms() const;
+
+private:
+ QList<QCLuceneTerm> termList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUERY_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qqueryparser.cpp b/tools/assistant/lib/fulltextsearch/qqueryparser.cpp
new file mode 100644
index 0000000000..ce1b512454
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qqueryparser.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qqueryparser_p.h"
+#include "qquery_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/queryParser/QueryParser.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneQueryParserPrivate::QCLuceneQueryParserPrivate()
+ : QSharedData()
+{
+ queryParser = 0;
+ deleteCLuceneQueryParser = true;
+}
+
+QCLuceneQueryParserPrivate::QCLuceneQueryParserPrivate(const QCLuceneQueryParserPrivate &other)
+ : QSharedData()
+{
+ queryParser = _CL_POINTER(other.queryParser);
+}
+
+QCLuceneQueryParserPrivate::~QCLuceneQueryParserPrivate()
+{
+ if (deleteCLuceneQueryParser)
+ _CLDECDELETE(queryParser);
+}
+
+
+QCLuceneQueryParser::QCLuceneQueryParser(const QString &field,
+ QCLuceneAnalyzer &analyzer)
+ : d(new QCLuceneQueryParserPrivate())
+ , field(field)
+ , analyzer(analyzer)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+
+ d->queryParser = new lucene::queryParser::QueryParser(fieldName,
+ analyzer.d->analyzer);
+
+ delete [] fieldName;
+}
+
+QCLuceneQueryParser::~QCLuceneQueryParser()
+{
+ // nothing todo
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(const QString &query)
+{
+ TCHAR *string = QStringToTChar(query);
+
+ QCLuceneQuery *retValue = 0;
+ lucene::search::Query* q = d->queryParser->parse(string);
+ if (q) {
+ retValue = new QCLuceneQuery();
+ retValue->d->query = q;
+ }
+
+ delete [] string;
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(QCLuceneReader &reader)
+{
+ QCLuceneQuery *retValue = 0;
+ lucene::search::Query* q = d->queryParser->parse(reader.d->reader);
+ if (q) {
+ retValue = new QCLuceneQuery();
+ retValue->d->query = q;
+ }
+
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(const QString &query, const QString &field,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneQueryParser parser(field, analyzer);
+ return parser.parse(query);
+}
+
+QCLuceneAnalyzer QCLuceneQueryParser::getAnalyzer()
+{
+ return analyzer;
+}
+
+QString QCLuceneQueryParser::getField()
+{
+ return field;
+}
+
+
+QCLuceneMultiFieldQueryParser::QCLuceneMultiFieldQueryParser(
+ const QStringList &fieldList, QCLuceneAnalyzer &analyzer)
+ : QCLuceneQueryParser(QLatin1String(""), analyzer)
+{
+ Q_UNUSED(fieldList)
+}
+
+QCLuceneMultiFieldQueryParser::~QCLuceneMultiFieldQueryParser()
+{
+ // nothing todo
+}
+
+QCLuceneQuery* QCLuceneMultiFieldQueryParser::parse(const QString &query,
+ const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneBooleanQuery *retValue = new QCLuceneBooleanQuery();
+ foreach (const QString &field, fieldList) {
+ QCLuceneQuery *q = QCLuceneQueryParser::parse(query, field, analyzer);
+ if (!q) {
+ delete retValue;
+ retValue = 0; break;
+ } else {
+ retValue->add(q, true, false, false);
+ }
+ }
+
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneMultiFieldQueryParser::parse(const QString &query,
+ const QStringList &fieldList,
+ QList<FieldFlags> flags,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneBooleanQuery *retValue = new QCLuceneBooleanQuery();
+ qint32 i = 0;
+ foreach (const QString &field, fieldList) {
+ QCLuceneQuery *q = QCLuceneQueryParser::parse(query, field, analyzer);
+ if (q) {
+ qint32 flag = flags.at(i);
+ switch (flag) {
+ case QCLuceneMultiFieldQueryParser::REQUIRED_FIELD: {
+ retValue->add(q, true, true, false);
+ } break;
+
+ case QCLuceneMultiFieldQueryParser::PROHIBITED_FIELD: {
+ retValue->add(q, true, false, true);
+ } break;
+
+ default: {
+ retValue->add(q, true, false, false);
+ } break;
+ }
+
+ ++i;
+ } else {
+ delete retValue;
+ retValue = 0; break;
+ }
+ }
+ return retValue;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qqueryparser_p.h b/tools/assistant/lib/fulltextsearch/qqueryparser_p.h
new file mode 100644
index 0000000000..976ee63b72
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qqueryparser_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QQUERYPARSER_P_H
+#define QQUERYPARSER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qreader_p.h"
+#include "qanalyzer_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(queryParser)
+ class QueryParser;
+CL_NS_END
+CL_NS_USE(queryParser)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneQuery;
+class QCLuceneMultiFieldQueryParser;
+
+class QHELP_EXPORT QCLuceneQueryParserPrivate : public QSharedData
+{
+public:
+ QCLuceneQueryParserPrivate();
+ QCLuceneQueryParserPrivate(const QCLuceneQueryParserPrivate &other);
+
+ ~QCLuceneQueryParserPrivate();
+
+ QueryParser *queryParser;
+ bool deleteCLuceneQueryParser;
+
+private:
+ QCLuceneQueryParserPrivate &operator=(const QCLuceneQueryParserPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneQueryParser
+{
+public:
+ QCLuceneQueryParser(const QString &field, QCLuceneAnalyzer &analyzer);
+ virtual ~QCLuceneQueryParser();
+
+ QCLuceneQuery* parse(const QString &query);
+ QCLuceneQuery* parse(QCLuceneReader &reader);
+ static QCLuceneQuery* parse(const QString &query, const QString &field,
+ QCLuceneAnalyzer &analyzer);
+ QCLuceneAnalyzer getAnalyzer();
+ QString getField();
+
+protected:
+ friend class QCLuceneMultiFieldQueryParser;
+ QSharedDataPointer<QCLuceneQueryParserPrivate> d;
+
+private:
+ QString field;
+ QCLuceneAnalyzer analyzer;
+};
+
+class QHELP_EXPORT QCLuceneMultiFieldQueryParser : public QCLuceneQueryParser
+{
+public:
+ enum FieldFlags {
+ NORMAL_FIELD = 0,
+ REQUIRED_FIELD = 1,
+ PROHIBITED_FIELD = 2
+ };
+
+ QCLuceneMultiFieldQueryParser(const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer);
+ ~QCLuceneMultiFieldQueryParser();
+
+ static QCLuceneQuery *parse(const QString &query, const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer);
+ static QCLuceneQuery *parse(const QString &query, const QStringList &fieldList,
+ QList<FieldFlags> flags, QCLuceneAnalyzer &analyzer);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUERYPARSER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qreader.cpp b/tools/assistant/lib/fulltextsearch/qreader.cpp
new file mode 100644
index 0000000000..792056d130
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qreader.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/util/Reader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneReaderPrivate::QCLuceneReaderPrivate()
+ : QSharedData()
+{
+ reader = 0;
+ deleteCLuceneReader = true;
+}
+
+QCLuceneReaderPrivate::QCLuceneReaderPrivate(const QCLuceneReaderPrivate &other)
+ : QSharedData()
+{
+ reader = _CL_POINTER(other.reader);
+}
+
+QCLuceneReaderPrivate::~QCLuceneReaderPrivate()
+{
+ if (deleteCLuceneReader)
+ _CLDECDELETE(reader);
+}
+
+
+QCLuceneReader::QCLuceneReader()
+ : d(new QCLuceneReaderPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneReader::~QCLuceneReader()
+{
+ // nothing todo
+}
+
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string);
+}
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value, qint32 length)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string, int32_t(length));
+}
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value, qint32 length,
+ bool copyData)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string, int32_t(length), copyData);
+}
+
+QCLuceneStringReader::~QCLuceneStringReader()
+{
+ delete [] string;
+}
+
+
+QCLuceneFileReader::QCLuceneFileReader(const QString &path, const QString &encoding,
+ qint32 cacheLength, qint32 cacheBuffer)
+ : QCLuceneReader()
+{
+ const QByteArray tmpPath = path.toLocal8Bit();
+ const QByteArray tmpEncoding = encoding.toAscii();
+ d->reader = new lucene::util::FileReader(tmpPath.constData(),
+ tmpEncoding.constData(), int32_t(cacheLength), int32_t(cacheBuffer));
+}
+
+QCLuceneFileReader::~QCLuceneFileReader()
+{
+ // nothing todo
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qreader_p.h b/tools/assistant/lib/fulltextsearch/qreader_p.h
new file mode 100644
index 0000000000..77c80077da
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qreader_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QREADER_P_H
+#define QREADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(util)
+ class Reader;
+CL_NS_END
+CL_NS_USE(util)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneField;
+class QCLuceneAnalyzer;
+class QCLuceneDocument;
+class QCLuceneQueryParser;
+class QCLuceneStandardTokenizer;
+
+class QHELP_EXPORT QCLuceneReaderPrivate : public QSharedData
+{
+public:
+ QCLuceneReaderPrivate();
+ QCLuceneReaderPrivate(const QCLuceneReaderPrivate &other);
+
+ ~QCLuceneReaderPrivate();
+
+ Reader* reader;
+ bool deleteCLuceneReader;
+
+private:
+ QCLuceneReaderPrivate &operator=(const QCLuceneReaderPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneReader
+{
+public:
+ QCLuceneReader();
+ virtual ~QCLuceneReader();
+
+protected:
+ friend class QCLuceneField;
+ friend class QCLuceneAnalyzer;
+ friend class QCLuceneDocument;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneStandardTokenizer;
+ QSharedDataPointer<QCLuceneReaderPrivate> d;
+};
+
+class QCLuceneStringReader : public QCLuceneReader
+{
+public:
+ QCLuceneStringReader(const QString &value);
+ QCLuceneStringReader(const QString &value, qint32 length);
+ QCLuceneStringReader(const QString &value, qint32 length, bool copyData);
+
+ ~QCLuceneStringReader();
+
+private:
+ TCHAR *string;
+};
+
+class QHELP_EXPORT QCLuceneFileReader : public QCLuceneReader
+{
+public:
+ QCLuceneFileReader(const QString &path, const QString &encoding,
+ qint32 cacheLength = 13, qint32 cacheBuffer = 14);
+ ~QCLuceneFileReader();
+};
+
+QT_END_NAMESPACE
+
+#endif // QREADER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qsearchable.cpp b/tools/assistant/lib/fulltextsearch/qsearchable.cpp
new file mode 100644
index 0000000000..2d76b02de3
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qsearchable.cpp
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qsearchable_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneSearchablePrivate::QCLuceneSearchablePrivate()
+ : QSharedData()
+{
+ searchable = 0;
+ deleteCLuceneSearchable = true;
+}
+
+QCLuceneSearchablePrivate::QCLuceneSearchablePrivate(const QCLuceneSearchablePrivate &other)
+ : QSharedData()
+{
+ searchable = _CL_POINTER(other.searchable);
+}
+
+QCLuceneSearchablePrivate::~QCLuceneSearchablePrivate()
+{
+ if (deleteCLuceneSearchable)
+ _CLDECDELETE(searchable);
+}
+
+
+QCLuceneSearchable::QCLuceneSearchable()
+ : d(new QCLuceneSearchablePrivate())
+{
+ // nothing todo
+}
+
+QCLuceneSearchable::~QCLuceneSearchable()
+{
+ // nothing todo
+}
+
+
+QCLuceneSearcher::QCLuceneSearcher()
+ : QCLuceneSearchable()
+{
+ // nothing todo
+}
+
+QCLuceneSearcher::~QCLuceneSearcher()
+{
+ // nothing todo;
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query)
+{
+ return search(query, QCLuceneFilter());
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneFilter &filter)
+{
+ return QCLuceneHits(*this, query, filter);
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneSort &sort)
+{
+ return QCLuceneHits(*this, query, QCLuceneFilter(), sort);
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneFilter &filter,
+ const QCLuceneSort &sort)
+{
+ return QCLuceneHits(*this, query, filter, sort);
+}
+
+
+QCLuceneIndexSearcher::QCLuceneIndexSearcher(const QString &path)
+ : QCLuceneSearcher()
+{
+ lucene::search::IndexSearcher *searcher =
+ new lucene::search::IndexSearcher(path);
+
+ reader.d->reader = searcher->getReader();
+ reader.d->deleteCLuceneIndexReader = false;
+
+ d->searchable = searcher;
+}
+
+QCLuceneIndexSearcher::QCLuceneIndexSearcher(const QCLuceneIndexReader &reader)
+ : QCLuceneSearcher()
+ , reader(reader)
+{
+ d->searchable = new lucene::search::IndexSearcher(reader.d->reader);
+}
+
+QCLuceneIndexSearcher::~QCLuceneIndexSearcher()
+{
+ // nothing todo
+}
+
+void QCLuceneIndexSearcher::close()
+{
+ d->searchable->close();
+}
+
+qint32 QCLuceneIndexSearcher::maxDoc() const
+{
+ return qint32(d->searchable->maxDoc());
+}
+
+QCLuceneIndexReader QCLuceneIndexSearcher::getReader()
+{
+ return reader;
+}
+
+bool QCLuceneIndexSearcher::doc(qint32 i, QCLuceneDocument &document)
+{
+ return d->searchable->doc(int32_t(i), document.d->document);
+}
+
+
+QCLuceneMultiSearcher::QCLuceneMultiSearcher(const QList<QCLuceneSearchable> searchables)
+: QCLuceneSearcher()
+{
+ lucene::search::Searchable** list=
+ _CL_NEWARRAY(lucene::search::Searchable*, searchables.count());
+
+ d->searchable = new lucene::search::MultiSearcher(list);
+
+ _CLDELETE_ARRAY(list);
+}
+
+QCLuceneMultiSearcher::~QCLuceneMultiSearcher()
+{
+ // nothing todo
+}
+
+void QCLuceneMultiSearcher::close()
+{
+ d->searchable->close();
+}
+
+qint32 QCLuceneMultiSearcher::maxDoc() const
+{
+ return qint32(d->searchable->maxDoc());
+}
+
+qint32 QCLuceneMultiSearcher::subDoc(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->subDoc(int32_t(index)));
+}
+
+qint32 QCLuceneMultiSearcher::subSearcher(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->subSearcher(int32_t(index)));
+}
+
+qint32 QCLuceneMultiSearcher::searcherIndex(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->searcherIndex(int32_t(index)));
+}
+
+bool QCLuceneMultiSearcher::doc(qint32 i, QCLuceneDocument &document)
+{
+ return d->searchable->doc(int32_t(i), document.d->document);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qsearchable_p.h b/tools/assistant/lib/fulltextsearch/qsearchable_p.h
new file mode 100644
index 0000000000..8e4da4443f
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qsearchable_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QSEARCHABLE_P_H
+#define QSEARCHABLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhits_p.h"
+#include "qsort_p.h"
+#include "qquery_p.h"
+#include "qfilter_p.h"
+#include "qdocument_p.h"
+#include "qindexreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Searcher;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneSearcher;
+class QCLuceneIndexSearcher;
+class QCLuceneMultiSearcher;
+
+class QHELP_EXPORT QCLuceneSearchablePrivate : public QSharedData
+{
+public:
+ QCLuceneSearchablePrivate();
+ QCLuceneSearchablePrivate(const QCLuceneSearchablePrivate &other);
+
+ ~QCLuceneSearchablePrivate();
+
+ Searcher *searchable;
+ bool deleteCLuceneSearchable;
+
+private:
+ QCLuceneSearchablePrivate &operator=(const QCLuceneSearchablePrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneSearchable
+{
+public:
+ virtual ~QCLuceneSearchable();
+
+protected:
+ friend class QCLuceneSearcher;
+ friend class QCLuceneIndexSearcher;
+ friend class QCLuceneMultiSearcher;
+ QSharedDataPointer<QCLuceneSearchablePrivate> d;
+
+private:
+ QCLuceneSearchable();
+};
+
+class QHELP_EXPORT QCLuceneSearcher : public QCLuceneSearchable
+{
+public:
+ QCLuceneSearcher();
+ virtual ~QCLuceneSearcher();
+
+ QCLuceneHits search(const QCLuceneQuery &query);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneFilter &filter);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneSort &sort);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneFilter &filter,
+ const QCLuceneSort &sort);
+
+protected:
+ friend class QCLuceneHits;
+};
+
+class QHELP_EXPORT QCLuceneIndexSearcher : public QCLuceneSearcher
+{
+public:
+ QCLuceneIndexSearcher(const QString &path);
+ QCLuceneIndexSearcher(const QCLuceneIndexReader &reader);
+ ~QCLuceneIndexSearcher();
+
+ void close();
+ qint32 maxDoc() const;
+ QCLuceneIndexReader getReader();
+ bool doc(qint32 i, QCLuceneDocument &document);
+
+private:
+ QCLuceneIndexReader reader;
+};
+
+class QHELP_EXPORT QCLuceneMultiSearcher : public QCLuceneSearcher
+{
+public:
+ QCLuceneMultiSearcher(const QList<QCLuceneSearchable> searchables);
+ ~QCLuceneMultiSearcher();
+
+ void close();
+ qint32 maxDoc() const;
+ qint32 subDoc(qint32 index) const;
+ qint32 subSearcher(qint32 index) const;
+ qint32 searcherIndex(qint32 index) const;
+ bool doc(qint32 i, QCLuceneDocument &document);
+};
+
+QT_END_NAMESPACE
+
+#endif // QSEARCHABLE_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qsort.cpp b/tools/assistant/lib/fulltextsearch/qsort.cpp
new file mode 100644
index 0000000000..06d7276259
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qsort.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qsort_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/Sort.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneSortPrivate::QCLuceneSortPrivate()
+ : QSharedData()
+{
+ sort = 0;
+ deleteCLuceneSort = true;
+}
+
+QCLuceneSortPrivate::QCLuceneSortPrivate (const QCLuceneSortPrivate &other)
+ : QSharedData()
+{
+ sort = _CL_POINTER(other.sort);
+}
+
+QCLuceneSortPrivate::~QCLuceneSortPrivate()
+{
+ if (deleteCLuceneSort)
+ _CLDECDELETE(sort);
+}
+
+
+QCLuceneSort::QCLuceneSort()
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+}
+
+QCLuceneSort::QCLuceneSort(const QStringList &fieldNames)
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+ setSort(fieldNames);
+}
+
+QCLuceneSort::QCLuceneSort(const QString &field, bool reverse)
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+ setSort(field, reverse);
+}
+
+QCLuceneSort::~QCLuceneSort()
+{
+ // nothing todo
+}
+
+QString QCLuceneSort::toString() const
+{
+ return TCharToQString(d->sort->toString());
+}
+
+void QCLuceneSort::setSort(const QStringList &fieldNames)
+{
+ TCHAR **nameArray = new TCHAR*[fieldNames.count()];
+ for (int i = 0; i < fieldNames.count(); ++i)
+ nameArray[i] = QStringToTChar(fieldNames.at(i));
+
+ d->sort->setSort((const TCHAR**)nameArray);
+
+ for (int i = 0; i < fieldNames.count(); ++i)
+ delete [] nameArray[i];
+ delete nameArray;
+}
+
+void QCLuceneSort::setSort(const QString &field, bool reverse)
+{
+ TCHAR *name = QStringToTChar(field);
+ d->sort->setSort(name, reverse);
+ delete [] name;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qsort_p.h b/tools/assistant/lib/fulltextsearch/qsort_p.h
new file mode 100644
index 0000000000..5ec2a06f02
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qsort_p.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 QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QSORT_P_H
+#define QSORT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Sort;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneField;
+
+class QHELP_EXPORT QCLuceneSortPrivate : public QSharedData
+{
+public:
+ QCLuceneSortPrivate();
+ QCLuceneSortPrivate (const QCLuceneSortPrivate &other);
+
+ ~QCLuceneSortPrivate();
+
+ Sort *sort;
+ bool deleteCLuceneSort;
+
+private:
+ QCLuceneSortPrivate &operator=(const QCLuceneSortPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneSort
+{
+public:
+ QCLuceneSort();
+ QCLuceneSort(const QStringList &fieldNames);
+ QCLuceneSort(const QString &field, bool reverse = false);
+
+ virtual ~QCLuceneSort();
+
+ QString toString() const;
+ void setSort(const QStringList &fieldNames);
+ void setSort(const QString &field, bool reverse = false);
+
+protected:
+ friend class QCLuceneHits;
+ QSharedDataPointer<QCLuceneSortPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSORT_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qterm.cpp b/tools/assistant/lib/fulltextsearch/qterm.cpp
new file mode 100644
index 0000000000..156586f645
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qterm.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qterm_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexReader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTermPrivate::QCLuceneTermPrivate()
+ : QSharedData()
+{
+ term = 0;
+ deleteCLuceneTerm = true;
+}
+
+QCLuceneTermPrivate::QCLuceneTermPrivate(const QCLuceneTermPrivate &other)
+ : QSharedData()
+{
+ term = _CL_POINTER(other.term);
+}
+
+QCLuceneTermPrivate::~QCLuceneTermPrivate()
+{
+ if (deleteCLuceneTerm)
+ _CLDECDELETE(term);
+}
+
+
+QCLuceneTerm::QCLuceneTerm()
+ : d(new QCLuceneTermPrivate())
+{
+ d->term = new lucene::index::Term();
+}
+
+QCLuceneTerm::QCLuceneTerm(const QString &field, const QString &text)
+ : d(new QCLuceneTermPrivate())
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ TCHAR *termText = QStringToTChar(text);
+
+ d->term = new lucene::index::Term(fieldName, termText);
+
+ delete [] fieldName;
+ delete [] termText;
+}
+
+QCLuceneTerm::QCLuceneTerm(const QCLuceneTerm &fieldTerm, const QString &text)
+ : d(new QCLuceneTermPrivate())
+{
+ TCHAR *termText = QStringToTChar(text);
+ d->term = new lucene::index::Term(fieldTerm.d->term, termText);
+ delete [] termText;
+}
+
+QCLuceneTerm::~QCLuceneTerm()
+{
+ // nothing todo
+}
+
+QString QCLuceneTerm::field() const
+{
+ return TCharToQString(d->term->field());
+}
+
+QString QCLuceneTerm::text() const
+{
+ return TCharToQString(d->term->text());
+}
+
+void QCLuceneTerm::set(const QString &field, const QString &text)
+{
+ set(field, text, true);
+}
+
+void QCLuceneTerm::set(const QCLuceneTerm &fieldTerm, const QString &text)
+{
+ set(fieldTerm.field(), text, false);
+}
+
+void QCLuceneTerm::set(const QString &field, const QString &text, bool internField)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ TCHAR *termText = QStringToTChar(text);
+
+ d->term->set(fieldName, termText, internField);
+
+ delete [] fieldName;
+ delete [] termText;
+}
+
+bool QCLuceneTerm::equals(const QCLuceneTerm &other) const
+{
+ return d->term->equals(other.d->term);
+}
+
+qint32 QCLuceneTerm::compareTo(const QCLuceneTerm &other) const
+{
+ return quint32(d->term->compareTo(other.d->term));
+}
+
+QString QCLuceneTerm::toString() const
+{
+ return TCharToQString(d->term->toString());
+}
+
+quint32 QCLuceneTerm::hashCode() const
+{
+ return quint32(d->term->hashCode());
+}
+
+quint32 QCLuceneTerm::textLength() const
+{
+ return quint32(d->term->textLength());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qterm_p.h b/tools/assistant/lib/fulltextsearch/qterm_p.h
new file mode 100644
index 0000000000..474c909f3a
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qterm_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QTERM_P_H
+#define QTERM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+
+CL_NS_DEF(index)
+ class Term;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneTermQuery;
+class QCLuceneRangeQuery;
+class QCLucenePrefixQuery;
+class QCLuceneIndexReader;
+class QCLucenePhraseQuery;
+
+class QHELP_EXPORT QCLuceneTermPrivate : public QSharedData
+{
+public:
+ QCLuceneTermPrivate();
+ QCLuceneTermPrivate(const QCLuceneTermPrivate &other);
+
+ ~QCLuceneTermPrivate();
+
+ Term *term;
+ bool deleteCLuceneTerm;
+
+private:
+ QCLuceneTermPrivate &operator=(const QCLuceneTermPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneTerm
+{
+public:
+ QCLuceneTerm();
+ QCLuceneTerm(const QString &field, const QString &text);
+ QCLuceneTerm(const QCLuceneTerm &fieldTerm, const QString &text);
+
+ virtual ~QCLuceneTerm();
+
+ QString field() const;
+ QString text() const;
+
+ void set(const QString &field, const QString &text);
+ void set(const QCLuceneTerm &fieldTerm, const QString &text);
+ void set(const QString &field, const QString &text, bool internField);
+
+ bool equals(const QCLuceneTerm &other) const;
+ qint32 compareTo(const QCLuceneTerm &other) const;
+
+ QString toString() const;
+ quint32 hashCode() const;
+ quint32 textLength() const;
+
+protected:
+ friend class QCLuceneTermQuery;
+ friend class QCLuceneRangeQuery;
+ friend class QCLucenePrefixQuery;
+ friend class QCLuceneIndexReader;
+ friend class QCLucenePhraseQuery;
+ QSharedDataPointer<QCLuceneTermPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTERM_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qtoken.cpp b/tools/assistant/lib/fulltextsearch/qtoken.cpp
new file mode 100644
index 0000000000..fa5d62a518
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtoken.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qtoken_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenPrivate::QCLuceneTokenPrivate()
+ : QSharedData()
+{
+ token = 0;
+ deleteCLuceneToken = true;
+}
+
+QCLuceneTokenPrivate::QCLuceneTokenPrivate(const QCLuceneTokenPrivate &other)
+ : QSharedData()
+{
+ token = _CL_POINTER(other.token);
+}
+
+QCLuceneTokenPrivate::~QCLuceneTokenPrivate()
+{
+ if (deleteCLuceneToken)
+ _CLDECDELETE(token);
+}
+
+
+QCLuceneToken::QCLuceneToken()
+ : d(new QCLuceneTokenPrivate())
+ , tokenText(0)
+ , tokenType(0)
+{
+ d->token = new lucene::analysis::Token();
+}
+
+QCLuceneToken::QCLuceneToken(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp)
+ : d(new QCLuceneTokenPrivate())
+ , tokenText(QStringToTChar(text))
+ , tokenType(QStringToTChar(defaultTyp))
+{
+ d->token = new lucene::analysis::Token(tokenText, int32_t(startOffset),
+ int32_t(endOffset), tokenType);
+}
+
+QCLuceneToken::~QCLuceneToken()
+{
+ delete [] tokenText;
+ delete [] tokenType;
+}
+
+quint32 QCLuceneToken::bufferLength() const
+{
+ return quint32(d->token->bufferLength());
+}
+
+void QCLuceneToken::growBuffer(quint32 size)
+{
+ d->token->growBuffer(size_t(size));
+}
+
+qint32 QCLuceneToken::positionIncrement() const
+{
+ return qint32(d->token->getPositionIncrement());
+}
+
+void QCLuceneToken::setPositionIncrement(qint32 positionIncrement)
+{
+ d->token->setPositionIncrement(int32_t(positionIncrement));
+}
+
+QString QCLuceneToken::termText() const
+{
+ return TCharToQString(d->token->termText());
+}
+
+void QCLuceneToken::setTermText(const QString &text)
+{
+ delete [] tokenText;
+ tokenText = QStringToTChar(text);
+ d->token->setText(tokenText);
+}
+
+quint32 QCLuceneToken::termTextLength() const
+{
+ return quint32(d->token->termTextLength());
+}
+
+void QCLuceneToken::resetTermTextLength() const
+{
+ d->token->resetTermTextLen();
+}
+
+qint32 QCLuceneToken::startOffset() const
+{
+ return quint32(d->token->startOffset());
+}
+
+void QCLuceneToken::setStartOffset(qint32 value)
+{
+ d->token->setStartOffset(int32_t(value));
+}
+
+qint32 QCLuceneToken::endOffset() const
+{
+ return quint32(d->token->endOffset());
+}
+
+void QCLuceneToken::setEndOffset(qint32 value)
+{
+ d->token->setEndOffset(int32_t(value));
+}
+
+QString QCLuceneToken::type() const
+{
+ return TCharToQString(d->token->type());
+}
+
+void QCLuceneToken::setType(const QString &type)
+{
+ delete [] tokenType;
+ tokenType = QStringToTChar(type);
+ d->token->setType(tokenType);
+}
+
+QString QCLuceneToken::toString() const
+{
+ return TCharToQString(d->token->toString());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qtoken_p.h b/tools/assistant/lib/fulltextsearch/qtoken_p.h
new file mode 100644
index 0000000000..1802f991b0
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtoken_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QTOKEN_P_H
+#define QTOKEN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class Token;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneTokenizer;
+class QCLuceneTokenStream;
+class QCLuceneStandardTokenizer;
+
+class QHELP_EXPORT QCLuceneTokenPrivate : public QSharedData
+{
+public:
+ QCLuceneTokenPrivate();
+ QCLuceneTokenPrivate(const QCLuceneTokenPrivate &other);
+
+ ~QCLuceneTokenPrivate();
+
+ Token *token;
+ bool deleteCLuceneToken;
+
+private:
+ QCLuceneTokenPrivate &operator=(const QCLuceneTokenPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneToken
+{
+public:
+ QCLuceneToken();
+ QCLuceneToken(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp = QLatin1String("word"));
+
+ virtual ~QCLuceneToken();
+
+ void set(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp = QLatin1String("word"));
+
+ quint32 bufferLength() const;
+ void growBuffer(quint32 size);
+
+ qint32 positionIncrement() const;
+ void setPositionIncrement(qint32 positionIncrement);
+
+ QString termText() const;
+ void setTermText(const QString &text);
+
+ quint32 termTextLength() const;
+ void resetTermTextLength() const;
+
+ qint32 startOffset() const;
+ void setStartOffset(qint32 value);
+
+ qint32 endOffset() const;
+ void setEndOffset(qint32 value);
+
+ QString type() const;
+ void setType(const QString &type);
+
+ QString toString() const;
+
+protected:
+ friend class QCLuceneTokenizer;
+ friend class QCLuceneTokenStream;
+ friend class QCLuceneStandardTokenizer;
+ QSharedDataPointer<QCLuceneTokenPrivate> d;
+
+private:
+ TCHAR *tokenText;
+ TCHAR *tokenType;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKEN_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qtokenizer.cpp b/tools/assistant/lib/fulltextsearch/qtokenizer.cpp
new file mode 100644
index 0000000000..9a07387a6f
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtokenizer.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qtokenizer_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenizer::QCLuceneTokenizer()
+ : QCLuceneTokenStream()
+{
+ // nothing todo
+}
+
+QCLuceneTokenizer::QCLuceneTokenizer(const QCLuceneReader &reader)
+ : QCLuceneTokenStream()
+ , reader(reader)
+{
+ // nothing todo
+}
+
+QCLuceneTokenizer::~QCLuceneTokenizer()
+{
+ close();
+}
+
+void QCLuceneTokenizer::close()
+{
+ d->tokenStream->close();
+}
+
+bool QCLuceneTokenizer::next(QCLuceneToken &token)
+{
+ return d->tokenStream->next(token.d->token);
+}
+
+
+QCLuceneStandardTokenizer::QCLuceneStandardTokenizer(const QCLuceneReader &reader)
+ : QCLuceneTokenizer(reader)
+{
+ d->tokenStream =
+ new lucene::analysis::standard::StandardTokenizer(reader.d->reader);
+}
+
+QCLuceneStandardTokenizer::~QCLuceneStandardTokenizer()
+{
+ // nothing todo
+}
+
+bool QCLuceneStandardTokenizer::readApostrophe(const QString &string,
+ QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadApostrophe(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+bool QCLuceneStandardTokenizer::readAt(const QString &string, QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadAt(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+bool QCLuceneStandardTokenizer::readCompany(const QString &string,
+ QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadCompany(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/fulltextsearch/qtokenizer_p.h b/tools/assistant/lib/fulltextsearch/qtokenizer_p.h
new file mode 100644
index 0000000000..1e7916c111
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtokenizer_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QTOKENIZER_P_H
+#define QTOKENIZER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtoken_p.h"
+#include "qreader_p.h"
+#include "qtokenstream_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class QHELP_EXPORT QCLuceneTokenizer : public QCLuceneTokenStream
+{
+public:
+ QCLuceneTokenizer(const QCLuceneReader &reader);
+ virtual ~QCLuceneTokenizer();
+
+ void close();
+ bool next(QCLuceneToken &token);
+
+protected:
+ friend class QCLuceneStandardTokenizer;
+
+private:
+ QCLuceneTokenizer();
+ QCLuceneReader reader;
+};
+
+class QHELP_EXPORT QCLuceneStandardTokenizer : public QCLuceneTokenizer
+{
+public:
+ QCLuceneStandardTokenizer(const QCLuceneReader &reader);
+ ~QCLuceneStandardTokenizer();
+
+ bool readApostrophe(const QString &string, QCLuceneToken &token);
+ bool readAt(const QString &string, QCLuceneToken &token);
+ bool readCompany(const QString &string, QCLuceneToken &token);
+};
+
+class QCLuceneCharTokenizer : public QCLuceneTokenizer
+{
+
+};
+
+class QCLuceneLetterTokenizer : public QCLuceneCharTokenizer
+{
+
+};
+
+class QCLuceneLowerCaseTokenizer : public QCLuceneLetterTokenizer
+{
+
+};
+
+class QCLuceneWhitespaceTokenizer : public QCLuceneCharTokenizer
+{
+
+};
+
+class QCLuceneKeywordTokenizer : public QCLuceneTokenizer
+{
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKENIZER_P_H
diff --git a/tools/assistant/lib/fulltextsearch/qtokenstream.cpp b/tools/assistant/lib/fulltextsearch/qtokenstream.cpp
new file mode 100644
index 0000000000..957a0c2c88
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtokenstream.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#include "qtokenstream_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenStreamPrivate::QCLuceneTokenStreamPrivate()
+ : QSharedData()
+{
+ tokenStream = 0;
+ deleteCLuceneTokenStream = true;
+}
+
+QCLuceneTokenStreamPrivate::QCLuceneTokenStreamPrivate(const QCLuceneTokenStreamPrivate &other)
+ : QSharedData()
+{
+ tokenStream = _CL_POINTER(other.tokenStream);
+}
+
+QCLuceneTokenStreamPrivate::~QCLuceneTokenStreamPrivate()
+{
+ if (deleteCLuceneTokenStream)
+ _CLDECDELETE(tokenStream);
+}
+
+
+QCLuceneTokenStream::QCLuceneTokenStream()
+ : d(new QCLuceneTokenStreamPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneTokenStream::~QCLuceneTokenStream()
+{
+ // nothing todo
+}
+
+void QCLuceneTokenStream::close()
+{
+ d->tokenStream->close();
+}
+
+bool QCLuceneTokenStream::next(QCLuceneToken &token)
+{
+ return d->tokenStream->next(token.d->token);
+}
+
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/tools/assistant/lib/fulltextsearch/qtokenstream_p.h b/tools/assistant/lib/fulltextsearch/qtokenstream_p.h
new file mode 100644
index 0000000000..ef6e71585f
--- /dev/null
+++ b/tools/assistant/lib/fulltextsearch/qtokenstream_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QCLucene library and is distributable under
+** the terms of the LGPL license as specified in the license.txt file.
+**
+****************************************************************************/
+
+#ifndef QTOKENSTREAM_P_H
+#define QTOKENSTREAM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtoken_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class TokenStream;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneAnalyzer;
+class QCLuceneTokenizer;
+class QCLuceneStopAnalyzer;
+class QCLuceneSimpleAnalyzer;
+class QCLuceneKeywordAnalyzer;
+class QCLuceneStandardAnalyzer;
+class QCLuceneWhitespaceAnalyzer;
+class QCLucenePerFieldAnalyzerWrapper;
+
+class QHELP_EXPORT QCLuceneTokenStreamPrivate : public QSharedData
+{
+public:
+ QCLuceneTokenStreamPrivate();
+ QCLuceneTokenStreamPrivate(const QCLuceneTokenStreamPrivate &other);
+
+ ~QCLuceneTokenStreamPrivate();
+
+ TokenStream *tokenStream;
+ bool deleteCLuceneTokenStream;
+
+private:
+ QCLuceneTokenStreamPrivate &operator=(const QCLuceneTokenStreamPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneTokenStream
+{
+public:
+ virtual ~QCLuceneTokenStream();
+
+ void close();
+ bool next(QCLuceneToken &token);
+
+protected:
+ friend class QCLuceneAnalyzer;
+ friend class QCLuceneTokenizer;
+ friend class QCLuceneStopAnalyzer;
+ friend class QCLuceneSimpleAnalyzer;
+ friend class QCLuceneKeywordAnalyzer;
+ friend class QCLuceneStandardAnalyzer;
+ friend class QCLuceneWhitespaceAnalyzer;
+ friend class QCLucenePerFieldAnalyzerWrapper;
+ QSharedDataPointer<QCLuceneTokenStreamPrivate> d;
+
+private:
+ QCLuceneTokenStream();
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKENSTREAM_P_H
diff --git a/tools/assistant/lib/helpsystem.qrc b/tools/assistant/lib/helpsystem.qrc
new file mode 100644
index 0000000000..10efc6df18
--- /dev/null
+++ b/tools/assistant/lib/helpsystem.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>images/1leftarrow.png</file>
+ <file>images/1rightarrow.png</file>
+ <file>images/3leftarrow.png</file>
+ <file>images/3rightarrow.png</file>
+ </qresource>
+</RCC>
diff --git a/tools/assistant/lib/images/1leftarrow.png b/tools/assistant/lib/images/1leftarrow.png
new file mode 100644
index 0000000000..bd1a5a2499
--- /dev/null
+++ b/tools/assistant/lib/images/1leftarrow.png
Binary files differ
diff --git a/tools/assistant/lib/images/1rightarrow.png b/tools/assistant/lib/images/1rightarrow.png
new file mode 100644
index 0000000000..0c0c44ae6f
--- /dev/null
+++ b/tools/assistant/lib/images/1rightarrow.png
Binary files differ
diff --git a/tools/assistant/lib/images/3leftarrow.png b/tools/assistant/lib/images/3leftarrow.png
new file mode 100644
index 0000000000..8d38b0f578
--- /dev/null
+++ b/tools/assistant/lib/images/3leftarrow.png
Binary files differ
diff --git a/tools/assistant/lib/images/3rightarrow.png b/tools/assistant/lib/images/3rightarrow.png
new file mode 100644
index 0000000000..c2faf501cc
--- /dev/null
+++ b/tools/assistant/lib/images/3rightarrow.png
Binary files differ
diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro
new file mode 100644
index 0000000000..bd9ed5370e
--- /dev/null
+++ b/tools/assistant/lib/lib.pro
@@ -0,0 +1,65 @@
+QT += sql xml network
+TEMPLATE = lib
+TARGET = QtHelp
+DEFINES += QHELP_LIB QT_CLUCENE_SUPPORT
+CONFIG += qt warn_on
+
+include(../../../src/qbase.pri)
+
+QMAKE_TARGET_PRODUCT = Help
+QMAKE_TARGET_DESCRIPTION = Help application framework.
+DEFINES -= QT_ASCII_CAST_WARNINGS
+
+qclucene = QtCLucene$${QT_LIBINFIX}
+if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
+ mac:qclucene = $${qclucene}_debug
+ win32:qclucene = $${qclucene}d
+}
+linux-lsb-g++:LIBS += --lsb-shared-libs=$$qclucene
+unix:QMAKE_PKGCONFIG_REQUIRES += QtNetwork QtSql QtXml
+LIBS += -l$$qclucene
+unix:QMAKE_PKGCONFIG_REQUIRES += QtNetwork QtSql QtXml
+
+RESOURCES += helpsystem.qrc
+
+SOURCES += qhelpenginecore.cpp \
+ qhelpengine.cpp \
+ qhelpdbreader.cpp \
+ qhelpcontentwidget.cpp \
+ qhelpindexwidget.cpp \
+ qhelpgenerator.cpp \
+ qhelpdatainterface.cpp \
+ qhelpprojectdata.cpp \
+ qhelpcollectionhandler.cpp \
+ qhelpsearchengine.cpp \
+ qhelpsearchquerywidget.cpp \
+ qhelpsearchresultwidget.cpp \
+ qhelpsearchindex_default.cpp \
+ qhelpsearchindexwriter_default.cpp \
+ qhelpsearchindexreader_default.cpp
+
+# access to clucene
+SOURCES += qhelpsearchindexwriter_clucene.cpp \
+ qhelpsearchindexreader_clucene.cpp
+
+HEADERS += qhelpenginecore.h \
+ qhelpengine.h \
+ qhelpengine_p.h \
+ qhelp_global.h \
+ qhelpdbreader_p.h \
+ qhelpcontentwidget.h \
+ qhelpindexwidget.h \
+ qhelpgenerator_p.h \
+ qhelpdatainterface_p.h \
+ qhelpprojectdata_p.h \
+ qhelpcollectionhandler_p.h \
+ qhelpsearchengine.h \
+ qhelpsearchquerywidget.h \
+ qhelpsearchresultwidget.h \
+ qhelpsearchindex_default_p.h \
+ qhelpsearchindexwriter_default_p.h \
+ qhelpsearchindexreader_default_p.h
+
+# access to clucene
+HEADERS += qhelpsearchindexwriter_clucene_p.h \
+ qhelpsearchindexreader_clucene_p.h
diff --git a/tools/assistant/lib/qhelp_global.h b/tools/assistant/lib/qhelp_global.h
new file mode 100644
index 0000000000..5f09a0807d
--- /dev/null
+++ b/tools/assistant/lib/qhelp_global.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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 QHELP_GLOBAL_H
+#define QHELP_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QString>
+#include <QtCore/QObject>
+#include <QtCore/QRegExp>
+#include <QtCore/QMutexLocker>
+#include <QtGui/QTextDocument>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+#if !defined(QT_SHARED) && !defined(QT_DLL)
+# define QHELP_EXPORT
+#elif defined(QHELP_LIB)
+# define QHELP_EXPORT Q_DECL_EXPORT
+#else
+# define QHELP_EXPORT Q_DECL_IMPORT
+#endif
+
+class QHelpGlobal {
+public:
+ static QString uniquifyConnectionName(const QString &name, void *pointer)
+ {
+ static int counter = 0;
+ static QMutex mutex;
+
+ QMutexLocker locker(&mutex);
+ if (++counter > 1000)
+ counter = 0;
+
+ return QString::fromLatin1("%1-%2-%3")
+ .arg(name).arg(long(pointer)).arg(counter);
+ };
+
+ static QString documentTitle(const QString &content)
+ {
+ QString title = QObject::tr("Untitled");
+ if (!content.isEmpty()) {
+ int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
+ int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
+ if ((end - start) > 0) {
+ title = content.mid(start, end - start);
+ if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) {
+ QTextDocument doc;
+ doc.setHtml(title);
+ title = doc.toPlainText();
+ }
+ }
+ }
+ return title;
+ };
+
+ static QString charsetFromData(const QByteArray &data)
+ {
+ QString content = QString::fromUtf8(data.constData(), data.size());
+ int start =
+ content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
+ if (start > 0) {
+ int end;
+ QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
+ while (start != -1) {
+ end = content.indexOf(QLatin1Char('>'), start) + 1;
+ const QString &meta = content.mid(start, end - start).toLower();
+ if (r.indexIn(meta) != -1)
+ return r.cap(1);
+ start = content.indexOf(QLatin1String("<meta"), end,
+ Qt::CaseInsensitive);
+ }
+ }
+ return QLatin1String("utf-8");
+ }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELP_GLOBAL_H
diff --git a/tools/assistant/lib/qhelpcollectionhandler.cpp b/tools/assistant/lib/qhelpcollectionhandler.cpp
new file mode 100644
index 0000000000..235659193f
--- /dev/null
+++ b/tools/assistant/lib/qhelpcollectionhandler.cpp
@@ -0,0 +1,595 @@
+/****************************************************************************
+**
+** 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 "qhelpcollectionhandler_p.h"
+#include "qhelp_global.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+
+#include <QtSql/QSqlError>
+#include <QtSql/QSqlDriver>
+
+QT_BEGIN_NAMESPACE
+
+QHelpCollectionHandler::QHelpCollectionHandler(const QString &collectionFile, QObject *parent)
+ : QObject(parent)
+ , m_dbOpened(false)
+ , m_collectionFile(collectionFile)
+ , m_connectionName(QString())
+{
+ QFileInfo fi(m_collectionFile);
+ if (!fi.isAbsolute())
+ m_collectionFile = fi.absoluteFilePath();
+ m_query.clear();
+}
+
+QHelpCollectionHandler::~QHelpCollectionHandler()
+{
+ m_query.clear();
+ if (m_dbOpened)
+ QSqlDatabase::removeDatabase(m_connectionName);
+}
+
+bool QHelpCollectionHandler::isDBOpened()
+{
+ if (m_dbOpened)
+ return true;
+ emit error(tr("The collection file is not set up yet!"));
+ return false;
+}
+
+QString QHelpCollectionHandler::collectionFile() const
+{
+ return m_collectionFile;
+}
+
+bool QHelpCollectionHandler::openCollectionFile()
+{
+ if (m_dbOpened)
+ return m_dbOpened;
+
+ m_connectionName = QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandler"), this);
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"),
+ m_connectionName);
+ if (db.driver()
+ && db.driver()->lastError().type() == QSqlError::ConnectionError) {
+ emit error(tr("Cannot load sqlite database driver!"));
+ return false;
+ }
+
+ db.setDatabaseName(collectionFile());
+ openingOk = db.open();
+ if (openingOk)
+ m_query = QSqlQuery(db);
+ }
+ if (!openingOk) {
+ QSqlDatabase::removeDatabase(m_connectionName);
+ emit error(tr("Cannot open collection file: %1").arg(collectionFile()));
+ return false;
+ }
+
+ m_query.exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
+ "AND Name=\'NamespaceTable\'"));
+ m_query.next();
+ if (m_query.value(0).toInt() < 1) {
+ if (!createTables(&m_query)) {
+ emit error(tr("Cannot create tables in file %1!").arg(collectionFile()));
+ return false;
+ }
+ }
+
+ m_dbOpened = true;
+ return m_dbOpened;
+}
+
+bool QHelpCollectionHandler::copyCollectionFile(const QString &fileName)
+{
+ if (!m_dbOpened)
+ return false;
+
+ QFileInfo fi(fileName);
+ if (fi.exists()) {
+ emit error(tr("The specified collection file already exists!"));
+ return false;
+ }
+
+ if (!fi.absoluteDir().exists() && !QDir().mkpath(fi.absolutePath())) {
+ emit error(tr("Cannot create directory: %1").arg(fi.absolutePath()));
+ return false;
+ }
+
+ QString colFile = fi.absoluteFilePath();
+ QString connectionName = QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandlerCopy"), this);
+ QSqlQuery *copyQuery = 0;
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), connectionName);
+ db.setDatabaseName(colFile);
+ openingOk = db.open();
+ if (openingOk)
+ copyQuery = new QSqlQuery(db);
+ }
+
+ if (!openingOk) {
+ emit error(tr("Cannot open collection file: %1").arg(colFile));
+ return false;
+ }
+
+ if (!createTables(copyQuery)) {
+ emit error(tr("Cannot copy collection file: %1").arg(colFile));
+ return false;
+ }
+
+ QString oldBaseDir = QFileInfo(collectionFile()).absolutePath();
+ QString oldFilePath;
+ QFileInfo newColFi(colFile);
+ m_query.exec(QLatin1String("SELECT Name, FilePath FROM NamespaceTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ oldFilePath = m_query.value(1).toString();
+ if (!QDir::isAbsolutePath(oldFilePath))
+ oldFilePath = oldBaseDir + QDir::separator() + oldFilePath;
+ copyQuery->bindValue(1, newColFi.absoluteDir().relativeFilePath(oldFilePath));
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT NamespaceId, Name FROM FolderTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->bindValue(1, m_query.value(1).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT NameId, FilterAttributeId FROM FilterTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toInt());
+ copyQuery->bindValue(1, m_query.value(1).toInt());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Key, Value FROM SettingsTable"));
+ while (m_query.next()) {
+ if (m_query.value(0).toString() == QLatin1String("CluceneSearchNamespaces"))
+ continue;
+ copyQuery->prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->bindValue(1, m_query.value(1));
+ copyQuery->exec();
+ }
+
+ copyQuery->clear();
+ delete copyQuery;
+ QSqlDatabase::removeDatabase(connectionName);
+ return true;
+}
+
+bool QHelpCollectionHandler::createTables(QSqlQuery *query)
+{
+ QStringList tables;
+ tables << QLatin1String("CREATE TABLE NamespaceTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT, "
+ "FilePath TEXT )")
+ << QLatin1String("CREATE TABLE FolderTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "NamespaceId INTEGER, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterAttributeTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterNameTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterTable ("
+ "NameId INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE SettingsTable ("
+ "Key TEXT PRIMARY KEY, "
+ "Value BLOB )");
+
+ foreach (QString q, tables) {
+ if (!query->exec(q))
+ return false;
+ }
+ return true;
+}
+
+QStringList QHelpCollectionHandler::customFilters() const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+bool QHelpCollectionHandler::removeCustomFilter(const QString &filterName)
+{
+ if (!isDBOpened() || filterName.isEmpty())
+ return false;
+
+ int filterNameId = -1;
+ m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ if (m_query.next())
+ filterNameId = m_query.value(0).toInt();
+
+ if (filterNameId < 0) {
+ emit error(tr("Unknown filter!"));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ m_query.bindValue(0, filterNameId);
+ m_query.exec();
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterNameTable WHERE Id=?"));
+ m_query.bindValue(0, filterNameId);
+ m_query.exec();
+
+ return true;
+}
+
+bool QHelpCollectionHandler::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ if (!isDBOpened() || filterName.isEmpty())
+ return false;
+
+ int nameId = -1;
+ m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ while (m_query.next()) {
+ nameId = m_query.value(0).toInt();
+ break;
+ }
+
+ m_query.exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
+ QStringList idsToInsert = attributes;
+ QMap<QString, int> attributeMap;
+ while (m_query.next()) {
+ attributeMap.insert(m_query.value(1).toString(),
+ m_query.value(0).toInt());
+ if (idsToInsert.contains(m_query.value(1).toString()))
+ idsToInsert.removeAll(m_query.value(1).toString());
+ }
+
+ foreach (QString id, idsToInsert) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, id);
+ m_query.exec();
+ attributeMap.insert(id, m_query.lastInsertId().toInt());
+ }
+
+ if (nameId < 0) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, filterName);
+ if (m_query.exec())
+ nameId = m_query.lastInsertId().toInt();
+ }
+
+ if (nameId < 0) {
+ emit error(tr("Cannot register filter %1!").arg(filterName));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ m_query.bindValue(0, nameId);
+ m_query.exec();
+
+ foreach (QString att, attributes) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ m_query.bindValue(0, nameId);
+ m_query.bindValue(1, attributeMap[att]);
+ if (!m_query.exec())
+ return false;
+ }
+ return true;
+}
+
+QHelpCollectionHandler::DocInfoList QHelpCollectionHandler::registeredDocumentations() const
+{
+ DocInfoList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT a.Name, a.FilePath, b.Name "
+ "FROM NamespaceTable a, FolderTable b WHERE a.Id=b.NamespaceId"));
+
+ while (m_query.next()) {
+ DocInfo info;
+ info.fileName = m_query.value(1).toString();
+ info.folderName = m_query.value(2).toString();
+ info.namespaceName = m_query.value(0).toString();
+ list.append(info);
+ }
+ }
+ return list;
+}
+
+bool QHelpCollectionHandler::registerDocumentation(const QString &fileName)
+{
+ if (!isDBOpened())
+ return false;
+
+ QHelpDBReader reader(fileName, QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandler"), this), 0);
+ if (!reader.init()) {
+ emit error(tr("Cannot open documentation file %1!").arg(fileName));
+ return false;
+ }
+
+ QString ns = reader.namespaceName();
+ if (ns.isEmpty()) {
+ emit error(tr("Invalid documentation file!"));
+ return false;
+ }
+
+ int nsId = registerNamespace(ns, fileName);
+ if (nsId < 1)
+ return false;
+
+ if (!registerVirtualFolder(reader.virtualFolder(), nsId))
+ return false;
+
+ addFilterAttributes(reader.filterAttributes());
+ foreach (QString filterName, reader.customFilters())
+ addCustomFilter(filterName, reader.filterAttributes(filterName));
+
+ optimizeDatabase(fileName);
+
+ return true;
+}
+
+bool QHelpCollectionHandler::unregisterDocumentation(const QString &namespaceName)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("SELECT Id FROM NamespaceTable WHERE Name=?"));
+ m_query.bindValue(0, namespaceName);
+ m_query.exec();
+
+ int nsId = -1;
+ if (m_query.next())
+ nsId = m_query.value(0).toInt();
+
+ if (nsId < 0) {
+ emit error(tr("The namespace %1 was not registered!").arg(namespaceName));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM NamespaceTable WHERE Id=?"));
+ m_query.bindValue(0, nsId);
+ m_query.exec();
+
+ m_query.prepare(QLatin1String("DELETE FROM FolderTable WHERE NamespaceId=?"));
+ m_query.bindValue(0, nsId);
+ return m_query.exec();
+}
+
+bool QHelpCollectionHandler::removeCustomValue(const QString &key)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("DELETE FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ return m_query.exec();
+}
+
+QVariant QHelpCollectionHandler::customValue(const QString &key,
+ const QVariant &defaultValue) const
+{
+ QVariant value = defaultValue;
+ if (m_dbOpened) {
+ m_query.prepare(QLatin1String("SELECT COUNT(Key) FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ if (!m_query.exec() || !m_query.next() || !m_query.value(0).toInt()) {
+ m_query.clear();
+ return defaultValue;
+ }
+
+ m_query.clear();
+ m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ if (m_query.exec() && m_query.next())
+ value = m_query.value(0);
+ m_query.clear();
+ }
+ return value;
+}
+
+bool QHelpCollectionHandler::setCustomValue(const QString &key,
+ const QVariant &value)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ m_query.exec();
+ if (m_query.next()) {
+ m_query.prepare(QLatin1String("UPDATE SettingsTable SET Value=? where Key=?"));
+ m_query.bindValue(0, value);
+ m_query.bindValue(1, key);
+ }
+ else {
+ m_query.prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
+ m_query.bindValue(0, key);
+ m_query.bindValue(1, value);
+ }
+ return m_query.exec();
+}
+
+bool QHelpCollectionHandler::addFilterAttributes(const QStringList &attributes)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ QSet<QString> atts;
+ while (m_query.next())
+ atts.insert(m_query.value(0).toString());
+
+ foreach (QString s, attributes) {
+ if (!atts.contains(s)) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, s);
+ m_query.exec();
+ }
+ }
+ return true;
+}
+
+QStringList QHelpCollectionHandler::filterAttributes() const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+QStringList QHelpCollectionHandler::filterAttributes(const QString &filterName) const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, "
+ "FilterTable b, FilterNameTable c WHERE a.Id=b.FilterAttributeId "
+ "AND b.NameId=c.Id AND c.Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+int QHelpCollectionHandler::registerNamespace(const QString &nspace, const QString &fileName)
+{
+ m_query.prepare(QLatin1String("SELECT COUNT(Id) FROM NamespaceTable WHERE Name=?"));
+ m_query.bindValue(0, nspace);
+ m_query.exec();
+ while (m_query.next()) {
+ if (m_query.value(0).toInt() > 0) {
+ emit error(tr("Namespace %1 already exists!").arg(nspace));
+ return -1;
+ }
+ }
+
+ QFileInfo fi(m_collectionFile);
+ m_query.prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
+ m_query.bindValue(0, nspace);
+ m_query.bindValue(1, fi.absoluteDir().relativeFilePath(fileName));
+ int namespaceId = -1;
+ if (m_query.exec())
+ namespaceId = m_query.lastInsertId().toInt();
+ if (namespaceId < 1) {
+ emit error(tr("Cannot register namespace!"));
+ return -1;
+ }
+ return namespaceId;
+}
+
+bool QHelpCollectionHandler::registerVirtualFolder(const QString &folderName, int namespaceId)
+{
+ m_query.prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
+ m_query.bindValue(0, namespaceId);
+ m_query.bindValue(1, folderName);
+ return m_query.exec();
+}
+
+void QHelpCollectionHandler::optimizeDatabase(const QString &fileName)
+{
+ if (!QFile::exists(fileName))
+ return;
+
+ { // according to removeDatabase() documentation
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("optimize"));
+ db.setDatabaseName(fileName);
+ if (!db.open()) {
+ QSqlDatabase::removeDatabase(QLatin1String("optimize"));
+ emit error(tr("Cannot open database to optimize!"));
+ return;
+ }
+
+ QSqlQuery query(db);
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS NameIndex ON IndexTable(Name)"));
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileNameIndex ON FileNameTable(Name)"));
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileIdIndex ON FileNameTable(FileId)"));
+
+ db.close();
+ }
+
+ QSqlDatabase::removeDatabase(QLatin1String("optimize"));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpcollectionhandler_p.h b/tools/assistant/lib/qhelpcollectionhandler_p.h
new file mode 100644
index 0000000000..2520694493
--- /dev/null
+++ b/tools/assistant/lib/qhelpcollectionhandler_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 QHELPCOLLECTIONHANDLER_H
+#define QHELPCOLLECTIONHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
+
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpCollectionHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ struct DocInfo
+ {
+ QString fileName;
+ QString folderName;
+ QString namespaceName;
+ };
+ typedef QList<DocInfo> DocInfoList;
+
+ QHelpCollectionHandler(const QString &collectionFile, QObject *parent = 0);
+ ~QHelpCollectionHandler();
+
+ QString collectionFile() const;
+
+ bool openCollectionFile();
+ bool copyCollectionFile(const QString &fileName);
+
+ QStringList customFilters() const;
+ bool removeCustomFilter(const QString &filterName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+
+ DocInfoList registeredDocumentations() const;
+ bool registerDocumentation(const QString &fileName);
+ bool unregisterDocumentation(const QString &namespaceName);
+
+ bool removeCustomValue(const QString &key);
+ QVariant customValue(const QString &key, const QVariant &defaultValue) const;
+ bool setCustomValue(const QString &key, const QVariant &value);
+
+ bool addFilterAttributes(const QStringList &attributes);
+ QStringList filterAttributes() const;
+ QStringList filterAttributes(const QString &filterName) const;
+
+ int registerNamespace(const QString &nspace, const QString &fileName);
+ bool registerVirtualFolder(const QString &folderName, int namespaceId);
+ void optimizeDatabase(const QString &fileName);
+
+signals:
+ void error(const QString &msg);
+
+private:
+ bool isDBOpened();
+ bool createTables(QSqlQuery *query);
+
+ bool m_dbOpened;
+ QString m_collectionFile;
+ QString m_connectionName;
+ mutable QSqlQuery m_query;
+};
+
+QT_END_NAMESPACE
+
+#endif //QHELPCOLLECTIONHANDLER_H
diff --git a/tools/assistant/lib/qhelpcontentwidget.cpp b/tools/assistant/lib/qhelpcontentwidget.cpp
new file mode 100644
index 0000000000..c70aef3ec7
--- /dev/null
+++ b/tools/assistant/lib/qhelpcontentwidget.cpp
@@ -0,0 +1,585 @@
+/****************************************************************************
+**
+** 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 "qhelpcontentwidget.h"
+#include "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QStack>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpContentItemPrivate
+{
+public:
+ QHelpContentItemPrivate(const QString &t, const QString &l,
+ QHelpDBReader *r, QHelpContentItem *p)
+ {
+ parent = p;
+ title = t;
+ link = l;
+ helpDBReader = r;
+ }
+
+ QList<QHelpContentItem*> childItems;
+ QHelpContentItem *parent;
+ QString title;
+ QString link;
+ QHelpDBReader *helpDBReader;
+};
+
+class QHelpContentProvider : public QThread
+{
+public:
+ QHelpContentProvider(QHelpEnginePrivate *helpEngine);
+ ~QHelpContentProvider();
+ void collectContents(const QString &customFilterName);
+ void stopCollecting();
+ QHelpContentItem *rootItem();
+ int nextChildCount() const;
+
+private:
+ void run();
+
+ QHelpEnginePrivate *m_helpEngine;
+ QHelpContentItem *m_rootItem;
+ QStringList m_filterAttributes;
+ QQueue<QHelpContentItem*> m_rootItems;
+ QMutex m_mutex;
+ bool m_abort;
+};
+
+class QHelpContentModelPrivate
+{
+public:
+ QHelpContentItem *rootItem;
+ QHelpContentProvider *qhelpContentProvider;
+};
+
+
+
+/*!
+ \class QHelpContentItem
+ \inmodule QtHelp
+ \brief The QHelpContentItem class provides an item for use with QHelpContentModel.
+ \since 4.4
+*/
+
+QHelpContentItem::QHelpContentItem(const QString &name, const QString &link,
+ QHelpDBReader *reader, QHelpContentItem *parent)
+{
+ d = new QHelpContentItemPrivate(name, link, reader, parent);
+}
+
+/*!
+ Destroys the help content item.
+*/
+QHelpContentItem::~QHelpContentItem()
+{
+ qDeleteAll(d->childItems);
+ delete d;
+}
+
+void QHelpContentItem::appendChild(QHelpContentItem *item)
+{
+ d->childItems.append(item);
+}
+
+/*!
+ Returns the child of the content item in the give \a row.
+
+ \sa parent()
+*/
+QHelpContentItem *QHelpContentItem::child(int row) const
+{
+ if (row >= childCount())
+ return 0;
+ return d->childItems.value(row);
+}
+
+/*!
+ Returns the number of child items.
+*/
+int QHelpContentItem::childCount() const
+{
+ return d->childItems.count();
+}
+
+/*!
+ Returns the row of this item from its parents view.
+*/
+int QHelpContentItem::row() const
+{
+ if (d->parent)
+ return d->parent->d->childItems.indexOf(const_cast<QHelpContentItem*>(this));
+ return 0;
+}
+
+/*!
+ Returns the title of the content item.
+*/
+QString QHelpContentItem::title() const
+{
+ return d->title;
+}
+
+/*!
+ Returns the URL of this content item.
+*/
+QUrl QHelpContentItem::url() const
+{
+ return d->helpDBReader->urlOfPath(d->link);
+}
+
+/*!
+ Returns the parent content item.
+*/
+QHelpContentItem *QHelpContentItem::parent() const
+{
+ return d->parent;
+}
+
+/*!
+ Returns the position of a given \a child.
+*/
+int QHelpContentItem::childPosition(QHelpContentItem *child) const
+{
+ return d->childItems.indexOf(child);
+}
+
+
+
+QHelpContentProvider::QHelpContentProvider(QHelpEnginePrivate *helpEngine)
+ : QThread(helpEngine)
+{
+ m_helpEngine = helpEngine;
+ m_rootItem = 0;
+ m_abort = false;
+}
+
+QHelpContentProvider::~QHelpContentProvider()
+{
+ stopCollecting();
+}
+
+void QHelpContentProvider::collectContents(const QString &customFilterName)
+{
+ m_mutex.lock();
+ m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
+ m_mutex.unlock();
+ if (!isRunning()) {
+ start(LowPriority);
+ } else {
+ stopCollecting();
+ start(LowPriority);
+ }
+}
+
+void QHelpContentProvider::stopCollecting()
+{
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+}
+
+QHelpContentItem *QHelpContentProvider::rootItem()
+{
+ QMutexLocker locker(&m_mutex);
+ return m_rootItems.dequeue();
+}
+
+int QHelpContentProvider::nextChildCount() const
+{
+ return m_rootItems.head()->childCount();
+}
+
+void QHelpContentProvider::run()
+{
+ QString title;
+ QString link;
+ int depth = 0;
+ QHelpContentItem *item = 0;
+
+ m_mutex.lock();
+ m_rootItem = new QHelpContentItem(QString(), QString(), 0);
+ m_rootItems.enqueue(m_rootItem);
+ QStringList atts = m_filterAttributes;
+ const QStringList fileNames = m_helpEngine->orderedFileNameList;
+ m_mutex.unlock();
+
+ foreach (QString dbFileName, fileNames) {
+ m_mutex.lock();
+ if (m_abort) {
+ m_abort = false;
+ m_mutex.unlock();
+ break;
+ }
+ m_mutex.unlock();
+ QHelpDBReader reader(dbFileName,
+ QHelpGlobal::uniquifyConnectionName(dbFileName +
+ QLatin1String("FromQHelpContentProvider"),
+ QThread::currentThread()), 0);
+ if (!reader.init())
+ continue;
+ foreach (const QByteArray& ba, reader.contentsForFilter(atts)) {
+ if (ba.size() < 1)
+ continue;
+
+ int _depth = 0;
+ bool _root = false;
+ QStack<QHelpContentItem*> stack;
+
+ QDataStream s(ba);
+ for (;;) {
+ s >> depth;
+ s >> link;
+ s >> title;
+ if (title.isEmpty())
+ break;
+CHECK_DEPTH:
+ if (depth == 0) {
+ m_mutex.lock();
+ item = new QHelpContentItem(title, link,
+ m_helpEngine->fileNameReaderMap.value(dbFileName), m_rootItem);
+ m_rootItem->appendChild(item);
+ m_mutex.unlock();
+ stack.push(item);
+ _depth = 1;
+ _root = true;
+ } else {
+ if (depth > _depth && _root) {
+ _depth = depth;
+ stack.push(item);
+ }
+ if (depth == _depth) {
+ item = new QHelpContentItem(title, link,
+ m_helpEngine->fileNameReaderMap.value(dbFileName), stack.top());
+ stack.top()->appendChild(item);
+ } else if (depth < _depth) {
+ stack.pop();
+ --_depth;
+ goto CHECK_DEPTH;
+ }
+ }
+ }
+ }
+ }
+ m_mutex.lock();
+ m_abort = false;
+ m_mutex.unlock();
+}
+
+
+
+/*!
+ \class QHelpContentModel
+ \inmodule QtHelp
+ \brief The QHelpContentModel class provides a model that supplies content to views.
+ \since 4.4
+*/
+
+/*!
+ \fn void QHelpContentModel::contentsCreationStarted()
+
+ This signal is emitted when the creation of the contents has
+ started. The current contents are invalid from this point on
+ until the signal contentsCreated() is emitted.
+
+ \sa isCreatingContents()
+*/
+
+/*!
+ \fn void QHelpContentModel::contentsCreated()
+
+ This signal is emitted when the contents have been created.
+*/
+
+QHelpContentModel::QHelpContentModel(QHelpEnginePrivate *helpEngine)
+ : QAbstractItemModel(helpEngine)
+{
+ d = new QHelpContentModelPrivate();
+ d->rootItem = 0;
+ d->qhelpContentProvider = new QHelpContentProvider(helpEngine);
+
+ connect(d->qhelpContentProvider, SIGNAL(finished()),
+ this, SLOT(insertContents()), Qt::QueuedConnection);
+ connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateContents()));
+}
+
+/*!
+ Destroys the help content model.
+*/
+QHelpContentModel::~QHelpContentModel()
+{
+ delete d->rootItem;
+ delete d;
+}
+
+void QHelpContentModel::invalidateContents(bool onShutDown)
+{
+ if (onShutDown)
+ disconnect(this, SLOT(insertContents()));
+ d->qhelpContentProvider->stopCollecting();
+ if (d->rootItem) {
+ delete d->rootItem;
+ d->rootItem = 0;
+ }
+ reset();
+}
+
+/*!
+ Creates new contents by querying the help system
+ for contents specified for the \a customFilterName.
+*/
+void QHelpContentModel::createContents(const QString &customFilterName)
+{
+ d->qhelpContentProvider->collectContents(customFilterName);
+ emit contentsCreationStarted();
+}
+
+void QHelpContentModel::insertContents()
+{
+ int count;
+ if (d->rootItem) {
+ count = d->rootItem->childCount() - 1;
+ beginRemoveRows(QModelIndex(), 0, count > 0 ? count : 0);
+ delete d->rootItem;
+ d->rootItem = 0;
+ endRemoveRows();
+ }
+
+ count = d->qhelpContentProvider->nextChildCount() - 1;
+ beginInsertRows(QModelIndex(), 0, count > 0 ? count : 0);
+ d->rootItem = d->qhelpContentProvider->rootItem();
+ endInsertRows();
+ reset();
+ emit contentsCreated();
+}
+
+/*!
+ Returns true if the contents are currently rebuilt, otherwise
+ false.
+*/
+bool QHelpContentModel::isCreatingContents() const
+{
+ return d->qhelpContentProvider->isRunning();
+}
+
+/*!
+ Returns the help content item at the model index position
+ \a index.
+*/
+QHelpContentItem *QHelpContentModel::contentItemAt(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return static_cast<QHelpContentItem*>(index.internalPointer());
+ else
+ return d->rootItem;
+}
+
+/*!
+ Returns the index of the item in the model specified by
+ the given \a row, \a column and \a parent index.
+*/
+QModelIndex QHelpContentModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!d->rootItem)
+ return QModelIndex();
+
+ QHelpContentItem *parentItem = contentItemAt(parent);
+ QHelpContentItem *item = parentItem->child(row);
+ if (!item)
+ return QModelIndex();
+ return createIndex(row, column, item);
+}
+
+/*!
+ Returns the parent of the model item with the given
+ \a index, or QModelIndex() if it has no parent.
+*/
+QModelIndex QHelpContentModel::parent(const QModelIndex &index) const
+{
+ QHelpContentItem *item = contentItemAt(index);
+ if (!item)
+ return QModelIndex();
+
+ QHelpContentItem *parentItem = static_cast<QHelpContentItem*>(item->parent());
+ if (!parentItem)
+ return QModelIndex();
+
+ QHelpContentItem *grandparentItem = static_cast<QHelpContentItem*>(parentItem->parent());
+ if (!grandparentItem)
+ return QModelIndex();
+
+ int row = grandparentItem->childPosition(parentItem);
+ return createIndex(row, index.column(), parentItem);
+}
+
+/*!
+ Returns the number of rows under the given \a parent.
+*/
+int QHelpContentModel::rowCount(const QModelIndex &parent) const
+{
+ QHelpContentItem *parentItem = contentItemAt(parent);
+ if (!parentItem)
+ return 0;
+ return parentItem->childCount();
+}
+
+/*!
+ Returns the number of columns under the given \a parent. Currently returns always 1.
+*/
+int QHelpContentModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+
+ return 1;
+}
+
+/*!
+ Returns the data stored under the given \a role for
+ the item referred to by the \a index.
+*/
+QVariant QHelpContentModel::data(const QModelIndex &index, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ QHelpContentItem *item = contentItemAt(index);
+ if (!item)
+ return QVariant();
+ return item->title();
+}
+
+
+
+/*!
+ \class QHelpContentWidget
+ \inmodule QtHelp
+ \brief The QHelpContentWidget class provides a tree view for displaying help content model items.
+ \since 4.4
+*/
+
+/*!
+ \fn void QHelpContentWidget::linkActivated(const QUrl &link)
+
+ This signal is emitted when a content item is activated and
+ its associated \a link should be shown.
+*/
+
+QHelpContentWidget::QHelpContentWidget()
+ : QTreeView(0)
+{
+ header()->hide();
+ setUniformRowHeights(true);
+ connect(this, SIGNAL(activated(const QModelIndex&)),
+ this, SLOT(showLink(const QModelIndex&)));
+}
+
+/*!
+ Returns the index of the content item with the \a link.
+ An invalid index is returned if no such an item exists.
+*/
+QModelIndex QHelpContentWidget::indexOf(const QUrl &link)
+{
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(model());
+ if (!contentModel || link.scheme() != QLatin1String("qthelp"))
+ return QModelIndex();
+
+ m_syncIndex = QModelIndex();
+ for (int i=0; i<contentModel->rowCount(); ++i) {
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(contentModel->index(i, 0));
+ if (itm && itm->url().host() == link.host()) {
+ QString path = link.path();
+ if (path.startsWith(QLatin1Char('/')))
+ path = path.mid(1);
+ if (searchContentItem(contentModel, contentModel->index(i, 0), path)) {
+ return m_syncIndex;
+ }
+ }
+ }
+ return QModelIndex();
+}
+
+bool QHelpContentWidget::searchContentItem(QHelpContentModel *model,
+ const QModelIndex &parent, const QString &path)
+{
+ QHelpContentItem *parentItem = model->contentItemAt(parent);
+ if (!parentItem)
+ return false;
+
+ if (QDir::cleanPath(parentItem->url().path()) == path) {
+ m_syncIndex = parent;
+ return true;
+ }
+
+ for (int i=0; i<parentItem->childCount(); ++i) {
+ if (searchContentItem(model, model->index(i, 0, parent), path))
+ return true;
+ }
+ return false;
+}
+
+void QHelpContentWidget::showLink(const QModelIndex &index)
+{
+ QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(model());
+ if (!contentModel)
+ return;
+
+ QHelpContentItem *item = contentModel->contentItemAt(index);
+ if (!item)
+ return;
+ QUrl url = item->url();
+ if (url.isValid())
+ emit linkActivated(url);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpcontentwidget.h b/tools/assistant/lib/qhelpcontentwidget.h
new file mode 100644
index 0000000000..ceab7fe5d6
--- /dev/null
+++ b/tools/assistant/lib/qhelpcontentwidget.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** 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 QHELPCONTENTWIDGET_H
+#define QHELPCONTENTWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QQueue>
+#include <QtCore/QString>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEnginePrivate;
+class QHelpDBReader;
+class QHelpContentItemPrivate;
+class QHelpContentModelPrivate;
+class QHelpEngine;
+class QHelpContentProvider;
+
+class QHELP_EXPORT QHelpContentItem
+{
+public:
+ ~QHelpContentItem();
+
+ QHelpContentItem *child(int row) const;
+ int childCount() const;
+ QString title() const;
+ QUrl url() const;
+ int row() const;
+ QHelpContentItem *parent() const;
+ int childPosition(QHelpContentItem *child) const;
+
+private:
+ QHelpContentItem(const QString &name, const QString &link,
+ QHelpDBReader *reader, QHelpContentItem *parent = 0);
+ void appendChild(QHelpContentItem *child);
+
+ QHelpContentItemPrivate *d;
+ friend class QHelpContentProvider;
+};
+
+class QHELP_EXPORT QHelpContentModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ ~QHelpContentModel();
+
+ void createContents(const QString &customFilterName);
+ QHelpContentItem *contentItemAt(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool isCreatingContents() const;
+
+Q_SIGNALS:
+ void contentsCreationStarted();
+ void contentsCreated();
+
+private Q_SLOTS:
+ void insertContents();
+ void invalidateContents(bool onShutDown = false);
+
+private:
+ QHelpContentModel(QHelpEnginePrivate *helpEngine);
+ QHelpContentModelPrivate *d;
+ friend class QHelpEnginePrivate;
+};
+
+class QHELP_EXPORT QHelpContentWidget : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ QModelIndex indexOf(const QUrl &link);
+
+Q_SIGNALS:
+ void linkActivated(const QUrl &link);
+
+private Q_SLOTS:
+ void showLink(const QModelIndex &index);
+
+private:
+ bool searchContentItem(QHelpContentModel *model,
+ const QModelIndex &parent, const QString &path);
+ QModelIndex m_syncIndex;
+
+private:
+ QHelpContentWidget();
+ friend class QHelpEngine;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/tools/assistant/lib/qhelpdatainterface.cpp b/tools/assistant/lib/qhelpdatainterface.cpp
new file mode 100644
index 0000000000..001c059cba
--- /dev/null
+++ b/tools/assistant/lib/qhelpdatainterface.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** 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 "qhelpdatainterface_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QHelpDataContentItem
+ \since 4.4
+ \brief The QHelpDataContentItem class provides an item which represents
+ a topic or section of the contents.
+
+ Every item holds several pieces of information, most notably the title
+ which can later be displayed in a contents overview. The reference is used
+ to store a relative file link to the corresponding section in the
+ documentation.
+*/
+
+/*!
+ Constructs a new content item with \a parent as parent item.
+ The constucted item has the title \a title and links to the
+ location specified by \a reference.
+*/
+QHelpDataContentItem::QHelpDataContentItem(QHelpDataContentItem *parent,
+ const QString &title, const QString &reference)
+ : m_title(title), m_reference(reference)
+{
+ if (parent)
+ parent->m_children.append(this);
+}
+
+/*!
+ Destructs the item and its children.
+*/
+QHelpDataContentItem::~QHelpDataContentItem()
+{
+ qDeleteAll(m_children);
+}
+
+/*!
+ Returns the title of the item.
+*/
+QString QHelpDataContentItem::title() const
+{
+ return m_title;
+}
+
+/*!
+ Returns the file reference of the item.
+*/
+QString QHelpDataContentItem::reference() const
+{
+ return m_reference;
+}
+
+/*!
+ Returns a list of all its child items.
+*/
+QList<QHelpDataContentItem*> QHelpDataContentItem::children() const
+{
+ return m_children;
+}
+
+bool QHelpDataIndexItem::operator==(const QHelpDataIndexItem & other) const
+{
+ return (other.name == name)
+ && (other.reference == reference);
+}
+
+
+
+/*!
+ \internal
+ \class QHelpDataFilterSection
+ \since 4.4
+*/
+
+/*!
+ Constructs a help data filter section.
+*/
+QHelpDataFilterSection::QHelpDataFilterSection()
+{
+ d = new QHelpDataFilterSectionData();
+}
+
+/*!
+ Adds the filter attribute \a filter to the filter attributes of
+ this section.
+*/
+void QHelpDataFilterSection::addFilterAttribute(const QString &filter)
+{
+ d->filterAttributes.append(filter);
+}
+
+/*!
+ Returns a list of all filter attributes defined for this section.
+*/
+QStringList QHelpDataFilterSection::filterAttributes() const
+{
+ return d->filterAttributes;
+}
+
+/*!
+ Adds the index item \a index to the list of indices.
+*/
+void QHelpDataFilterSection::addIndex(const QHelpDataIndexItem &index)
+{
+ d->indices.append(index);
+}
+
+/*!
+ Sets the filter sections list of indices to \a indices.
+*/
+void QHelpDataFilterSection::setIndices(const QList<QHelpDataIndexItem> &indices)
+{
+ d->indices = indices;
+}
+
+/*!
+ Returns the list of indices.
+*/
+QList<QHelpDataIndexItem> QHelpDataFilterSection::indices() const
+{
+ return d->indices;
+}
+
+/*!
+ Adds the top level content item \a content to the filter section.
+*/
+void QHelpDataFilterSection::addContent(QHelpDataContentItem *content)
+{
+ d->contents.append(content);
+}
+
+/*!
+ Sets the list of top level content items of the filter section to
+ \a contents.
+*/
+void QHelpDataFilterSection::setContents(const QList<QHelpDataContentItem*> &contents)
+{
+ qDeleteAll(d->contents);
+ d->contents = contents;
+}
+
+/*!
+ Returns a list of top level content items.
+*/
+QList<QHelpDataContentItem*> QHelpDataFilterSection::contents() const
+{
+ return d->contents;
+}
+
+/*!
+ Adds the file \a file to the filter section.
+*/
+void QHelpDataFilterSection::addFile(const QString &file)
+{
+ d->files.append(file);
+}
+
+/*!
+ Set the list of files to \a files.
+*/
+void QHelpDataFilterSection::setFiles(const QStringList &files)
+{
+ d->files = files;
+}
+
+/*!
+ Returns the list of files.
+*/
+QStringList QHelpDataFilterSection::files() const
+{
+ return d->files;
+}
+
+/*!
+ \internal
+ \class QHelpDataInterface
+ \since 4.4
+*/
+
+/*!
+ \fn QHelpDataInterface::QHelpDataInterface()
+
+ Constructs a new help data interface.
+*/
+
+/*!
+ \fn QHelpDataInterface::~QHelpDataInterface()
+
+ Destroys the help data interface.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::namespaceName() const = 0
+
+ Returns the namespace name of the help data set.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::virtualFolder() const = 0
+
+ Returns the virtual folder of the help data set.
+*/
+
+/*!
+ \fn QList<QHelpDataCustomFilter> QHelpDataInterface::customFilters () const = 0
+
+ Returns a list of custom filters. Defining custom filters is optional.
+*/
+
+/*!
+ \fn QList<QHelpDataFilterSection> QHelpDataInterface::filterSections() const = 0
+
+ Returns a list of filter sections.
+*/
+
+/*!
+ \fn QMap<QString, QVariant> QHelpDataInterface::metaData() const = 0
+
+ Returns a map of meta data. A meta data item can hold almost any data
+ and is identified by its name.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::rootPath() const = 0
+
+ Returns the root file path of the documentation data. All referenced file
+ path or links of content items are relative to this path.
+*/
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpdatainterface_p.h b/tools/assistant/lib/qhelpdatainterface_p.h
new file mode 100644
index 0000000000..2d05cc6335
--- /dev/null
+++ b/tools/assistant/lib/qhelpdatainterface_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** 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 QHELPDATAINTERFACE_H
+#define QHELPDATAINTERFACE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QSharedData>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHELP_EXPORT QHelpDataContentItem
+{
+public:
+ QHelpDataContentItem(QHelpDataContentItem *parent, const QString &title,
+ const QString &reference);
+ ~QHelpDataContentItem();
+
+ QString title() const;
+ QString reference() const;
+ QList<QHelpDataContentItem*> children() const;
+
+private:
+ QString m_title;
+ QString m_reference;
+ QList<QHelpDataContentItem*> m_children;
+};
+
+struct QHELP_EXPORT QHelpDataIndexItem {
+ QHelpDataIndexItem() {}
+ QHelpDataIndexItem(const QString &n, const QString &id, const QString &r)
+ : name(n), identifier(id), reference(r) {}
+
+ QString name;
+ QString identifier;
+ QString reference;
+
+ bool operator==(const QHelpDataIndexItem & other) const;
+};
+
+class QHelpDataFilterSectionData : public QSharedData
+{
+public:
+ ~QHelpDataFilterSectionData()
+ {
+ qDeleteAll(contents);
+ }
+
+ QStringList filterAttributes;
+ QList<QHelpDataIndexItem> indices;
+ QList<QHelpDataContentItem*> contents;
+ QStringList files;
+};
+
+class QHELP_EXPORT QHelpDataFilterSection
+{
+public:
+ QHelpDataFilterSection();
+
+ void addFilterAttribute(const QString &filter);
+ QStringList filterAttributes() const;
+
+ void addIndex(const QHelpDataIndexItem &index);
+ void setIndices(const QList<QHelpDataIndexItem> &indices);
+ QList<QHelpDataIndexItem> indices() const;
+
+ void addContent(QHelpDataContentItem *content);
+ void setContents(const QList<QHelpDataContentItem*> &contents);
+ QList<QHelpDataContentItem*> contents() const;
+
+ void addFile(const QString &file);
+ void setFiles(const QStringList &files);
+ QStringList files() const;
+
+private:
+ QSharedDataPointer<QHelpDataFilterSectionData> d;
+};
+
+struct QHELP_EXPORT QHelpDataCustomFilter {
+ QStringList filterAttributes;
+ QString name;
+};
+
+class QHELP_EXPORT QHelpDataInterface
+{
+public:
+ QHelpDataInterface() {}
+ virtual ~QHelpDataInterface() {}
+
+ virtual QString namespaceName() const = 0;
+ virtual QString virtualFolder() const = 0;
+ virtual QList<QHelpDataCustomFilter> customFilters() const = 0;
+ virtual QList<QHelpDataFilterSection> filterSections() const = 0;
+ virtual QMap<QString, QVariant> metaData() const = 0;
+ virtual QString rootPath() const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPDATAINTERFACE_H
diff --git a/tools/assistant/lib/qhelpdbreader.cpp b/tools/assistant/lib/qhelpdbreader.cpp
new file mode 100644
index 0000000000..76994a759f
--- /dev/null
+++ b/tools/assistant/lib/qhelpdbreader.cpp
@@ -0,0 +1,580 @@
+/****************************************************************************
+**
+** 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 "qhelpdbreader_p.h"
+#include "qhelp_global.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QFile>
+#include <QtSql/QSqlError>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpDBReader::QHelpDBReader(const QString &dbName)
+ : QObject(0)
+{
+ initObject(dbName,
+ QHelpGlobal::uniquifyConnectionName(QLatin1String("QHelpDBReader"),
+ this));
+}
+
+QHelpDBReader::QHelpDBReader(const QString &dbName, const QString &uniqueId,
+ QObject *parent)
+ : QObject(parent)
+{
+ initObject(dbName, uniqueId);
+}
+
+void QHelpDBReader::initObject(const QString &dbName, const QString &uniqueId)
+{
+ m_dbName = dbName;
+ m_uniqueId = uniqueId;
+ m_initDone = false;
+ m_query = 0;
+ m_useAttributesCache = false;
+}
+
+QHelpDBReader::~QHelpDBReader()
+{
+ if (m_initDone) {
+ delete m_query;
+ QSqlDatabase::removeDatabase(m_uniqueId);
+ }
+}
+
+bool QHelpDBReader::init()
+{
+ if (m_initDone)
+ return true;
+
+ if (!QFile::exists(m_dbName))
+ return false;
+
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), m_uniqueId);
+ db.setDatabaseName(m_dbName);
+ if (!db.open()) {
+ m_error = tr("Cannot open database '%1' '%2': %3").arg(m_dbName, m_uniqueId, db.lastError().text());
+ QSqlDatabase::removeDatabase(m_uniqueId);
+ return false;
+ }
+
+ m_initDone = true;
+ m_query = new QSqlQuery(db);
+
+ return true;
+}
+
+QString QHelpDBReader::databaseName() const
+{
+ return m_dbName;
+}
+
+QString QHelpDBReader::errorMessage() const
+{
+ return m_error;
+}
+
+QString QHelpDBReader::namespaceName() const
+{
+ if (!m_namespace.isEmpty())
+ return m_namespace;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM NamespaceTable"));
+ if (m_query->next())
+ m_namespace = m_query->value(0).toString();
+ }
+ return m_namespace;
+}
+
+QString QHelpDBReader::virtualFolder() const
+{
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM FolderTable WHERE Id=1"));
+ if (m_query->next())
+ return m_query->value(0).toString();
+ }
+ return QString();
+}
+
+QList<QStringList> QHelpDBReader::filterAttributeSets() const
+{
+ QList<QStringList> result;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT a.Id, b.Name FROM FileAttributeSetTable a, "
+ "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id ORDER BY a.Id"));
+ int oldId = -1;
+ while (m_query->next()) {
+ int id = m_query->value(0).toInt();
+ if (id != oldId) {
+ result.append(QStringList());
+ oldId = id;
+ }
+ result.last().append(m_query->value(1).toString());
+ }
+ }
+ return result;
+}
+
+bool QHelpDBReader::fileExists(const QString &virtualFolder,
+ const QString &filePath,
+ const QStringList &filterAttributes) const
+{
+ if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query)
+ return false;
+
+//SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id AND b.Name='qtdoc' AND a.Name='qstring.html' AND a.FileId=c.FileId AND c.FilterAttributeId=d.Id AND d.Name='qtrefdoc'
+
+ QString query;
+ namespaceName();
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b "
+ "WHERE a.FolderId=b.Id AND b.Name=\'%1\' AND a.Name=\'%2\'")).arg(quote(virtualFolder)).arg(quote(filePath));
+ } else {
+ query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, "
+ "FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id "
+ "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND "
+ "c.FilterAttributeId=d.Id AND d.Name=\'%3\'"))
+ .arg(quote(virtualFolder)).arg(quote(filePath))
+ .arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT COUNT(a.Name) FROM FileNameTable a, "
+ "FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id "
+ "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND "
+ "c.FilterAttributeId=d.Id AND d.Name=\'%3\'"))
+ .arg(quote(virtualFolder)).arg(quote(filePath))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+ m_query->exec(query);
+ if (m_query->next() && m_query->isValid() && m_query->value(0).toInt())
+ return true;
+ return false;
+}
+
+QByteArray QHelpDBReader::fileData(const QString &virtualFolder,
+ const QString &filePath) const
+{
+ QByteArray ba;
+ if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query)
+ return ba;
+
+ namespaceName();
+ m_query->prepare(QLatin1String("SELECT a.Data FROM FileDataTable a, FileNameTable b, FolderTable c, "
+ "NamespaceTable d WHERE a.Id=b.FileId AND (b.Name=? OR b.Name=?) AND b.FolderId=c.Id "
+ "AND c.Name=? AND c.NamespaceId=d.Id AND d.Name=?"));
+ m_query->bindValue(0, filePath);
+ m_query->bindValue(1, QLatin1String("./") + filePath);
+ m_query->bindValue(2, virtualFolder);
+ m_query->bindValue(3, m_namespace);
+ m_query->exec();
+ if (m_query->next() && m_query->isValid())
+ ba = qUncompress(m_query->value(0).toByteArray());
+ return ba;
+}
+
+QStringList QHelpDBReader::customFilters() const
+{
+ QStringList lst;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query->next())
+ lst.append(m_query->value(0).toString());
+ }
+ return lst;
+}
+
+QStringList QHelpDBReader::filterAttributes(const QString &filterName) const
+{
+ QStringList lst;
+ if (m_query) {
+ if (filterName.isEmpty()) {
+ m_query->prepare(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ } else {
+ m_query->prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, "
+ "FilterTable b, FilterNameTable c WHERE c.Name=? "
+ "AND c.Id=b.NameId AND b.FilterAttributeId=a.Id"));
+ m_query->bindValue(0, filterName);
+ }
+ m_query->exec();
+ while (m_query->next())
+ lst.append(m_query->value(0).toString());
+ }
+ return lst;
+}
+
+QStringList QHelpDBReader::indicesForFilter(const QStringList &filterAttributes) const
+{
+ QStringList indices;
+ if (!m_query)
+ return indices;
+
+ //SELECT DISTINCT a.Name FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId AND b.FilterAttributeId=c.Id AND c.Name in ('4.2.3', 'qt')
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QLatin1String("SELECT DISTINCT Name FROM IndexTable");
+ } else {
+ query = QString(QLatin1String("SELECT DISTINCT a.Name FROM IndexTable a, "
+ "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId "
+ "AND b.FilterAttributeId=c.Id AND c.Name='%1'")).arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT DISTINCT a.Name FROM IndexTable a, "
+ "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId "
+ "AND b.FilterAttributeId=c.Id AND c.Name='%1'"))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (!m_query->value(0).toString().isEmpty())
+ indices.append(m_query->value(0).toString());
+ }
+ return indices;
+}
+
+void QHelpDBReader::linksForKeyword(const QString &keyword, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const
+{
+ if (!m_query)
+ return;
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, FileNameTable d, "
+ "FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id "
+ "AND a.Name='%1'")).arg(quote(keyword));
+ } else if (m_useAttributesCache) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id "
+ "FROM IndexTable a, "
+ "FileNameTable d, FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND a.Name='%1'"))
+ .arg(quote(keyword));
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (m_indicesCache.contains(m_query->value(5).toInt())) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+ }
+ return;
+ } else {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword))
+ .arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ QString title;
+ m_query->exec(query);
+ while (m_query->next()) {
+ title = m_query->value(0).toString();
+ if (title.isEmpty()) // generate a title + corresponding path
+ title = keyword + QLatin1String(" : ") + m_query->value(3).toString();
+ linkMap.insertMulti(title, buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+}
+
+void QHelpDBReader::linksForIdentifier(const QString &id,
+ const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const
+{
+ if (!m_query)
+ return;
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, FileNameTable d, FolderTable e, "
+ "NamespaceTable f WHERE a.FileId=d.FileId AND "
+ "d.FolderId=e.Id AND a.NamespaceId=f.Id AND a.Identifier='%1'"))
+ .arg(quote(id));
+ } else if (m_useAttributesCache) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id "
+ "FROM IndexTable a,"
+ "FileNameTable d, FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND a.Identifier='%1'"))
+ .arg(quote(id));
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (m_indicesCache.contains(m_query->value(5).toInt())) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+ }
+ return;
+ } else {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Identifier='%1' AND c.Name='%2'")).arg(quote(id))
+ .arg(quote(filterAttributes.first()));
+ for (int i=0; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, "
+ "d.Name, a.Anchor FROM IndexTable a, IndexFilterTable b, "
+ "FilterAttributeTable c, FileNameTable d, "
+ "FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id "
+ "AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id AND "
+ "a.Identifier='%1' AND c.Name='%2'")).arg(quote(id))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+}
+
+QUrl QHelpDBReader::buildQUrl(const QString &ns, const QString &folder,
+ const QString &relFileName, const QString &anchor) const
+{
+ QUrl url;
+ url.setScheme(QLatin1String("qthelp"));
+ url.setAuthority(ns);
+ url.setPath(folder + QLatin1Char('/') + relFileName);
+ url.setFragment(anchor);
+ return url;
+}
+
+QList<QByteArray> QHelpDBReader::contentsForFilter(const QStringList &filterAttributes) const
+{
+ QList<QByteArray> contents;
+ if (!m_query)
+ return contents;
+
+ //SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='qt' INTERSECT SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='3.3.8';
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QLatin1String("SELECT Data from ContentsTable");
+ } else {
+ query = QString(QLatin1String("SELECT a.Data FROM ContentsTable a, "
+ "ContentsFilterTable b, FilterAttributeTable c "
+ "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id "
+ "AND c.Name='%1'")).arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.Data FROM ContentsTable a, "
+ "ContentsFilterTable b, FilterAttributeTable c "
+ "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id "
+ "AND c.Name='%1'")).arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ contents.append(m_query->value(0).toByteArray());
+ }
+ return contents;
+}
+
+QUrl QHelpDBReader::urlOfPath(const QString &relativePath) const
+{
+ QUrl url;
+ if (!m_query)
+ return url;
+
+ m_query->exec(QLatin1String("SELECT a.Name, b.Name FROM NamespaceTable a, "
+ "FolderTable b WHERE a.id=b.NamespaceId and a.Id=1"));
+ if (m_query->next()) {
+ QString rp = relativePath;
+ QString anchor;
+ int i = rp.indexOf(QLatin1Char('#'));
+ if (i > -1) {
+ rp = relativePath.left(i);
+ anchor = relativePath.mid(i+1);
+ }
+ url = buildQUrl(m_query->value(0).toString(),
+ m_query->value(1).toString(), rp, anchor);
+ }
+ return url;
+}
+
+QStringList QHelpDBReader::files(const QStringList &filterAttributes,
+ const QString &extensionFilter) const
+{
+ QStringList lst;
+ if (!m_query)
+ return lst;
+
+ QString query;
+ QString extension;
+ if (!extensionFilter.isEmpty())
+ extension = QString(QLatin1String("AND b.Name like \'%.%1\'")).arg(extensionFilter);
+
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, "
+ "FileNameTable b WHERE b.FolderId=a.Id %1"))
+ .arg(extension);
+ } else {
+ query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, "
+ "FileNameTable b, FileFilterTable c, FilterAttributeTable d "
+ "WHERE b.FolderId=a.Id AND b.FileId=c.FileId "
+ "AND c.FilterAttributeId=d.Id AND d.Name=\'%1\' %2"))
+ .arg(quote(filterAttributes.first())).arg(extension);
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.Name, b.Name FROM "
+ "FolderTable a, FileNameTable b, FileFilterTable c, "
+ "FilterAttributeTable d WHERE b.FolderId=a.Id AND "
+ "b.FileId=c.FileId AND c.FilterAttributeId=d.Id AND "
+ "d.Name=\'%1\' %2")).arg(quote(filterAttributes.at(i)))
+ .arg(extension));
+ }
+ }
+ m_query->exec(query);
+ while (m_query->next()) {
+ lst.append(m_query->value(0).toString() + QLatin1Char('/')
+ + m_query->value(1).toString());
+ }
+
+ return lst;
+}
+
+QVariant QHelpDBReader::metaData(const QString &name) const
+{
+ QVariant v;
+ if (!m_query)
+ return v;
+
+ m_query->prepare(QLatin1String("SELECT COUNT(Value), Value FROM MetaDataTable "
+ "WHERE Name=?"));
+ m_query->bindValue(0, name);
+ if (m_query->exec() && m_query->next()
+ && m_query->value(0).toInt() == 1)
+ v = m_query->value(1);
+ return v;
+}
+
+QString QHelpDBReader::mergeList(const QStringList &list) const
+{
+ QString str;
+ foreach (QString s, list)
+ str.append(QLatin1Char('\'') + quote(s) + QLatin1String("\', "));
+ if (str.endsWith(QLatin1String(", ")))
+ str = str.left(str.length()-2);
+ return str;
+}
+
+QString QHelpDBReader::quote(const QString &string) const
+{
+ QString s = string;
+ s.replace(QLatin1Char('\''), QLatin1String("\'\'"));
+ return s;
+}
+
+QSet<int> QHelpDBReader::indexIds(const QStringList &attributes) const
+{
+ QSet<int> ids;
+
+ if (attributes.isEmpty())
+ return ids;
+
+ QString query = QString(QLatin1String("SELECT a.IndexId FROM IndexFilterTable a, "
+ "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id "
+ "AND b.Name='%1'")).arg(attributes.first());
+ for (int i=0; i<attributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.IndexId FROM "
+ "IndexFilterTable a, FilterAttributeTable b WHERE "
+ "a.FilterAttributeId=b.Id AND b.Name='%1'"))
+ .arg(attributes.at(i)));
+ }
+
+ if (!m_query->exec(query))
+ return ids;
+
+ while (m_query->next())
+ ids.insert(m_query->value(0).toInt());
+
+ return ids;
+}
+
+bool QHelpDBReader::createAttributesCache(const QStringList &attributes,
+ const QSet<int> &indexIds)
+{
+ m_useAttributesCache = false;
+
+ if (attributes.count() < 2) {
+ m_viewAttributes.clear();
+ return true;
+ }
+
+ bool needUpdate = !m_viewAttributes.count();
+
+ foreach (QString s, attributes)
+ m_viewAttributes.remove(s);
+
+ if (m_viewAttributes.count() || needUpdate) {
+ m_viewAttributes.clear();
+ m_indicesCache = indexIds;
+ }
+ foreach (QString s, attributes)
+ m_viewAttributes.insert(s);
+ m_useAttributesCache = true;
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpdbreader_p.h b/tools/assistant/lib/qhelpdbreader_p.h
new file mode 100644
index 0000000000..08fc382b86
--- /dev/null
+++ b/tools/assistant/lib/qhelpdbreader_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** 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 QHELPDBREADER_H
+#define QHELPDBREADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+#include <QtCore/QByteArray>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QSqlQuery;
+
+class QHelpDBReader : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpDBReader(const QString &dbName);
+ QHelpDBReader(const QString &dbName, const QString &uniqueId,
+ QObject *parent);
+ ~QHelpDBReader();
+
+ bool init();
+
+ QString errorMessage() const;
+
+ QString databaseName() const;
+ QString namespaceName() const;
+ QString virtualFolder() const;
+ QList<QStringList> filterAttributeSets() const;
+ QStringList files(const QStringList &filterAttributes,
+ const QString &extensionFilter = QString()) const;
+ bool fileExists(const QString &virtualFolder, const QString &filePath,
+ const QStringList &filterAttributes = QStringList()) const;
+ QByteArray fileData(const QString &virtualFolder,
+ const QString &filePath) const;
+
+ QStringList customFilters() const;
+ QStringList filterAttributes(const QString &filterName = QString()) const;
+ QStringList indicesForFilter(const QStringList &filterAttributes) const;
+ void linksForKeyword(const QString &keyword, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const;
+
+ void linksForIdentifier(const QString &id, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const;
+
+ QList<QByteArray> contentsForFilter(const QStringList &filterAttributes) const;
+ QUrl urlOfPath(const QString &relativePath) const;
+
+ QSet<int> indexIds(const QStringList &attributes) const;
+ bool createAttributesCache(const QStringList &attributes,
+ const QSet<int> &indexIds);
+ QVariant metaData(const QString &name) const;
+
+private:
+ void initObject(const QString &dbName, const QString &uniqueId);
+ QUrl buildQUrl(const QString &ns, const QString &folder,
+ const QString &relFileName, const QString &anchor) const;
+ QString mergeList(const QStringList &list) const;
+ QString quote(const QString &string) const;
+
+ bool m_initDone;
+ QString m_dbName;
+ QString m_uniqueId;
+ QString m_error;
+ QSqlQuery *m_query;
+ mutable QString m_namespace;
+ QSet<QString> m_viewAttributes;
+ bool m_useAttributesCache;
+ QSet<int> m_indicesCache;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/lib/qhelpengine.cpp b/tools/assistant/lib/qhelpengine.cpp
new file mode 100644
index 0000000000..6a603b7284
--- /dev/null
+++ b/tools/assistant/lib/qhelpengine.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** 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 "qhelpengine.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+#include "qhelpcontentwidget.h"
+#include "qhelpindexwidget.h"
+#include "qhelpsearchengine.h"
+#include "qhelpcollectionhandler_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibrary>
+#include <QtCore/QPluginLoader>
+#include <QtGui/QApplication>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpEnginePrivate::QHelpEnginePrivate()
+ : QHelpEngineCorePrivate()
+ , contentModel(0)
+ , contentWidget(0)
+ , indexModel(0)
+ , indexWidget(0)
+ , searchEngine(0)
+{
+}
+
+QHelpEnginePrivate::~QHelpEnginePrivate()
+{
+}
+
+void QHelpEnginePrivate::init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore)
+{
+ QHelpEngineCorePrivate::init(collectionFile, helpEngineCore);
+
+ contentModel = new QHelpContentModel(this);
+ indexModel = new QHelpIndexModel(this);
+
+ connect(helpEngineCore, SIGNAL(setupFinished()),
+ this, SLOT(applyCurrentFilter()));
+ connect(helpEngineCore, SIGNAL(currentFilterChanged(const QString&)),
+ this, SLOT(applyCurrentFilter()));
+
+}
+
+void QHelpEnginePrivate::applyCurrentFilter()
+{
+ if (!error.isEmpty())
+ return;
+ contentModel->createContents(currentFilter);
+ indexModel->createIndex(currentFilter);
+}
+
+void QHelpEnginePrivate::setContentsWidgetBusy()
+{
+ contentWidget->setCursor(Qt::WaitCursor);
+}
+
+void QHelpEnginePrivate::unsetContentsWidgetBusy()
+{
+ contentWidget->unsetCursor();
+}
+
+void QHelpEnginePrivate::setIndexWidgetBusy()
+{
+ indexWidget->setCursor(Qt::WaitCursor);
+}
+
+void QHelpEnginePrivate::unsetIndexWidgetBusy()
+{
+ indexWidget->unsetCursor();
+}
+
+void QHelpEnginePrivate::stopDataCollection()
+{
+ contentModel->invalidateContents(true);
+ indexModel->invalidateIndex(true);
+}
+
+
+
+/*!
+ \class QHelpEngine
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpEngine class provides access to contents and
+ indices of the help engine.
+
+
+*/
+
+/*!
+ Constructs a new help engine with the given \a parent. The help
+ engine uses the information stored in the \a collectionFile for
+ providing help. If the collection file does not already exist,
+ it will be created.
+*/
+QHelpEngine::QHelpEngine(const QString &collectionFile, QObject *parent)
+ : QHelpEngineCore(d = new QHelpEnginePrivate(), parent)
+{
+ d->init(collectionFile, this);
+}
+
+/*!
+ Destroys the help engine object.
+*/
+QHelpEngine::~QHelpEngine()
+{
+ d->stopDataCollection();
+}
+
+/*!
+ Returns the content model.
+*/
+QHelpContentModel *QHelpEngine::contentModel() const
+{
+ return d->contentModel;
+}
+
+/*!
+ Returns the index model.
+*/
+QHelpIndexModel *QHelpEngine::indexModel() const
+{
+ return d->indexModel;
+}
+
+/*!
+ Returns the content widget.
+*/
+QHelpContentWidget *QHelpEngine::contentWidget()
+{
+ if (!d->contentWidget) {
+ d->contentWidget = new QHelpContentWidget();
+ d->contentWidget->setModel(d->contentModel);
+ connect(d->contentModel, SIGNAL(contentsCreationStarted()),
+ d, SLOT(setContentsWidgetBusy()));
+ connect(d->contentModel, SIGNAL(contentsCreated()),
+ d, SLOT(unsetContentsWidgetBusy()));
+ }
+ return d->contentWidget;
+}
+
+/*!
+ Returns the index widget.
+*/
+QHelpIndexWidget *QHelpEngine::indexWidget()
+{
+ if (!d->indexWidget) {
+ d->indexWidget = new QHelpIndexWidget();
+ d->indexWidget->setModel(d->indexModel);
+ connect(d->indexModel, SIGNAL(indexCreationStarted()),
+ d, SLOT(setIndexWidgetBusy()));
+ connect(d->indexModel, SIGNAL(indexCreated()),
+ d, SLOT(unsetIndexWidgetBusy()));
+ }
+ return d->indexWidget;
+}
+
+/*!
+ Returns the default search engine.
+*/
+QHelpSearchEngine* QHelpEngine::searchEngine()
+{
+ if (!d->searchEngine)
+ d->searchEngine = new QHelpSearchEngine(this, this);
+ return d->searchEngine;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpengine.h b/tools/assistant/lib/qhelpengine.h
new file mode 100644
index 0000000000..9c80ff312d
--- /dev/null
+++ b/tools/assistant/lib/qhelpengine.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QHELPENGINE_H
+#define QHELPENGINE_H
+
+#include <QtHelp/qhelpenginecore.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpEnginePrivate;
+class QHelpSearchEngine;
+
+class QHELP_EXPORT QHelpEngine : public QHelpEngineCore
+{
+ Q_OBJECT
+
+public:
+ QHelpEngine(const QString &collectionFile, QObject *parent = 0);
+ ~QHelpEngine();
+
+ QHelpContentModel *contentModel() const;
+ QHelpIndexModel *indexModel() const;
+
+ QHelpContentWidget *contentWidget();
+ QHelpIndexWidget *indexWidget();
+
+ QHelpSearchEngine *searchEngine();
+
+private:
+ QHelpEnginePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/lib/qhelpengine_p.h b/tools/assistant/lib/qhelpengine_p.h
new file mode 100644
index 0000000000..287329aeeb
--- /dev/null
+++ b/tools/assistant/lib/qhelpengine_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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 QHELPENGINE_P_H
+#define QHELPENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QMap>
+#include <QtCore/QStringList>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QSqlQuery;
+
+class QHelpEngineCore;
+class QHelpDBReader;
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpSearchEngine;
+class QHelpCollectionHandler;
+
+class QHelpEngineCorePrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpEngineCorePrivate();
+ virtual ~QHelpEngineCorePrivate();
+
+ virtual void init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore);
+
+ void clearMaps();
+ bool setup();
+
+ QMap<QString, QHelpDBReader*> readerMap;
+ QMap<QString, QHelpDBReader*> fileNameReaderMap;
+ QMultiMap<QString, QHelpDBReader*> virtualFolderMap;
+ QStringList orderedFileNameList;
+
+ QHelpCollectionHandler *collectionHandler;
+ QString currentFilter;
+ QString error;
+ bool needsSetup;
+ bool autoSaveFilter;
+
+protected:
+ QHelpEngineCore *q;
+
+private slots:
+ void errorReceived(const QString &msg);
+};
+
+
+class QHelpEnginePrivate : public QHelpEngineCorePrivate
+{
+ Q_OBJECT
+
+public:
+ QHelpEnginePrivate();
+ ~QHelpEnginePrivate();
+
+ void init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore);
+
+ QHelpContentModel *contentModel;
+ QHelpContentWidget *contentWidget;
+
+ QHelpIndexModel *indexModel;
+ QHelpIndexWidget *indexWidget;
+
+ QHelpSearchEngine *searchEngine;
+
+ void stopDataCollection();
+
+ friend class QHelpContentProvider;
+ friend class QHelpContentModel;
+ friend class QHelpIndexProvider;
+ friend class QHelpIndexModel;
+
+public slots:
+ void setContentsWidgetBusy();
+ void unsetContentsWidgetBusy();
+ void setIndexWidgetBusy();
+ void unsetIndexWidgetBusy();
+
+private slots:
+ void applyCurrentFilter();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/lib/qhelpenginecore.cpp b/tools/assistant/lib/qhelpenginecore.cpp
new file mode 100644
index 0000000000..85bd9fd8a4
--- /dev/null
+++ b/tools/assistant/lib/qhelpenginecore.cpp
@@ -0,0 +1,727 @@
+/****************************************************************************
+**
+** 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 "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+#include "qhelpcollectionhandler_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibrary>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QFileInfo>
+#include <QtCore/QThread>
+#include <QtGui/QApplication>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpEngineCorePrivate::QHelpEngineCorePrivate()
+{
+ QHelpGlobal::uniquifyConnectionName(QString(), this);
+ autoSaveFilter = true;
+}
+
+void QHelpEngineCorePrivate::init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore)
+{
+ q = helpEngineCore;
+ collectionHandler = new QHelpCollectionHandler(collectionFile, helpEngineCore);
+ connect(collectionHandler, SIGNAL(error(const QString&)),
+ this, SLOT(errorReceived(const QString&)));
+ needsSetup = true;
+}
+
+QHelpEngineCorePrivate::~QHelpEngineCorePrivate()
+{
+ delete collectionHandler;
+ clearMaps();
+}
+
+void QHelpEngineCorePrivate::clearMaps()
+{
+ QMap<QString, QHelpDBReader*>::iterator it = readerMap.begin();
+ while (it != readerMap.end()) {
+ delete it.value();
+ ++it;
+ }
+ readerMap.clear();
+ fileNameReaderMap.clear();
+ virtualFolderMap.clear();
+ orderedFileNameList.clear();
+}
+
+bool QHelpEngineCorePrivate::setup()
+{
+ error.clear();
+ if (!needsSetup)
+ return true;
+
+ needsSetup = false;
+ emit q->setupStarted();
+ clearMaps();
+
+ if (!collectionHandler->openCollectionFile()) {
+ emit q->setupFinished();
+ return false;
+ }
+
+ const QHelpCollectionHandler::DocInfoList docList =
+ collectionHandler->registeredDocumentations();
+ QFileInfo fi(collectionHandler->collectionFile());
+ QString absFileName;
+ foreach(const QHelpCollectionHandler::DocInfo &info, docList) {
+ if (QDir::isAbsolutePath(info.fileName)) {
+ absFileName = info.fileName;
+ } else {
+ absFileName = QFileInfo(fi.absolutePath() + QDir::separator() + info.fileName)
+ .absoluteFilePath();
+ }
+ QHelpDBReader *reader = new QHelpDBReader(absFileName,
+ QHelpGlobal::uniquifyConnectionName(info.fileName, this), this);
+ if (!reader->init()) {
+ emit q->warning(tr("Cannot open documentation file %1: %2!")
+ .arg(absFileName, reader->errorMessage()));
+ continue;
+ }
+
+ readerMap.insert(info.namespaceName, reader);
+ fileNameReaderMap.insert(absFileName, reader);
+ virtualFolderMap.insert(info.folderName, reader);
+ orderedFileNameList.append(absFileName);
+ }
+ q->currentFilter();
+ emit q->setupFinished();
+ return true;
+}
+
+void QHelpEngineCorePrivate::errorReceived(const QString &msg)
+{
+ error = msg;
+}
+
+
+
+/*!
+ \class QHelpEngineCore
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpEngineCore class provides the core functionality
+ of the help system.
+
+ Before the help engine can be used, it must be initialized by
+ calling setupData(). At the beginning of the setup process the
+ signal setupStarted() is emitted. From this point on until
+ the signal setupFinished() is emitted, is the help data in an
+ undefined meaning unusable state.
+
+ The core help engine can be used to perform different tasks.
+ By calling linksForIdentifier() the engine returns
+ urls specifying the file locations inside the help system. The
+ actual file data can then be retrived by calling fileData(). In
+ contrast to all other functions in this class, linksForIdentifier()
+ depends on the currently set custom filter. Depending on the filter,
+ the function may return different hits.
+
+ Every help engine can contain any number of custom filters. A custom
+ filter is defined by a name and set of filter attributes and can be
+ added to the help engine by calling addCustomFilter(). Analogous,
+ it is removed by calling removeCustomFilter(). customFilters() returns
+ all defined filters.
+
+ The help engine also offers the possiblity to set and read values
+ in a persistant way comparable to ini files or Windows registry
+ entries. For more information see setValue() or value().
+
+ This class does not offer any GUI components or functionality for
+ indices or contents. If you need one of those use QHelpEngine
+ instead.
+*/
+
+/*!
+ \fn void QHelpEngineCore::setupStarted()
+
+ This signal is emitted when setup is started.
+*/
+
+/*!
+ \fn void QHelpEngineCore::setupFinished()
+
+ This signal is emitted when the setup is complete.
+*/
+
+/*!
+ \fn void QHelpEngineCore::currentFilterChanged(const QString &newFilter)
+
+ This signal is emitted when the current filter is changed to
+ \a newFilter.
+*/
+
+/*!
+ \fn void QHelpEngineCore::warning(const QString &msg)
+
+ This signal is emitted when a non critical error occurs.
+ The warning message is stored in \a msg.
+*/
+
+/*!
+ Constructs a new core help engine with a \a parent. The help engine
+ uses the information stored in the \a collectionFile to provide help.
+ If the collection file does not exist yet, it'll be created.
+*/
+QHelpEngineCore::QHelpEngineCore(const QString &collectionFile, QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpEngineCorePrivate();
+ d->init(collectionFile, this);
+}
+
+/*!
+ \internal
+*/
+QHelpEngineCore::QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
+ QObject *parent)
+ : QObject(parent)
+{
+ d = helpEngineCorePrivate;
+}
+
+/*!
+ Destructs the help engine.
+*/
+QHelpEngineCore::~QHelpEngineCore()
+{
+ delete d;
+}
+
+/*!
+ \property QHelpEngineCore::collectionFile
+ \brief the absolute file name of the collection file currently used.
+ \since 4.5
+
+ Setting this property leaves the help engine in an invalid state. It is
+ important to invoke setupData() or any getter function in order to setup
+ the help engine again.
+*/
+QString QHelpEngineCore::collectionFile() const
+{
+ return d->collectionHandler->collectionFile();
+}
+
+void QHelpEngineCore::setCollectionFile(const QString &fileName)
+{
+ if (fileName == collectionFile())
+ return;
+
+ if (d->collectionHandler) {
+ delete d->collectionHandler;
+ d->collectionHandler = 0;
+ d->clearMaps();
+ }
+ d->init(fileName, this);
+ d->needsSetup = true;
+}
+
+/*!
+ Sets up the help engine by processing the information found
+ in the collection file and returns true if successful; otherwise
+ returns false.
+
+ By calling the function, the help
+ engine is forced to initialize itself immediately. Most of
+ the times, this function does not have to be called
+ explicitly because getter functions which depend on a correctly
+ set up help engine do that themselves.
+
+ \note \c{qsqlite4.dll} needs to be deployed with the application as the
+ help system uses the sqlite driver when loading help collections.
+*/
+bool QHelpEngineCore::setupData()
+{
+ d->needsSetup = true;
+ return d->setup();
+}
+
+/*!
+ Creates the file \a fileName and copies all contents from
+ the current collection file into the newly created file,
+ and returns true if successful; otherwise returns false.
+
+ The copying process makes sure that file references to Qt
+ Collection files (\c{.qch}) files are updated accordingly.
+*/
+bool QHelpEngineCore::copyCollectionFile(const QString &fileName)
+{
+ if (!d->setup())
+ return false;
+ return d->collectionHandler->copyCollectionFile(fileName);
+}
+
+/*!
+ Returns the namespace name defined for the Qt compressed help file (.qch)
+ specified by its \a documentationFileName. If the file is not valid, an
+ empty string is returned.
+
+ \sa documentationFileName()
+*/
+QString QHelpEngineCore::namespaceName(const QString &documentationFileName)
+{
+ QHelpDBReader reader(documentationFileName,
+ QHelpGlobal::uniquifyConnectionName(QLatin1String("GetNamespaceName"),
+ QThread::currentThread()), 0);
+ if (reader.init())
+ return reader.namespaceName();
+ return QString();
+}
+
+/*!
+ Registers the Qt compressed help file (.qch) contained in the file
+ \a documentationFileName. One compressed help file, uniquely
+ identified by its namespace can only be registered once.
+ True is returned if the registration was successful, otherwise
+ false.
+
+ \sa unregisterDocumentation(), error()
+*/
+bool QHelpEngineCore::registerDocumentation(const QString &documentationFileName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->registerDocumentation(documentationFileName);
+}
+
+/*!
+ Unregisters the Qt compressed help file (.qch) identified by its
+ \a namespaceName from the help collection. Returns true
+ on success, otherwise false.
+
+ \sa registerDocumentation(), error()
+*/
+bool QHelpEngineCore::unregisterDocumentation(const QString &namespaceName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->unregisterDocumentation(namespaceName);
+}
+
+/*!
+ Returns the absolute file name of the Qt compressed help file (.qch)
+ identified by the \a namespaceName. If there is no Qt compressed help file
+ with the specified namespace registered, an empty string is returned.
+
+ \sa namespaceName()
+*/
+QString QHelpEngineCore::documentationFileName(const QString &namespaceName)
+{
+ QString res;
+ if (!d->setup())
+ return res;
+ const QHelpCollectionHandler::DocInfoList docList = d->collectionHandler->registeredDocumentations();
+ foreach(const QHelpCollectionHandler::DocInfo info, docList) {
+ if (info.namespaceName == namespaceName) {
+ QFileInfo fi(d->collectionHandler->collectionFile());
+ fi.setFile(fi.absolutePath() + QDir::separator() + info.fileName);
+ res = QDir::cleanPath(fi.absoluteFilePath());
+ break;
+ }
+ }
+ return res;
+}
+
+/*!
+ Returns a list of all registered Qt compressed help files of the current collection file.
+ The returned names are the namespaces of the registered Qt compressed help files (.qch).
+*/
+QStringList QHelpEngineCore::registeredDocumentations() const
+{
+ QStringList list;
+ if (!d->setup())
+ return list;
+ const QHelpCollectionHandler::DocInfoList docList = d->collectionHandler->registeredDocumentations();
+ foreach(const QHelpCollectionHandler::DocInfo info, docList) {
+ list.append(info.namespaceName);
+ }
+ return list;
+}
+
+/*!
+ Returns a list of custom filters.
+
+ \sa addCustomFilter(), removeCustomFilter()
+*/
+QStringList QHelpEngineCore::customFilters() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->customFilters();
+}
+
+/*!
+ Adds the new custom filter \a filterName. The filter attributes
+ are specified by \a attributes. The function returns false if
+ the filter can not be added, e.g. when the filter already exists.
+
+ \sa customFilters(), removeCustomFilter()
+*/
+bool QHelpEngineCore::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->addCustomFilter(filterName,
+ attributes);
+}
+
+/*!
+ Returns true if the filter \a filterName was removed successfully,
+ otherwise false.
+
+ \sa addCustomFilter(), customFilters()
+*/
+bool QHelpEngineCore::removeCustomFilter(const QString &filterName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->removeCustomFilter(filterName);
+}
+
+/*!
+ Returns a list of all defined filter attributes.
+*/
+QStringList QHelpEngineCore::filterAttributes() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->filterAttributes();
+}
+
+/*!
+ Returns a list of filter attributes used by the custom
+ filter \a filterName.
+*/
+QStringList QHelpEngineCore::filterAttributes(const QString &filterName) const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->filterAttributes(filterName);
+}
+
+/*!
+ \property QHelpEngineCore::currentFilter
+ \brief the name of the custom filter currently applied.
+ \since 4.5
+
+ Setting this property will save the new custom filter permanently in the
+ help collection file. To set a custom filter without saving it
+ permanently, disable the auto save filter mode.
+
+ \sa autoSaveFilter()
+*/
+QString QHelpEngineCore::currentFilter() const
+{
+ if (!d->setup())
+ return QString();
+
+ if (d->currentFilter.isEmpty()) {
+ QString filter =
+ d->collectionHandler->customValue(QLatin1String("CurrentFilter"),
+ QString()).toString();
+ if (!filter.isEmpty()
+ && d->collectionHandler->customFilters().contains(filter))
+ d->currentFilter = filter;
+ }
+ return d->currentFilter;
+}
+
+void QHelpEngineCore::setCurrentFilter(const QString &filterName)
+{
+ if (!d->setup() || filterName == d->currentFilter)
+ return;
+ d->currentFilter = filterName;
+ if (d->autoSaveFilter) {
+ d->collectionHandler->setCustomValue(QLatin1String("CurrentFilter"),
+ d->currentFilter);
+ }
+ emit currentFilterChanged(d->currentFilter);
+}
+
+/*!
+ Returns a list of filter attributes for the different filter sections
+ defined in the Qt compressed help file with the given namespace
+ \a namespaceName.
+*/
+QList<QStringList> QHelpEngineCore::filterAttributeSets(const QString &namespaceName) const
+{
+ if (d->setup()) {
+ QHelpDBReader *reader = d->readerMap.value(namespaceName);
+ if (reader)
+ return reader->filterAttributeSets();
+ }
+ return QList<QStringList>();
+}
+
+/*!
+ Returns a list of files contained in the Qt compressed help file \a
+ namespaceName. The files can be filtered by \a filterAttributes as
+ well as by their extension \a extensionFilter (e.g. 'html').
+*/
+QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
+ const QStringList &filterAttributes,
+ const QString &extensionFilter)
+{
+ QList<QUrl> res;
+ if (!d->setup())
+ return res;
+ QHelpDBReader *reader = d->readerMap.value(namespaceName);
+ if (!reader) {
+ d->error = tr("The specified namespace does not exist!");
+ return res;
+ }
+
+ QUrl url;
+ url.setScheme(QLatin1String("qthelp"));
+ url.setAuthority(namespaceName);
+
+ const QStringList files = reader->files(filterAttributes, extensionFilter);
+ foreach (const QString file, files) {
+ url.setPath(QLatin1String("/") + file);
+ res.append(url);
+ }
+ return res;
+}
+
+/*!
+ Returns an invalid URL if the file \a url cannot be found.
+ If the file exists, either the same url is returned or a
+ different url if the file is located in a different namespace
+ which is merged via a common virtual folder.
+*/
+QUrl QHelpEngineCore::findFile(const QUrl &url) const
+{
+ QUrl res;
+ if (!d->setup() || !url.isValid() || url.toString().count(QLatin1Char('/')) < 4
+ || url.scheme() != QLatin1String("qthelp"))
+ return res;
+
+ QString ns = url.authority();
+ QString filePath = QDir::cleanPath(url.path());
+ if (filePath.startsWith(QLatin1Char('/')))
+ filePath = filePath.mid(1);
+ QString virtualFolder = filePath.mid(0, filePath.indexOf(QLatin1Char('/'), 1));
+ filePath = filePath.mid(virtualFolder.length()+1);
+
+ QHelpDBReader *defaultReader = 0;
+ if (d->readerMap.contains(ns)) {
+ defaultReader = d->readerMap.value(ns);
+ if (defaultReader->fileExists(virtualFolder, filePath))
+ return url;
+ }
+
+ QStringList filterAtts = filterAttributes(currentFilter());
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ if (reader->fileExists(virtualFolder, filePath, filterAtts)) {
+ res = url;
+ res.setAuthority(reader->namespaceName());
+ return res;
+ }
+ }
+
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ if (reader->fileExists(virtualFolder, filePath)) {
+ res = url;
+ res.setAuthority(reader->namespaceName());
+ break;
+ }
+ }
+
+ return res;
+}
+
+/*!
+ Returns the data of the file specified by \a url. If the
+ file does not exist, an empty QByteArray is returned.
+
+ \sa findFile()
+*/
+QByteArray QHelpEngineCore::fileData(const QUrl &url) const
+{
+ if (!d->setup() || !url.isValid() || url.toString().count(QLatin1Char('/')) < 4
+ || url.scheme() != QLatin1String("qthelp"))
+ return QByteArray();
+
+ QString ns = url.authority();
+ QString filePath = QDir::cleanPath(url.path());
+ if (filePath.startsWith(QLatin1Char('/')))
+ filePath = filePath.mid(1);
+ QString virtualFolder = filePath.mid(0, filePath.indexOf(QLatin1Char('/'), 1));
+ filePath = filePath.mid(virtualFolder.length()+1);
+
+ QByteArray ba;
+ QHelpDBReader *defaultReader = 0;
+ if (d->readerMap.contains(ns)) {
+ defaultReader = d->readerMap.value(ns);
+ ba = defaultReader->fileData(virtualFolder, filePath);
+ }
+
+ if (ba.isEmpty()) {
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ ba = reader->fileData(virtualFolder, filePath);
+ if (!ba.isEmpty())
+ return ba;
+ }
+ }
+ return ba;
+}
+
+/*!
+ Returns a map of hits found for the \a id. A hit contains the
+ title of the document and the url where the keyword is located.
+ The result depends on the current filter, meaning only the keywords
+ registered for the current filter will be returned.
+*/
+QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const
+{
+ QMap<QString, QUrl> linkMap;
+ if (!d->setup())
+ return linkMap;
+
+ QStringList atts = filterAttributes(d->currentFilter);
+ foreach (QHelpDBReader *reader, d->readerMap)
+ reader->linksForIdentifier(id, atts, linkMap);
+
+ return linkMap;
+}
+
+/*!
+ Removes the \a key from the settings section in the
+ collection file. Returns true if the value was removed
+ successfully, otherwise false.
+
+ \sa customValue(), setCustomValue()
+*/
+bool QHelpEngineCore::removeCustomValue(const QString &key)
+{
+ d->error.clear();
+ return d->collectionHandler->removeCustomValue(key);
+}
+
+/*!
+ Returns the value assigned to the \a key. If the requested
+ key does not exist, the specified \a defaultValue is
+ returned.
+
+ \sa setCustomValue(), removeCustomValue()
+*/
+QVariant QHelpEngineCore::customValue(const QString &key, const QVariant &defaultValue) const
+{
+ if (!d->setup())
+ return QVariant();
+ return d->collectionHandler->customValue(key, defaultValue);
+}
+
+/*!
+ Save the \a value under the \a key. If the key already exist,
+ the value will be overwritten. Returns true if the value was
+ saved successfully, otherwise false.
+
+ \sa customValue(), removeCustomValue()
+*/
+bool QHelpEngineCore::setCustomValue(const QString &key, const QVariant &value)
+{
+ d->error.clear();
+ return d->collectionHandler->setCustomValue(key, value);
+}
+
+/*!
+ Returns the meta data for the Qt compressed help file \a
+ documentationFileName. If there is no data available for
+ \a name, an invalid QVariant() is returned. The meta
+ data is defined when creating the Qt compressed help file and
+ cannot be modified later. Common meta data includes e.g.
+ the author of the documentation.
+*/
+QVariant QHelpEngineCore::metaData(const QString &documentationFileName,
+ const QString &name)
+{
+ QHelpDBReader reader(documentationFileName, QLatin1String("GetMetaData"), 0);
+
+ if (reader.init())
+ return reader.metaData(name);
+ return QVariant();
+}
+
+/*!
+ Returns a description of the last error that occured.
+*/
+QString QHelpEngineCore::error() const
+{
+ return d->error;
+}
+
+/*!
+ \property QHelpEngineCore::autoSaveFilter
+ \brief whether QHelpEngineCore is in auto save filter mode or not.
+ \since 4.5
+
+ If QHelpEngineCore is in auto save filter mode, the current filter is
+ automatically saved when it is changed by the setCurrentFilter()
+ function. The filter is saved persistently in the help collection file.
+
+ By default, this mode is on.
+*/
+void QHelpEngineCore::setAutoSaveFilter(bool save)
+{
+ d->autoSaveFilter = save;
+}
+
+bool QHelpEngineCore::autoSaveFilter() const
+{
+ return d->autoSaveFilter;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpenginecore.h b/tools/assistant/lib/qhelpenginecore.h
new file mode 100644
index 0000000000..92ba2fd703
--- /dev/null
+++ b/tools/assistant/lib/qhelpenginecore.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** 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 QHELPENGINECORE_H
+#define QHELPENGINECORE_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEngineCorePrivate;
+
+class QHELP_EXPORT QHelpEngineCore : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool autoSaveFilter READ autoSaveFilter WRITE setAutoSaveFilter)
+ Q_PROPERTY(QString collectionFile READ collectionFile WRITE setCollectionFile)
+ Q_PROPERTY(QString currentFilter READ currentFilter WRITE setCurrentFilter)
+
+public:
+ QHelpEngineCore(const QString &collectionFile, QObject *parent = 0);
+ virtual ~QHelpEngineCore();
+
+ bool setupData();
+
+ QString collectionFile() const;
+ void setCollectionFile(const QString &fileName);
+
+ bool copyCollectionFile(const QString &fileName);
+
+ static QString namespaceName(const QString &documentationFileName);
+ bool registerDocumentation(const QString &documentationFileName);
+ bool unregisterDocumentation(const QString &namespaceName);
+ QString documentationFileName(const QString &namespaceName);
+
+ QStringList customFilters() const;
+ bool removeCustomFilter(const QString &filterName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+
+ QStringList filterAttributes() const;
+ QStringList filterAttributes(const QString &filterName) const;
+
+ QString currentFilter() const;
+ void setCurrentFilter(const QString &filterName);
+
+ QStringList registeredDocumentations() const;
+ QList<QStringList> filterAttributeSets(const QString &namespaceName) const;
+ QList<QUrl> files(const QString namespaceName,
+ const QStringList &filterAttributes,
+ const QString &extensionFilter = QString());
+ QUrl findFile(const QUrl &url) const;
+ QByteArray fileData(const QUrl &url) const;
+
+ QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+
+ bool removeCustomValue(const QString &key);
+ QVariant customValue(const QString &key,
+ const QVariant &defaultValue = QVariant()) const;
+ bool setCustomValue(const QString &key, const QVariant &value);
+
+ static QVariant metaData(const QString &documentationFileName,
+ const QString &name);
+
+ QString error() const;
+
+ void setAutoSaveFilter(bool save);
+ bool autoSaveFilter() const;
+
+Q_SIGNALS:
+ void setupStarted();
+ void setupFinished();
+ void currentFilterChanged(const QString &newFilter);
+ void warning(const QString &msg);
+
+protected:
+ QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
+ QObject *parent);
+
+private:
+ QHelpEngineCorePrivate *d;
+ friend class QHelpEngineCorePrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPENGINECORE_H
diff --git a/tools/assistant/lib/qhelpgenerator.cpp b/tools/assistant/lib/qhelpgenerator.cpp
new file mode 100644
index 0000000000..03df3cc524
--- /dev/null
+++ b/tools/assistant/lib/qhelpgenerator.cpp
@@ -0,0 +1,823 @@
+/****************************************************************************
+**
+** 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 "qhelpgenerator_p.h"
+#include "qhelpdatainterface_p.h"
+
+#include <math.h>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QVariant>
+#include <QtCore/QDateTime>
+#include <QtCore/QTextCodec>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpGeneratorPrivate
+{
+public:
+ QHelpGeneratorPrivate();
+ ~QHelpGeneratorPrivate();
+
+ QString error;
+ QSqlQuery *query;
+
+ int namespaceId;
+ int virtualFolderId;
+
+ QMap<QString, int> fileMap;
+ QMap<int, QSet<int> > fileFilterMap;
+
+ double progress;
+ double oldProgress;
+ double contentStep;
+ double fileStep;
+ double indexStep;
+};
+
+QHelpGeneratorPrivate::QHelpGeneratorPrivate()
+{
+ query = 0;
+ namespaceId = -1;
+ virtualFolderId = -1;
+}
+
+QHelpGeneratorPrivate::~QHelpGeneratorPrivate()
+{
+}
+
+
+
+/*!
+ \internal
+ \class QHelpGenerator
+ \since 4.4
+ \brief The QHelpGenerator class generates a new
+ Qt compressed help file (.qch).
+
+ The help generator takes a help data structure as
+ input for generating a new Qt compressed help files. Since
+ the generation may takes some time, the generator emits
+ various signals to inform about its current state.
+*/
+
+/*!
+ \fn void QHelpGenerator::statusChanged(const QString &msg)
+
+ This signal is emitted when the generation status changes.
+ The status is basically a specific task like inserting
+ files or building up the keyword index. The parameter
+ \a msg contains the detailed status description.
+*/
+
+/*!
+ \fn void QHelpGenerator::progressChanged(double progress)
+
+ This signal is emitted when the progress changes. The
+ \a progress ranges from 0 to 100.
+*/
+
+/*!
+ \fn void QHelpGenerator::warning(const QString &msg)
+
+ This signal is emitted when a non critical error occurs,
+ e.g. when a referenced file cannot be found. \a msg
+ contains the exact warning message.
+*/
+
+/*!
+ Constructs a new help generator with the give \a parent.
+*/
+QHelpGenerator::QHelpGenerator(QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpGeneratorPrivate;
+}
+
+/*!
+ Destructs the help generator.
+*/
+QHelpGenerator::~QHelpGenerator()
+{
+ delete d;
+}
+
+/*!
+ Takes the \a helpData and generates a new documentation
+ set from it. The Qt compressed help file is written to \a
+ outputFileName. Returns true on success, otherwise false.
+*/
+bool QHelpGenerator::generate(QHelpDataInterface *helpData,
+ const QString &outputFileName)
+{
+ emit progressChanged(0);
+ d->error.clear();
+ if (!helpData || helpData->namespaceName().isEmpty()) {
+ d->error = tr("Invalid help data!");
+ return false;
+ }
+
+ QString outFileName = outputFileName;
+ if (outFileName.isEmpty()) {
+ d->error = tr("No output file name specified!");
+ return false;
+ }
+
+ QFileInfo fi(outFileName);
+ if (fi.exists()) {
+ if (!fi.dir().remove(fi.fileName())) {
+ d->error = tr("The file %1 cannot be overwritten!").arg(outFileName);
+ return false;
+ }
+ }
+
+ setupProgress(helpData);
+
+ emit statusChanged(tr("Building up file structure..."));
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("builder"));
+ db.setDatabaseName(outFileName);
+ openingOk = db.open();
+ if (openingOk)
+ d->query = new QSqlQuery(db);
+ }
+
+ if (!openingOk) {
+ d->error = tr("Cannot open data base file %1!").arg(outFileName);
+ cleanupDB();
+ return false;
+ }
+
+ addProgress(1.0);
+ createTables();
+ insertFileNotFoundFile();
+ insertMetaData(helpData->metaData());
+
+ if (!registerVirtualFolder(helpData->virtualFolder(), helpData->namespaceName())) {
+ d->error = tr("Cannot register namespace %1!").arg(helpData->namespaceName());
+ cleanupDB();
+ return false;
+ }
+ addProgress(1.0);
+
+ emit statusChanged(tr("Insert custom filters..."));
+ foreach (QHelpDataCustomFilter f, helpData->customFilters()) {
+ if (!registerCustomFilter(f.name, f.filterAttributes, true)) {
+ cleanupDB();
+ return false;
+ }
+ }
+ addProgress(1.0);
+
+ int i = 1;
+ QList<QHelpDataFilterSection>::const_iterator it = helpData->filterSections().constBegin();
+ while (it != helpData->filterSections().constEnd()) {
+ emit statusChanged(tr("Insert help data for filter section (%1 of %2)...")
+ .arg(i++).arg(helpData->filterSections().count()));
+ insertFilterAttributes((*it).filterAttributes());
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ foreach (QHelpDataContentItem *itm, (*it).contents())
+ writeTree(s, itm, 0);
+ if (!insertFiles((*it).files(), helpData->rootPath(), (*it).filterAttributes())
+ || !insertContents(ba, (*it).filterAttributes())
+ || !insertKeywords((*it).indices(), (*it).filterAttributes())) {
+ cleanupDB();
+ return false;
+ }
+ ++it;
+ }
+
+ cleanupDB();
+ emit progressChanged(100);
+ emit statusChanged(tr("Documentation successfully generated."));
+ return true;
+}
+
+void QHelpGenerator::setupProgress(QHelpDataInterface *helpData)
+{
+ d->progress = 0;
+ d->oldProgress = 0;
+
+ int numberOfFiles = 0;
+ int numberOfIndices = 0;
+ QList<QHelpDataFilterSection>::const_iterator it = helpData->filterSections().constBegin();
+ while (it != helpData->filterSections().constEnd()) {
+ numberOfFiles += (*it).files().count();
+ numberOfIndices += (*it).indices().count();
+ ++it;
+ }
+ // init 2%
+ // filters 1%
+ // contents 10%
+ // files 60%
+ // indices 27%
+ d->contentStep = 10.0/(double)helpData->customFilters().count();
+ d->fileStep = 60.0/(double)numberOfFiles;
+ d->indexStep = 27.0/(double)numberOfIndices;
+}
+
+void QHelpGenerator::addProgress(double step)
+{
+ d->progress += step;
+ if ((d->progress-d->oldProgress) >= 1.0 && d->progress <= 100.0) {
+ d->oldProgress = d->progress;
+ emit progressChanged(ceil(d->progress));
+ }
+}
+
+void QHelpGenerator::cleanupDB()
+{
+ if (d->query) {
+ d->query->clear();
+ delete d->query;
+ d->query = 0;
+ }
+ QSqlDatabase::removeDatabase(QLatin1String("builder"));
+}
+
+void QHelpGenerator::writeTree(QDataStream &s, QHelpDataContentItem *item, int depth)
+{
+ QString fReference = QDir::cleanPath(item->reference());
+ if (fReference.startsWith(QLatin1String("./")))
+ fReference = fReference.mid(2);
+
+ s << depth;
+ s << fReference;
+ s << item->title();
+ foreach (QHelpDataContentItem *i, item->children())
+ writeTree(s, i, depth+1);
+}
+
+/*!
+ Returns the last error message.
+*/
+QString QHelpGenerator::error() const
+{
+ return d->error;
+}
+
+bool QHelpGenerator::createTables()
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
+ "AND Name=\'NamespaceTable\'"));
+ d->query->next();
+ if (d->query->value(0).toInt() > 0) {
+ d->error = tr("Some tables already exist!");
+ return false;
+ }
+
+ QStringList tables;
+ tables << QLatin1String("CREATE TABLE NamespaceTable ("
+ "Id INTEGER PRIMARY KEY,"
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterAttributeTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterNameTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterTable ("
+ "NameId INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE IndexTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT, "
+ "Identifier TEXT, "
+ "NamespaceId INTEGER, "
+ "FileId INTEGER, "
+ "Anchor TEXT )")
+ << QLatin1String("CREATE TABLE IndexItemTable ("
+ "Id INTEGER, "
+ "IndexId INTEGER )")
+ << QLatin1String("CREATE TABLE IndexFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "IndexId INTEGER )")
+ << QLatin1String("CREATE TABLE ContentsTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "NamespaceId INTEGER, "
+ "Data BLOB )")
+ << QLatin1String("CREATE TABLE ContentsFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "ContentsId INTEGER )")
+ << QLatin1String("CREATE TABLE FileAttributeSetTable ("
+ "Id INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE FileDataTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Data BLOB )")
+ << QLatin1String("CREATE TABLE FileFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "FileId INTEGER )")
+ << QLatin1String("CREATE TABLE FileNameTable ("
+ "FolderId INTEGER, "
+ "Name TEXT, "
+ "FileId INTEGER, "
+ "Title TEXT )")
+ << QLatin1String("CREATE TABLE FolderTable("
+ "Id INTEGER PRIMARY KEY, "
+ "Name Text, "
+ "NamespaceID INTEGER )")
+ << QLatin1String("CREATE TABLE MetaDataTable("
+ "Name Text, "
+ "Value BLOB )");
+
+ foreach (QString q, tables) {
+ if (!d->query->exec(q)) {
+ d->error = tr("Cannot create tables!");
+ return false;
+ }
+ }
+
+ d->query->exec(QLatin1String("INSERT INTO MetaDataTable VALUES('qchVersion', '1.0')"));
+
+ d->query->prepare(QLatin1String("INSERT INTO MetaDataTable VALUES('CreationDate', ?)"));
+ d->query->bindValue(0, QDateTime::currentDateTime().toString(Qt::ISODate));
+ d->query->exec();
+
+ return true;
+}
+
+bool QHelpGenerator::insertFileNotFoundFile()
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT id FROM FileNameTable WHERE Name=\'\'"));
+ if (d->query->next() && d->query->isValid())
+ return true;
+
+ d->query->prepare(QLatin1String("INSERT INTO FileDataTable VALUES (Null, ?)"));
+ d->query->bindValue(0, QByteArray());
+ if (!d->query->exec())
+ return false;
+
+ int fileId = d->query->lastInsertId().toInt();
+ d->query->prepare(QLatin1String("INSERT INTO FileNameTable (FolderId, Name, FileId, Title) "
+ " VALUES (0, '', ?, '')"));
+ d->query->bindValue(0, fileId);
+ if (fileId > -1 && d->query->exec()) {
+ d->fileMap.insert(QString(), fileId);
+ return true;
+ }
+ return false;
+}
+
+bool QHelpGenerator::registerVirtualFolder(const QString &folderName, const QString &ns)
+{
+ if (!d->query || folderName.isEmpty() || ns.isEmpty())
+ return false;
+
+ d->query->prepare(QLatin1String("SELECT Id FROM FolderTable WHERE Name=?"));
+ d->query->bindValue(0, folderName);
+ d->query->exec();
+ d->query->next();
+ if (d->query->isValid() && d->query->value(0).toInt() > 0)
+ return true;
+
+ d->namespaceId = -1;
+ d->query->prepare(QLatin1String("SELECT Id FROM NamespaceTable WHERE Name=?"));
+ d->query->bindValue(0, ns);
+ d->query->exec();
+ while (d->query->next()) {
+ d->namespaceId = d->query->value(0).toInt();
+ break;
+ }
+
+ if (d->namespaceId < 0) {
+ d->query->prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, ns);
+ if (d->query->exec())
+ d->namespaceId = d->query->lastInsertId().toInt();
+ }
+
+ if (d->namespaceId > 0) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FolderTable WHERE Name=?"));
+ d->query->bindValue(0, folderName);
+ d->query->exec();
+ while (d->query->next())
+ d->virtualFolderId = d->query->value(0).toInt();
+
+ if (d->virtualFolderId > 0)
+ return true;
+
+ d->query->prepare(QLatin1String("INSERT INTO FolderTable (NamespaceId, Name) "
+ "VALUES (?, ?)"));
+ d->query->bindValue(0, d->namespaceId);
+ d->query->bindValue(1, folderName);
+ if (d->query->exec()) {
+ d->virtualFolderId = d->query->lastInsertId().toInt();
+ return d->virtualFolderId > 0;
+ }
+ }
+ d->error = tr("Cannot register virtual folder!");
+ return false;
+}
+
+bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPath,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert files..."));
+ QList<int> filterAtts;
+ foreach (QString filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterAttributeTable WHERE Name=?"));
+ d->query->bindValue(0, filterAtt);
+ d->query->exec();
+ if (d->query->next())
+ filterAtts.append(d->query->value(0).toInt());
+ }
+
+ int filterSetId = -1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileAttributeSetTable"));
+ if (d->query->next())
+ filterSetId = d->query->value(0).toInt();
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+ foreach (int attId, filterAtts) {
+ d->query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable VALUES(?, ?)"));
+ d->query->bindValue(0, filterSetId);
+ d->query->bindValue(1, attId);
+ d->query->exec();
+ }
+
+ QString title;
+ QString charSet;
+ QMap<int, QSet<int> > tmpFileFilterMap;
+ QList<FileNameTableData> fileNameDataList;
+ QList<QByteArray> fileDataList;
+
+ int tableFileId = 1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileDataTable"));
+ if (d->query->next())
+ tableFileId = d->query->value(0).toInt() + 1;
+
+ FileNameTableData fileNameData;
+
+ int i = 0;
+ foreach (QString file, files) {
+ QFileInfo fi(rootPath + QDir::separator() + file);
+ if (!fi.exists()) {
+ emit warning(tr("The file %1 does not exist! Skipping it.")
+ .arg(fi.absoluteFilePath()));
+ continue;
+ }
+
+ QFile f(fi.absoluteFilePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ emit warning(tr("Cannot open file %1! Skipping it.")
+ .arg(fi.absoluteFilePath()));
+ continue;
+ }
+
+ title.clear();
+ QByteArray data;
+ data = f.readAll();
+
+ if (fi.suffix() == QLatin1String("html") || fi.suffix() == QLatin1String("htm")) {
+ charSet = QHelpGlobal::charsetFromData(data);
+ QTextStream stream(&data);
+ stream.setCodec(QTextCodec::codecForName(charSet.toLatin1().constData()));
+ title = QHelpGlobal::documentTitle(stream.readAll());
+ } else {
+ title = fi.fileName();
+ }
+
+ QString fName = QDir::cleanPath(file);
+ if (fName.startsWith(QLatin1String("./")))
+ fName = fName.mid(2);
+
+ int fileId = -1;
+ if (!d->fileMap.contains(fName)) {
+ fileDataList.append(qCompress(data));
+
+ fileNameData.name = fName;
+ fileNameData.fileId = tableFileId;
+ fileNameData.title = title;
+ fileNameDataList.append(fileNameData);
+
+ d->fileMap.insert(fName, tableFileId);
+ d->fileFilterMap.insert(tableFileId, filterAtts.toSet());
+ tmpFileFilterMap.insert(tableFileId, filterAtts.toSet());
+
+ ++tableFileId;
+ } else {
+ fileId = d->fileMap.value(fName);
+ foreach (int filter, filterAtts) {
+ if (!d->fileFilterMap.value(fileId).contains(filter)
+ && !tmpFileFilterMap.value(fileId).contains(filter)) {
+ d->fileFilterMap[fileId].insert(filter);
+ tmpFileFilterMap[fileId].insert(filter);
+ }
+ }
+ }
+ }
+
+ if (tmpFileFilterMap.count()) {
+ d->query->exec(QLatin1String("BEGIN"));
+ QMap<int, QSet<int> >::const_iterator it = tmpFileFilterMap.constBegin();
+ while (it != tmpFileFilterMap.constEnd()) {
+ QSet<int>::const_iterator i = it.value().constBegin();
+ while (i != it.value().constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileFilterTable VALUES(?, ?)"));
+ d->query->bindValue(0, *i);
+ d->query->bindValue(1, it.key());
+ d->query->exec();
+ ++i;
+ }
+ ++it;
+ }
+
+ QList<QByteArray>::const_iterator fileIt = fileDataList.constBegin();
+ while (fileIt != fileDataList.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileDataTable VALUES (Null, ?)"));
+ d->query->bindValue(0, *fileIt);
+ d->query->exec();
+ ++fileIt;
+ if (++i%20 == 0)
+ addProgress(d->fileStep*20.0);
+ }
+
+ QList<FileNameTableData>::const_iterator fileNameIt = fileNameDataList.constBegin();
+ while (fileNameIt != fileNameDataList.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileNameTable (FolderId, Name, FileId, Title) "
+ " VALUES (?, ?, ?, ?)"));
+ d->query->bindValue(0, 1);
+ d->query->bindValue(1, (*fileNameIt).name);
+ d->query->bindValue(2, (*fileNameIt).fileId);
+ d->query->bindValue(3, (*fileNameIt).title);
+ d->query->exec();
+ ++fileNameIt;
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+ }
+
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileDataTable"));
+ if (d->query->next()
+ && d->query->value(0).toInt() == tableFileId-1) {
+ addProgress(d->fileStep*(i%20));
+ return true;
+ }
+ return false;
+}
+
+bool QHelpGenerator::registerCustomFilter(const QString &filterName, const QStringList &filterAttribs,
+ bool forceUpdate)
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
+ QStringList idsToInsert = filterAttribs;
+ QMap<QString, int> attributeMap;
+ while (d->query->next()) {
+ attributeMap.insert(d->query->value(1).toString(),
+ d->query->value(0).toInt());
+ if (idsToInsert.contains(d->query->value(1).toString()))
+ idsToInsert.removeAll(d->query->value(1).toString());
+ }
+
+ foreach (QString id, idsToInsert) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, id);
+ d->query->exec();
+ attributeMap.insert(id, d->query->lastInsertId().toInt());
+ }
+
+ int nameId = -1;
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ d->query->bindValue(0, filterName);
+ d->query->exec();
+ while (d->query->next()) {
+ nameId = d->query->value(0).toInt();
+ break;
+ }
+
+ if (nameId < 0) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, filterName);
+ if (d->query->exec())
+ nameId = d->query->lastInsertId().toInt();
+ } else if (!forceUpdate) {
+ d->error = tr("The filter %1 is already registered!").arg(filterName);
+ return false;
+ }
+
+ if (nameId < 0) {
+ d->error = tr("Cannot register filter %1!").arg(filterName);
+ return false;
+ }
+
+ d->query->prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ d->query->bindValue(0, nameId);
+ d->query->exec();
+
+ foreach (QString att, filterAttribs) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ d->query->bindValue(0, nameId);
+ d->query->bindValue(1, attributeMap[att]);
+ if (!d->query->exec())
+ return false;
+ }
+ return true;
+}
+
+bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> keywords,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert indices..."));
+ int indexId = 1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM IndexTable"));
+ if (d->query->next())
+ indexId = d->query->value(0).toInt() + 1;
+
+ QList<int> filterAtts;
+ foreach (QString filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterAttributeTable WHERE Name=?"));
+ d->query->bindValue(0, filterAtt);
+ d->query->exec();
+ if (d->query->next())
+ filterAtts.append(d->query->value(0).toInt());
+ }
+
+ int pos = -1;
+ QString fileName;
+ QString anchor;
+ QString fName;
+ int fileId = 1;
+ QList<int> indexFilterTable;
+
+ int i = 0;
+ d->query->exec(QLatin1String("BEGIN"));
+ foreach (QHelpDataIndexItem itm, keywords) {
+ pos = itm.reference.indexOf(QLatin1Char('#'));
+ fileName = itm.reference.left(pos);
+ if (pos > -1)
+ anchor = itm.reference.mid(pos+1);
+ else
+ anchor.clear();
+
+ fName = QDir::cleanPath(fileName);
+ if (fName.startsWith(QLatin1String("./")))
+ fName = fName.mid(2);
+
+ if (d->fileMap.contains(fName))
+ fileId = d->fileMap.value(fName);
+ else
+ fileId = 1;
+
+ d->query->prepare(QLatin1String("INSERT INTO IndexTable (Name, Identifier, NamespaceId, FileId, Anchor) "
+ "VALUES(?, ?, ?, ?, ?)"));
+ d->query->bindValue(0, itm.name);
+ d->query->bindValue(1, itm.identifier);
+ d->query->bindValue(2, d->namespaceId);
+ d->query->bindValue(3, fileId);
+ d->query->bindValue(4, anchor);
+ d->query->exec();
+
+ indexFilterTable.append(indexId++);
+ if (++i%100 == 0)
+ addProgress(d->indexStep*100.0);
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+
+ d->query->exec(QLatin1String("BEGIN"));
+ foreach (int idx, indexFilterTable) {
+ foreach (int a, filterAtts) {
+ d->query->prepare(QLatin1String("INSERT INTO IndexFilterTable (FilterAttributeId, IndexId) "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, a);
+ d->query->bindValue(1, idx);
+ d->query->exec();
+ }
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+
+ d->query->exec(QLatin1String("SELECT COUNT(Id) FROM IndexTable"));
+ if (d->query->next() && d->query->value(0).toInt() >= keywords.count())
+ return true;
+ return false;
+}
+
+bool QHelpGenerator::insertContents(const QByteArray &ba,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert contents..."));
+ d->query->prepare(QLatin1String("INSERT INTO ContentsTable (NamespaceId, Data) "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, d->namespaceId);
+ d->query->bindValue(1, ba);
+ d->query->exec();
+ int contentId = d->query->lastInsertId().toInt();
+ if (contentId < 1) {
+ d->error = tr("Cannot insert contents!");
+ return false;
+ }
+
+ // associate the filter attributes
+ foreach (QString filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("INSERT INTO ContentsFilterTable (FilterAttributeId, ContentsId) "
+ "SELECT Id, ? FROM FilterAttributeTable WHERE Name=?"));
+ d->query->bindValue(0, contentId);
+ d->query->bindValue(1, filterAtt);
+ d->query->exec();
+ if (!d->query->isActive()) {
+ d->error = tr("Cannot register contents!");
+ return false;
+ }
+ }
+ addProgress(d->contentStep);
+ return true;
+}
+
+bool QHelpGenerator::insertFilterAttributes(const QStringList &attributes)
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ QSet<QString> atts;
+ while (d->query->next())
+ atts.insert(d->query->value(0).toString());
+
+ foreach (QString s, attributes) {
+ if (!atts.contains(s)) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, s);
+ d->query->exec();
+ }
+ }
+ return true;
+}
+
+bool QHelpGenerator::insertMetaData(const QMap<QString, QVariant> &metaData)
+{
+ if (!d->query)
+ return false;
+
+ QMap<QString, QVariant>::const_iterator it = metaData.constBegin();
+ while (it != metaData.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO MetaDataTable VALUES(?, ?)"));
+ d->query->bindValue(0, it.key());
+ d->query->bindValue(1, it.value());
+ d->query->exec();
+ ++it;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpgenerator_p.h b/tools/assistant/lib/qhelpgenerator_p.h
new file mode 100644
index 0000000000..ddf2aed466
--- /dev/null
+++ b/tools/assistant/lib/qhelpgenerator_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** 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 QHELPGENERATOR_H
+#define QHELPGENERATOR_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+#include "qhelpdatainterface_p.h"
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHelpGeneratorPrivate;
+
+class QHELP_EXPORT QHelpGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpGenerator(QObject *parent = 0);
+ ~QHelpGenerator();
+
+ bool generate(QHelpDataInterface *helpData,
+ const QString &outputFileName);
+ QString error() const;
+
+Q_SIGNALS:
+ void statusChanged(const QString &msg);
+ void progressChanged(double progress);
+ void warning(const QString &msg);
+
+private:
+ struct FileNameTableData
+ {
+ QString name;
+ int fileId;
+ QString title;
+ };
+
+ void writeTree(QDataStream &s, QHelpDataContentItem *item, int depth);
+ bool createTables();
+ bool insertFileNotFoundFile();
+ bool registerCustomFilter(const QString &filterName,
+ const QStringList &filterAttribs, bool forceUpdate = false);
+ bool registerVirtualFolder(const QString &folderName, const QString &ns);
+ bool insertFilterAttributes(const QStringList &attributes);
+ bool insertKeywords(const QList<QHelpDataIndexItem> keywords,
+ const QStringList &filterAttributes);
+ bool insertFiles(const QStringList &files, const QString &rootPath,
+ const QStringList &filterAttributes);
+ bool insertContents(const QByteArray &ba,
+ const QStringList &filterAttributes);
+ bool insertMetaData(const QMap<QString, QVariant> &metaData);
+ void cleanupDB();
+ void setupProgress(QHelpDataInterface *helpData);
+ void addProgress(double step);
+
+ QHelpGeneratorPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/lib/qhelpindexwidget.cpp b/tools/assistant/lib/qhelpindexwidget.cpp
new file mode 100644
index 0000000000..7db9867584
--- /dev/null
+++ b/tools/assistant/lib/qhelpindexwidget.cpp
@@ -0,0 +1,445 @@
+/****************************************************************************
+**
+** 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 "qhelpindexwidget.h"
+#include "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtGui/QListView>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpIndexProvider : public QThread
+{
+public:
+ QHelpIndexProvider(QHelpEnginePrivate *helpEngine);
+ ~QHelpIndexProvider();
+ void collectIndices(const QString &customFilterName);
+ void stopCollecting();
+ QStringList indices() const;
+ QList<QHelpDBReader*> activeReaders() const;
+ QSet<int> indexIds(QHelpDBReader *reader) const;
+
+private:
+ void run();
+
+ QHelpEnginePrivate *m_helpEngine;
+ QStringList m_indices;
+ QList<QHelpDBReader*> m_activeReaders;
+ QMap<QHelpDBReader*, QSet<int> > m_indexIds;
+ QStringList m_filterAttributes;
+ mutable QMutex m_mutex;
+ bool m_abort;
+};
+
+class QHelpIndexModelPrivate
+{
+public:
+ QHelpIndexModelPrivate(QHelpEnginePrivate *hE)
+ {
+ helpEngine = hE;
+ indexProvider = new QHelpIndexProvider(helpEngine);
+ insertedRows = 0;
+ }
+
+ QHelpEnginePrivate *helpEngine;
+ QHelpIndexProvider *indexProvider;
+ QStringList indices;
+ int insertedRows;
+ QString currentFilter;
+ QList<QHelpDBReader*> activeReaders;
+};
+
+static bool caseInsensitiveLessThan(const QString &as, const QString &bs)
+{
+ return QString::compare(as, bs, Qt::CaseInsensitive) < 0;
+}
+
+QHelpIndexProvider::QHelpIndexProvider(QHelpEnginePrivate *helpEngine)
+ : QThread(helpEngine)
+{
+ m_helpEngine = helpEngine;
+ m_abort = false;
+}
+
+QHelpIndexProvider::~QHelpIndexProvider()
+{
+ stopCollecting();
+}
+
+void QHelpIndexProvider::collectIndices(const QString &customFilterName)
+{
+ m_mutex.lock();
+ m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
+ m_mutex.unlock();
+ if (!isRunning()) {
+ start(LowPriority);
+ } else {
+ stopCollecting();
+ start(LowPriority);
+ }
+}
+
+void QHelpIndexProvider::stopCollecting()
+{
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+}
+
+QStringList QHelpIndexProvider::indices() const
+{
+ QMutexLocker lck(&m_mutex);
+ return m_indices;
+}
+
+QList<QHelpDBReader*> QHelpIndexProvider::activeReaders() const
+{
+ QMutexLocker lck(&m_mutex);
+ return m_activeReaders;
+}
+
+QSet<int> QHelpIndexProvider::indexIds(QHelpDBReader *reader) const
+{
+ QMutexLocker lck(&m_mutex);
+ if (m_indexIds.contains(reader))
+ return m_indexIds.value(reader);
+ return QSet<int>();
+}
+
+void QHelpIndexProvider::run()
+{
+ m_mutex.lock();
+ QStringList atts = m_filterAttributes;
+ m_indices.clear();
+ m_activeReaders.clear();
+ QSet<QString> indicesSet;
+ m_mutex.unlock();
+
+ foreach (QString dbFileName, m_helpEngine->fileNameReaderMap.keys()) {
+ m_mutex.lock();
+ if (m_abort) {
+ m_abort = false;
+ m_mutex.unlock();
+ return;
+ }
+ m_mutex.unlock();
+ QHelpDBReader reader(dbFileName,
+ QHelpGlobal::uniquifyConnectionName(dbFileName +
+ QLatin1String("FromIndexProvider"),
+ QThread::currentThread()), 0);
+ if (!reader.init())
+ continue;
+ QStringList lst = reader.indicesForFilter(atts);
+ if (!lst.isEmpty()) {
+ m_mutex.lock();
+ foreach (QString s, lst)
+ indicesSet.insert(s);
+ if (m_abort) {
+ m_abort = false;
+ m_mutex.unlock();
+ return;
+ }
+ QHelpDBReader *orgReader = m_helpEngine->fileNameReaderMap.value(dbFileName);
+ m_indexIds.insert(orgReader, reader.indexIds(atts));
+ m_activeReaders.append(orgReader);
+ m_mutex.unlock();
+ }
+ }
+ m_mutex.lock();
+ m_indices = indicesSet.values();
+ qSort(m_indices.begin(), m_indices.end(), caseInsensitiveLessThan);
+ m_abort = false;
+ m_mutex.unlock();
+}
+
+
+
+/*!
+ \class QHelpIndexModel
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpIndexModel class provides a model that
+ supplies index keywords to views.
+
+
+*/
+
+/*!
+ \fn void QHelpIndexModel::indexCreationStarted()
+
+ This signal is emitted when the creation of a new index
+ has started. The current index is invalid from this
+ point on until the signal indexCreated() is emitted.
+
+ \sa isCreatingIndex()
+*/
+
+/*!
+ \fn void QHelpIndexModel::indexCreated()
+
+ This signal is emitted when the index has been created.
+*/
+
+QHelpIndexModel::QHelpIndexModel(QHelpEnginePrivate *helpEngine)
+ : QStringListModel(helpEngine)
+{
+ d = new QHelpIndexModelPrivate(helpEngine);
+
+ connect(d->indexProvider, SIGNAL(finished()), this, SLOT(insertIndices()));
+ connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateIndex()));
+}
+
+QHelpIndexModel::~QHelpIndexModel()
+{
+ delete d;
+}
+
+void QHelpIndexModel::invalidateIndex(bool onShutDown)
+{
+ if (onShutDown)
+ disconnect(this, SLOT(insertIndices()));
+ d->indexProvider->stopCollecting();
+ d->indices.clear();
+ filter(QString());
+}
+
+/*!
+ Creates a new index by querying the help system for
+ keywords for the specified \a customFilterName.
+*/
+void QHelpIndexModel::createIndex(const QString &customFilterName)
+{
+ d->currentFilter = customFilterName;
+ d->indexProvider->collectIndices(customFilterName);
+ emit indexCreationStarted();
+}
+
+void QHelpIndexModel::insertIndices()
+{
+ d->indices = d->indexProvider->indices();
+ d->activeReaders = d->indexProvider->activeReaders();
+ QStringList attributes = d->helpEngine->q->filterAttributes(d->currentFilter);
+ if (attributes.count() > 1) {
+ foreach (QHelpDBReader *r, d->activeReaders)
+ r->createAttributesCache(attributes, d->indexProvider->indexIds(r));
+ }
+ filter(QString());
+ emit indexCreated();
+}
+
+/*!
+ Returns true if the index is currently built up, otherwise
+ false.
+*/
+bool QHelpIndexModel::isCreatingIndex() const
+{
+ return d->indexProvider->isRunning();
+}
+
+/*!
+ Returns all hits found for the \a keyword. A hit consists of
+ the URL and the document title.
+*/
+QMap<QString, QUrl> QHelpIndexModel::linksForKeyword(const QString &keyword) const
+{
+ QMap<QString, QUrl> linkMap;
+ QStringList filterAttributes = d->helpEngine->q->filterAttributes(d->currentFilter);
+ foreach (QHelpDBReader *reader, d->activeReaders)
+ reader->linksForKeyword(keyword, filterAttributes, linkMap);
+ return linkMap;
+}
+
+/*!
+ Filters the indices and returns the model index of the best
+ matching keyword. In a first step, only the keywords containing
+ \a filter are kept in the model's index list. Analogously, if
+ \a wildcard is not empty, only the keywords matched are left
+ in the index list. In a second step, the best match is
+ determined and its index model returned. When specifying a
+ wildcard expression, the \a filter string is used to
+ search for the best match.
+*/
+QModelIndex QHelpIndexModel::filter(const QString &filter, const QString &wildcard)
+{
+ if (filter.isEmpty()) {
+ setStringList(d->indices);
+ return index(-1, 0, QModelIndex());
+ }
+
+ QStringList lst;
+ int goodMatch = -1;
+ int perfectMatch = -1;
+
+ if (!wildcard.isEmpty()) {
+ QRegExp regExp(wildcard, Qt::CaseInsensitive);
+ regExp.setPatternSyntax(QRegExp::Wildcard);
+ foreach (QString index, d->indices) {
+ if (index.contains(regExp)) {
+ lst.append(index);
+ if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) {
+ if (goodMatch == -1)
+ goodMatch = lst.count()-1;
+ if (filter.length() == index.length()){
+ perfectMatch = lst.count()-1;
+ }
+ } else if (perfectMatch > -1 && index == filter) {
+ perfectMatch = lst.count()-1;
+ }
+ }
+ }
+ } else {
+ foreach (QString index, d->indices) {
+ if (index.contains(filter, Qt::CaseInsensitive)) {
+ lst.append(index);
+ if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) {
+ if (goodMatch == -1)
+ goodMatch = lst.count()-1;
+ if (filter.length() == index.length()){
+ perfectMatch = lst.count()-1;
+ }
+ } else if (perfectMatch > -1 && index == filter) {
+ perfectMatch = lst.count()-1;
+ }
+ }
+ }
+
+ }
+
+ if (perfectMatch == -1)
+ perfectMatch = qMax(0, goodMatch);
+
+ setStringList(lst);
+ return index(perfectMatch, 0, QModelIndex());
+}
+
+
+
+/*!
+ \class QHelpIndexWidget
+ \inmodule QtHelp
+ \since 4.4
+ \brief The QHelpIndexWidget class provides a list view
+ displaying the QHelpIndexModel.
+*/
+
+/*!
+ \fn void QHelpIndexWidget::linkActivated(const QUrl &link,
+ const QString &keyword)
+
+ This signal is emitted when an item is activated and its
+ associated \a link should be shown. To know where the link
+ belongs to, the \a keyword is given as a second paremeter.
+*/
+
+/*!
+ \fn void QHelpIndexWidget::linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword)
+
+ This signal is emitted when the item representing the \a keyword
+ is activated and the item has more than one link associated.
+ The \a links consist of the document title and their URL.
+*/
+
+QHelpIndexWidget::QHelpIndexWidget()
+ : QListView(0)
+{
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+ setUniformItemSizes(true);
+ connect(this, SIGNAL(activated(const QModelIndex&)),
+ this, SLOT(showLink(const QModelIndex&)));
+}
+
+void QHelpIndexWidget::showLink(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+
+ QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel*>(model());
+ if (!indexModel)
+ return;
+ QVariant v = indexModel->data(index, Qt::DisplayRole);
+ QString name;
+ if (v.isValid())
+ name = v.toString();
+
+ QMap<QString, QUrl> links = indexModel->linksForKeyword(name);
+ if (links.count() == 1) {
+ emit linkActivated(links.constBegin().value(), name);
+ } else if (links.count() > 1) {
+ emit linksActivated(links, name);
+ }
+}
+
+/*!
+ Activates the current item which will result eventually in
+ the emitting of a linkActivated() or linksActivated()
+ signal.
+*/
+void QHelpIndexWidget::activateCurrentItem()
+{
+ showLink(currentIndex());
+}
+
+/*!
+ Filters the indices according to \a filter or \a wildcard.
+ The item with the best match is set as current item.
+
+ \sa QHelpIndexModel::filter()
+*/
+void QHelpIndexWidget::filterIndices(const QString &filter, const QString &wildcard)
+{
+ QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel*>(model());
+ if (!indexModel)
+ return;
+ QModelIndex idx = indexModel->filter(filter, wildcard);
+ if (idx.isValid())
+ setCurrentIndex(idx);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpindexwidget.h b/tools/assistant/lib/qhelpindexwidget.h
new file mode 100644
index 0000000000..46b9e4c95c
--- /dev/null
+++ b/tools/assistant/lib/qhelpindexwidget.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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 QHELPINDEXWIDGET_H
+#define QHELPINDEXWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtGui/QStringListModel>
+#include <QtGui/QListView>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEnginePrivate;
+class QHelpIndexModelPrivate;
+
+class QHELP_EXPORT QHelpIndexModel : public QStringListModel
+{
+ Q_OBJECT
+
+public:
+ void createIndex(const QString &customFilterName);
+ QModelIndex filter(const QString &filter,
+ const QString &wildcard = QString());
+
+ QMap<QString, QUrl> linksForKeyword(const QString &keyword) const;
+ bool isCreatingIndex() const;
+
+Q_SIGNALS:
+ void indexCreationStarted();
+ void indexCreated();
+
+private Q_SLOTS:
+ void insertIndices();
+ void invalidateIndex(bool onShutDown = false);
+
+private:
+ QHelpIndexModel(QHelpEnginePrivate *helpEngine);
+ ~QHelpIndexModel();
+
+ QHelpIndexModelPrivate *d;
+ friend class QHelpEnginePrivate;
+};
+
+class QHELP_EXPORT QHelpIndexWidget : public QListView
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void linkActivated(const QUrl &link, const QString &keyword);
+ void linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword);
+
+public Q_SLOTS:
+ void filterIndices(const QString &filter,
+ const QString &wildcard = QString());
+ void activateCurrentItem();
+
+private Q_SLOTS:
+ void showLink(const QModelIndex &index);
+
+private:
+ QHelpIndexWidget();
+ friend class QHelpEngine;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp
new file mode 100644
index 0000000000..fcb8cf6753
--- /dev/null
+++ b/tools/assistant/lib/qhelpprojectdata.cpp
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** 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 "qhelpprojectdata_p.h"
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QStack>
+#include <QtCore/QMap>
+#include <QtCore/QVariant>
+#include <QtXml/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpProjectDataPrivate : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+
+ QString virtualFolder;
+ QString namespaceName;
+ QString rootPath;
+
+ QStringList fileList;
+ QList<QHelpDataCustomFilter> customFilterList;
+ QList<QHelpDataFilterSection> filterSectionList;
+ QMap<QString, QVariant> metaData;
+
+ QString errorMsg;
+
+private:
+ void readProject();
+ void readCustomFilter();
+ void readFilterSection();
+ void readTOC();
+ void readKeywords();
+ void readFiles();
+ void raiseUnknownTokenError();
+};
+
+void QHelpProjectDataPrivate::raiseUnknownTokenError()
+{
+ raiseError(QObject::tr("Unknown token."));
+}
+
+void QHelpProjectDataPrivate::readData(const QByteArray &contents)
+{
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("QtHelpProject")
+ && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
+ readProject();
+ else
+ raiseError(QObject::tr("Unknown token. Expected \"QtHelpProject\"!"));
+ }
+ }
+
+ if (hasError()) {
+ raiseError(QObject::tr("Error in line %1: %2").arg(lineNumber())
+ .arg(errorString()));
+ }
+}
+
+void QHelpProjectDataPrivate::readProject()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("virtualFolder")) {
+ virtualFolder = readElementText();
+ if (virtualFolder.contains(QLatin1String("/")))
+ raiseError(QObject::tr("A virtual folder must not contain a \'/\' character!"));
+ } else if (name() == QLatin1String("namespace")) {
+ namespaceName = readElementText();
+ if (namespaceName.contains(QLatin1String("/")))
+ raiseError(QObject::tr("A namespace must not contain a \'/\' character!"));
+ } else if (name() == QLatin1String("customFilter")) {
+ readCustomFilter();
+ } else if (name() == QLatin1String("filterSection")) {
+ readFilterSection();
+ } else if (name() == QLatin1String("metaData")) {
+ QString n = attributes().value(QLatin1String("name")).toString();
+ if (!metaData.contains(n))
+ metaData[n] = attributes().value(QLatin1String("value")).toString();
+ else
+ metaData.insert(n, attributes().value(QLatin1String("value")).toString());
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement() && name() == QLatin1String("QtHelpProject")) {
+ if (namespaceName.isEmpty())
+ raiseError(QObject::tr("Missing namespace in QtHelpProject."));
+ else if (virtualFolder.isEmpty())
+ raiseError(QObject::tr("Missing virtual folder in QtHelpProject"));
+ break;
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readCustomFilter()
+{
+ QHelpDataCustomFilter filter;
+ filter.name = attributes().value(QLatin1String("name")).toString();
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("filterAttribute"))
+ filter.filterAttributes.append(readElementText());
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement() && name() == QLatin1String("customFilter")) {
+ break;
+ }
+ }
+ customFilterList.append(filter);
+}
+
+void QHelpProjectDataPrivate::readFilterSection()
+{
+ filterSectionList.append(QHelpDataFilterSection());
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("filterAttribute"))
+ filterSectionList.last().addFilterAttribute(readElementText());
+ else if (name() == QLatin1String("toc"))
+ readTOC();
+ else if (name() == QLatin1String("keywords"))
+ readKeywords();
+ else if (name() == QLatin1String("files"))
+ readFiles();
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement() && name() == QLatin1String("filterSection")) {
+ break;
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readTOC()
+{
+ QStack<QHelpDataContentItem*> contentStack;
+ QHelpDataContentItem *itm = 0;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("section")) {
+ QString title = attributes().value(QLatin1String("title")).toString();
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ if (contentStack.isEmpty()) {
+ itm = new QHelpDataContentItem(0, title, ref);
+ filterSectionList.last().addContent(itm);
+ } else {
+ itm = new QHelpDataContentItem(contentStack.top(), title, ref);
+ }
+ contentStack.push(itm);
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("section")) {
+ contentStack.pop();
+ continue;
+ } else if (name() == QLatin1String("toc") && contentStack.isEmpty()) {
+ break;
+ } else {
+ raiseUnknownTokenError();
+ }
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readKeywords()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("keyword")) {
+ if (attributes().value(QLatin1String("ref")).toString().isEmpty()
+ || (attributes().value(QLatin1String("name")).toString().isEmpty()
+ && attributes().value(QLatin1String("id")).toString().isEmpty()))
+ raiseError(QObject::tr("Missing attribute in keyword at line %1.")
+ .arg(lineNumber()));
+ filterSectionList.last().addIndex(
+ QHelpDataIndexItem(attributes().value(QLatin1String("name")).toString(),
+ attributes().value(QLatin1String("id")).toString(),
+ attributes().value(QLatin1String("ref")).toString()));
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("keyword"))
+ continue;
+ else if (name() == QLatin1String("keywords"))
+ break;
+ else
+ raiseUnknownTokenError();
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readFiles()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ filterSectionList.last().addFile(readElementText());
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("file"))
+ continue;
+ else if (name() == QLatin1String("files"))
+ break;
+ else
+ raiseUnknownTokenError();
+ }
+ }
+}
+
+
+
+/*!
+ \internal
+ \class QHelpProjectData
+ \since 4.4
+ \brief The QHelpProjectData class stores all information found
+ in a Qt help project file.
+
+ The structure is filled with data by calling readData(). The
+ specified file has to have the Qt help project file format in
+ order to be read successfully. Possible reading errors can be
+ retrieved by calling errorMessage().
+*/
+
+/*!
+ Constructs a Qt help project data structure.
+*/
+QHelpProjectData::QHelpProjectData()
+{
+ d = new QHelpProjectDataPrivate;
+}
+
+/*!
+ Destroys the help project data.
+*/
+QHelpProjectData::~QHelpProjectData()
+{
+ delete d;
+}
+
+/*!
+ Reads the file \a fileName and stores the help data. The file has to
+ have the Qt help project file format. Returns true if the file
+ was successfully read, otherwise false.
+
+ \sa errorMessage()
+*/
+bool QHelpProjectData::readData(const QString &fileName)
+{
+ d->rootPath = QFileInfo(fileName).absolutePath();
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ d->errorMsg = QObject::tr("The input file %1 could not be opened!")
+ .arg(fileName);
+ return false;
+ }
+
+ d->readData(file.readAll());
+ return !d->hasError();
+}
+
+/*!
+ Returns an error message if the reading of the Qt help project
+ file failed. Otherwise, an empty QString is returned.
+
+ \sa readData()
+*/
+QString QHelpProjectData::errorMessage() const
+{
+ if (d->hasError())
+ return d->errorString();
+ return d->errorMsg;
+}
+
+/*!
+ \reimp
+*/
+QString QHelpProjectData::namespaceName() const
+{
+ return d->namespaceName;
+}
+
+/*!
+ \reimp
+*/
+QString QHelpProjectData::virtualFolder() const
+{
+ return d->virtualFolder;
+}
+
+/*!
+ \reimp
+*/
+QList<QHelpDataCustomFilter> QHelpProjectData::customFilters() const
+{
+ return d->customFilterList;
+}
+
+/*!
+ \reimp
+*/
+QList<QHelpDataFilterSection> QHelpProjectData::filterSections() const
+{
+ return d->filterSectionList;
+}
+
+/*!
+ \reimp
+*/
+QMap<QString, QVariant> QHelpProjectData::metaData() const
+{
+ return d->metaData;
+}
+
+/*!
+ \reimp
+*/
+QString QHelpProjectData::rootPath() const
+{
+ return d->rootPath;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpprojectdata_p.h b/tools/assistant/lib/qhelpprojectdata_p.h
new file mode 100644
index 0000000000..52eb723537
--- /dev/null
+++ b/tools/assistant/lib/qhelpprojectdata_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 QHELPPROJECTDATA_H
+#define QHELPPROJECTDATA_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+#include "qhelpdatainterface_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHelpProjectDataPrivate;
+
+class QHELP_EXPORT QHelpProjectData : public QHelpDataInterface
+{
+public:
+ QHelpProjectData();
+ ~QHelpProjectData();
+
+ bool readData(const QString &fileName);
+ QString errorMessage() const;
+
+ QString namespaceName() const;
+ QString virtualFolder() const;
+ QList<QHelpDataCustomFilter> customFilters() const;
+ QList<QHelpDataFilterSection> filterSections() const;
+ QMap<QString, QVariant> metaData() const;
+ QString rootPath() const;
+
+private:
+ QHelpProjectDataPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp
new file mode 100644
index 0000000000..9025f4f692
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchengine.cpp
@@ -0,0 +1,445 @@
+/****************************************************************************
+**
+** 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 "qhelpenginecore.h"
+#include "qhelpsearchengine.h"
+#include "qhelpsearchquerywidget.h"
+#include "qhelpsearchresultwidget.h"
+
+#if defined(QT_CLUCENE_SUPPORT)
+# include "qhelpsearchindexreader_clucene_p.h"
+# include "qhelpsearchindexwriter_clucene_p.h"
+#else
+# include "qhelpsearchindexreader_default_p.h"
+# include "qhelpsearchindexwriter_default_p.h"
+#endif
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QVariant>
+#include <QtCore/QThread>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_CLUCENE_SUPPORT)
+ using namespace qt::fulltextsearch::clucene;
+#else
+ using namespace qt::fulltextsearch::std;
+#endif
+
+class QHelpSearchEnginePrivate : public QObject
+{
+ Q_OBJECT
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ QHelpSearchEnginePrivate(QHelpEngineCore *helpEngine)
+ : queryWidget(0)
+ , resultWidget(0)
+ , helpEngine(helpEngine)
+ {
+ hitList.clear();
+ indexReader = 0;
+ indexWriter = 0;
+ }
+
+ ~QHelpSearchEnginePrivate()
+ {
+ hitList.clear();
+ delete indexReader;
+ delete indexWriter;
+ }
+
+ int hitsCount() const
+ {
+ int count = 0;
+ if (indexReader)
+ count = indexReader->hitsCount();
+
+ return count;
+ }
+
+ QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const
+ {
+ QList<QHelpSearchEngine::SearchHit> returnValue;
+ if (indexReader) {
+ for (int i = start; i < end && i < hitsCount(); ++i)
+ returnValue.append(indexReader->hit(i));
+ }
+ return returnValue;
+ }
+
+ void updateIndex(bool reindex = false)
+ {
+ if (helpEngine.isNull())
+ return;
+
+ if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
+ return;
+
+ if (!indexWriter) {
+ indexWriter = new QHelpSearchIndexWriter();
+
+ connect(indexWriter, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
+ connect(indexWriter, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
+ connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex()));
+ }
+
+ if (indexWriter) {
+ indexWriter->cancelIndexing();
+ indexWriter->updateIndex(helpEngine->collectionFile(),
+ indexFilesFolder(), reindex);
+ }
+ }
+
+ void cancelIndexing()
+ {
+ if (indexWriter)
+ indexWriter->cancelIndexing();
+ }
+
+ void search(const QList<QHelpSearchQuery> &queryList)
+ {
+ if (helpEngine.isNull())
+ return;
+
+ if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
+ return;
+
+ if (!indexReader) {
+ indexReader = new QHelpSearchIndexReader();
+
+ connect(indexReader, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
+ connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
+ }
+
+ if (indexReader) {
+ m_queryList = queryList;
+ indexReader->cancelSearching();
+ indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
+ }
+ }
+
+ void cancelSearching()
+ {
+ if (indexReader)
+ indexReader->cancelSearching();
+ }
+
+ QString indexFilesFolder() const
+ {
+ QString indexFilesFolder = QLatin1String(".fulltextsearch");
+ if (helpEngine && !helpEngine->collectionFile().isEmpty()) {
+ QFileInfo fi(helpEngine->collectionFile());
+ indexFilesFolder = fi.absolutePath() + QDir::separator()
+ + QLatin1Char('.')
+ + fi.fileName().left(fi.fileName().lastIndexOf(QLatin1String(".qhc")));
+ }
+ return indexFilesFolder;
+ }
+
+private slots:
+ void optimizeIndex()
+ {
+#if defined(QT_CLUCENE_SUPPORT)
+ if (indexWriter && !helpEngine.isNull()) {
+ indexWriter->optimizeIndex();
+ }
+#endif
+ }
+
+private:
+ friend class QHelpSearchEngine;
+
+ QHelpSearchQueryWidget *queryWidget;
+ QHelpSearchResultWidget *resultWidget;
+
+ QHelpSearchIndexReader *indexReader;
+ QHelpSearchIndexWriter *indexWriter;
+
+ QPointer<QHelpEngineCore> helpEngine;
+ QList<QHelpSearchEngine::SearchHit> hitList;
+
+ QList<QHelpSearchQuery> m_queryList;
+};
+
+#include "qhelpsearchengine.moc"
+
+
+/*!
+ \class QHelpSearchQuery
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchQuery class contains the field name and the associated
+ search term
+
+ The QHelpSearchQuery class contains the field name and the associated search
+ term. Depending on the field the search term might get split up into seperate
+ terms to be parsed differently by the search engine.
+
+ \sa QHelpSearchQueryWidget
+*/
+
+/*!
+ \fn QHelpSearchQuery::QHelpSearchQuery()
+
+ Constructs a new empty QHelpSearchQuery.
+*/
+
+/*!
+ \fn QHelpSearchQuery::QHelpSearchQuery(FieldName field, const QStringList &wordList)
+
+ Constructs a new QHelpSearchQuery and initializes it with the given \a field and \a wordList.
+*/
+
+/*!
+ \enum QHelpSearchQuery::FieldName
+ This enum type specifies the field names that are handled by the search engine.
+
+ \value DEFAULT the default field provided by the search widget, several terms should be
+ splitted and stored in the wordlist except search terms enclosed in quotes.
+ \value FUZZY a field only provided in use with clucene. Terms should be split in seperate
+ words and passed to the search engine.
+ \value WITHOUT a field only provided in use with clucene. Terms should be split in seperate
+ words and passed to the search engine.
+ \value PHRASE a field only provided in use with clucene. Terms should not be split in seperate
+ words.
+ \value ALL a field only provided in use with clucene. Terms should be split in seperate
+ words and passed to the search engine
+ \value ATLEAST a field only provided in use with clucene. Terms should be split in seperate
+ words and passed to the search engine
+*/
+
+/*!
+ \class QHelpSearchEngine
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchEngine class provides access to widgets reusable
+ to integrate fulltext search as well as to index and search documentation.
+
+ Before the search engine can be used, one has to instantiate at least a
+ QHelpEngineCore object that needs to be passed to the search engines constructor.
+ This is required as the search engine needs to be connected to the help
+ engines setupFinished() signal to know when it can start to index documentation.
+
+ After starting the indexing process the signal indexingStarted() is emitted and
+ on the end of the indexing process the indexingFinished() is emited. To stop
+ the indexing one can call cancelIndexing().
+
+ While the indexing process has finished, the search engine can now be used to search
+ thru its index for a given term. To do this one may use the possibility of creating the
+ QHelpSearchQuery list by self or reuse the QHelpSearchQueryWidget which has the inbuild
+ functionality to set up a proper search querys list that get's passed to the search engines
+ search() function.
+
+ After the list of querys has been passed to the search engine, the signal searchingStarted()
+ is emited and after the search has finished the searchingFinished() signal is emited. The
+ search process can be stopped by calling cancelSearching().
+
+ If the search succeeds, the searchingFinished() will be called with the search hits count,
+ which can be reused to fetch the search hits from the search engine. Calling the hits()
+ function with the range of hits you would like to get will return a list of the requested
+ SearchHits. They basically constist at the moment of a pair of strings where the values
+ of that pair are the documentation file path and the page title.
+
+ To display the given hits use the QHelpSearchResultWidget or build up your own one if you need
+ more advanced functionality. Note that the QHelpSearchResultWidget can not be instantiated
+ directly, you must retrieve the widget from the search engine in use as all connections will be
+ established for you by the widget itself.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::indexingStarted()
+
+ This signal is emitted when indexing process is started.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::indexingFinished()
+
+ This signal is emitted when the indexing process is complete.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::searchingStarted()
+
+ This signal is emitted when the search process is started.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::searchingFinished(int hits)
+
+ This signal is emitted when the search process is complete.
+ The hit count is stored in \a hits.
+*/
+
+/*!
+ Constructs a new search engine with the given \a parent. The search engine
+ uses the given \a helpEngine to access the documentation that needs to be indexed.
+ The QHelpEngine's setupFinished() signal is automatically connected to the
+ QHelpSearchEngine's indexing function, so that new documentation will be indexed
+ after the signal is emited.
+*/
+QHelpSearchEngine::QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpSearchEnginePrivate(helpEngine);
+
+ connect(helpEngine, SIGNAL(setupFinished()), this, SLOT(indexDocumentation()));
+
+ connect(d, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
+ connect(d, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
+ connect(d, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
+ connect(d, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
+}
+
+/*!
+ Destructs the search engine.
+*/
+QHelpSearchEngine::~QHelpSearchEngine()
+{
+ delete d;
+}
+
+/*!
+ Returns a widget to use as input widget. Depending on your search engine
+ configuration you will get a different widget with more or less subwidgets.
+*/
+QHelpSearchQueryWidget* QHelpSearchEngine::queryWidget()
+{
+ if (!d->queryWidget)
+ d->queryWidget = new QHelpSearchQueryWidget();
+
+ return d->queryWidget;
+}
+
+/*!
+ Returns a widget that can hold and display the search results.
+*/
+QHelpSearchResultWidget* QHelpSearchEngine::resultWidget()
+{
+ if (!d->resultWidget)
+ d->resultWidget = new QHelpSearchResultWidget(this);
+
+ return d->resultWidget;
+}
+
+/*!
+ Returns the amount of hits the search engine found.
+*/
+int QHelpSearchEngine::hitsCount() const
+{
+ return d->hitsCount();
+}
+
+/*!
+ \typedef QHelpSearchEngine::SearchHit
+
+ Typedef for QPair<QString, QString>.
+ The values of that pair are the documentation file path and the page title.
+
+ \sa hits()
+*/
+
+/*!
+ Returns a list of search hits within the range of \a start \a end.
+*/
+QList<QHelpSearchEngine::SearchHit> QHelpSearchEngine::hits(int start, int end) const
+{
+ return d->hits(start, end);
+}
+
+/*!
+ Returns the list of queries last searched for.
+ \since 4.5
+*/
+QList<QHelpSearchQuery> QHelpSearchEngine::query() const
+{
+ return d->m_queryList;
+}
+
+/*!
+ Forces the search engine to reindex all documentation files.
+*/
+void QHelpSearchEngine::reindexDocumentation()
+{
+ d->updateIndex(true);
+}
+
+/*!
+ Stops the indexing process.
+*/
+void QHelpSearchEngine::cancelIndexing()
+{
+ d->cancelIndexing();
+}
+
+/*!
+ Stops the search process.
+*/
+void QHelpSearchEngine::cancelSearching()
+{
+ d->cancelSearching();
+}
+
+/*!
+ Starts the search process using the given list of querys \a queryList
+ build by the search field name and the values to search for.
+*/
+void QHelpSearchEngine::search(const QList<QHelpSearchQuery> &queryList)
+{
+ d->search(queryList);
+}
+
+void QHelpSearchEngine::indexDocumentation()
+{
+ d->updateIndex();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchengine.h b/tools/assistant/lib/qhelpsearchengine.h
new file mode 100644
index 0000000000..bd14d3ef83
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchengine.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHENGINE_H
+#define QHELPSEARCHENGINE_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QUrl>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEngineCore;
+class QHelpSearchQueryWidget;
+class QHelpSearchResultWidget;
+class QHelpSearchEnginePrivate;
+
+class QHELP_EXPORT QHelpSearchQuery
+{
+public:
+ enum FieldName { DEFAULT = 0, FUZZY, WITHOUT, PHRASE, ALL, ATLEAST };
+
+ QHelpSearchQuery()
+ : fieldName(DEFAULT) { wordList.clear(); }
+ QHelpSearchQuery(FieldName field, const QStringList &wordList)
+ : fieldName(field), wordList(wordList) {}
+
+ FieldName fieldName;
+ QStringList wordList;
+};
+
+class QHELP_EXPORT QHelpSearchEngine : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent = 0);
+ ~QHelpSearchEngine();
+
+ QHelpSearchQueryWidget* queryWidget();
+ QHelpSearchResultWidget* resultWidget();
+
+ int hitsCount() const;
+
+ typedef QPair<QString, QString> SearchHit;
+ QList<SearchHit> hits(int start, int end) const;
+
+ QList<QHelpSearchQuery> query() const;
+
+public Q_SLOTS:
+ void reindexDocumentation();
+ void cancelIndexing();
+
+ void search(const QList<QHelpSearchQuery> &queryList);
+ void cancelSearching();
+
+Q_SIGNALS:
+ void indexingStarted();
+ void indexingFinished();
+
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private Q_SLOTS:
+ void indexDocumentation();
+
+private:
+ QHelpSearchEnginePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHENGINE_H
diff --git a/tools/assistant/lib/qhelpsearchindex_default.cpp b/tools/assistant/lib/qhelpsearchindex_default.cpp
new file mode 100644
index 0000000000..defba91955
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindex_default.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 "qhelpsearchindex_default_p.h"
+
+QT_BEGIN_NAMESPACE
+
+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;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchindex_default_p.h b/tools/assistant/lib/qhelpsearchindex_default_p.h
new file mode 100644
index 0000000000..b9ada2d725
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindex_default_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHINDEXDEFAULT_H
+#define QHELPSEARCHINDEXDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QString>
+#include <QtCore/QVector>
+#include <QtCore/QDataStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtHelpInternal {
+
+struct Document {
+ Document(qint16 d, qint16 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;
+};
+
+struct DocumentInfo : public Document {
+ DocumentInfo()
+ : Document(-1, 0), documentTitle(QString()), documentUrl(QString()) {}
+
+ DocumentInfo(qint16 d, qint16 f, const QString &title, const QString &url)
+ : Document(d, f), documentTitle(title), documentUrl(url) {}
+
+ DocumentInfo(const Document &document, const QString &title, const QString &url)
+ : Document(document.docNumber, document.frequency), documentTitle(title), documentUrl(url) {}
+
+ QString documentTitle;
+ QString documentUrl;
+};
+
+struct Entry {
+ Entry(qint16 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;
+};
+
+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; }
+};
+
+struct TermInfo {
+ TermInfo() : frequency(-1) {}
+ TermInfo(const QString &t, int f, QVector<DocumentInfo> l)
+ : term(t), frequency(f), documents(l) {}
+
+ bool operator<(const TermInfo &i2) const { return frequency < i2.frequency; }
+
+ QString term;
+ int frequency;
+ QVector<DocumentInfo>documents;
+};
+
+} // namespace QtHelpInternal
+
+using QtHelpInternal::Document;
+using QtHelpInternal::DocumentInfo;
+using QtHelpInternal::Entry;
+using QtHelpInternal::PosEntry;
+using QtHelpInternal::Term;
+using QtHelpInternal::TermInfo;
+
+QDataStream &operator>>(QDataStream &s, Document &l);
+QDataStream &operator<<(QDataStream &s, const Document &l);
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXDEFAULT_H
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
new file mode 100644
index 0000000000..82a3a17d3f
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** 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 "qhelpenginecore.h"
+#include "fulltextsearch/qsearchable_p.h"
+#include "fulltextsearch/qqueryparser_p.h"
+#include "fulltextsearch/qindexreader_p.h"
+#include "qhelpsearchindexreader_clucene_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace clucene {
+
+QHelpSearchIndexReader::QHelpSearchIndexReader()
+ : QThread()
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexReader::~QHelpSearchIndexReader()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexReader::cancelSearching()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexReader::search(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList)
+{
+ QMutexLocker lock(&mutex);
+
+ this->hitList.clear();
+ this->m_cancel = false;
+ this->m_query = queryList;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+
+ start(QThread::NormalPriority);
+}
+
+int QHelpSearchIndexReader::hitsCount() const
+{
+ return hitList.count();
+}
+
+QHelpSearchEngine::SearchHit QHelpSearchIndexReader::hit(int index) const
+{
+ return hitList.at(index);
+}
+
+void QHelpSearchIndexReader::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const QString collectionFile(this->m_collectionFile);
+ const QList<QHelpSearchQuery> &queryList = this->m_query;
+ const QString indexPath(m_indexFilesFolder);
+
+ mutex.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ QFileInfo fInfo(indexPath);
+ if (fInfo.exists() && !fInfo.isWritable()) {
+ qWarning("Full Text Search, could not read index (missing permissions).");
+ return;
+ }
+
+ if(QCLuceneIndexReader::indexExists(indexPath)) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+ mutex.unlock();
+
+ emit searchingStarted();
+
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ QCLuceneBooleanQuery booleanQuery;
+ if (!buildQuery(booleanQuery, queryList)) {
+ emit searchingFinished(0);
+ return;
+ }
+
+ const QStringList attribList = engine.filterAttributes(engine.currentFilter());
+ if (!attribList.isEmpty()) {
+ QCLuceneStandardAnalyzer analyzer;
+ QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+")
+ + attribList.join(QLatin1String(" +")), QLatin1String("attribute"),
+ analyzer);
+
+ if (!query) {
+ emit searchingFinished(0);
+ return;
+ }
+ booleanQuery.add(query, true, true, false);
+ }
+
+ QCLuceneIndexSearcher indexSearcher(indexPath);
+ QCLuceneHits hits = indexSearcher.search(booleanQuery);
+ const QStringList namespaceList = engine.registeredDocumentations();
+
+ QSet<QString> pathSet;
+ QCLuceneDocument document;
+ for (qint32 i = 0; i < hits.length(); i++) {
+ document = hits.document(i);
+ const QString path = document.get(QLatin1String("path"));
+ if (!pathSet.contains(path) && namespaceList.contains(
+ document.get(QLatin1String("namespace")), Qt::CaseInsensitive)) {
+ pathSet.insert(path);
+ hitList.append(qMakePair(path, document.get(QLatin1String("title"))));
+ }
+ document.clear();
+
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ emit searchingFinished(0);
+ return;
+ }
+ mutex.unlock();
+ }
+
+ indexSearcher.close();
+ int count = hitList.count();
+ if (count > 0)
+ boostSearchHits(engine, hitList, queryList);
+ emit searchingFinished(hitList.count());
+
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch(...) {
+ hitList.clear();
+ emit searchingFinished(0);
+ }
+#endif
+ }
+}
+
+bool QHelpSearchIndexReader::defaultQuery(const QString &term,
+ QCLuceneBooleanQuery &booleanQuery)
+{
+ QCLuceneStandardAnalyzer analyzer;
+
+ const QLatin1String c("content");
+ const QLatin1String t("titleTokenized");
+
+ QCLuceneQuery *query = QCLuceneQueryParser::parse(term, c, analyzer);
+ QCLuceneQuery *query2 = QCLuceneQueryParser::parse(term, t, analyzer);
+ if (query && query2) {
+ booleanQuery.add(query, true, false, false);
+ booleanQuery.add(query2, true, false, false);
+ return true;
+ }
+
+ return false;
+}
+
+bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery,
+ const QList<QHelpSearchQuery> &queryList)
+{
+ foreach (const QHelpSearchQuery query, queryList) {
+ switch (query.fieldName) {
+ case QHelpSearchQuery::FUZZY: {
+ const QLatin1String fuzzy("~");
+ foreach (const QString term, query.wordList) {
+ if (term.isEmpty() || !defaultQuery(term.toLower() + fuzzy, booleanQuery))
+ return false;
+ }
+ } break;
+
+ case QHelpSearchQuery::WITHOUT: {
+ QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+
+ QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm(
+ QLatin1String("content"), term.toLower()));
+ QCLuceneQuery *query2 = new QCLuceneTermQuery(QCLuceneTerm(
+ QLatin1String("titleTokenized"), term.toLower()));
+
+ if (query && query2) {
+ booleanQuery.add(query, true, false, true);
+ booleanQuery.add(query2, true, false, true);
+ } else {
+ return false;
+ }
+ }
+ } break;
+
+ case QHelpSearchQuery::PHRASE: {
+ const QString term = query.wordList.at(0).toLower();
+ if (term.contains(QLatin1Char(' '))) {
+ QStringList termList = term.split(QLatin1String(" "));
+ QCLucenePhraseQuery *q = new QCLucenePhraseQuery();
+ QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString t, termList) {
+ if (!stopWords.contains(t, Qt::CaseInsensitive))
+ q->addTerm(QCLuceneTerm(QLatin1String("content"), t.toLower()));
+ }
+ booleanQuery.add(q, true, true, false);
+ } else {
+ QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm(
+ QLatin1String("content"), term.toLower()));
+ QCLuceneQuery *query2 = new QCLuceneTermQuery(QCLuceneTerm(
+ QLatin1String("titleTokenized"), term.toLower()));
+
+ if (query && query2) {
+ booleanQuery.add(query, true, true, false);
+ booleanQuery.add(query2, true, false, false);
+ } else {
+ return false;
+ }
+ }
+ } break;
+
+ case QHelpSearchQuery::ALL: {
+ QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+
+ QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm(
+ QLatin1String("content"), term.toLower()));
+
+ if (query) {
+ booleanQuery.add(query, true, true, false);
+ } else {
+ return false;
+ }
+ }
+ } break;
+
+ case QHelpSearchQuery::DEFAULT: {
+ QCLuceneStandardAnalyzer analyzer;
+ foreach (const QString t, query.wordList) {
+ QCLuceneQuery *query = QCLuceneQueryParser::parse(t.toLower(),
+ QLatin1String("content"), analyzer);
+
+ if (query)
+ booleanQuery.add(query, true, true, false);
+ }
+ } break;
+
+ case QHelpSearchQuery::ATLEAST: {
+ foreach (const QString term, query.wordList) {
+ if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery))
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine,
+ QList<QHelpSearchEngine::SearchHit> &hitList,
+ const QList<QHelpSearchQuery> &queryList)
+{
+ foreach (const QHelpSearchQuery query, queryList) {
+ if (query.fieldName != QHelpSearchQuery::DEFAULT)
+ continue;
+
+ QString joinedQuery = query.wordList.join(QLatin1String(" "));
+
+ QCLuceneStandardAnalyzer analyzer;
+ QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse(
+ joinedQuery, QLatin1String("content"), analyzer);
+
+ if (parsedQuery) {
+ joinedQuery = parsedQuery->toString();
+ delete parsedQuery;
+ }
+
+ int length = QString(QLatin1String("content:")).length();
+ int index = joinedQuery.indexOf(QLatin1String("content:"));
+
+ QString term;
+ int nextIndex = 0;
+ QStringList searchTerms;
+ while (index != -1) {
+ nextIndex = joinedQuery.indexOf(QLatin1String("content:"), index + 1);
+ term = joinedQuery.mid(index + length, nextIndex - (length + index))
+ .simplified();
+ if (term.startsWith(QLatin1String("\""))
+ && term.endsWith(QLatin1String("\""))) {
+ searchTerms.append(term.remove(QLatin1String("\"")));
+ } else {
+ searchTerms += term.split(QLatin1Char(' '));
+ }
+ index = nextIndex;
+ }
+ searchTerms.removeDuplicates();
+
+ int count = qMin(75, hitList.count());
+ QMap<int, QHelpSearchEngine::SearchHit> hitMap;
+ for (int i = 0; i < count; ++i) {
+ const QHelpSearchEngine::SearchHit &hit = hitList.at(i);
+ QString data = QString::fromUtf8(engine.fileData(hit.first));
+
+ int counter = 0;
+ foreach (const QString& term, searchTerms)
+ counter += data.count(term, Qt::CaseInsensitive);
+ hitMap.insertMulti(counter, hit);
+ }
+
+ QList<QHelpSearchEngine::SearchHit> boostedList;
+ QMap<int, QHelpSearchEngine::SearchHit>::const_iterator i;
+ for (i = hitMap.constEnd(), --i; i != hitMap.constBegin(); --i)
+ boostedList.append(i.value());
+ boostedList += hitList.mid(count - 1, hitList.count());
+
+ hitList = boostedList;
+ }
+}
+
+ } // namespace clucene
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
new file mode 100644
index 0000000000..892c4e67fd
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHINDEXREADERCLUCENE_H
+#define QHELPSEARCHINDEXREADERCLUCENE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchengine.h"
+#include "fulltextsearch/qquery_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QWaitCondition>
+
+class QHelpEngineCore;
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace clucene {
+
+class QHelpSearchIndexReader : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexReader();
+ ~QHelpSearchIndexReader();
+
+ void cancelSearching();
+ void search(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList);
+
+ int hitsCount() const;
+ QHelpSearchEngine::SearchHit hit(int index) const;
+
+signals:
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ void run();
+ bool defaultQuery(const QString &term,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool buildQuery(QCLuceneBooleanQuery &booleanQuery,
+ const QList<QHelpSearchQuery> &queryList);
+ void boostSearchHits(const QHelpEngineCore &engine,
+ QList<QHelpSearchEngine::SearchHit> &hitList,
+ const QList<QHelpSearchQuery> &queryList);
+
+private:
+ QMutex mutex;
+ QList<QHelpSearchEngine::SearchHit> hitList;
+ QWaitCondition waitCondition;
+
+ bool m_cancel;
+ QString m_collectionFile;
+ QList<QHelpSearchQuery> m_query;
+ QString m_indexFilesFolder;
+};
+
+ } // namespace clucene
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXREADERCLUCENE_H
diff --git a/tools/assistant/lib/qhelpsearchindexreader_default.cpp b/tools/assistant/lib/qhelpsearchindexreader_default.cpp
new file mode 100644
index 0000000000..617d0d2d62
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexreader_default.cpp
@@ -0,0 +1,653 @@
+/****************************************************************************
+**
+** 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 "qhelpenginecore.h"
+#include "qhelpsearchindexreader_default_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QtCore/QVariant>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDataStream>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace std {
+
+namespace {
+ QStringList 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;
+ }
+}
+
+
+Reader::Reader()
+ : indexPath(QString())
+ , indexFile(QString())
+ , documentFile(QString())
+{
+ termList.clear();
+ indexTable.clear();
+ searchIndexTable.clear();
+}
+
+Reader::~Reader()
+{
+ reset();
+ searchIndexTable.clear();
+}
+
+bool Reader::readIndex()
+{
+ if (indexTable.contains(indexFile))
+ return true;
+
+ QFile idxFile(indexFile);
+ if (!idxFile.open(QFile::ReadOnly))
+ return false;
+
+ QString key;
+ int numOfDocs;
+ EntryTable entryTable;
+ QVector<Document> docs;
+ QDataStream dictStream(&idxFile);
+ while (!dictStream.atEnd()) {
+ dictStream >> key;
+ dictStream >> numOfDocs;
+ docs.resize(numOfDocs);
+ dictStream >> docs;
+ entryTable.insert(key, new Entry(docs));
+ }
+ idxFile.close();
+
+ if (entryTable.isEmpty())
+ return false;
+
+ QFile docFile(documentFile);
+ if (!docFile.open(QFile::ReadOnly))
+ return false;
+
+ QString title, url;
+ DocumentList documentList;
+ QDataStream docStream(&docFile);
+ while (!docStream.atEnd()) {
+ docStream >> title;
+ docStream >> url;
+ documentList.append(QStringList(title) << url);
+ }
+ docFile.close();
+
+ if (documentList.isEmpty()) {
+ cleanupIndex(entryTable);
+ return false;
+ }
+
+ indexTable.insert(indexFile, Index(entryTable, documentList));
+ return true;
+}
+
+bool Reader::initCheck() const
+{
+ return !searchIndexTable.isEmpty();
+}
+
+void Reader::setIndexPath(const QString &path)
+{
+ indexPath = path;
+}
+
+void Reader::filterFilesForAttributes(const QStringList &attributes)
+{
+ searchIndexTable.clear();
+ for(IndexTable::ConstIterator it = indexTable.begin(); it != indexTable.end(); ++it) {
+ const QString fileName = it.key();
+ bool containsAll = true;
+ QStringList split = fileName.split(QLatin1String("@"));
+ foreach (const QString attribute, attributes) {
+ if (!split.contains(attribute, Qt::CaseInsensitive)) {
+ containsAll = false;
+ break;
+ }
+ }
+
+ if (containsAll)
+ searchIndexTable.insert(fileName, it.value());
+ }
+}
+
+void Reader::setIndexFile(const QString &namespaceName, const QString &attributes)
+{
+ QString extention = namespaceName + QLatin1String("@") + attributes;
+ indexFile = indexPath + QLatin1String("/indexdb40.") + extention;
+ documentFile = indexPath + QLatin1String("/indexdoc40.") + extention;
+}
+
+bool Reader::splitSearchTerm(const QString &searchTerm, QStringList *terms,
+ QStringList *termSeq, QStringList *seqWords)
+{
+ QString term = searchTerm;
+
+ term = term.simplified();
+ term = term.replace(QLatin1String("\'"), QLatin1String("\""));
+ term = term.replace(QLatin1String("`"), QLatin1String("\""));
+ term = term.replace(QLatin1String("-"), QLatin1String(" "));
+ term = term.replace(QRegExp(QLatin1String("\\s[\\S]?\\s")), QLatin1String(" "));
+
+ *terms = term.split(QLatin1Char(' '));
+ QStringList::iterator it = terms->begin();
+ for (; it != terms->end(); ++it) {
+ (*it) = (*it).simplified();
+ (*it) = (*it).toLower();
+ (*it) = (*it).replace(QLatin1String("\""), QLatin1String(""));
+ }
+
+ if (term.contains(QLatin1Char('\"'))) {
+ if ((term.count(QLatin1Char('\"')))%2 == 0) {
+ int beg = 0;
+ int end = 0;
+ QString s;
+ beg = term.indexOf(QLatin1Char('\"'), beg);
+ while (beg != -1) {
+ beg++;
+ end = term.indexOf(QLatin1Char('\"'), beg);
+ s = term.mid(beg, end - beg);
+ s = s.toLower();
+ s = s.simplified();
+ if (s.contains(QLatin1Char('*'))) {
+ qWarning("Full Text Search, using a wildcard within phrases is not allowed.");
+ return false;
+ }
+ *seqWords += s.split(QLatin1Char(' '));
+ *termSeq << s;
+ beg = term.indexOf(QLatin1Char('\"'), end + 1);
+ }
+ } else {
+ qWarning("Full Text Search, the closing quotation mark is missing.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Reader::searchInIndex(const QStringList &terms)
+{
+ foreach (const QString term, terms) {
+ QVector<Document> documents;
+
+ for(IndexTable::ConstIterator it = searchIndexTable.begin();
+ it != searchIndexTable.end(); ++it) {
+ EntryTable entryTable = it.value().first;
+ DocumentList documentList = it.value().second;
+
+ if (term.contains(QLatin1Char('*')))
+ documents = setupDummyTerm(getWildcardTerms(term, entryTable), entryTable);
+ else if (entryTable.value(term))
+ documents = entryTable.value(term)->documents;
+ else
+ continue;
+
+ if (!documents.isEmpty()) {
+ DocumentInfo info;
+ QString title, url;
+ QVector<DocumentInfo> documentsInfo;
+ foreach(const Document doc, documents) {
+ info.docNumber = doc.docNumber;
+ info.frequency = doc.frequency;
+ info.documentUrl = documentList.at(doc.docNumber).at(1);
+ info.documentTitle = documentList.at(doc.docNumber).at(0);
+ documentsInfo.append(info);
+ }
+
+ bool found = false;
+ for(QList<TermInfo>::Iterator tit = termList.begin();
+ tit != termList.end(); ++tit) {
+ TermInfo *t = &(*tit);
+ if(t->term == term) {
+ t->documents += documentsInfo;
+ t->frequency += documentsInfo.count();
+ found = true; break;
+ }
+ }
+ if (!found)
+ termList.append(TermInfo(term, documentsInfo.count(), documentsInfo));
+ }
+ }
+ }
+ qSort(termList);
+}
+
+QVector<DocumentInfo> Reader::hits()
+{
+ QVector<DocumentInfo> documents;
+ if (!termList.count())
+ return documents;
+
+ documents = termList.takeFirst().documents;
+ for(QList<TermInfo>::Iterator it = termList.begin(); it != termList.end(); ++it) {
+ TermInfo *t = &(*it);
+ QVector<DocumentInfo> docs = t->documents;
+ for(QVector<DocumentInfo>::Iterator minDoc_it = documents.begin();
+ minDoc_it != documents.end(); ) {
+ bool found = false;
+ for (QVector<DocumentInfo>::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 = documents.erase(minDoc_it);
+ else
+ ++minDoc_it;
+ }
+ }
+
+ qSort(documents);
+ return documents;
+}
+
+bool Reader::searchForPattern(const QStringList &patterns, const QStringList &words,
+ const QByteArray &data)
+{
+ if (data.isEmpty())
+ return false;
+
+ for(QHash<QString, PosEntry*>::ConstIterator mit =
+ miniIndex.begin(); mit != miniIndex.end(); ++mit) {
+ delete mit.value();
+ }
+ miniIndex.clear();
+
+ wordNum = 3;
+ QStringList::ConstIterator cIt = words.begin();
+ for ( ; cIt != words.end(); ++cIt )
+ miniIndex.insert(*cIt, new PosEntry(0));
+
+ QTextStream s(data);
+ 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 )
+ buildMiniIndex( 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 )
+ buildMiniIndex( QString(str,i) );
+ i = 0;
+ }
+ c = buf[++j];
+ }
+ if ( i > 1 )
+ buildMiniIndex( QString(str,i) );
+
+ 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 = miniIndex[ wordLst[0] ]->positions;
+ for ( int j = 1; j < (int)wordLst.count(); ++j ) {
+ b = miniIndex[ 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;
+}
+
+QVector<Document> Reader::setupDummyTerm(const QStringList &terms,
+ const EntryTable &entryTable)
+{
+ QList<Term> termList;
+ for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) {
+ if (entryTable.value(*it)) {
+ Entry *e = entryTable.value(*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;
+}
+
+QStringList Reader::getWildcardTerms(const QString &term,
+ const EntryTable &entryTable)
+{
+ QStringList lst;
+ QStringList terms = split(term);
+ QStringList::Iterator iter;
+
+ for(EntryTable::ConstIterator it = entryTable.begin();
+ it != entryTable.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;
+}
+
+void Reader::buildMiniIndex(const QString &string)
+{
+ if (miniIndex[string])
+ miniIndex[string]->positions.append(wordNum);
+ ++wordNum;
+}
+
+void Reader::reset()
+{
+ for(IndexTable::Iterator it = indexTable.begin();
+ it != indexTable.end(); ++it) {
+ cleanupIndex(it.value().first);
+ it.value().second.clear();
+ }
+}
+
+void Reader::cleanupIndex(EntryTable &entryTable)
+{
+ for(EntryTable::ConstIterator it =
+ entryTable.begin(); it != entryTable.end(); ++it) {
+ delete it.value();
+ }
+
+ entryTable.clear();
+}
+
+
+QHelpSearchIndexReader::QHelpSearchIndexReader()
+ : QThread()
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexReader::~QHelpSearchIndexReader()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexReader::cancelSearching()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexReader::search(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList)
+{
+ QMutexLocker lock(&mutex);
+
+ this->hitList.clear();
+ this->m_cancel = false;
+ this->m_query = queryList;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+
+ start(QThread::NormalPriority);
+}
+
+int QHelpSearchIndexReader::hitsCount() const
+{
+ return hitList.count();
+}
+
+QHelpSearchEngine::SearchHit QHelpSearchIndexReader::hit(int index) const
+{
+ return hitList.at(index);
+}
+
+void QHelpSearchIndexReader::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const QList<QHelpSearchQuery> &queryList = this->m_query;
+ const QLatin1String key("DefaultSearchNamespaces");
+ const QString collectionFile(this->m_collectionFile);
+ const QString indexPath = m_indexFilesFolder;
+
+ mutex.unlock();
+
+ QString queryTerm;
+ foreach (const QHelpSearchQuery query, queryList) {
+ if (query.fieldName == QHelpSearchQuery::DEFAULT) {
+ queryTerm = query.wordList.at(0);
+ break;
+ }
+ }
+
+ if (queryTerm.isEmpty())
+ return;
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ const QStringList registeredDocs = engine.registeredDocumentations();
+ const QStringList indexedNamespaces = engine.customValue(key).toString().
+ split(QLatin1String("|"), QString::SkipEmptyParts);
+
+ emit searchingStarted();
+
+ // setup the reader
+ m_reader.setIndexPath(indexPath);
+ foreach(const QString namespaceName, registeredDocs) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this ???
+ return;
+ }
+ mutex.unlock();
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (QStringList attributes, attributeSets) {
+ // read all index files
+ m_reader.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ if (!m_reader.readIndex()) {
+ qWarning("Full Text Search, could not read file for namespace: %s.",
+ namespaceName.toUtf8().constData());
+ }
+ }
+ }
+
+ // get the current filter attributes and minimize the index files table
+ m_reader.filterFilesForAttributes(engine.filterAttributes(engine.currentFilter()));
+
+ hitList.clear();
+ QStringList terms, termSeq, seqWords;
+ if (m_reader.initCheck() && // check if we could read anything
+ m_reader.splitSearchTerm(queryTerm, &terms, &termSeq, &seqWords) ) {
+
+ // search for term(s)
+ m_reader.searchInIndex(terms); // TODO: should this be interruptible as well ???
+
+ QVector<DocumentInfo> hits = m_reader.hits();
+ if (!hits.isEmpty()) {
+ if (termSeq.isEmpty()) {
+ foreach (const DocumentInfo docInfo, hits) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this, speed issue while locking???
+ return;
+ }
+ mutex.unlock();
+ hitList.append(qMakePair(docInfo.documentTitle, docInfo.documentUrl));
+ }
+ } else {
+ foreach (const DocumentInfo docInfo, hits) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this, speed issue while locking???
+ return;
+ }
+ mutex.unlock();
+
+ if (m_reader.searchForPattern(termSeq, seqWords, engine.fileData(docInfo.documentUrl))) // TODO: should this be interruptible as well ???
+ hitList.append(qMakePair(docInfo.documentTitle, docInfo.documentUrl));
+ }
+ }
+ }
+ }
+
+ emit searchingFinished(hitList.count());
+}
+
+ } // namespace std
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchindexreader_default_p.h b/tools/assistant/lib/qhelpsearchindexreader_default_p.h
new file mode 100644
index 0000000000..22480f7956
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexreader_default_p.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 QHELPSEARCHINDEXREADERDEFAULT_H
+#define QHELPSEARCHINDEXREADERDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchindex_default_p.h"
+#include "qhelpsearchengine.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QPair>
+#include <QtCore/QList>
+#include <QtCore/QMutex>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QObject>
+#include <QtCore/QVector>
+#include <QtCore/QByteArray>
+#include <QtCore/QStringList>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+struct Entry;
+struct PosEntry;
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace std {
+
+class Reader
+{
+ typedef QList<QStringList> DocumentList;
+ typedef QHash<QString, Entry*> EntryTable;
+ typedef QPair<EntryTable, DocumentList> Index;
+ typedef QHash<QString, Index> IndexTable;
+
+public:
+ Reader();
+ ~Reader();
+
+ bool readIndex();
+ bool initCheck() const;
+ void setIndexPath(const QString &path);
+ void filterFilesForAttributes(const QStringList &attributes);
+ void setIndexFile(const QString &namespaceName, const QString &attributes);
+ bool splitSearchTerm(const QString &searchTerm, QStringList *terms,
+ QStringList *termSeq, QStringList *seqWords);
+
+ void searchInIndex(const QStringList &terms);
+ QVector<DocumentInfo> hits();
+ bool searchForPattern(const QStringList &patterns,
+ const QStringList &words, const QByteArray &data);
+
+private:
+ QVector<Document> setupDummyTerm(const QStringList &terms, const EntryTable &entryTable);
+ QStringList getWildcardTerms(const QString &term, const EntryTable &entryTable);
+ void buildMiniIndex(const QString &string);
+ void reset();
+ void cleanupIndex(EntryTable &entryTable);
+
+private:
+ uint wordNum;
+ QString indexPath;
+ QString indexFile;
+ QString documentFile;
+
+ IndexTable indexTable;
+ QList<TermInfo> termList;
+ IndexTable searchIndexTable;
+ QHash<QString, PosEntry*> miniIndex;
+};
+
+
+class QHelpSearchIndexReader : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexReader();
+ ~QHelpSearchIndexReader();
+
+ void cancelSearching();
+ void search(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList);
+
+ int hitsCount() const;
+ QHelpSearchEngine::SearchHit hit(int index) const;
+
+signals:
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ void run();
+
+private:
+ QMutex mutex;
+ Reader m_reader;
+ QWaitCondition waitCondition;
+ QList<QHelpSearchEngine::SearchHit> hitList;
+
+ bool m_cancel;
+ QList<QHelpSearchQuery> m_query;
+ QString m_collectionFile;
+ QString m_indexFilesFolder;
+};
+
+ } // namespace std
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXREADERDEFAULT_H
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
new file mode 100644
index 0000000000..e53bbaecdf
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** 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 "qhelpenginecore.h"
+#include "qhelp_global.h"
+#include "fulltextsearch/qhits_p.h"
+#include "fulltextsearch/qquery_p.h"
+#include "fulltextsearch/qanalyzer_p.h"
+#include "fulltextsearch/qdocument_p.h"
+#include "fulltextsearch/qsearchable_p.h"
+#include "fulltextsearch/qindexreader_p.h"
+#include "fulltextsearch/qindexwriter_p.h"
+#include "qhelpsearchindexwriter_clucene_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QString>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <QtNetwork/QLocalSocket>
+#include <QtNetwork/QLocalServer>
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace clucene {
+
+class DocumentHelper
+{
+public:
+ DocumentHelper(const QString& fileName, const QByteArray &data)
+ : fileName(fileName) , data(readData(data)) {}
+ ~DocumentHelper() {}
+
+ bool addFieldsToDocument(QCLuceneDocument *document,
+ const QString &namespaceName, const QString &attributes = QString())
+ {
+ if (!document)
+ return false;
+
+ if(!data.isEmpty()) {
+ QString parsedData = parseData();
+ QString parsedTitle = QHelpGlobal::documentTitle(data);
+
+ if(!parsedData.isEmpty()) {
+ document->add(new QCLuceneField(QLatin1String("content"),
+ parsedData,QCLuceneField::INDEX_TOKENIZED));
+ document->add(new QCLuceneField(QLatin1String("path"), fileName,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(QLatin1String("title"), parsedTitle,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(QLatin1String("titleTokenized"), parsedTitle,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
+ document->add(new QCLuceneField(QLatin1String("namespace"), namespaceName,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(QLatin1String("attribute"), attributes,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+private:
+ QString readData(const QByteArray &data)
+ {
+ QTextStream textStream(data);
+ QByteArray charSet = QHelpGlobal::charsetFromData(data).toLatin1();
+ textStream.setCodec(QTextCodec::codecForName(charSet.constData()));
+
+ QString stream = textStream.readAll();
+ if (stream.isNull() || stream.isEmpty())
+ return QString();
+
+ return stream;
+ }
+
+ QString parseData() const
+ {
+ const int length = data.length();
+ const QChar *buf = data.unicode();
+
+ QString parsedContent;
+ parsedContent.reserve(length);
+
+ bool valid = true;
+ int j = 0, count = 0;
+
+ QChar c;
+ while (j < length) {
+ c = buf[j++];
+ if (c == QLatin1Char('<') || c == QLatin1Char('&')) {
+ if (count > 1)
+ parsedContent.append(QLatin1Char(' '));
+ count = 0;
+ valid = false;
+ continue;
+ }
+ if ((c == QLatin1Char('>') || c == QLatin1Char(';')) && !valid) {
+ valid = true;
+ continue;
+ }
+ if (!valid)
+ continue;
+
+ if (c.isLetterOrNumber() || c.isPrint()) {
+ ++count;
+ parsedContent.append(c.toLower());
+ } else {
+ if (count > 1)
+ parsedContent.append(QLatin1Char(' '));
+ count = 0;
+ }
+ }
+
+ return parsedContent;
+ }
+
+private:
+ QString fileName;
+ QString data;
+};
+
+
+QHelpSearchIndexWriter::QHelpSearchIndexWriter()
+ : QThread(0)
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexWriter::~QHelpSearchIndexWriter()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexWriter::cancelIndexing()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex)
+{
+ mutex.lock();
+ this->m_cancel = false;
+ this->m_reindex = reindex;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+ mutex.unlock();
+
+ start(QThread::NormalPriority);
+}
+
+void QHelpSearchIndexWriter::optimizeIndex()
+{
+ if (QCLuceneIndexReader::indexExists(m_indexFilesFolder)) {
+ if (QCLuceneIndexReader::isLocked(m_indexFilesFolder))
+ return;
+
+ QCLuceneStandardAnalyzer analyzer;
+ QCLuceneIndexWriter writer(m_indexFilesFolder, analyzer, false);
+ writer.optimize();
+ writer.close();
+ }
+}
+
+void QHelpSearchIndexWriter::run()
+{
+ QMutexLocker mutexLocker(&mutex);
+
+ if (m_cancel)
+ return;
+
+ const bool reindex = this->m_reindex;
+ const QString collectionFile(this->m_collectionFile);
+
+ mutexLocker.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ const QLatin1String key("CluceneIndexedNamespaces");
+ if (reindex)
+ engine.setCustomValue(key, QLatin1String(""));
+
+ QMap<QString, QDateTime> indexMap;
+ const QLatin1String oldKey("CluceneSearchNamespaces");
+ if (!engine.customValue(oldKey, QString()).isNull()) {
+ // old style qhc file < 4.4.2, need to convert...
+ const QStringList indexedNamespaces = engine.customValue(oldKey).
+ toString().split(QLatin1String("|"), QString::SkipEmptyParts);
+ foreach (const QString& nameSpace, indexedNamespaces)
+ indexMap.insert(nameSpace, QDateTime());
+ engine.removeCustomValue(oldKey);
+ } else {
+ QDataStream dataStream(engine.customValue(key).toByteArray());
+ dataStream >> indexMap;
+ }
+
+ QString indexPath = m_indexFilesFolder;
+
+ QFileInfo fInfo(indexPath);
+ if (fInfo.exists() && !fInfo.isWritable()) {
+ qWarning("Full Text Search, could not create index (missing permissions).");
+ return;
+ }
+
+ emit indexingStarted();
+
+ QCLuceneIndexWriter *writer = 0;
+ QCLuceneStandardAnalyzer analyzer;
+ const QStringList registeredDocs = engine.registeredDocumentations();
+
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+
+ QLocalServer localServer;
+ bool otherInstancesRunning = true;
+ if (!localSocket.waitForConnected()) {
+ otherInstancesRunning = false;
+ localServer.listen(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+ }
+
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ // check if it's locked, and if the other instance is running
+ if (!otherInstancesRunning && QCLuceneIndexReader::isLocked(indexPath))
+ QCLuceneIndexReader::unlock(indexPath);
+
+ if (QCLuceneIndexReader::isLocked(indexPath)) {
+ // poll unless indexing finished to fake progress
+ while (QCLuceneIndexReader::isLocked(indexPath)) {
+ mutexLocker.relock();
+ if (m_cancel)
+ break;
+ mutexLocker.unlock();
+ this->sleep(1);
+ }
+ emit indexingFinished();
+ return;
+ }
+
+ if (QCLuceneIndexReader::indexExists(indexPath) && !reindex) {
+ foreach(const QString& namespaceName, registeredDocs) {
+ mutexLocker.relock();
+ if (m_cancel) {
+ emit indexingFinished();
+ return;
+ }
+ mutexLocker.unlock();
+
+ if (!indexMap.contains(namespaceName)) {
+ // make sure we remove some partly indexed stuff
+ removeDocuments(indexPath, namespaceName);
+ } else {
+ QString path = engine.documentationFileName(namespaceName);
+ if (indexMap.value(namespaceName) < QFileInfo(path).lastModified()) {
+ // make sure we remove some outdated indexed stuff
+ indexMap.remove(namespaceName);
+ removeDocuments(indexPath, namespaceName);
+ }
+
+ if (indexMap.contains(namespaceName)) {
+ // make sure we really have content indexed for namespace
+ // NOTE: Extra variable just for GCC 3.3.5
+ QLatin1String key("namespace");
+ QCLuceneTermQuery query(QCLuceneTerm(key, namespaceName));
+ QCLuceneIndexSearcher indexSearcher(indexPath);
+ QCLuceneHits hits = indexSearcher.search(query);
+ if (hits.length() <= 0)
+ indexMap.remove(namespaceName);
+ }
+ }
+ }
+ writer = new QCLuceneIndexWriter(indexPath, analyzer, false);
+ } else {
+ indexMap.clear();
+ writer = new QCLuceneIndexWriter(indexPath, analyzer, true);
+ }
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch (...) {
+ qWarning("Full Text Search, could not create index writer.");
+ return;
+ }
+#endif
+
+ writer->setMergeFactor(100);
+ writer->setMinMergeDocs(1000);
+ writer->setMaxFieldLength(QCLuceneIndexWriter::DEFAULT_MAX_FIELD_LENGTH);
+
+ QStringList namespaces;
+ foreach(const QString& namespaceName, registeredDocs) {
+ mutexLocker.relock();
+ if (m_cancel) {
+ writer->close();
+ delete writer;
+ emit indexingFinished();
+ return;
+ }
+ mutexLocker.unlock();
+
+ namespaces.append(namespaceName);
+ if (indexMap.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ if (attributeSets.isEmpty()) {
+ const QList<QUrl> docFiles = indexableFiles(&engine, namespaceName,
+ QStringList());
+ if (!addDocuments(docFiles, engine, QStringList(), namespaceName,
+ writer, analyzer))
+ break;
+ } else {
+ bool bail = false;
+ foreach (const QStringList& attributes, attributeSets) {
+ const QList<QUrl> docFiles = indexableFiles(&engine,
+ namespaceName, attributes);
+ if (!addDocuments(docFiles, engine, attributes, namespaceName,
+ writer, analyzer)) {
+ bail = true;
+ break;
+ }
+ }
+ if (bail)
+ break;
+ }
+
+ mutexLocker.relock();
+ if (!m_cancel) {
+ QString path(engine.documentationFileName(namespaceName));
+ indexMap.insert(namespaceName, QFileInfo(path).lastModified());
+ writeIndexMap(engine, indexMap);
+ }
+ mutexLocker.unlock();
+ }
+
+ writer->close();
+ delete writer;
+
+ mutexLocker.relock();
+ if (!m_cancel) {
+ mutexLocker.unlock();
+
+ QStringList indexedNamespaces = indexMap.keys();
+ foreach(const QString& namespaceName, indexedNamespaces) {
+ mutexLocker.relock();
+ if (m_cancel)
+ break;
+ mutexLocker.unlock();
+
+ if (!namespaces.contains(namespaceName)) {
+ indexMap.remove(namespaceName);
+ writeIndexMap(engine, indexMap);
+ removeDocuments(indexPath, namespaceName);
+ }
+ }
+ }
+ emit indexingFinished();
+}
+
+bool QHelpSearchIndexWriter::addDocuments(const QList<QUrl> docFiles,
+ const QHelpEngineCore &engine, const QStringList &attributes,
+ const QString &namespaceName, QCLuceneIndexWriter *writer,
+ QCLuceneAnalyzer &analyzer)
+{
+ QMutexLocker locker(&mutex);
+ const QString attrList = attributes.join(QLatin1String(" "));
+
+ locker.unlock();
+ foreach(const QUrl& url, docFiles) {
+ QCLuceneDocument document;
+ DocumentHelper helper(url.toString(), engine.fileData(url));
+ if (helper.addFieldsToDocument(&document, namespaceName, attrList))
+ writer->addDocument(document, analyzer);
+
+ locker.relock();
+ if (m_cancel)
+ return false;
+ locker.unlock();
+ }
+
+ return true;
+}
+
+void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath,
+ const QString &namespaceName)
+{
+ if (namespaceName.isEmpty() || QCLuceneIndexReader::isLocked(indexPath))
+ return;
+
+ QCLuceneIndexReader reader = QCLuceneIndexReader::open(indexPath);
+ reader.deleteDocuments(QCLuceneTerm(QLatin1String("namespace"),
+ namespaceName));
+
+ reader.close();
+}
+
+bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore& engine,
+ const QMap<QString, QDateTime>& indexMap)
+{
+ QByteArray bArray;
+
+ QDataStream data(&bArray, QIODevice::ReadWrite);
+ data << indexMap;
+
+ return engine.setCustomValue(QLatin1String("CluceneIndexedNamespaces"),
+ bArray);
+}
+
+QList<QUrl> QHelpSearchIndexWriter::indexableFiles(QHelpEngineCore *helpEngine,
+ const QString &namespaceName, const QStringList &attributes) const
+{
+ QList<QUrl> docFiles = helpEngine->files(namespaceName, attributes,
+ QLatin1String("html"));
+ docFiles += helpEngine->files(namespaceName, attributes, QLatin1String("htm"));
+ docFiles += helpEngine->files(namespaceName, attributes, QLatin1String("txt"));
+
+ return docFiles;
+}
+
+
+ } // namespace clucene
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h b/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h
new file mode 100644
index 0000000000..55c852b86f
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHINDEXWRITERCLUCENE_H
+#define QHELPSEARCHINDEXWRITERCLUCENE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpenginecore.h"
+#include "fulltextsearch/qanalyzer_p.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QDateTime>
+#include <QtCore/QStringList>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace clucene {
+
+class QHelpSearchIndexWriter : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexWriter();
+ ~QHelpSearchIndexWriter();
+
+ void cancelIndexing();
+ void updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex);
+ void optimizeIndex();
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+private:
+ void run();
+
+ bool addDocuments(const QList<QUrl> docFiles, const QHelpEngineCore &engine,
+ const QStringList &attributes, const QString &namespaceName,
+ QCLuceneIndexWriter *writer, QCLuceneAnalyzer &analyzer);
+ void removeDocuments(const QString &indexPath, const QString &namespaceName);
+
+ bool writeIndexMap(QHelpEngineCore& engine,
+ const QMap<QString, QDateTime>& indexMap);
+
+ QList<QUrl> indexableFiles(QHelpEngineCore *helpEngine,
+ const QString &namespaceName, const QStringList &attributes) const;
+
+private:
+ QMutex mutex;
+ QWaitCondition waitCondition;
+
+ bool m_cancel;
+ bool m_reindex;
+ QString m_collectionFile;
+ QString m_indexFilesFolder;
+};
+
+ } // namespace clucene
+ } // namespace fulltextsearch
+} // namespace clucene
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXWRITERCLUCENE_H
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp
new file mode 100644
index 0000000000..d55b984bcd
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** 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 "qhelpsearchindexwriter_default_p.h"
+#include "qhelp_global.h"
+#include "qhelpenginecore.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QSet>
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QtCore/QRegExp>
+#include <QtCore/QVariant>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace std {
+
+Writer::Writer(const QString &path)
+ : indexPath(path)
+ , indexFile(QString())
+ , documentFile(QString())
+{
+ // nothing todo
+}
+
+Writer::~Writer()
+{
+ reset();
+}
+
+void Writer::reset()
+{
+ for(QHash<QString, Entry*>::ConstIterator it =
+ index.begin(); it != index.end(); ++it) {
+ delete it.value();
+ }
+
+ index.clear();
+ documentList.clear();
+}
+
+bool Writer::writeIndex() const
+{
+ bool status;
+ QFile idxFile(indexFile);
+ if (!(status = idxFile.open(QFile::WriteOnly)))
+ return status;
+
+ QDataStream indexStream(&idxFile);
+ for(QHash<QString, Entry*>::ConstIterator it =
+ index.begin(); it != index.end(); ++it) {
+ indexStream << it.key();
+ indexStream << it.value()->documents.count();
+ indexStream << it.value()->documents;
+ }
+ idxFile.close();
+
+ QFile docFile(documentFile);
+ if (!(status = docFile.open(QFile::WriteOnly)))
+ return status;
+
+ QDataStream docStream(&docFile);
+ foreach(const QStringList list, documentList) {
+ docStream << list.at(0);
+ docStream << list.at(1);
+ }
+ docFile.close();
+
+ return status;
+}
+
+void Writer::removeIndex() const
+{
+ QFile idxFile(indexFile);
+ if (idxFile.exists())
+ idxFile.remove();
+
+ QFile docFile(documentFile);
+ if (docFile.exists())
+ docFile.remove();
+}
+
+void Writer::setIndexFile(const QString &namespaceName, const QString &attributes)
+{
+ QString extention = namespaceName + QLatin1String("@") + attributes;
+ indexFile = indexPath + QLatin1String("/indexdb40.") + extention;
+ documentFile = indexPath + QLatin1String("/indexdoc40.") + extention;
+}
+
+void Writer::insertInIndex(const QString &string, int docNum)
+{
+ if (string == QLatin1String("amp") || string == QLatin1String("nbsp"))
+ return;
+
+ Entry *entry = 0;
+ if (index.count())
+ entry = index[string];
+
+ if (entry) {
+ if (entry->documents.last().docNumber != docNum)
+ entry->documents.append(Document(docNum, 1));
+ else
+ entry->documents.last().frequency++;
+ } else {
+ index.insert(string, new Entry(docNum));
+ }
+}
+
+void Writer::insertInDocumentList(const QString &title, const QString &url)
+{
+ documentList.append(QStringList(title) << url);
+}
+
+
+QHelpSearchIndexWriter::QHelpSearchIndexWriter()
+ : QThread()
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexWriter::~QHelpSearchIndexWriter()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexWriter::cancelIndexing()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ bool reindex)
+{
+ QMutexLocker lock(&mutex);
+
+ this->m_cancel = false;
+ this->m_reindex = reindex;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+
+ start(QThread::NormalPriority);
+}
+
+void QHelpSearchIndexWriter::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const bool reindex(this->m_reindex);
+ const QLatin1String key("DefaultSearchNamespaces");
+ const QString collectionFile(this->m_collectionFile);
+ const QString indexPath = m_indexFilesFolder;
+
+ mutex.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ if (reindex)
+ engine.setCustomValue(key, QLatin1String(""));
+
+ const QStringList registeredDocs = engine.registeredDocumentations();
+ const QStringList indexedNamespaces = engine.customValue(key).toString().
+ split(QLatin1String("|"), QString::SkipEmptyParts);
+
+ emit indexingStarted();
+
+ QStringList namespaces;
+ Writer writer(indexPath);
+ foreach(const QString namespaceName, registeredDocs) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+ mutex.unlock();
+
+ // if indexed, continue
+ namespaces.append(namespaceName);
+ if (indexedNamespaces.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (QStringList attributes, attributeSets) {
+ // cleanup maybe old or unfinished files
+ writer.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ writer.removeIndex();
+
+ QSet<QString> documentsSet;
+ const QList<QUrl> docFiles = engine.files(namespaceName, attributes);
+ foreach(QUrl url, docFiles) {
+ if (m_cancel)
+ return;
+
+ // get rid of duplicated files
+ if (url.hasFragment())
+ url.setFragment(QString());
+
+ QString s = url.toString();
+ if (s.endsWith(QLatin1String(".html"))
+ || s.endsWith(QLatin1String(".htm"))
+ || s.endsWith(QLatin1String(".txt")))
+ documentsSet.insert(s);
+ }
+
+ int docNum = 0;
+ const QStringList documentsList(documentsSet.toList());
+ foreach(const QString url, documentsList) {
+ if (m_cancel)
+ return;
+
+ QByteArray data(engine.fileData(url));
+ if (data.isEmpty())
+ continue;
+
+ QTextStream s(data);
+ QString en = QHelpGlobal::charsetFromData(data);
+ s.setCodec(QTextCodec::codecForName(en.toLatin1().constData()));
+
+ QString text = s.readAll();
+ if (text.isNull())
+ continue;
+
+ QString title = QHelpGlobal::documentTitle(text);
+
+ int j = 0;
+ int i = 0;
+ bool valid = true;
+ const QChar *buf = text.unicode();
+ QChar str[64];
+ QChar c = buf[0];
+
+ while ( j < text.length() ) {
+ if (m_cancel)
+ return;
+
+ if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
+ valid = false;
+ if ( i > 1 )
+ writer.insertInIndex(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 )
+ writer.insertInIndex(QString(str,i), docNum);
+ i = 0;
+ }
+ c = buf[++j];
+ }
+ if ( i > 1 )
+ writer.insertInIndex(QString(str,i), docNum);
+
+ docNum++;
+ writer.insertInDocumentList(title, url);
+ }
+
+ if (writer.writeIndex()) {
+ engine.setCustomValue(key, addNamespace(
+ engine.customValue(key).toString(), namespaceName));
+ }
+
+ writer.reset();
+ }
+ }
+
+ QStringListIterator qsli(indexedNamespaces);
+ while (qsli.hasNext()) {
+ const QString namespaceName = qsli.next();
+ if (namespaces.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (QStringList attributes, attributeSets) {
+ writer.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ writer.removeIndex();
+ }
+
+ engine.setCustomValue(key, removeNamespace(
+ engine.customValue(key).toString(), namespaceName));
+ }
+
+ emit indexingFinished();
+}
+
+QString QHelpSearchIndexWriter::addNamespace(const QString namespaces,
+ const QString &namespaceName)
+{
+ QString value = namespaces;
+ if (!value.contains(namespaceName))
+ value.append(namespaceName).append(QLatin1String("|"));
+
+ return value;
+}
+
+QString QHelpSearchIndexWriter::removeNamespace(const QString namespaces,
+ const QString &namespaceName)
+{
+ QString value = namespaces;
+ if (value.contains(namespaceName))
+ value.remove(namespaceName + QLatin1String("|"));
+
+ return value;
+}
+
+ } // namespace std
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default_p.h b/tools/assistant/lib/qhelpsearchindexwriter_default_p.h
new file mode 100644
index 0000000000..015eb5a2d4
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchindexwriter_default_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHINDEXWRITERDEFAULT_H
+#define QHELPSEARCHINDEXWRITERDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchindex_default_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QStringList>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+namespace qt {
+ namespace fulltextsearch {
+ namespace std {
+
+class Writer
+{
+public:
+ Writer(const QString &path);
+ ~Writer();
+
+ void reset();
+ bool writeIndex() const;
+ void removeIndex() const;
+ void setIndexFile(const QString &namespaceName, const QString &attributes);
+ void insertInIndex(const QString &string, int docNum);
+ void insertInDocumentList(const QString &title, const QString &url);
+
+private:
+ QString indexPath;
+ QString indexFile;
+ QString documentFile;
+
+ QHash<QString, Entry*> index;
+ QList<QStringList> documentList;
+};
+
+
+class QHelpSearchIndexWriter : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexWriter();
+ ~QHelpSearchIndexWriter();
+
+ void cancelIndexing();
+ void updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex);
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+private:
+ void run();
+ QString addNamespace(const QString namespaces, const QString &namespaceName);
+ QString removeNamespace(const QString namespaces, const QString &namespaceName);
+
+private:
+ QMutex mutex;
+ QWaitCondition waitCondition;
+
+ bool m_cancel;
+ bool m_reindex;
+ QString m_collectionFile;
+ QString m_indexFilesFolder;
+};
+
+ } // namespace std
+ } // namespace fulltextsearch
+} // namespace qt
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXWRITERDEFAULT_H
diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp
new file mode 100644
index 0000000000..c018ffc64c
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** 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 "qhelpsearchquerywidget.h"
+
+#include <QtCore/QDebug>
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpSearchQueryWidgetPrivate : public QObject
+{
+ Q_OBJECT
+
+private:
+ QHelpSearchQueryWidgetPrivate()
+ : QObject()
+ {
+ searchButton = 0;
+ advancedSearchWidget = 0;
+ showHideAdvancedSearchButton = 0;
+ defaultQuery = 0;
+ exactQuery = 0;
+ similarQuery = 0;
+ withoutQuery = 0;
+ allQuery = 0;
+ atLeastQuery = 0;
+ }
+
+ ~QHelpSearchQueryWidgetPrivate()
+ {
+ // nothing todo
+ }
+
+ QString escapeString(const QString &text)
+ {
+ QString retValue = text;
+ const QString escape(QLatin1String("\\"));
+ QStringList escapableCharsList;
+ escapableCharsList << QLatin1String("\\") << QLatin1String("+")
+ << QLatin1String("-") << QLatin1String("!") << QLatin1String("(")
+ << QLatin1String(")") << QLatin1String(":") << QLatin1String("^")
+ << QLatin1String("[") << QLatin1String("]") << QLatin1String("{")
+ << QLatin1String("}") << QLatin1String("~");
+
+ // make sure we won't end up with an empty string
+ foreach (const QString escapeChar, escapableCharsList) {
+ if (retValue.contains(escapeChar))
+ retValue.replace(escapeChar, QLatin1String(""));
+ }
+ if (retValue.trimmed().isEmpty())
+ return retValue;
+
+ retValue = text; // now realy escape the string...
+ foreach (const QString escapeChar, escapableCharsList) {
+ if (retValue.contains(escapeChar))
+ retValue.replace(escapeChar, escape + escapeChar);
+ }
+ return retValue;
+ }
+
+ QStringList buildTermList(const QString query)
+ {
+ bool s = false;
+ QString phrase;
+ QStringList wordList;
+ QString searchTerm = query;
+
+ for (int i = 0; i < searchTerm.length(); ++i) {
+ if (searchTerm[i] == QLatin1Char('\"') && !s) {
+ s = true;
+ phrase = searchTerm[i];
+ continue;
+ }
+ if (searchTerm[i] != QLatin1Char('\"') && s)
+ phrase += searchTerm[i];
+ if (searchTerm[i] == QLatin1Char('\"') && s) {
+ s = false;
+ phrase += searchTerm[i];
+ wordList.append(phrase);
+ searchTerm.remove(phrase);
+ }
+ }
+ if (s)
+ searchTerm.replace(phrase, phrase.mid(1));
+
+ const QRegExp exp(QLatin1String("\\s+"));
+ wordList += searchTerm.split(exp, QString::SkipEmptyParts);
+ return wordList;
+ }
+
+private slots:
+ void showHideAdvancedSearch()
+ {
+ bool hidden = advancedSearchWidget->isHidden();
+ if (hidden) {
+ advancedSearchWidget->show();
+ showHideAdvancedSearchButton->setText((QLatin1String("-")));
+ } else {
+ advancedSearchWidget->hide();
+ showHideAdvancedSearchButton->setText((QLatin1String("+")));
+ }
+
+ defaultQuery->setEnabled(!hidden);
+ }
+
+private:
+ friend class QHelpSearchQueryWidget;
+
+ QPushButton *searchButton;
+ QWidget* advancedSearchWidget;
+ QToolButton *showHideAdvancedSearchButton;
+ QLineEdit *defaultQuery;
+ QLineEdit *exactQuery;
+ QLineEdit *similarQuery;
+ QLineEdit *withoutQuery;
+ QLineEdit *allQuery;
+ QLineEdit *atLeastQuery;
+};
+
+#include "qhelpsearchquerywidget.moc"
+
+
+/*!
+ \class QHelpSearchQueryWidget
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchQueryWidget class provides a simple line edit or
+ an advanced widget to enable the user to input a search term in a
+ standardized input mask.
+*/
+
+/*!
+ \fn void QHelpSearchQueryWidget::search()
+
+ This signal is emitted when a the user has the search button invoked.
+ After reciving the signal you can ask the QHelpSearchQueryWidget for the build list
+ of QHelpSearchQuery's that you may pass to the QHelpSearchEngine's search() function.
+*/
+
+/*!
+ Constructs a new search query widget with the given \a parent.
+*/
+QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ d = new QHelpSearchQueryWidgetPrivate();
+
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+
+ QHBoxLayout* hBoxLayout = new QHBoxLayout();
+ QLabel *label = new QLabel(tr("Search for:"), this);
+ d->defaultQuery = new QLineEdit(this);
+ d->searchButton = new QPushButton(tr("Search"), this);
+ hBoxLayout->addWidget(label);
+ hBoxLayout->addWidget(d->defaultQuery);
+ hBoxLayout->addWidget(d->searchButton);
+
+ vLayout->addLayout(hBoxLayout);
+
+ connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search()));
+ connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+
+#if defined(QT_CLUCENE_SUPPORT)
+ hBoxLayout = new QHBoxLayout();
+ d->showHideAdvancedSearchButton = new QToolButton(this);
+ d->showHideAdvancedSearchButton->setText(QLatin1String("+"));
+ d->showHideAdvancedSearchButton->setMinimumSize(25, 20);
+
+ label = new QLabel(tr("Advanced search"), this);
+ QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
+ label->setSizePolicy(sizePolicy);
+
+ QFrame* hLine = new QFrame(this);
+ hLine->setFrameStyle(QFrame::HLine);
+ hBoxLayout->addWidget(d->showHideAdvancedSearchButton);
+ hBoxLayout->addWidget(label);
+ hBoxLayout->addWidget(hLine);
+
+ vLayout->addLayout(hBoxLayout);
+
+ // setup advanced search layout
+ d->advancedSearchWidget = new QWidget(this);
+ QGridLayout *gLayout = new QGridLayout(d->advancedSearchWidget);
+ gLayout->setMargin(0);
+
+ label = new QLabel(tr("words <B>similar</B> to:"), this);
+ gLayout->addWidget(label, 0, 0);
+ d->similarQuery = new QLineEdit(this);
+ gLayout->addWidget(d->similarQuery, 0, 1);
+
+ label = new QLabel(tr("<B>without</B> the words:"), this);
+ gLayout->addWidget(label, 1, 0);
+ d->withoutQuery = new QLineEdit(this);
+ gLayout->addWidget(d->withoutQuery, 1, 1);
+
+ label = new QLabel(tr("with <B>exact phrase</B>:"), this);
+ gLayout->addWidget(label, 2, 0);
+ d->exactQuery = new QLineEdit(this);
+ gLayout->addWidget(d->exactQuery, 2, 1);
+
+ label = new QLabel(tr("with <B>all</B> of the words:"), this);
+ gLayout->addWidget(label, 3, 0);
+ d->allQuery = new QLineEdit(this);
+ gLayout->addWidget(d->allQuery, 3, 1);
+
+ label = new QLabel(tr("with <B>at least one</B> of the words:"), this);
+ gLayout->addWidget(label, 4, 0);
+ d->atLeastQuery = new QLineEdit(this);
+ gLayout->addWidget(d->atLeastQuery, 4, 1);
+
+ vLayout->addWidget(d->advancedSearchWidget);
+ d->advancedSearchWidget->hide();
+
+ connect(d->exactQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->similarQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->withoutQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->allQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->atLeastQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()),
+ d, SLOT(showHideAdvancedSearch()));
+#endif
+}
+
+/*!
+ Destroys the search query widget.
+*/
+QHelpSearchQueryWidget::~QHelpSearchQueryWidget()
+{
+ delete d;
+}
+
+/*!
+ Returns a list of querys to use in combination with the search engines
+ search(QList<QHelpSearchQuery> &query) function.
+*/
+QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
+{
+#if !defined(QT_CLUCENE_SUPPORT)
+ QList<QHelpSearchQuery> queryList;
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
+ QStringList(d->defaultQuery->text())));
+
+ return queryList;
+#else
+ QList<QHelpSearchQuery> queryList;
+ if (d->defaultQuery->isEnabled()) {
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
+ d->buildTermList(d->escapeString(d->defaultQuery->text()))));
+ } else {
+ const QRegExp exp(QLatin1String("\\s+"));
+ QStringList lst = d->similarQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList fuzzy;
+ foreach (const QString term, lst)
+ fuzzy += d->buildTermList(d->escapeString(term));
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy));
+ }
+
+ lst = d->withoutQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList without;
+ foreach (const QString term, lst)
+ without.append(d->escapeString(term));
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without));
+ }
+
+ if (!d->exactQuery->text().isEmpty()) {
+ QString phrase = d->exactQuery->text().remove(QLatin1Char('\"'));
+ phrase = d->escapeString(phrase.simplified());
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase)));
+ }
+
+ lst = d->allQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList all;
+ foreach (const QString term, lst)
+ all.append(d->escapeString(term));
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all));
+ }
+
+ lst = d->atLeastQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList atLeast;
+ foreach (const QString term, lst)
+ atLeast += d->buildTermList(d->escapeString(term));
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast));
+ }
+ }
+ return queryList;
+#endif
+}
+
+/*! \reimp
+*/
+void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
+{
+ if (focusEvent->reason() != Qt::MouseFocusReason) {
+ d->defaultQuery->selectAll();
+ d->defaultQuery->setFocus();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchquerywidget.h b/tools/assistant/lib/qhelpsearchquerywidget.h
new file mode 100644
index 0000000000..f4bcf3e7d7
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchquerywidget.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHQUERYWIDGET_H
+#define QHELPSEARCHQUERYWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+#include <QtHelp/qhelpsearchengine.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QFocusEvent;
+class QHelpSearchQueryWidgetPrivate;
+
+class QHELP_EXPORT QHelpSearchQueryWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchQueryWidget(QWidget *parent = 0);
+ ~QHelpSearchQueryWidget();
+
+ QList<QHelpSearchQuery> query() const;
+
+Q_SIGNALS:
+ void search();
+
+private:
+ void focusInEvent(QFocusEvent *focusEvent);
+
+private:
+ QHelpSearchQueryWidgetPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHQUERYWIDGET_H
diff --git a/tools/assistant/lib/qhelpsearchresultwidget.cpp b/tools/assistant/lib/qhelpsearchresultwidget.cpp
new file mode 100644
index 0000000000..e72cf97ba3
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchresultwidget.cpp
@@ -0,0 +1,439 @@
+/****************************************************************************
+**
+** 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 "qhelpsearchresultwidget.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QHeaderView>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QToolButton>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QTextBrowser>
+#include <QtGui/QTreeWidgetItem>
+
+QT_BEGIN_NAMESPACE
+
+class QDefaultResultWidget : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ QDefaultResultWidget(QWidget *parent = 0)
+ : QTreeWidget(parent)
+ {
+ header()->hide();
+ connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ this, SLOT(itemActivated(QTreeWidgetItem*, int)));
+ }
+
+ void showResultPage(const QList<QHelpSearchEngine::SearchHit> hits)
+ {
+ foreach (const QHelpSearchEngine::SearchHit hit, hits)
+ new QTreeWidgetItem(this, QStringList(hit.first) << hit.second);
+ }
+
+signals:
+ void requestShowLink(const QUrl &url);
+
+private slots:
+ void itemActivated(QTreeWidgetItem *item, int /* column */)
+ {
+ if (item) {
+ QString data = item->data(1, Qt::DisplayRole).toString();
+ emit requestShowLink(data);
+ }
+ }
+};
+
+
+class QCLuceneResultWidget : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ QCLuceneResultWidget(QWidget *parent = 0)
+ : QTextBrowser(parent)
+ {
+ connect(this, SIGNAL(anchorClicked(const QUrl&)),
+ this, SIGNAL(requestShowLink(const QUrl&)));
+ setContextMenuPolicy(Qt::NoContextMenu);
+ }
+
+ void showResultPage(const QList<QHelpSearchEngine::SearchHit> hits, bool isIndexing)
+ {
+ QString htmlFile = QString(QLatin1String("<html><head><title>%1</title></head><body>"))
+ .arg(tr("Search Results"));
+
+ int count = hits.count();
+ if (count != 0) {
+ if (isIndexing)
+ htmlFile += QString(QLatin1String("<div style=\"text-align:left; font-weight:bold; color:red\">"
+ "%1&nbsp;<span style=\"font-weight:normal; color:black\">"
+ "%2</span></div></div><br>")).arg(tr("Note:"))
+ .arg(tr("The search results may not be complete since the "
+ "documentation is still being indexed!"));
+
+ foreach (const QHelpSearchEngine::SearchHit hit, hits) {
+ htmlFile += QString(QLatin1String("<div style=\"text-align:left; font-weight:bold\""
+ "><a href=\"%1\">%2</a><div style=\"color:green; font-weight:normal;"
+ " margin:5px\">%1</div></div><p></p>"))
+ .arg(hit.first).arg(hit.second);
+ }
+ } else {
+ htmlFile += QLatin1String("<div align=\"center\"><br><br><h2>")
+ + tr("Your search did not match any documents.")
+ + QLatin1String("</h2><div>");
+ if (isIndexing)
+ htmlFile += QLatin1String("<div align=\"center\"><h3>")
+ + tr("(The reason for this might be that the documentation "
+ "is still being indexed.)")
+ + QLatin1String("</h3><div>");
+ }
+
+ htmlFile += QLatin1String("</body></html>");
+
+ setHtml(htmlFile);
+ }
+
+signals:
+ void requestShowLink(const QUrl &url);
+
+private slots:
+ void setSource(const QUrl & /* name */) {}
+};
+
+
+class QHelpSearchResultWidgetPrivate : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void setResults(int hitsCount)
+ {
+ if (!searchEngine.isNull()) {
+#if defined(QT_CLUCENE_SUPPORT)
+ showFirstResultPage();
+ updateNextButtonState(((hitsCount > 20) ? true : false));
+#else
+ resultTreeWidget->clear();
+ resultTreeWidget->showResultPage(searchEngine->hits(0, hitsCount));
+#endif
+ }
+ }
+
+ void showNextResultPage()
+ {
+ if (!searchEngine.isNull()
+ && resultLastToShow < searchEngine->hitsCount()) {
+ resultLastToShow += 20;
+ resultFirstToShow += 20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ if (resultLastToShow >= searchEngine->hitsCount())
+ updateNextButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showLastResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ resultLastToShow = searchEngine->hitsCount();
+ resultFirstToShow = resultLastToShow - (resultLastToShow % 20);
+
+ if (resultFirstToShow == resultLastToShow)
+ resultFirstToShow -= 20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ updateNextButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showFirstResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ resultLastToShow = 20;
+ resultFirstToShow = 0;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ updatePrevButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showPreviousResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ int count = resultLastToShow % 20;
+ if (count == 0 || resultLastToShow != searchEngine->hitsCount())
+ count = 20;
+
+ resultLastToShow -= count;
+ resultFirstToShow = resultLastToShow -20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ if (resultFirstToShow == 0)
+ updatePrevButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void updatePrevButtonState(bool state = true)
+ {
+ firstResultPage->setEnabled(state);
+ previousResultPage->setEnabled(state);
+ }
+
+ void updateNextButtonState(bool state = true)
+ {
+ nextResultPage->setEnabled(state);
+ lastResultPage->setEnabled(state);
+ }
+
+ void indexingStarted()
+ {
+ isIndexing = true;
+ }
+
+ void indexingFinished()
+ {
+ isIndexing = false;
+ }
+
+private:
+ QHelpSearchResultWidgetPrivate(QHelpSearchEngine *engine)
+ : QObject()
+ , searchEngine(engine)
+ , isIndexing(false)
+ {
+ resultTreeWidget = 0;
+ resultTextBrowser = 0;
+
+ resultLastToShow = 20;
+ resultFirstToShow = 0;
+
+ firstResultPage = 0;
+ previousResultPage = 0;
+ hitsLabel = 0;
+ nextResultPage = 0;
+ lastResultPage = 0;
+
+ connect(searchEngine, SIGNAL(indexingStarted()),
+ this, SLOT(indexingStarted()));
+ connect(searchEngine, SIGNAL(indexingFinished()),
+ this, SLOT(indexingFinished()));
+ }
+
+ ~QHelpSearchResultWidgetPrivate()
+ {
+ delete searchEngine;
+ }
+
+ QToolButton* setupToolButton(const QString &iconPath)
+ {
+ QToolButton *button = new QToolButton();
+ button->setEnabled(false);
+ button->setAutoRaise(true);
+ button->setIcon(QIcon(iconPath));
+ button->setIconSize(QSize(12, 12));
+ button->setMaximumSize(QSize(16, 16));
+
+ return button;
+ }
+
+ void updateHitRange()
+ {
+ int last = 0;
+ int first = 0;
+ int count = 0;
+
+ if (!searchEngine.isNull()) {
+ count = searchEngine->hitsCount();
+ if (count > 0) {
+ first = resultFirstToShow +1;
+ last = resultLastToShow > count ? count : resultLastToShow;
+ }
+ }
+ hitsLabel->setText(tr("%1 - %2 of %3 Hits").arg(first).arg(last).arg(count));
+ }
+
+private:
+ friend class QHelpSearchResultWidget;
+
+ QPointer<QHelpSearchEngine> searchEngine;
+
+ QDefaultResultWidget *resultTreeWidget;
+ QCLuceneResultWidget *resultTextBrowser;
+
+ int resultLastToShow;
+ int resultFirstToShow;
+ bool isIndexing;
+
+ QToolButton *firstResultPage;
+ QToolButton *previousResultPage;
+ QLabel *hitsLabel;
+ QToolButton *nextResultPage;
+ QToolButton *lastResultPage;
+};
+
+#include "qhelpsearchresultwidget.moc"
+
+
+/*!
+ \class QHelpSearchResultWidget
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchResultWidget class provides either a tree
+ widget or a text browser depending on the used search engine to display
+ the hits found by the search.
+*/
+
+/*!
+ \fn void QHelpSearchResultWidget::requestShowLink(const QUrl &link)
+
+ This signal is emitted when a item is activated and its associated
+ \a link should be shown.
+*/
+
+QHelpSearchResultWidget::QHelpSearchResultWidget(QHelpSearchEngine *engine)
+ : QWidget(0)
+ , d(new QHelpSearchResultWidgetPrivate(engine))
+{
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+ vLayout->setSpacing(0);
+
+#if defined(QT_CLUCENE_SUPPORT)
+ QHBoxLayout *hBoxLayout = new QHBoxLayout();
+#ifndef Q_OS_MAC
+ hBoxLayout->setMargin(0);
+ hBoxLayout->setSpacing(0);
+#endif
+ hBoxLayout->addWidget(d->firstResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/3leftarrow.png")));
+
+ hBoxLayout->addWidget(d->previousResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/1leftarrow.png")));
+
+ d->hitsLabel = new QLabel(tr("0 - 0 of 0 Hits"), this);
+ d->hitsLabel->setEnabled(false);
+ hBoxLayout->addWidget(d->hitsLabel);
+ d->hitsLabel->setAlignment(Qt::AlignCenter);
+ d->hitsLabel->setMinimumSize(QSize(150, d->hitsLabel->height()));
+
+ hBoxLayout->addWidget(d->nextResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/1rightarrow.png")));
+
+ hBoxLayout->addWidget(d->lastResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/3rightarrow.png")));
+
+ QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ hBoxLayout->addItem(spacer);
+
+ vLayout->addLayout(hBoxLayout);
+
+ d->resultTextBrowser = new QCLuceneResultWidget(this);
+ vLayout->addWidget(d->resultTextBrowser);
+
+ connect(d->resultTextBrowser, SIGNAL(requestShowLink(const QUrl&)), this,
+ SIGNAL(requestShowLink(const QUrl&)));
+
+ connect(d->nextResultPage, SIGNAL(clicked()), d, SLOT(showNextResultPage()));
+ connect(d->lastResultPage, SIGNAL(clicked()), d, SLOT(showLastResultPage()));
+ connect(d->firstResultPage, SIGNAL(clicked()), d, SLOT(showFirstResultPage()));
+ connect(d->previousResultPage, SIGNAL(clicked()), d, SLOT(showPreviousResultPage()));
+
+ connect(d->firstResultPage, SIGNAL(clicked()), d, SLOT(updateNextButtonState()));
+ connect(d->previousResultPage, SIGNAL(clicked()), d, SLOT(updateNextButtonState()));
+ connect(d->nextResultPage, SIGNAL(clicked()), d, SLOT(updatePrevButtonState()));
+ connect(d->lastResultPage, SIGNAL(clicked()), d, SLOT(updatePrevButtonState()));
+
+#else
+ d->resultTreeWidget = new QDefaultResultWidget(this);
+ vLayout->addWidget(d->resultTreeWidget);
+ connect(d->resultTreeWidget, SIGNAL(requestShowLink(const QUrl&)), this,
+ SIGNAL(requestShowLink(const QUrl&)));
+#endif
+
+ connect(engine, SIGNAL(searchingFinished(int)), d, SLOT(setResults(int)));
+}
+
+/*!
+ Destroys the search result widget.
+*/
+QHelpSearchResultWidget::~QHelpSearchResultWidget()
+{
+ delete d;
+}
+
+/*!
+ Returns a reference of the URL that the item at \a point owns, or an
+ empty URL if no item exists at that point.
+*/
+QUrl QHelpSearchResultWidget::linkAt(const QPoint &point)
+{
+ QUrl url;
+#if defined(QT_CLUCENE_SUPPORT)
+ if (d->resultTextBrowser)
+ url = d->resultTextBrowser->anchorAt(point);
+#else
+ if (d->resultTreeWidget) {
+ QTreeWidgetItem *item = d->resultTreeWidget->itemAt(point);
+ if (item)
+ url = item->data(1, Qt::DisplayRole).toString();
+ }
+#endif
+ return url;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpsearchresultwidget.h b/tools/assistant/lib/qhelpsearchresultwidget.h
new file mode 100644
index 0000000000..26bc1d97a5
--- /dev/null
+++ b/tools/assistant/lib/qhelpsearchresultwidget.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QHELPSEARCHRESULTWIDGET_H
+#define QHELPSEARCHRESULTWIDGET_H
+
+#include <QtHelp/qhelpsearchengine.h>
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QPoint>
+#include <QtCore/QObject>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpSearchResultWidgetPrivate;
+
+class QHELP_EXPORT QHelpSearchResultWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ~QHelpSearchResultWidget();
+ QUrl linkAt(const QPoint &point);
+
+Q_SIGNALS:
+ void requestShowLink(const QUrl &url);
+
+private:
+ friend class QHelpSearchEngine;
+
+ QHelpSearchResultWidgetPrivate *d;
+ QHelpSearchResultWidget(QHelpSearchEngine *engine);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHRESULTWIDGET_H
diff --git a/tools/assistant/tools/assistant/Info_mac.plist b/tools/assistant/tools/assistant/Info_mac.plist
new file mode 100644
index 0000000000..76369a1c51
--- /dev/null
+++ b/tools/assistant/tools/assistant/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</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+</dict>
+</plist>
diff --git a/tools/assistant/tools/assistant/aboutdialog.cpp b/tools/assistant/tools/assistant/aboutdialog.cpp
new file mode 100644
index 0000000000..629f249bf2
--- /dev/null
+++ b/tools/assistant/tools/assistant/aboutdialog.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** 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 <QtCore/QBuffer>
+
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QMessageBox>
+#include <QtGui/QDesktopServices>
+
+#include "aboutdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+AboutLabel::AboutLabel(QWidget *parent)
+ : QTextBrowser(parent)
+{
+ setFrameStyle(QFrame::NoFrame);
+ QPalette p;
+ p.setColor(QPalette::Base, p.color(QPalette::Background));
+ setPalette(p);
+}
+
+void AboutLabel::setText(const QString &text, const QByteArray &resources)
+{
+ QDataStream in(resources);
+ in >> m_resourceMap;
+
+ QTextBrowser::setText(text);
+}
+
+QSize AboutLabel::minimumSizeHint() const
+{
+ QTextDocument *doc = document();
+ doc->adjustSize();
+ return QSize(int(doc->size().width()), int(doc->size().height()));
+}
+
+QVariant AboutLabel::loadResource(int type, const QUrl &name)
+{
+ if (type == 2 || type == 3) {
+ if (m_resourceMap.contains(name.toString())) {
+ return m_resourceMap.value(name.toString());
+ }
+ }
+ return QVariant();
+}
+
+void AboutLabel::setSource(const QUrl &url)
+{
+ if (url.isValid()
+ && (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("ftp")
+ || url.scheme() == QLatin1String("mailto") || url.path().endsWith(QLatin1String("pdf")))) {
+ if (!QDesktopServices::openUrl(url)) {
+ QMessageBox::warning(this, tr("Warning"),
+ tr("Unable to launch external application.\n"),
+ tr("OK"));
+ }
+ }
+}
+
+AboutDialog::AboutDialog(QWidget *parent)
+ : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint|Qt::WindowTitleHint|Qt::WindowSystemMenuHint)
+{
+ m_pixmapLabel = 0;
+ m_aboutLabel = new AboutLabel();
+
+ m_closeButton = new QPushButton();
+ m_closeButton->setText(tr("&Close"));
+ connect(m_closeButton, SIGNAL(clicked()),
+ this, SLOT(close()));
+
+ m_layout = new QGridLayout(this);
+ m_layout->addWidget(m_aboutLabel, 1, 0, 1, -1);
+ m_layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1, 1, 1);
+ m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 0, 1, 1);
+ m_layout->addWidget(m_closeButton, 3, 1, 1, 1);
+ m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 2, 1, 1);
+}
+
+void AboutDialog::setText(const QString &text, const QByteArray &resources)
+{
+ m_aboutLabel->setText(text, resources);
+ updateSize();
+}
+
+void AboutDialog::setPixmap(const QPixmap &pixmap)
+{
+ if (!m_pixmapLabel) {
+ m_pixmapLabel = new QLabel();
+ m_layout->addWidget(m_pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter);
+ }
+ m_pixmapLabel->setPixmap(pixmap);
+ updateSize();
+}
+
+QString AboutDialog::documentTitle() const
+{
+ return m_aboutLabel->documentTitle();
+}
+
+void AboutDialog::updateSize()
+{
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
+ int limit = qMin(screenSize.width()/2, 500);
+
+#ifdef Q_WS_MAC
+ limit = qMin(screenSize.width()/2, 420);
+#endif
+
+ layout()->activate();
+ int width = layout()->totalMinimumSize().width();
+
+ if (width > limit)
+ width = limit;
+
+ QFontMetrics fm(qApp->font("QWorkspaceTitleBar"));
+ int windowTitleWidth = qMin(fm.width(windowTitle()) + 50, limit);
+ if (windowTitleWidth > width)
+ width = windowTitleWidth;
+
+ layout()->activate();
+ int height = (layout()->hasHeightForWidth())
+ ? layout()->totalHeightForWidth(width)
+ : layout()->totalMinimumSize().height();
+ setFixedSize(width, height);
+ QCoreApplication::removePostedEvents(this, QEvent::LayoutRequest);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/aboutdialog.h b/tools/assistant/tools/assistant/aboutdialog.h
new file mode 100644
index 0000000000..d62a220dce
--- /dev/null
+++ b/tools/assistant/tools/assistant/aboutdialog.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** 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 ABOUTDIALOG_H
+#define ABOUTDIALOG_H
+
+#include <QtGui/QTextBrowser>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QLabel;
+class QPushButton;
+class QGridLayout;
+
+class AboutLabel : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ AboutLabel(QWidget *parent = 0);
+ void setText(const QString &text, const QByteArray &resources);
+ QSize minimumSizeHint() const;
+
+private:
+ QVariant loadResource(int type, const QUrl &name);
+ void setSource(const QUrl &url);
+
+ QMap<QString, QByteArray> m_resourceMap;
+};
+
+class AboutDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ AboutDialog(QWidget *parent = 0);
+ void setText(const QString &text, const QByteArray &resources);
+ void setPixmap(const QPixmap &pixmap);
+ QString documentTitle() const;
+
+private:
+ void updateSize();
+
+ QLabel *m_pixmapLabel;
+ AboutLabel *m_aboutLabel;
+ QPushButton *m_closeButton;
+ QGridLayout *m_layout;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/assistant.icns b/tools/assistant/tools/assistant/assistant.icns
new file mode 100644
index 0000000000..6291dd3975
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.icns
Binary files differ
diff --git a/tools/assistant/tools/assistant/assistant.ico b/tools/assistant/tools/assistant/assistant.ico
new file mode 100644
index 0000000000..9e1b83f1b6
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.ico
Binary files differ
diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro
new file mode 100644
index 0000000000..1cbd1d32db
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.pro
@@ -0,0 +1,89 @@
+include($$QT_SOURCE_TREE/tools/shared/fontpanel/fontpanel.pri)
+
+TEMPLATE = app
+LANGUAGE = C++
+TARGET = assistant
+
+DEFINES += QT_CLUCENE_SUPPORT
+
+contains(QT_CONFIG, webkit) {
+ QT += webkit
+}
+
+CONFIG += qt warn_on help
+
+QT += network
+
+PROJECTNAME = Assistant
+DESTDIR = ../../../../bin
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+### Work around a qmake issue when statically linking to
+### not-yet-installed plugins
+LIBS += -L$$QT_BUILD_TREE/plugins/sqldrivers
+
+HEADERS += helpviewer.h \
+ mainwindow.h \
+ indexwindow.h \
+ topicchooser.h \
+ contentwindow.h \
+ searchwidget.h \
+ preferencesdialog.h \
+ filternamedialog.h \
+ centralwidget.h \
+ installdialog.h \
+ bookmarkmanager.h \
+ remotecontrol.h \
+ cmdlineparser.h \
+ aboutdialog.h \
+ qtdocinstaller.h
+
+win32 {
+ HEADERS += remotecontrol_win.h
+}
+
+SOURCES += helpviewer.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ indexwindow.cpp \
+ topicchooser.cpp \
+ contentwindow.cpp \
+ searchwidget.cpp \
+ preferencesdialog.cpp \
+ filternamedialog.cpp \
+ centralwidget.cpp \
+ installdialog.cpp \
+ bookmarkmanager.cpp \
+ remotecontrol.cpp \
+ cmdlineparser.cpp \
+ aboutdialog.cpp \
+ qtdocinstaller.cpp
+
+FORMS += topicchooser.ui \
+ preferencesdialog.ui \
+ filternamedialog.ui \
+ installdialog.ui \
+ bookmarkdialog.ui
+
+RESOURCES += assistant.qrc assistant_images.qrc
+
+win32 {
+ !wince*:LIBS += -lshell32
+ RC_FILE = assistant.rc
+}
+
+mac {
+ ICON = assistant.icns
+ TARGET = Assistant
+ QMAKE_INFO_PLIST = Info_mac.plist
+}
+
+contains(CONFIG, static): {
+ SQLPLUGINS = $$unique(sql-plugins)
+ contains(SQLPLUGINS, sqlite): {
+ QTPLUGIN += qsqlite
+ DEFINES += USE_STATIC_SQLITE_PLUGIN
+ }
+}
diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch
new file mode 100644
index 0000000000..550cd898fb
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.qch
Binary files differ
diff --git a/tools/assistant/tools/assistant/assistant.qrc b/tools/assistant/tools/assistant/assistant.qrc
new file mode 100644
index 0000000000..dddf1be759
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>assistant.qch</file>
+ </qresource>
+</RCC>
diff --git a/tools/assistant/tools/assistant/assistant.rc b/tools/assistant/tools/assistant/assistant.rc
new file mode 100644
index 0000000000..b4786ceaaf
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "assistant.ico"
diff --git a/tools/assistant/tools/assistant/assistant_images.qrc b/tools/assistant/tools/assistant/assistant_images.qrc
new file mode 100644
index 0000000000..58e03b54dd
--- /dev/null
+++ b/tools/assistant/tools/assistant/assistant_images.qrc
@@ -0,0 +1,36 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>images/trolltech-logo.png</file>
+ <file>images/assistant-128.png</file>
+ <file>images/assistant.png</file>
+ <file>images/wrap.png</file>
+#mac
+ <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/previous.png</file>
+ <file>images/mac/print.png</file>
+ <file>images/mac/synctoc.png</file>
+ <file>images/mac/zoomin.png</file>
+ <file>images/mac/zoomout.png</file>
+ <file>images/mac/resetzoom.png</file>
+#win
+ <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/zoomin.png</file>
+ <file>images/win/zoomout.png</file>
+ <file>images/win/resetzoom.png</file>
+ </qresource>
+</RCC>
diff --git a/tools/assistant/tools/assistant/bookmarkdialog.ui b/tools/assistant/tools/assistant/bookmarkdialog.ui
new file mode 100644
index 0000000000..7a878f9656
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkdialog.ui
@@ -0,0 +1,146 @@
+<ui version="4.0" >
+ <class>BookmarkDialog</class>
+ <widget class="QDialog" name="BookmarkDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>450</width>
+ <height>135</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Add Bookmark</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Bookmark:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Add in Folder:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QLineEdit" name="bookmarkEdit" />
+ </item>
+ <item>
+ <widget class="QComboBox" name="bookmarkFolders" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3" >
+ <item>
+ <widget class="QToolButton" name="toolButton" >
+ <property name="minimumSize" >
+ <size>
+ <width>25</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Ignored" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4" >
+ <item>
+ <widget class="QPushButton" name="newFolderButton" >
+ <property name="text" >
+ <string>New Folder</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>BookmarkDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>BookmarkDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp
new file mode 100644
index 0000000000..6f5732ff4b
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp
@@ -0,0 +1,874 @@
+/****************************************************************************
+**
+** 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 "bookmarkmanager.h"
+#include "centralwidget.h"
+
+#include <QtGui/QMenu>
+#include <QtGui/QIcon>
+#include <QtGui/QStyle>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtCore/QEvent>
+#include <QtGui/QComboBox>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMessageBox>
+#include <QtGui/QHeaderView>
+#include <QtGui/QToolButton>
+#include <QtGui/QPushButton>
+#include <QtGui/QApplication>
+#include <QtHelp/QHelpEngineCore>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QSortFilterProxyModel>
+
+QT_BEGIN_NAMESPACE
+
+BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title,
+ const QString &url, QWidget *parent)
+ : QDialog(parent)
+ , m_url(url)
+ , m_title(title)
+ , bookmarkManager(manager)
+{
+ installEventFilter(this);
+
+ ui.setupUi(this);
+ ui.bookmarkEdit->setText(title);
+ ui.newFolderButton->setVisible(false);
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+ ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+
+ proxyModel = new QSortFilterProxyModel(this);
+ proxyModel->setFilterKeyColumn(0);
+ proxyModel->setDynamicSortFilter(true);
+ proxyModel->setFilterRole(Qt::UserRole + 10);
+ proxyModel->setSourceModel(bookmarkManager->treeBookmarkModel());
+ proxyModel->setFilterRegExp(QRegExp(QLatin1String("Folder"),
+ Qt::CaseSensitive, QRegExp::FixedString));
+ ui.treeView->setModel(proxyModel);
+
+ ui.treeView->expandAll();
+ ui.treeView->setVisible(false);
+ ui.treeView->header()->setVisible(false);
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(addAccepted()));
+ connect(ui.newFolderButton, SIGNAL(clicked()), this, SLOT(addNewFolder()));
+ connect(ui.toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked()));
+ connect(ui.bookmarkEdit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(textChanged(const QString&)));
+
+ connect(bookmarkManager->treeBookmarkModel(), SIGNAL(itemChanged(QStandardItem*)),
+ this, SLOT(itemChanged(QStandardItem*)));
+
+ connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(const QString&)), this,
+ SLOT(selectBookmarkFolder(const QString&)));
+
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this,
+ SLOT(customContextMenuRequested(const QPoint&)));
+
+ connect(ui.treeView->selectionModel(),
+ SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
+ this, SLOT(currentChanged(const QModelIndex&, const QModelIndex&)));
+}
+
+BookmarkDialog::~BookmarkDialog()
+{
+}
+
+void BookmarkDialog::addAccepted()
+{
+ const QItemSelection selection = ui.treeView->selectionModel()->selection();
+ const QModelIndexList list = selection.indexes();
+
+ QModelIndex index;
+ if (!list.isEmpty())
+ index = proxyModel->mapToSource(list.at(0));
+
+ bookmarkManager->addNewBookmark(index, ui.bookmarkEdit->text(), m_url);
+ accept();
+}
+
+void BookmarkDialog::addNewFolder()
+{
+ const QItemSelection selection = ui.treeView->selectionModel()->selection();
+ const QModelIndexList list = selection.indexes();
+
+ QModelIndex index;
+ if (!list.isEmpty())
+ index = list.at(0);
+
+ QModelIndex newFolder =
+ bookmarkManager->addNewFolder(proxyModel->mapToSource(index));
+ if (newFolder.isValid()) {
+ ui.treeView->expand(index);
+ const QModelIndex &index = proxyModel->mapFromSource(newFolder);
+ ui.treeView->selectionModel()->setCurrentIndex(index,
+ QItemSelectionModel::ClearAndSelect);
+
+ ui.bookmarkFolders->clear();
+ ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+
+ const QString name = index.data().toString();
+ ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name));
+ }
+ ui.treeView->setFocus();
+}
+
+void BookmarkDialog::toolButtonClicked()
+{
+ bool visible = !ui.treeView->isVisible();
+ ui.treeView->setVisible(visible);
+ ui.newFolderButton->setVisible(visible);
+
+ if (visible) {
+ resize(QSize(width(), 400));
+ ui.toolButton->setText(QLatin1String("-"));
+ } else {
+ resize(width(), minimumHeight());
+ ui.toolButton->setText(QLatin1String("+"));
+ }
+}
+
+void BookmarkDialog::itemChanged(QStandardItem *item)
+{
+ if (renameItem != item) {
+ renameItem = item;
+ oldText = item->text();
+ return;
+ }
+
+ if (item->text() != oldText) {
+ ui.bookmarkFolders->clear();
+ ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+
+ QString name = tr("Bookmarks");
+ const QModelIndex& index = ui.treeView->currentIndex();
+ if (index.isValid())
+ name = index.data().toString();
+ ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name));
+ }
+}
+
+void BookmarkDialog::textChanged(const QString& string)
+{
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!string.isEmpty());
+}
+
+void BookmarkDialog::selectBookmarkFolder(const QString &folderName)
+{
+ if (folderName.isEmpty())
+ return;
+
+ if (folderName == tr("Bookmarks")) {
+ ui.treeView->clearSelection();
+ return;
+ }
+
+ QStandardItemModel *model = bookmarkManager->treeBookmarkModel();
+ QList<QStandardItem*> list = model->findItems(folderName,
+ Qt::MatchCaseSensitive | Qt::MatchRecursive, 0);
+ if (!list.isEmpty()) {
+ QModelIndex index = model->indexFromItem(list.at(0));
+ ui.treeView->selectionModel()->setCurrentIndex(
+ proxyModel->mapFromSource(index), QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+void BookmarkDialog::customContextMenuRequested(const QPoint &point)
+{
+ QModelIndex index = ui.treeView->indexAt(point);
+ if (!index.isValid())
+ return;
+
+ QMenu menu(QLatin1String(""), this);
+
+ QAction *removeItem = menu.addAction(tr("Delete Folder"));
+ QAction *renameItem = menu.addAction(tr("Rename Folder"));
+
+ QAction *picked_action = menu.exec(ui.treeView->mapToGlobal(point));
+ if (!picked_action)
+ return;
+
+ if (picked_action == removeItem) {
+ bookmarkManager->removeBookmarkItem(ui.treeView,
+ proxyModel->mapToSource(index));
+ ui.bookmarkFolders->clear();
+ ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+
+ QString name = tr("Bookmarks");
+ index = ui.treeView->currentIndex();
+ if (index.isValid())
+ name = index.data().toString();
+ ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name));
+ }
+ else if (picked_action == renameItem) {
+ QStandardItem *item = bookmarkManager->treeBookmarkModel()->
+ itemFromIndex(proxyModel->mapToSource(index));
+ if (item) {
+ item->setEditable(true);
+ ui.treeView->edit(index);
+ item->setEditable(false);
+ }
+ }
+}
+
+void BookmarkDialog::currentChanged(const QModelIndex& current,
+ const QModelIndex& previous)
+{
+ Q_UNUSED(previous)
+
+ if (!current.isValid()) {
+ ui.bookmarkFolders->setCurrentIndex(
+ ui.bookmarkFolders->findText(tr("Bookmarks")));
+ return;
+ }
+
+ ui.bookmarkFolders->setCurrentIndex(
+ ui.bookmarkFolders->findText(current.data().toString()));
+}
+
+bool BookmarkDialog::eventFilter(QObject *object, QEvent *e)
+{
+ if (object == this && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+
+ QModelIndex index = ui.treeView->currentIndex();
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ const QModelIndex& source = proxyModel->mapToSource(index);
+ QStandardItem *item =
+ bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
+ if (item) {
+ item->setEditable(true);
+ ui.treeView->edit(index);
+ item->setEditable(false);
+ }
+ } break;
+
+ case Qt::Key_Delete: {
+ bookmarkManager->removeBookmarkItem(ui.treeView,
+ proxyModel->mapToSource(index));
+ ui.bookmarkFolders->clear();
+ ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+
+ QString name = tr("Bookmarks");
+ index = ui.treeView->currentIndex();
+ if (index.isValid())
+ name = index.data().toString();
+ ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name));
+ } break;
+
+ default:
+ break;
+ }
+ }
+ return QObject::eventFilter(object, e);
+}
+
+
+
+
+BookmarkWidget::BookmarkWidget(BookmarkManager *manager, QWidget *parent,
+ bool showButtons)
+ : QWidget(parent)
+ , addButton(0)
+ , removeButton(0)
+ , bookmarkManager(manager)
+{
+ setup(showButtons);
+ installEventFilter(this);
+}
+
+BookmarkWidget::~BookmarkWidget()
+{
+}
+
+void BookmarkWidget::removeClicked()
+{
+ const QModelIndex& index = treeView->currentIndex();
+ if (searchField->text().isEmpty()) {
+ bookmarkManager->removeBookmarkItem(treeView,
+ filterBookmarkModel->mapToSource(index));
+ }
+}
+
+void BookmarkWidget::filterChanged()
+{
+ bool searchBookmarks = searchField->text().isEmpty();
+ if (!searchBookmarks) {
+ regExp.setPattern(searchField->text());
+ filterBookmarkModel->setSourceModel(bookmarkManager->listBookmarkModel());
+ } else {
+ regExp.setPattern(QLatin1String(""));
+ filterBookmarkModel->setSourceModel(bookmarkManager->treeBookmarkModel());
+ }
+
+ if (addButton)
+ addButton->setEnabled(searchBookmarks);
+
+ if (removeButton)
+ removeButton->setEnabled(searchBookmarks);
+
+ filterBookmarkModel->setFilterRegExp(regExp);
+
+ QModelIndex index = treeView->indexAt(QPoint(1, 1));
+ if (index.isValid())
+ treeView->setCurrentIndex(index);
+
+ if (searchBookmarks)
+ expandItems();
+}
+
+void BookmarkWidget::expand(const QModelIndex& index)
+{
+ const QModelIndex& source = filterBookmarkModel->mapToSource(index);
+ QStandardItem *item = bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
+ if (item)
+ item->setData(treeView->isExpanded(index), Qt::UserRole + 11);
+}
+
+void BookmarkWidget::activated(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+
+ QString data = index.data(Qt::UserRole + 10).toString();
+ if (data != QLatin1String("Folder"))
+ emit requestShowLink(data);
+}
+
+void BookmarkWidget::customContextMenuRequested(const QPoint &point)
+{
+ QModelIndex index = treeView->indexAt(point);
+ if (!index.isValid())
+ return;
+
+ QAction *showItem = 0;
+ QAction *removeItem = 0;
+ QAction *renameItem = 0;
+ QAction *showItemNewTab = 0;
+
+ QMenu menu(QLatin1String(""), this);
+ QString data = index.data(Qt::UserRole + 10).toString();
+ if (data == QLatin1String("Folder")) {
+ removeItem = menu.addAction(tr("Delete Folder"));
+ renameItem = menu.addAction(tr("Rename Folder"));
+ } else {
+ showItem = menu.addAction(tr("Show Bookmark"));
+ showItemNewTab = menu.addAction(tr("Show Bookmark in New Tab"));
+ if (searchField->text().isEmpty()) {
+ menu.addSeparator();
+ removeItem = menu.addAction(tr("Delete Bookmark"));
+ renameItem = menu.addAction(tr("Rename Bookmark"));
+ }
+ }
+
+ QAction *picked_action = menu.exec(treeView->mapToGlobal(point));
+ if (!picked_action)
+ return;
+
+ if (picked_action == showItem) {
+ emit requestShowLink(data);
+ }
+ else if (picked_action == showItemNewTab) {
+ CentralWidget::instance()->setSourceInNewTab(data);
+ }
+ else if (picked_action == removeItem) {
+ bookmarkManager->removeBookmarkItem(treeView,
+ filterBookmarkModel->mapToSource(index));
+ }
+ else if (picked_action == renameItem) {
+ const QModelIndex& source = filterBookmarkModel->mapToSource(index);
+ QStandardItem *item =
+ bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
+ if (item) {
+ item->setEditable(true);
+ treeView->edit(index);
+ item->setEditable(false);
+ }
+ }
+}
+
+void BookmarkWidget::setup(bool showButtons)
+{
+ regExp.setPatternSyntax(QRegExp::FixedString);
+ regExp.setCaseSensitivity(Qt::CaseInsensitive);
+
+ QLayout *vlayout = new QVBoxLayout(this);
+ vlayout->setMargin(4);
+
+ QLabel *label = new QLabel(tr("Filter:"), this);
+ vlayout->addWidget(label);
+
+ searchField = new QLineEdit(this);
+ vlayout->addWidget(searchField);
+ connect(searchField, SIGNAL(textChanged(const QString &)), this,
+ SLOT(filterChanged()));
+
+ treeView = new TreeView(this);
+ vlayout->addWidget(treeView);
+
+ QString system = QLatin1String("win");
+#ifdef Q_OS_MAC
+ system = QLatin1String("mac");
+#endif
+
+ if (showButtons) {
+ QLayout *hlayout = new QHBoxLayout();
+ vlayout->addItem(hlayout);
+
+ hlayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding));
+
+ addButton = new QToolButton(this);
+ addButton->setText(tr("Add"));
+ addButton->setIcon(QIcon(QString::fromUtf8(
+ ":/trolltech/assistant/images/%1/addtab.png").arg(system)));
+ addButton->setAutoRaise(true);
+ addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ hlayout->addWidget(addButton);
+ connect(addButton, SIGNAL(clicked()), this, SIGNAL(addBookmark()));
+
+ removeButton = new QToolButton(this);
+ removeButton->setText(tr("Remove"));
+ removeButton->setIcon(QIcon(QString::fromUtf8(
+ ":/trolltech/assistant/images/%1/closetab.png").arg(system)));
+ removeButton->setAutoRaise(true);
+ removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ hlayout->addWidget(removeButton);
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
+ }
+
+ filterBookmarkModel = new QSortFilterProxyModel(this);
+ treeView->setModel(filterBookmarkModel);
+
+ treeView->setDragEnabled(true);
+ treeView->setAcceptDrops(true);
+ treeView->setAutoExpandDelay(1000);
+ treeView->setDropIndicatorShown(true);
+ treeView->header()->setVisible(false);
+ treeView->viewport()->installEventFilter(this);
+ treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(treeView, SIGNAL(expanded(const QModelIndex&)), this,
+ SLOT(expand(const QModelIndex&)));
+
+ connect(treeView, SIGNAL(collapsed(const QModelIndex&)), this,
+ SLOT(expand(const QModelIndex&)));
+
+ connect(treeView, SIGNAL(activated(const QModelIndex&)), this,
+ SLOT(activated(const QModelIndex&)));
+
+ connect(treeView, SIGNAL(customContextMenuRequested(const QPoint&)),
+ this, SLOT(customContextMenuRequested(const QPoint&)));
+
+ filterBookmarkModel->setFilterKeyColumn(0);
+ filterBookmarkModel->setDynamicSortFilter(true);
+ filterBookmarkModel->setSourceModel(bookmarkManager->treeBookmarkModel());
+
+ expandItems();
+}
+
+void BookmarkWidget::expandItems()
+{
+ QStandardItemModel *model = bookmarkManager->treeBookmarkModel();
+ QList<QStandardItem*>list = model->findItems(QLatin1String("*"),
+ Qt::MatchWildcard | Qt::MatchRecursive, 0);
+ foreach (const QStandardItem* item, list) {
+ const QModelIndex& index = model->indexFromItem(item);
+ treeView->setExpanded(filterBookmarkModel->mapFromSource(index),
+ item->data(Qt::UserRole + 11).toBool());
+ }
+}
+
+void BookmarkWidget::focusInEvent(QFocusEvent *e)
+{
+ if (e->reason() != Qt::MouseFocusReason) {
+ searchField->selectAll();
+ searchField->setFocus();
+
+ QModelIndex index = treeView->indexAt(QPoint(1, 1));
+ if (index.isValid())
+ treeView->setCurrentIndex(index);
+
+ }
+}
+
+bool BookmarkWidget::eventFilter(QObject *object, QEvent *e)
+{
+ if (object == this && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ QModelIndex index = treeView->currentIndex();
+ switch (ke->key()) {
+ if (index.isValid() && searchField->text().isEmpty()) {
+ case Qt::Key_F2: {
+ const QModelIndex& source = filterBookmarkModel->mapToSource(index);
+ QStandardItem *item =
+ bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
+ if (item) {
+ item->setEditable(true);
+ treeView->edit(index);
+ item->setEditable(false);
+ }
+ } break;
+
+ case Qt::Key_Delete: {
+ bookmarkManager->removeBookmarkItem(treeView,
+ filterBookmarkModel->mapToSource(index));
+ } break;
+ }
+
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ treeView->subclassKeyPressEvent(ke);
+ break;
+
+ case Qt::Key_Enter: {
+ case Qt::Key_Return:
+ index = treeView->selectionModel()->currentIndex();
+ if (index.isValid()) {
+ QString data = index.data(Qt::UserRole + 10).toString();
+ if (!data.isEmpty() && data != QLatin1String("Folder"))
+ emit requestShowLink(data);
+ }
+ } break;
+
+ case Qt::Key_Escape:
+ emit escapePressed();
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (object == treeView->viewport() && e->type() == QEvent::MouseButtonRelease) {
+ const QModelIndex& index = treeView->currentIndex();
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (index.isValid() && (me->button() == Qt::MidButton)) {
+ QString data = index.data(Qt::UserRole + 10).toString();
+ if (!data.isEmpty() && data != QLatin1String("Folder"))
+ CentralWidget::instance()->setSourceInNewTab(data);
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+
+
+
+BookmarkModel::BookmarkModel(int rows, int columns, QObject * parent)
+ : QStandardItemModel(rows, columns, parent)
+{
+}
+
+BookmarkModel::~BookmarkModel()
+{
+}
+
+Qt::DropActions BookmarkModel::supportedDropActions() const
+{
+ return Qt::MoveAction;
+}
+
+Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const
+{
+ Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
+ if (index.data(Qt::UserRole + 10).toString() == QLatin1String("Folder"))
+ return (Qt::ItemIsDropEnabled | defaultFlags) &~ Qt::ItemIsDragEnabled;
+
+ return (Qt::ItemIsDragEnabled | defaultFlags) &~ Qt::ItemIsDropEnabled;
+}
+
+
+
+
+BookmarkManager::BookmarkManager(QHelpEngineCore* _helpEngine)
+ : treeModel(new BookmarkModel(0, 1, this))
+ , listModel(new BookmarkModel(0, 1, this))
+ , helpEngine(_helpEngine)
+{
+ folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
+ treeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Bookmark"));
+ listModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Bookmark"));
+
+ connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this,
+ SLOT(itemChanged(QStandardItem*)));
+}
+
+BookmarkManager::~BookmarkManager()
+{
+ treeModel->clear();
+ listModel->clear();
+}
+
+BookmarkModel* BookmarkManager::treeBookmarkModel()
+{
+ return treeModel;
+}
+
+BookmarkModel* BookmarkManager::listBookmarkModel()
+{
+ return listModel;
+}
+
+void BookmarkManager::saveBookmarks()
+{
+ qint32 depth = 0;
+ QByteArray bookmarks;
+ QDataStream stream(&bookmarks, QIODevice::WriteOnly);
+ QStandardItem *root = treeModel->invisibleRootItem();
+
+ for (int i = 0; i < root->rowCount(); ++i) {
+ const QStandardItem *item = root->child(i);
+ stream << depth; // root
+ stream << item->data(Qt::DisplayRole).toString();
+ stream << item->data(Qt::UserRole + 10).toString();
+ stream << item->data(Qt::UserRole + 11).toBool();
+
+ if (item->rowCount() > 0) {
+ readBookmarksRecursive(item, stream, (depth +1));
+ }
+ }
+ helpEngine->setCustomValue(QLatin1String("Bookmarks"), bookmarks);
+}
+
+QStringList BookmarkManager::bookmarkFolders() const
+{
+ QStringList folders(tr("Bookmarks"));
+
+ QList<QStandardItem*>list = treeModel->findItems(QLatin1String("*"),
+ Qt::MatchWildcard | Qt::MatchRecursive, 0);
+
+ QString data;
+ foreach (const QStandardItem *item, list) {
+ data = item->data(Qt::UserRole + 10).toString();
+ if (data == QLatin1String("Folder"))
+ folders << item->data(Qt::DisplayRole).toString();
+ }
+ return folders;
+}
+
+QModelIndex BookmarkManager::addNewFolder(const QModelIndex& index)
+{
+ QStandardItem *item = new QStandardItem(uniqueFolderName());
+ item->setEditable(false);
+ item->setData(false, Qt::UserRole + 11);
+ item->setData(QLatin1String("Folder"), Qt::UserRole + 10);
+ item->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon));
+
+ if (index.isValid()) {
+ treeModel->itemFromIndex(index)->appendRow(item);
+ } else {
+ treeModel->appendRow(item);
+ }
+ return treeModel->indexFromItem(item);
+}
+
+void BookmarkManager::removeBookmarkItem(QTreeView *treeView, const QModelIndex& index)
+{
+ QStandardItem *item = treeModel->itemFromIndex(index);
+ if (item) {
+ QString data = index.data(Qt::UserRole + 10).toString();
+ if (data == QLatin1String("Folder") && item->rowCount() > 0) {
+ int value = QMessageBox::question(treeView, tr("Remove"),
+ tr("You are going to delete a Folder, this will also<br>"
+ "remove it's content. Are you sure to continue?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
+
+ if (value == QMessageBox::Cancel)
+ return;
+ }
+
+ if (data != QLatin1String("Folder")) {
+ QList<QStandardItem*>itemList = listModel->findItems(item->text());
+ foreach (const QStandardItem *i, itemList) {
+ if (i->data(Qt::UserRole + 10) == data) {
+ listModel->removeRow(i->row());
+ break;
+ }
+ }
+ } else {
+ removeBookmarkFolderItems(item);
+ }
+ treeModel->removeRow(item->row(), index.parent());
+ }
+}
+
+void BookmarkManager::showBookmarkDialog(QWidget* parent, const QString &name,
+ const QString &url)
+{
+ BookmarkDialog dialog(this, name, url, parent);
+ dialog.exec();
+}
+
+void BookmarkManager::addNewBookmark(const QModelIndex& index,
+ const QString &name, const QString &url)
+{
+ QStandardItem *item = new QStandardItem(name);
+ item->setEditable(false);
+ item->setData(false, Qt::UserRole + 11);
+ item->setData(url, Qt::UserRole + 10);
+
+ if (index.isValid()) {
+ treeModel->itemFromIndex(index)->appendRow(item);
+ listModel->appendRow(item->clone());
+ } else {
+ treeModel->appendRow(item);
+ listModel->appendRow(item->clone());
+ }
+}
+
+void BookmarkManager::itemChanged(QStandardItem *item)
+{
+ if (renameItem != item) {
+ renameItem = item;
+ oldText = item->text();
+ return;
+ }
+
+ if (item->text() != oldText) {
+ if (item->data(Qt::UserRole + 10).toString() != QLatin1String("Folder")) {
+ QList<QStandardItem*>itemList = listModel->findItems(oldText);
+ if (itemList.count() > 0)
+ itemList.at(0)->setText(item->text());
+ }
+ }
+}
+
+void BookmarkManager::setupBookmarkModels()
+{
+ treeModel->clear();
+ listModel->clear();
+
+ qint32 depth;
+ bool expanded;
+ QString name, type;
+ QList<int> lastDepths;
+ QList<QStandardItem*> parents;
+
+ QByteArray ba = helpEngine->customValue(QLatin1String("Bookmarks")).toByteArray();
+ QDataStream stream(ba);
+ while (!stream.atEnd()) {
+ stream >> depth >> name >> type >> expanded;
+
+ QStandardItem *item = new QStandardItem(name);
+ item->setEditable(false);
+ item->setData(type, Qt::UserRole + 10);
+ item->setData(expanded, Qt::UserRole + 11);
+ if (depth == 0) {
+ parents.clear(); lastDepths.clear();
+ treeModel->appendRow(item);
+ parents << item; lastDepths << depth;
+ } else {
+ if (depth <= lastDepths.last()) {
+ while (depth <= lastDepths.last() && parents.count() > 0) {
+ parents.pop_back(); lastDepths.pop_back();
+ }
+ }
+ parents.last()->appendRow(item);
+ if (type == QLatin1String("Folder")) {
+ parents << item; lastDepths << depth;
+ }
+ }
+
+ if (type == QLatin1String("Folder"))
+ item->setIcon(folderIcon);
+ else
+ listModel->appendRow(item->clone());
+ }
+}
+
+QString BookmarkManager::uniqueFolderName() const
+{
+ QString folderName = tr("New Folder");
+ QList<QStandardItem*> list = treeModel->findItems(folderName,
+ Qt::MatchContains | Qt::MatchRecursive, 0);
+ if (!list.isEmpty()) {
+ QStringList names;
+ foreach (const QStandardItem *item, list)
+ names << item->text();
+
+ for (int i = 1; i <= names.count(); ++i) {
+ folderName = (tr("New Folder") + QLatin1String(" %1")).arg(i);
+ if (!names.contains(folderName))
+ break;
+ }
+ }
+ return folderName;
+}
+
+void BookmarkManager::removeBookmarkFolderItems(QStandardItem *item)
+{
+ for (int j = 0; j < item->rowCount(); ++j) {
+ QStandardItem *child = item->child(j);
+ if (child->rowCount() > 0)
+ removeBookmarkFolderItems(child);
+
+ QString data = child->data(Qt::UserRole + 10).toString();
+ QList<QStandardItem*>itemList = listModel->findItems(child->text());
+ foreach (const QStandardItem *i, itemList) {
+ if (i->data(Qt::UserRole + 10) == data) {
+ listModel->removeRow(i->row());
+ break;
+ }
+ }
+ }
+}
+
+void BookmarkManager::readBookmarksRecursive(const QStandardItem *item,
+ QDataStream &stream,
+ const qint32 depth) const
+{
+ for (int j = 0; j < item->rowCount(); ++j) {
+ const QStandardItem *child = item->child(j);
+ stream << depth;
+ stream << child->data(Qt::DisplayRole).toString();
+ stream << child->data(Qt::UserRole + 10).toString();
+ stream << child->data(Qt::UserRole + 11).toBool();
+
+ if (child->rowCount() > 0)
+ readBookmarksRecursive(child, stream, (depth +1));
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h
new file mode 100644
index 0000000000..ab905d13e5
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmanager.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** 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 BOOKMARKMANAGER_H
+#define BOOKMARKMANAGER_H
+
+#include "ui_bookmarkdialog.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QByteArray>
+#include <QtCore/QDataStream>
+
+#include <QtGui/QIcon>
+#include <QtGui/QDialog>
+#include <QtGui/QWidget>
+#include <QtGui/QTreeView>
+#include <QtGui/QStandardItemModel>
+
+QT_BEGIN_NAMESPACE
+
+class QEvent;
+class QLineEdit;
+class QTreeView;
+class QToolButton;
+class QStandardItem;
+class QHelpEngineCore;
+class QAbstractItemModel;
+class QSortFilterProxyModel;
+
+class BookmarkManager;
+
+class BookmarkDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ BookmarkDialog(BookmarkManager *manager, const QString &title,
+ const QString &url, QWidget *parent = 0);
+ ~BookmarkDialog();
+
+private slots:
+ void addAccepted();
+ void addNewFolder();
+ void toolButtonClicked();
+ void itemChanged(QStandardItem *item);
+ void textChanged(const QString& string);
+ void selectBookmarkFolder(const QString &folderName);
+ void customContextMenuRequested(const QPoint &point);
+ void currentChanged(const QModelIndex& current, const QModelIndex& previous);
+
+private:
+ bool eventFilter(QObject *object, QEvent *e);
+
+private:
+ QString m_url;
+ QString m_title;
+
+ QString oldText;
+ QStandardItem *renameItem;
+
+ Ui::BookmarkDialog ui;
+ BookmarkManager *bookmarkManager;
+ QSortFilterProxyModel *proxyModel;
+};
+
+class TreeView : public QTreeView {
+ Q_OBJECT
+public:
+ TreeView(QWidget* parent = 0) : QTreeView(parent) {}
+ void subclassKeyPressEvent(QKeyEvent* event)
+ {
+ QTreeView::keyPressEvent(event);
+ }
+};
+
+class BookmarkWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ BookmarkWidget(BookmarkManager *manager, QWidget *parent = 0,
+ bool showButtons = true);
+ ~BookmarkWidget();
+
+signals:
+ void addBookmark();
+ void requestShowLink(const QUrl &url);
+ void escapePressed();
+
+private slots:
+ void removeClicked();
+ void filterChanged();
+ void expand(const QModelIndex& index);
+ void activated(const QModelIndex &index);
+ void customContextMenuRequested(const QPoint &point);
+
+private:
+ void setup(bool showButtons);
+ void expandItems();
+ void focusInEvent(QFocusEvent *e);
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ QRegExp regExp;
+ TreeView *treeView;
+ QLineEdit *searchField;
+ QToolButton *addButton;
+ QToolButton *removeButton;
+ BookmarkManager *bookmarkManager;
+ QSortFilterProxyModel* filterBookmarkModel;
+};
+
+class BookmarkModel : public QStandardItemModel
+{
+ Q_OBJECT
+
+public:
+ BookmarkModel(int rows, int columns, QObject *parent = 0);
+ ~BookmarkModel();
+
+ Qt::DropActions supportedDropActions() const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+};
+
+class BookmarkManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ BookmarkManager(QHelpEngineCore* helpEngine);
+ ~BookmarkManager();
+
+ BookmarkModel* treeBookmarkModel();
+ BookmarkModel* listBookmarkModel();
+
+ void saveBookmarks();
+ QStringList bookmarkFolders() const;
+ QModelIndex addNewFolder(const QModelIndex& index);
+ void removeBookmarkItem(QTreeView *treeView, const QModelIndex& index);
+ void showBookmarkDialog(QWidget* parent, const QString &name, const QString &url);
+ void addNewBookmark(const QModelIndex& index, const QString &name, const QString &url);
+ void setupBookmarkModels();
+
+private slots:
+ void itemChanged(QStandardItem *item);
+
+private:
+ QString uniqueFolderName() const;
+ void removeBookmarkFolderItems(QStandardItem *item);
+ void readBookmarksRecursive(const QStandardItem *item, QDataStream &stream,
+ const qint32 depth) const;
+
+private:
+ QString oldText;
+ QIcon folderIcon;
+
+ BookmarkModel *treeModel;
+ BookmarkModel *listModel;
+ QStandardItem *renameItem;
+ QHelpEngineCore *helpEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp
new file mode 100644
index 0000000000..1b0e6712ff
--- /dev/null
+++ b/tools/assistant/tools/assistant/centralwidget.cpp
@@ -0,0 +1,1080 @@
+/****************************************************************************
+**
+** 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 "centralwidget.h"
+#include "helpviewer.h"
+#include "searchwidget.h"
+#include "mainwindow.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QEvent>
+#include <QtCore/QTimer>
+
+#include <QtGui/QMenu>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QPrinter>
+#include <QtGui/QLineEdit>
+#include <QtGui/QCheckBox>
+#include <QtGui/QTabBar>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolButton>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QTextCursor>
+#include <QtGui/QPrintDialog>
+#include <QtGui/QApplication>
+#include <QtGui/QTextDocumentFragment>
+#include <QtGui/QPrintPreviewDialog>
+#include <QtGui/QPageSetupDialog>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpSearchEngine>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ HelpViewer* helpViewerFromTabPosition(const QTabWidget *widget, const QPoint &point)
+ {
+ QTabBar *tabBar = qFindChild<QTabBar*>(widget);
+ for (int i = 0; i < tabBar->count(); ++i) {
+ if (tabBar->tabRect(i).contains(point))
+ return qobject_cast<HelpViewer*>(widget->widget(i));
+ }
+ return 0;
+ }
+ CentralWidget *staticCentralWidget = 0;
+}
+
+FindWidget::FindWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QString system = QLatin1String("win");
+ QHBoxLayout *hboxLayout = new QHBoxLayout(this);
+#ifdef Q_OS_MAC
+ system = QLatin1String("mac");
+#else
+ hboxLayout->setSpacing(6);
+ hboxLayout->setMargin(0);
+#endif
+
+ toolClose = new QToolButton(this);
+ toolClose->setIcon(QIcon(QString::fromUtf8(":/trolltech/assistant/images/%1/closetab.png").arg(system)));
+ toolClose->setAutoRaise(true);
+ hboxLayout->addWidget(toolClose);
+
+ editFind = new QLineEdit(this);
+ editFind->setMinimumSize(QSize(150, 0));
+ connect(editFind, SIGNAL(textChanged(const QString&)),
+ this, SLOT(updateButtons()));
+ hboxLayout->addWidget(editFind);
+
+ toolPrevious = new QToolButton(this);
+ toolPrevious->setAutoRaise(true);
+ toolPrevious->setText(tr("Previous"));
+ toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ toolPrevious->setIcon(QIcon(QString::fromUtf8(":/trolltech/assistant/images/%1/previous.png").arg(system)));
+ hboxLayout->addWidget(toolPrevious);
+
+ toolNext = new QToolButton(this);
+ toolNext->setAutoRaise(true);
+ toolNext->setText(tr("Next"));
+ toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ toolNext->setIcon(QIcon(QString::fromUtf8(":/trolltech/assistant/images/%1/next.png").arg(system)));
+ hboxLayout->addWidget(toolNext);
+
+ checkCase = new QCheckBox(tr("Case Sensitive"), this);
+ hboxLayout->addWidget(checkCase);
+
+ checkWholeWords = new QCheckBox(tr("Whole words"), this);
+ hboxLayout->addWidget(checkWholeWords);
+#if !defined(QT_NO_WEBKIT)
+ checkWholeWords->hide();
+#endif
+
+ labelWrapped = new QLabel(this);
+ labelWrapped->setMinimumSize(QSize(0, 20));
+ labelWrapped->setMaximumSize(QSize(105, 20));
+ labelWrapped->setTextFormat(Qt::RichText);
+ labelWrapped->setScaledContents(true);
+ labelWrapped->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter);
+ labelWrapped->setText(tr("<img src=\":/trolltech/assistant/images/wrap.png\">&nbsp;Search wrapped"));
+ hboxLayout->addWidget(labelWrapped);
+
+ QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ hboxLayout->addItem(spacerItem);
+ setMinimumWidth(minimumSizeHint().width());
+ labelWrapped->hide();
+
+ updateButtons();
+}
+
+FindWidget::~FindWidget()
+{
+}
+
+void FindWidget::updateButtons()
+{
+ if (editFind->text().isEmpty()) {
+ toolPrevious->setEnabled(false);
+ toolNext->setEnabled(false);
+ } else {
+ toolPrevious->setEnabled(true);
+ toolNext->setEnabled(true);
+ }
+}
+
+
+CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent)
+ : QWidget(parent)
+ , findBar(0)
+ , tabWidget(0)
+ , helpEngine(engine)
+ , printer(0)
+ , m_searchWidget(0)
+{
+ staticCentralWidget = this;
+
+ lastTabPage = 0;
+ globalActionList.clear();
+ collectionFile = helpEngine->collectionFile();
+ usesDefaultCollection = parent->usesDefaultCollection();
+
+ QString system = QLatin1String("win");
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+
+#ifdef Q_OS_MAC
+ system = QLatin1String("mac");
+#else
+ vboxLayout->setMargin(0);
+#endif
+
+ tabWidget = new QTabWidget(this);
+ connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPageChanged(int)));
+
+ QToolButton *newTabButton = new QToolButton(this);
+ newTabButton->setAutoRaise(true);
+ newTabButton->setToolTip(tr("Add new page"));
+ newTabButton->setIcon(QIcon(QString::fromUtf8(":/trolltech/assistant/images/%1/addtab.png").arg(system)));
+
+ tabWidget->setCornerWidget(newTabButton, Qt::TopLeftCorner);
+ connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));
+
+ QToolButton *closeTabButton = new QToolButton(this);
+ closeTabButton->setEnabled(false);
+ closeTabButton->setAutoRaise(true);
+ closeTabButton->setToolTip(tr("Close current page"));
+ closeTabButton->setIcon(QIcon(QString::fromUtf8(":/trolltech/assistant/images/%1/closetab.png").arg(system)));
+
+ tabWidget->setCornerWidget(closeTabButton, Qt::TopRightCorner);
+ connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeTab()));
+
+ vboxLayout->addWidget(tabWidget);
+
+ findBar = new QWidget(this);
+ findWidget = new FindWidget(findBar);
+ findBar->setMinimumHeight(findWidget->minimumSizeHint().height());
+ findWidget->move(0, 0);
+ vboxLayout->addWidget(findBar);
+ findBar->hide();
+ findWidget->editFind->installEventFilter(this);
+ connect(findWidget->toolClose, SIGNAL(clicked()), findBar, SLOT(hide()));
+
+ connect(findWidget->toolNext, SIGNAL(clicked()), this, SLOT(findNext()));
+ connect(findWidget->editFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
+ connect(findWidget->editFind, SIGNAL(textChanged(const QString&)), this, SLOT(findCurrentText(const QString&)));
+ connect(findWidget->toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
+
+ QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
+ if (tabBar) {
+ tabBar->installEventFilter(this);
+ tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(tabBar, SIGNAL(customContextMenuRequested(const QPoint&)),
+ this, SLOT(showTabBarContextMenu(const QPoint&)));
+ }
+
+ QPalette p = qApp->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));
+ qApp->setPalette(p);
+}
+
+CentralWidget::~CentralWidget()
+{
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ QString zoomCount;
+ QString currentPages;
+ QLatin1Char sep('|');
+ for (int i = 1; i < tabWidget->count(); ++i) {
+ HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
+ if (viewer && viewer->source().isValid()) {
+ currentPages.append(viewer->source().toString()).append(sep);
+#if !defined(QT_NO_WEBKIT)
+ zoomCount.append(QString::number(viewer->textSizeMultiplier())).
+ append(sep);
+#else
+ zoomCount.append(QString::number(viewer->zoom())).append(sep);
+#endif
+ }
+ }
+ engine.setCustomValue(QLatin1String("LastTabPage"), lastTabPage);
+ engine.setCustomValue(QLatin1String("LastShownPages"), currentPages);
+#if !defined(QT_NO_WEBKIT)
+ engine.setCustomValue(QLatin1String("LastPagesZoomWebView"), zoomCount);
+#else
+ engine.setCustomValue(QLatin1String("LastPagesZoomTextBrowser"), zoomCount);
+#endif
+}
+
+CentralWidget *CentralWidget::instance()
+{
+ return staticCentralWidget;
+}
+
+void CentralWidget::newTab()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ setSourceInNewTab(viewer->source());
+}
+
+void CentralWidget::zoomIn()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->zoomIn();
+
+ if (tabWidget->currentWidget() == m_searchWidget)
+ m_searchWidget->zoomIn();
+}
+
+void CentralWidget::zoomOut()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->zoomOut();
+
+ if (tabWidget->currentWidget() == m_searchWidget)
+ m_searchWidget->zoomOut();
+}
+
+void CentralWidget::findNext()
+{
+ find(findWidget->editFind->text(), true, false);
+}
+
+void CentralWidget::nextPage()
+{
+ if(tabWidget->currentIndex() < tabWidget->count() -1)
+ tabWidget->setCurrentIndex(tabWidget->currentIndex() +1);
+ else
+ tabWidget->setCurrentIndex(0);
+}
+
+void CentralWidget::resetZoom()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->resetZoom();
+
+ if (tabWidget->currentWidget() == m_searchWidget)
+ m_searchWidget->resetZoom();
+}
+
+void CentralWidget::previousPage()
+{
+ int index = tabWidget->currentIndex() -1;
+ if(index >= 0)
+ tabWidget->setCurrentIndex(index);
+ else
+ tabWidget->setCurrentIndex(tabWidget->count() -1);
+}
+
+void CentralWidget::findPrevious()
+{
+ find(findWidget->editFind->text(), false, true);
+}
+
+void CentralWidget::closeTab()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (!viewer|| tabWidget->count() == 1)
+ return;
+
+ tabWidget->removeTab(tabWidget->indexOf(viewer));
+ QTimer::singleShot(0, viewer, SLOT(deleteLater()));
+}
+
+void CentralWidget::setSource(const QUrl &url)
+{
+ HelpViewer* viewer = currentHelpViewer();
+ HelpViewer* lastViewer = qobject_cast<HelpViewer*>(tabWidget->widget(lastTabPage));
+
+ if (!viewer && !lastViewer) {
+ viewer = new HelpViewer(helpEngine, this);
+ viewer->installEventFilter(this);
+ lastTabPage = tabWidget->addTab(viewer, QString());
+ tabWidget->setCurrentIndex(lastTabPage);
+ connectSignals();
+ } else
+ viewer = lastViewer;
+
+ viewer->setSource(url);
+ currentPageChanged(lastTabPage);
+ viewer->setFocus(Qt::OtherFocusReason);
+ tabWidget->setCurrentIndex(lastTabPage);
+ tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle()));
+}
+
+void CentralWidget::setLastShownPages()
+{
+#if !defined(QT_NO_WEBKIT)
+ QLatin1String zoom("LastPagesZoomWebView");
+#else
+ QLatin1String zoom("LastPagesZoomTextBrowser");
+#endif
+
+ const QStringList lastShownPageList =
+ helpEngine->customValue(QLatin1String("LastShownPages")).toString().
+ split(QLatin1Char('|'), QString::SkipEmptyParts);
+
+ if (!lastShownPageList.isEmpty()) {
+ QVector<QString>zoomList = helpEngine->customValue(zoom).toString().
+ split(QLatin1Char('|'), QString::SkipEmptyParts).toVector();
+ if (zoomList.isEmpty())
+ zoomList.fill(QLatin1String("0.0"), lastShownPageList.size());
+ else if(zoomList.count() < lastShownPageList.count()) {
+ zoomList.insert(zoomList.count(),
+ lastShownPageList.count() - zoomList.count(), QLatin1String("0.0"));
+ }
+
+ QVector<QString>::const_iterator zIt = zoomList.constBegin();
+ QStringList::const_iterator it = lastShownPageList.constBegin();
+ for (; it != lastShownPageList.constEnd(); ++it, ++zIt)
+ setSourceInNewTab((*it), (*zIt).toFloat());
+
+ tabWidget->setCurrentIndex(helpEngine->customValue(
+ QLatin1String("LastTabPage"), 1).toInt());
+ } else {
+ if (usesDefaultCollection)
+ setSource(QUrl(QLatin1String("help")));
+ }
+}
+
+bool CentralWidget::hasSelection() const
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ return viewer ? viewer->hasSelection() : false;
+}
+
+QUrl CentralWidget::currentSource() const
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ return viewer->source();
+
+ return QUrl();
+}
+
+QString CentralWidget::currentTitle() const
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ return viewer->documentTitle();
+
+ return QString();
+}
+
+void CentralWidget::copySelection()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->copy();
+}
+
+void CentralWidget::showTextSearch()
+{
+ findBar->show();
+ findWidget->editFind->selectAll();
+ findWidget->editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+void CentralWidget::initPrinter()
+{
+#ifndef QT_NO_PRINTER
+ if (!printer)
+ printer = new QPrinter(QPrinter::HighResolution);
+#endif
+}
+
+void CentralWidget::print()
+{
+#ifndef QT_NO_PRINTER
+ HelpViewer* viewer = currentHelpViewer();
+ if (!viewer)
+ return;
+
+ initPrinter();
+
+ QPrintDialog *dlg = new QPrintDialog(printer, this);
+#if defined(QT_NO_WEBKIT)
+ if (viewer->textCursor().hasSelection())
+ dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
+#endif
+ dlg->addEnabledOption(QAbstractPrintDialog::PrintPageRange);
+ dlg->addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
+ dlg->setWindowTitle(tr("Print Document"));
+ if (dlg->exec() == QDialog::Accepted) {
+ viewer->print(printer);
+ }
+ delete dlg;
+#endif
+}
+
+void CentralWidget::printPreview()
+{
+#ifndef QT_NO_PRINTER
+ initPrinter();
+ QPrintPreviewDialog preview(printer, this);
+ connect(&preview, SIGNAL(paintRequested(QPrinter *)), SLOT(printPreview(QPrinter *)));
+ preview.exec();
+#endif
+}
+
+void CentralWidget::printPreview(QPrinter *p)
+{
+#ifndef QT_NO_PRINTER
+ HelpViewer *viewer = currentHelpViewer();
+ if (viewer)
+ viewer->print(p);
+#endif
+}
+
+void CentralWidget::pageSetup()
+{
+#ifndef QT_NO_PRINTER
+ initPrinter();
+ QPageSetupDialog dlg(printer);
+ dlg.exec();
+#endif
+}
+
+bool CentralWidget::isHomeAvailable() const
+{
+ return currentHelpViewer() ? true : false;
+}
+
+void CentralWidget::home()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->home();
+}
+
+bool CentralWidget::isForwardAvailable() const
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ return viewer->isForwardAvailable();
+
+ return false;
+}
+
+void CentralWidget::forward()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->forward();
+}
+
+bool CentralWidget::isBackwardAvailable() const
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ return viewer->isBackwardAvailable();
+
+ return false;
+}
+
+void CentralWidget::backward()
+{
+ HelpViewer* viewer = currentHelpViewer();
+ if (viewer)
+ viewer->backward();
+}
+
+
+QList<QAction*> CentralWidget::globalActions() const
+{
+ return globalActionList;
+}
+
+void CentralWidget::setGlobalActions(const QList<QAction*> &actions)
+{
+ globalActionList = actions;
+}
+
+void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom)
+{
+ HelpViewer* viewer;
+
+#if defined(QT_NO_WEBKIT)
+ viewer = currentHelpViewer();
+ if (viewer && viewer->launchedWithExternalApp(url))
+ return;
+#endif
+
+ viewer = new HelpViewer(helpEngine, this);
+ viewer->installEventFilter(this);
+ viewer->setSource(url);
+ viewer->setFocus(Qt::OtherFocusReason);
+ tabWidget->setCurrentIndex(tabWidget->addTab(viewer,
+ quoteTabTitle(viewer->documentTitle())));
+
+ QFont font = qApp->font();
+ bool userFont = helpEngine->customValue(QLatin1String("useBrowserFont")).toBool();
+ if (userFont) {
+ font = qVariantValue<QFont>(helpEngine->customValue(
+ QLatin1String("browserFont")));
+ }
+
+#if !defined(QT_NO_WEBKIT)
+ QWebSettings* settings = QWebSettings::globalSettings();
+ if (!userFont) {
+ int fontSize = settings->fontSize(QWebSettings::DefaultFontSize);
+ QString fontFamily = settings->fontFamily(QWebSettings::StandardFont);
+ font = QFont(fontFamily, fontSize);
+ }
+
+ QWebView* view = qobject_cast<QWebView*> (viewer);
+ if (view) {
+ settings = view->settings();
+ settings->setFontFamily(QWebSettings::StandardFont, font.family());
+ settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
+ } else if (viewer) {
+ viewer->setFont(font);
+ }
+ viewer->setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom);
+#else
+ font.setPointSize((int)(font.pointSize() + zoom));
+ viewer->setFont(font);
+ viewer->setZoom((int)zoom);
+#endif
+
+ connectSignals();
+}
+
+HelpViewer *CentralWidget::newEmptyTab()
+{
+ HelpViewer* viewer = new HelpViewer(helpEngine, this);
+ viewer->installEventFilter(this);
+ viewer->setFocus(Qt::OtherFocusReason);
+#if defined(QT_NO_WEBKIT)
+ viewer->setDocumentTitle(tr("unknown"));
+#endif
+ tabWidget->setCurrentIndex(tabWidget->addTab(viewer, tr("unknown")));
+
+ connectSignals();
+ return viewer;
+}
+
+void CentralWidget::findCurrentText(const QString &text)
+{
+ find(text, false, false);
+}
+
+void CentralWidget::connectSignals()
+{
+ const HelpViewer* viewer = currentHelpViewer();
+ if (viewer) {
+ connect(viewer, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool)));
+ connect(viewer, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
+ connect(viewer, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
+ connect(viewer, SIGNAL(sourceChanged(const QUrl&)), this, SIGNAL(sourceChanged(const QUrl&)));
+ connect(viewer, SIGNAL(highlighted(const QString&)), this, SIGNAL(highlighted(const QString&)));
+
+ connect(viewer, SIGNAL(sourceChanged(const QUrl&)), this, SLOT(setTabTitle(const QUrl&)));
+ }
+}
+
+HelpViewer *CentralWidget::currentHelpViewer() const
+{
+ return qobject_cast<HelpViewer*>(tabWidget->currentWidget());
+}
+
+void CentralWidget::activateTab(bool onlyHelpViewer)
+{
+ if (currentHelpViewer()) {
+ currentHelpViewer()->setFocus();
+ } else {
+ int idx = 0;
+ if (onlyHelpViewer)
+ idx = lastTabPage;
+ tabWidget->setCurrentIndex(idx);
+ tabWidget->currentWidget()->setFocus();
+ }
+}
+
+void CentralWidget::setTabTitle(const QUrl& url)
+{
+ int tab = lastTabPage;
+ HelpViewer* viewer = currentHelpViewer();
+
+#if !defined(QT_NO_WEBKIT)
+ if (!viewer || viewer->source() != url) {
+ QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
+ for (tab = 0; tab < tabBar->count(); ++tab) {
+ viewer = qobject_cast<HelpViewer*>(tabWidget->widget(tab));
+ if (viewer && viewer->source() == url)
+ break;
+ }
+ }
+#else
+ Q_UNUSED(url)
+#endif
+
+ if (viewer) {
+ tabWidget->setTabText(tab,
+ quoteTabTitle(viewer->documentTitle().trimmed()));
+ }
+}
+
+void CentralWidget::currentPageChanged(int index)
+{
+ const HelpViewer *viewer = currentHelpViewer();
+
+ if (viewer || tabWidget->count() == 1)
+ lastTabPage = index;
+
+ bool enabled = false;
+ if (viewer) {
+ enabled = true;
+ if (!m_searchWidget)
+ enabled = tabWidget->count() > 1;
+ }
+
+ tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled(enabled);
+ tabWidget->cornerWidget(Qt::TopLeftCorner)->setEnabled(m_searchWidget ? enabled : true);
+
+ emit currentViewerChanged();
+}
+
+void CentralWidget::showTabBarContextMenu(const QPoint &point)
+{
+ HelpViewer* viewer = helpViewerFromTabPosition(tabWidget, point);
+ if (!viewer)
+ return;
+
+ QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
+
+ QMenu menu(QLatin1String(""), tabBar);
+ QAction *new_page = menu.addAction(tr("Add New Page"));
+ QAction *close_page = menu.addAction(tr("Close This Page"));
+ QAction *close_pages = menu.addAction(tr("Close Other Pages"));
+ menu.addSeparator();
+ QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page..."));
+
+ if (tabBar->count() == 1) {
+ close_page->setEnabled(false);
+ close_pages->setEnabled(false);
+ } else if (m_searchWidget && tabBar->count() == 2) {
+ close_pages->setEnabled(false);
+ }
+
+ QAction *picked_action = menu.exec(tabBar->mapToGlobal(point));
+ if (!picked_action)
+ return;
+
+ if (picked_action == new_page)
+ setSourceInNewTab(viewer->source());
+
+ if (picked_action == close_page) {
+ tabWidget->removeTab(tabWidget->indexOf(viewer));
+ QTimer::singleShot(0, viewer, SLOT(deleteLater()));
+ }
+
+ if (picked_action == close_pages) {
+ int currentPage = tabWidget->indexOf(viewer);
+ for (int i = tabBar->count() -1; i >= 0; --i) {
+ viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
+ if (i != currentPage && viewer) {
+ tabWidget->removeTab(i);
+ QTimer::singleShot(0, viewer, SLOT(deleteLater()));
+
+ if (i < currentPage)
+ --currentPage;
+ }
+ }
+ }
+
+ if (picked_action == newBookmark)
+ emit addNewBookmark(viewer->documentTitle(), viewer->source().toString());
+}
+
+bool CentralWidget::eventFilter(QObject *object, QEvent *e)
+{
+ if (currentHelpViewer() == object && e->type() == QEvent::KeyPress){
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Backspace) {
+ HelpViewer *viewer = currentHelpViewer();
+#if defined(QT_NO_WEBKIT)
+ if (viewer && viewer->isBackwardAvailable()) {
+#else
+ if (viewer && viewer->isBackwardAvailable() && !viewer->hasFocus()) {
+#endif
+ viewer->backward();
+ return true;
+ }
+ }
+ }
+
+ QTabBar *tabBar = qobject_cast<QTabBar*>(object);
+ bool mousRel = e->type() == QEvent::MouseButtonRelease;
+ bool dblClick = e->type() == QEvent::MouseButtonDblClick;
+
+ if (tabBar && (mousRel || dblClick)) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(e);
+ HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, mouseEvent->pos());
+ if (!m_searchWidget && tabWidget->count() <= 1)
+ return QWidget::eventFilter(object, e);
+
+ if (viewer && (mouseEvent->button() == Qt::MidButton || dblClick)) {
+ tabWidget->removeTab(tabWidget->indexOf(viewer));
+ QTimer::singleShot(0, viewer, SLOT(deleteLater()));
+ currentPageChanged(tabWidget->currentIndex());
+ return true;
+ }
+ } else if (object == findWidget->editFind && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Escape) {
+ findBar->hide();
+ HelpViewer *hv = currentHelpViewer();
+ if (hv)
+ hv->setFocus();
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+void CentralWidget::keyPressEvent(QKeyEvent *e)
+{
+ QString text = e->text();
+ if (text.startsWith(QLatin1Char('/'))) {
+ if (!findBar->isVisible()) {
+ findBar->show();
+ findWidget->editFind->clear();
+ } else {
+ findWidget->editFind->selectAll();
+ }
+ findWidget->editFind->setFocus();
+ return;
+ }
+ QWidget::keyPressEvent(e);
+}
+
+void CentralWidget::find(QString ttf, bool forward, bool backward)
+{
+ QTextCursor cursor;
+ QTextDocument *doc = 0;
+ QTextBrowser *browser = 0;
+
+ HelpViewer* viewer = currentHelpViewer();
+ QPalette p = findWidget->editFind->palette();
+ p.setColor(QPalette::Active, QPalette::Base, Qt::white);
+
+#if !defined(QT_NO_WEBKIT)
+ Q_UNUSED(forward)
+ Q_UNUSED(doc)
+ Q_UNUSED(browser)
+
+ if (viewer) {
+ QWebPage::FindFlags options;
+ if (backward)
+ options |= QWebPage::FindBackward;
+
+ if (findWidget->checkCase->isChecked())
+ options |= QWebPage::FindCaseSensitively;
+
+ bool found = viewer->findText(ttf, options);
+ findWidget->labelWrapped->hide();
+
+ if (!found) {
+ options |= QWebPage::FindWrapsAroundDocument;
+ found = viewer->findText(ttf, options);
+
+ if (!found) {
+ p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
+ } else {
+ findWidget->labelWrapped->show();
+ }
+ }
+ }
+#else
+ if (viewer) {
+ doc = viewer->document();
+ cursor = viewer->textCursor();
+ browser = qobject_cast<QTextBrowser*>(viewer);
+ }
+
+ if (tabWidget->currentWidget() == m_searchWidget) {
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(m_searchWidget);
+ if (browser) {
+ doc = browser->document();
+ cursor = browser->textCursor();
+ }
+ }
+
+ if (!browser || !doc || cursor.isNull())
+ return;
+
+ QTextDocument::FindFlags options;
+
+ if (cursor.hasSelection())
+ cursor.setPosition(forward ? cursor.position() : cursor.anchor(), QTextCursor::MoveAnchor);
+
+ QTextCursor newCursor = cursor;
+
+ if (!ttf.isEmpty()) {
+ if (backward)
+ options |= QTextDocument::FindBackward;
+
+ if (findWidget->checkCase->isChecked())
+ options |= QTextDocument::FindCaseSensitively;
+
+ if (findWidget->checkWholeWords->isChecked())
+ options |= QTextDocument::FindWholeWords;
+
+ newCursor = doc->find(ttf, cursor, options);
+ findWidget->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 = cursor;
+ } else {
+ findWidget->labelWrapped->show();
+ }
+ }
+ }
+#endif
+
+ if (!findWidget->isVisible())
+ findWidget->show();
+
+#if defined(QT_NO_WEBKIT)
+ if (browser)
+ browser->setTextCursor(newCursor);
+#endif
+ findWidget->editFind->setPalette(p);
+}
+
+void CentralWidget::activateSearch()
+{
+ if (tabWidget->widget(0) != m_searchWidget)
+ createSearchWidget(helpEngine->searchEngine());
+
+ tabWidget->setCurrentWidget(m_searchWidget);
+ m_searchWidget->setFocus();
+}
+
+void CentralWidget::updateBrowserFont()
+{
+ QFont font = qApp->font();
+ bool userFont = helpEngine->customValue(QLatin1String("useBrowserFont")).toBool();
+ if (userFont) {
+ font = qVariantValue<QFont>(helpEngine->customValue(
+ QLatin1String("browserFont")));
+ }
+
+#if !defined(QT_NO_WEBKIT)
+ QWebSettings* settings = QWebSettings::globalSettings();
+ if (!userFont) {
+ int fontSize = settings->fontSize(QWebSettings::DefaultFontSize);
+ QString fontFamily = settings->fontFamily(QWebSettings::StandardFont);
+ font = QFont(fontFamily, fontSize);
+ }
+#endif
+
+ QWidget* widget = 0;
+ for (int i = 0; i < tabWidget->count(); ++i) {
+ widget = tabWidget->widget(i);
+#if !defined(QT_NO_WEBKIT)
+ QWebView* view = qobject_cast<QWebView*> (widget);
+ if (view) {
+ settings = view->settings();
+ settings->setFontFamily(QWebSettings::StandardFont, font.family());
+ settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
+ } else if (widget) {
+ if (!userFont)
+ font = qApp->font();
+ widget->setFont(font);
+ }
+#else
+ if (widget && widget->font() != font)
+ widget->setFont(font);
+#endif
+ }
+}
+
+void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine)
+{
+ if (!m_searchWidget) {
+ m_searchWidget = new SearchWidget(searchEngine, this);
+ connect(m_searchWidget, SIGNAL(requestShowLink(const QUrl&)), this,
+ SLOT(setSourceFromSearch(const QUrl&)));
+ connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(const QUrl&)), this,
+ SLOT(setSourceFromSearchInNewTab(const QUrl&)));
+ }
+ tabWidget->insertTab(0, m_searchWidget, tr("Search"));
+}
+
+void CentralWidget::removeSearchWidget()
+{
+ tabWidget->removeTab(0);
+}
+
+QString CentralWidget::quoteTabTitle(const QString &title) const
+{
+ QString s = title;
+ return s.replace(QLatin1Char('&'), QLatin1String("&&"));
+}
+
+void
+CentralWidget::setSourceFromSearch(const QUrl &url)
+{
+ setSource(url);
+ highlightSearchTerms();
+}
+
+void
+CentralWidget::setSourceFromSearchInNewTab(const QUrl &url)
+{
+ setSourceInNewTab(url);
+ highlightSearchTerms();
+}
+
+void
+CentralWidget::highlightSearchTerms()
+{
+#if defined(QT_NO_WEBKIT)
+ HelpViewer *viewer = currentHelpViewer();
+ if (!viewer)
+ return;
+
+ QHelpSearchEngine* searchEngine = helpEngine->searchEngine();
+ QList<QHelpSearchQuery> queryList = searchEngine->query();
+
+ QStringList terms;
+ foreach (QHelpSearchQuery query, queryList) {
+ switch (query.fieldName) {
+ default: break;
+ case QHelpSearchQuery::ALL: {
+ case QHelpSearchQuery::PHRASE:
+ case QHelpSearchQuery::DEFAULT:
+ case QHelpSearchQuery::ATLEAST:
+ foreach (QString term, query.wordList)
+ terms.append(term.remove(QLatin1String("\"")));
+ }
+ }
+ }
+
+ viewer->viewport()->setUpdatesEnabled(false);
+
+ QTextCharFormat marker;
+ marker.setForeground(Qt::red);
+
+ QTextCursor firstHit;
+
+ QTextCursor c = viewer->textCursor();
+ c.beginEditBlock();
+ foreach (const QString& term, terms) {
+ c.movePosition(QTextCursor::Start);
+ viewer->setTextCursor(c);
+
+ while (viewer->find(term, QTextDocument::FindWholeWords)) {
+ QTextCursor hit = viewer->textCursor();
+ if (firstHit.isNull() || hit.position() < firstHit.position())
+ firstHit = hit;
+
+ hit.mergeCharFormat(marker);
+ }
+ }
+
+ if (firstHit.isNull()) {
+ firstHit = viewer->textCursor();
+ firstHit.movePosition(QTextCursor::Start);
+ }
+ firstHit.clearSelection();
+ c.endEditBlock();
+ viewer->setTextCursor(firstHit);
+
+ viewer->viewport()->setUpdatesEnabled(true);
+#endif
+}
+
+void CentralWidget::closeTabAt(int index)
+{
+ HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(index));
+ tabWidget->removeTab(index);
+ QTimer::singleShot(0, viewer, SLOT(deleteLater()));
+}
+
+QMap<int, QString> CentralWidget::currentSourceFileList() const
+{
+ QMap<int, QString> sourceList;
+ for (int i = 1; i < tabWidget->count(); ++i) {
+ HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
+ if (viewer && viewer->source().isValid())
+ sourceList.insert(i, viewer->source().host());
+ }
+ return sourceList;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h
new file mode 100644
index 0000000000..75bd8be7d6
--- /dev/null
+++ b/tools/assistant/tools/assistant/centralwidget.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** 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 CENTRALWIDGET_H
+#define CENTRALWIDGET_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QPoint>
+#include <QtCore/QObject>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QEvent;
+class QLabel;
+class QAction;
+class QCheckBox;
+class QLineEdit;
+class QToolButton;
+
+class HelpViewer;
+class QTabWidget;
+class QHelpEngine;
+class CentralWidget;
+class PrintHelper;
+class MainWindow;
+
+class SearchWidget;
+class QHelpSearchEngine;
+
+class FindWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ FindWidget(QWidget *parent = 0);
+ ~FindWidget();
+
+signals:
+ void findNext();
+ void findPrevious();
+
+private slots:
+ void updateButtons();
+
+private:
+ QLineEdit *editFind;
+ QCheckBox *checkCase;
+ QLabel *labelWrapped;
+ QToolButton *toolNext;
+ QToolButton *toolClose;
+ QToolButton *toolPrevious;
+ QCheckBox *checkWholeWords;
+
+ friend class CentralWidget;
+};
+
+class CentralWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CentralWidget(QHelpEngine *engine, MainWindow *parent);
+ ~CentralWidget();
+
+ void setLastShownPages();
+ bool hasSelection() const;
+ QUrl currentSource() const;
+ QString currentTitle() const;
+ bool isHomeAvailable() const;
+ bool isForwardAvailable() const;
+ bool isBackwardAvailable() const;
+ QList<QAction*> globalActions() const;
+ void setGlobalActions(const QList<QAction*> &actions);
+ HelpViewer *currentHelpViewer() const;
+ void activateTab(bool onlyHelpViewer = false);
+ void activateSearch();
+ void createSearchWidget(QHelpSearchEngine *searchEngine);
+ void removeSearchWidget();
+
+ void closeTabAt(int index);
+ QMap<int, QString> currentSourceFileList() const;
+
+ static CentralWidget *instance();
+
+public slots:
+ void zoomIn();
+ void zoomOut();
+ void findNext();
+ void nextPage();
+ void resetZoom();
+ void previousPage();
+ void findPrevious();
+ void copySelection();
+ void showTextSearch();
+ void print();
+ void pageSetup();
+ void printPreview();
+ void updateBrowserFont();
+ void setSource(const QUrl &url);
+ void setSourceInNewTab(const QUrl &url, qreal zoom = 0.0);
+ void findCurrentText(const QString &text);
+ HelpViewer *newEmptyTab();
+ void home();
+ void forward();
+ void backward();
+
+signals:
+ void currentViewerChanged();
+ void copyAvailable(bool yes);
+ void sourceChanged(const QUrl &url);
+ void highlighted(const QString &link);
+ void forwardAvailable(bool available);
+ void backwardAvailable(bool available);
+ void addNewBookmark(const QString &title, const QString &url);
+
+protected:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void newTab();
+ void closeTab();
+ void setTabTitle(const QUrl& url);
+ void currentPageChanged(int index);
+ void showTabBarContextMenu(const QPoint &point);
+ void printPreview(QPrinter *printer);
+ void setSourceFromSearch(const QUrl &url);
+ void setSourceFromSearchInNewTab(const QUrl &url);
+
+private:
+ void connectSignals();
+ bool eventFilter(QObject *object, QEvent *e);
+ void find(QString ttf, bool forward, bool backward);
+ void initPrinter();
+ QString quoteTabTitle(const QString &title) const;
+ void highlightSearchTerms();
+
+private:
+ int lastTabPage;
+ QString collectionFile;
+ QList<QAction*> globalActionList;
+
+ QWidget *findBar;
+ QTabWidget* tabWidget;
+ FindWidget *findWidget;
+ QHelpEngine *helpEngine;
+ QPrinter *printer;
+ bool usesDefaultCollection;
+
+ SearchWidget* m_searchWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // CENTRALWIDGET_H
diff --git a/tools/assistant/tools/assistant/cmdlineparser.cpp b/tools/assistant/tools/assistant/cmdlineparser.cpp
new file mode 100644
index 0000000000..0dae785404
--- /dev/null
+++ b/tools/assistant/tools/assistant/cmdlineparser.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFileInfo>
+#include <QtGui/QMessageBox>
+
+#include "cmdlineparser.h"
+
+QT_BEGIN_NAMESPACE
+
+#define CHECK_NEXT_ARG \
+ ++i < arguments.count() && !arguments.at(i).startsWith(QLatin1String("-"))
+
+CmdLineParser::CmdLineParser()
+ : m_enableRemoteControl(false),
+ m_contents(Untouched),
+ m_index(Untouched),
+ m_bookmarks(Untouched),
+ m_search(Untouched),
+ m_register(None),
+ m_copy(false),
+ m_quiet(false)
+{
+ m_helpMessage = QLatin1String(
+ "Usage: assistant [Options]\n\n"
+ "-collectionFile file Uses the specified collection\n"
+ " file instead of the default one\n"
+ "-showUrl url Shows the document with the\n"
+ " url.\n"
+ "-enableRemoteControl Enables Assistant to be\n"
+ " remotely controlled.\n"
+ "-show widget Shows the specified dockwidget\n"
+ " which can be \"contents\", \"index\",\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-activate widget Activates the specified dockwidget\n"
+ " which can be \"contents\", \"index\",\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-hide widget Hides the specified dockwidget\n"
+ " which can be \"contents\", \"index\"\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-register helpFile Registers the specified help file\n"
+ " (.qch) in the given collection\n"
+ " file.\n"
+ "-unregister helpFile Unregisters the specified help file\n"
+ " (.qch) from the give collection\n"
+ " file.\n"
+ "-setCurrentFilter filter Set the filter as the active filter.\n"
+ "-quiet Does not display any error or\n"
+ " status message.\n"
+ "-help Displays this help.\n"
+ );
+}
+
+CmdLineParser::Result CmdLineParser::parse(const QStringList &arguments)
+{
+ QString error;
+ bool showHelp = false;
+
+ for (int j=1; j<arguments.count(); ++j) {
+ if (arguments.at(j).toLower() == QLatin1String("-quiet")) {
+ m_quiet = true;
+ break;
+ }
+ }
+
+ for (int i=1; i<arguments.count(); ++i) {
+ QString arg = arguments.at(i).toLower();
+ if (arg == QLatin1String("-collectionfile")) {
+ if (CHECK_NEXT_ARG) {
+ m_collectionFile = getFileName(arguments.at(i));
+ if (m_collectionFile.isEmpty()) {
+ error = QObject::tr("The specified collection file does not exist!");
+ break;
+ }
+ } else {
+ error = QObject::tr("Missing collection file!");
+ break;
+ }
+ } else if (arg == QLatin1String("-showurl")) {
+ if (CHECK_NEXT_ARG) {
+ QUrl url(arguments.at(i));
+ if (url.isValid()) {
+ m_url = url;
+ } else {
+ error = QObject::tr("Invalid URL!");
+ break;
+ }
+ } else {
+ error = QObject::tr("Missing URL!");
+ break;
+ }
+ } else if (arg == QLatin1String("-enableremotecontrol")) {
+ m_enableRemoteControl = true;
+ } else if (arg == QLatin1String("-show")) {
+ if (CHECK_NEXT_ARG) {
+ arg = arguments.at(i).toLower();
+ if (arg == QLatin1String("contents")) {
+ m_contents = Show;
+ } else if (arg == QLatin1String("index")) {
+ m_index = Show;
+ } else if (arg == QLatin1String("bookmarks")) {
+ m_bookmarks = Show;
+ } else if (arg == QLatin1String("search")) {
+ m_search = Show;
+ } else {
+ error = QObject::tr("Unknown widget: %1").arg(arg);
+ break;
+ }
+ } else {
+ error = QObject::tr("Missing widget!");
+ break;
+ }
+ } else if (arg == QLatin1String("-hide")) {
+ if (CHECK_NEXT_ARG) {
+ arg = arguments.at(i).toLower();
+ if (arg == QLatin1String("contents")) {
+ m_contents = Hide;
+ } else if (arg == QLatin1String("index")) {
+ m_index = Hide;
+ } else if (arg == QLatin1String("bookmarks")) {
+ m_bookmarks = Hide;
+ } else if (arg == QLatin1String("search")) {
+ m_search = Hide;
+ } else {
+ error = QObject::tr("Unknown widget: %1").arg(arg);
+ break;
+ }
+ } else {
+ error = QObject::tr("Missing widget!");
+ break;
+ }
+ } else if (arg == QLatin1String("-activate")) {
+ if (CHECK_NEXT_ARG) {
+ arg = arguments.at(i).toLower();
+ if (arg == QLatin1String("contents")) {
+ m_contents = Activate;
+ } else if (arg == QLatin1String("index")) {
+ m_index = Activate;
+ } else if (arg == QLatin1String("bookmarks")) {
+ m_bookmarks = Activate;
+ } else if (arg == QLatin1String("search")) {
+ m_search = Activate;
+ } else {
+ error = QObject::tr("Unknown widget: %1").arg(arg);
+ break;
+ }
+ } else {
+ error = QObject::tr("Missing widget!");
+ break;
+ }
+ } else if (arg == QLatin1String("-register")) {
+ if (CHECK_NEXT_ARG) {
+ m_helpFile = getFileName(arguments.at(i));
+ if (m_helpFile.isEmpty()) {
+ error = QObject::tr("The specified Qt help file does not exist!");
+ break;
+ }
+ m_register = Register;
+ } else {
+ error = QObject::tr("Missing help file!");
+ break;
+ }
+ } else if (arg == QLatin1String("-unregister")) {
+ if (CHECK_NEXT_ARG) {
+ m_helpFile = getFileName(arguments.at(i));
+ if (m_helpFile.isEmpty()) {
+ error = QObject::tr("The specified Qt help file does not exist!");
+ break;
+ }
+ m_register = Unregister;
+ } else {
+ error = QObject::tr("Missing help file!");
+ break;
+ }
+ } else if (arg == QLatin1String("-setcurrentfilter")) {
+ if (CHECK_NEXT_ARG) {
+ m_currentFilter = arguments.at(i);
+ } else {
+ error = QObject::tr("Missing filter argument!");
+ break;
+ }
+ } else if (arg == QLatin1String("-quiet")) {
+ continue;
+ } else if (arg == QLatin1String("-help")) {
+ showHelp = true;
+ } else if (arg == QLatin1String("-copy")) {
+ m_copy = true;
+ } else {
+ error = QObject::tr("Unknown option: %1").arg(arg);
+ break;
+ }
+ }
+
+ if (!error.isEmpty()) {
+ showMessage(error + QLatin1String("\n\n\n") + m_helpMessage, true);
+ return Error;
+ } else if (showHelp) {
+ showMessage(m_helpMessage, false);
+ return Help;
+ }
+ return Ok;
+}
+
+QString CmdLineParser::getFileName(const QString &fileName)
+{
+ QFileInfo fi(fileName);
+ if (!fi.exists())
+ return QString();
+ return fi.absoluteFilePath();
+}
+
+void CmdLineParser::showMessage(const QString &msg, bool error)
+{
+ if (m_quiet)
+ return;
+#ifdef Q_OS_WIN
+ QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");
+ if (error)
+ QMessageBox::critical(0, QObject::tr("Qt Assistant"), s);
+ else
+ QMessageBox::information(0, QObject::tr("Qt Assistant"), s);
+#else
+ fprintf(error ? stderr : stdout, "%s\n", qPrintable(msg));
+#endif
+}
+
+void CmdLineParser::setCollectionFile(const QString &file)
+{
+ m_collectionFile = file;
+}
+
+QString CmdLineParser::collectionFile() const
+{
+ return m_collectionFile;
+}
+
+QUrl CmdLineParser::url() const
+{
+ return m_url;
+}
+
+bool CmdLineParser::enableRemoteControl() const
+{
+ return m_enableRemoteControl;
+}
+
+CmdLineParser::ShowState CmdLineParser::contents() const
+{
+ return m_contents;
+}
+
+CmdLineParser::ShowState CmdLineParser::index() const
+{
+ return m_index;
+}
+
+CmdLineParser::ShowState CmdLineParser::bookmarks() const
+{
+ return m_bookmarks;
+}
+
+CmdLineParser::ShowState CmdLineParser::search() const
+{
+ return m_search;
+}
+
+QString CmdLineParser::currentFilter() const
+{
+ return m_currentFilter;
+}
+
+CmdLineParser::RegisterState CmdLineParser::registerRequest() const
+{
+ return m_register;
+}
+
+QString CmdLineParser::helpFile() const
+{
+ return m_helpFile;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/cmdlineparser.h b/tools/assistant/tools/assistant/cmdlineparser.h
new file mode 100644
index 0000000000..332d46468a
--- /dev/null
+++ b/tools/assistant/tools/assistant/cmdlineparser.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 CMDLINEPARSER_H
+#define CMDLINEPARSER_H
+
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class CmdLineParser
+{
+public:
+ enum Result {Ok, Help, Error};
+ enum ShowState {Untouched, Show, Hide, Activate};
+ enum RegisterState {None, Register, Unregister};
+
+ CmdLineParser();
+ Result parse(const QStringList &arguments);
+
+ void setCollectionFile(const QString &file);
+ QString collectionFile() const;
+ QString cloneFile() const;
+ QUrl url() const;
+ bool enableRemoteControl() const;
+ ShowState contents() const;
+ ShowState index() const;
+ ShowState bookmarks() const;
+ ShowState search() const;
+ QString currentFilter() const;
+ RegisterState registerRequest() const;
+ QString helpFile() const;
+
+ bool copy() const { return m_copy; }
+
+ void showMessage(const QString &msg, bool error);
+
+private:
+ QString getFileName(const QString &fileName);
+
+ QString m_helpMessage;
+ QString m_collectionFile;
+ QString m_cloneFile;
+ QString m_helpFile;
+ QUrl m_url;
+ bool m_enableRemoteControl;
+
+ ShowState m_contents;
+ ShowState m_index;
+ ShowState m_bookmarks;
+ ShowState m_search;
+ RegisterState m_register;
+ QString m_currentFilter;
+ bool m_copy;
+ bool m_quiet;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/contentwindow.cpp b/tools/assistant/tools/assistant/contentwindow.cpp
new file mode 100644
index 0000000000..ef272e8ca7
--- /dev/null
+++ b/tools/assistant/tools/assistant/contentwindow.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** 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 "contentwindow.h"
+#include "centralwidget.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QMenu>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpContentWidget>
+
+QT_BEGIN_NAMESPACE
+
+ContentWindow::ContentWindow(QHelpEngine *helpEngine)
+ : m_helpEngine(helpEngine)
+ , m_contentWidget(0)
+ , m_expandDepth(-2)
+{
+ m_contentWidget = m_helpEngine->contentWidget();
+ m_contentWidget->viewport()->installEventFilter(this);
+ m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(4);
+ layout->addWidget(m_contentWidget);
+
+ connect(m_contentWidget, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(showContextMenu(QPoint)));
+ connect(m_contentWidget, SIGNAL(linkActivated(QUrl)), this,
+ SIGNAL(linkActivated(QUrl)));
+
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ connect(contentModel, SIGNAL(contentsCreated()), this, SLOT(expandTOC()));
+}
+
+ContentWindow::~ContentWindow()
+{
+}
+
+bool ContentWindow::syncToContent(const QUrl& url)
+{
+ QModelIndex idx = m_contentWidget->indexOf(url);
+ if (!idx.isValid())
+ return false;
+ m_contentWidget->setCurrentIndex(idx);
+ return true;
+}
+
+void ContentWindow::expandTOC()
+{
+ if (m_expandDepth > -2) {
+ expandToDepth(m_expandDepth);
+ m_expandDepth = -2;
+ }
+}
+
+void ContentWindow::expandToDepth(int depth)
+{
+ m_expandDepth = depth;
+ if (depth == -1)
+ m_contentWidget->expandAll();
+ else
+ m_contentWidget->expandToDepth(depth);
+}
+
+void ContentWindow::focusInEvent(QFocusEvent *e)
+{
+ if (e->reason() != Qt::MouseFocusReason)
+ m_contentWidget->setFocus();
+}
+
+void ContentWindow::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Escape)
+ emit escapePressed();
+}
+
+bool ContentWindow::eventFilter(QObject *o, QEvent *e)
+{
+ if (m_contentWidget && o == m_contentWidget->viewport() && e->type()
+ == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (m_contentWidget->indexAt(me->pos()).isValid()
+ && me->button() == Qt::LeftButton) {
+ itemClicked(m_contentWidget->currentIndex());
+ } else if (m_contentWidget->indexAt(me->pos()).isValid()
+ && me->button() == Qt::MidButton) {
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(m_contentWidget->currentIndex());
+ CentralWidget::instance()->setSourceInNewTab(itm->url());
+ }
+ }
+ return QWidget::eventFilter(o, e);
+}
+
+void ContentWindow::showContextMenu(const QPoint &pos)
+{
+ if (!m_contentWidget->indexAt(pos).isValid())
+ return;
+
+ QMenu menu;
+ QAction *curTab = menu.addAction(tr("Open Link"));
+ QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
+ menu.move(m_contentWidget->mapToGlobal(pos));
+
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(m_contentWidget->currentIndex());
+
+ QAction *action = menu.exec();
+ if (curTab == action)
+ emit linkActivated(itm->url());
+ else if (newTab == action)
+ CentralWidget::instance()->setSourceInNewTab(itm->url());
+}
+
+void ContentWindow::itemClicked(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(index);
+ if (itm)
+ emit linkActivated(itm->url());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/contentwindow.h b/tools/assistant/tools/assistant/contentwindow.h
new file mode 100644
index 0000000000..ab8f8ddeb6
--- /dev/null
+++ b/tools/assistant/tools/assistant/contentwindow.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** 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 CONTENTWINDOW_H
+#define CONTENTWINDOW_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QModelIndex>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngine;
+class QHelpContentWidget;
+
+class ContentWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ContentWindow(QHelpEngine *helpEngine);
+ ~ContentWindow();
+
+ bool syncToContent(const QUrl &url);
+ void expandToDepth(int depth);
+
+signals:
+ void linkActivated(const QUrl &link);
+ void escapePressed();
+
+private slots:
+ void showContextMenu(const QPoint &pos);
+ void expandTOC();
+ void itemClicked(const QModelIndex &index);
+
+private:
+ void focusInEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+
+ QHelpEngine *m_helpEngine;
+ QHelpContentWidget *m_contentWidget;
+ int m_expandDepth;
+};
+
+QT_END_NAMESPACE
+
+#endif // CONTENTWINDOW_H
diff --git a/tools/assistant/tools/assistant/doc/HOWTO b/tools/assistant/tools/assistant/doc/HOWTO
new file mode 100644
index 0000000000..0e5b67b6e8
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/HOWTO
@@ -0,0 +1,17 @@
+How to build/ update a new assistant.qch for Assistant internal help
+
+- in case of update:
+ - open assistant.qdocconf, update year and qt version
+
+- all other cases:
+ - ..\..\..\..\qdoc3\debug\qdoc3.exe assistant.qdocconf
+ will generate an folder html containing all required stuff
+
+ - cp assistant.qhp to generated html folder
+ - run qhelpgenerator html\assistant.qhp -o ..\assistant.qch
+
+ - rebuild assistant
+
+- to test you changes:
+ - remove assistant.qch in your cache directory
+ - restart assistant
diff --git a/tools/assistant/tools/assistant/doc/assistant.qdoc b/tools/assistant/tools/assistant/doc/assistant.qdoc
new file mode 100644
index 0000000000..0d13490655
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/assistant.qdoc
@@ -0,0 +1,434 @@
+/*!
+ \page assistant.html
+ \title Qt Assistant
+
+ \chapter Introduction
+
+ This document introduces \e{Qt Assistant}, a tool for presenting on-line
+ documentation. It also introduces the Qt Reference Documentation which
+ is accessible using \e{Qt Assistant}, or with a web browser. The document is
+ divided into the following sections:
+
+ Table of contents:
+
+ \list
+ \o \l{Introduction}
+ \o \l{The One-Minute Guide to Using Qt Assistant}
+ \o \l{Introduction to the Qt Reference Documentation}
+ \o \l{Qt Assistant in More Detail}
+ \o \l{Full Text Searching}
+ \endlist
+
+ \chapter The One-Minute Guide to Using Qt Assistant
+
+ Once you have installed Qt, \QA should be ready to run:
+
+ \list
+ \o On Windows, \QA is available as a menu option on the Qt menu.
+ \o On Mac OS X, \QA is installed in the /Developer/Applications/Qt directory.
+ \o On Unix/Linux, open a terminal, type \c{assistant} and press \key{Enter}.
+ \endlist
+
+ When you start up \QA, you will be presented with a standard main window
+ application, with a menu bar and toolbar. Below these, on the left hand
+ side are navigation windows called \e{Contents}, \e{Index} and \e{Bookmarks}.
+ On the right, taking up most of the space, is the \e{Documentation} window.
+ By default, \QA loads the Qt reference documentation along with the manuals
+ of other Qt tools, like \QD or \QL.
+
+ \QA works in a similar way to a Web browser. If you click hyperlinks
+ (cross-references), the \e{Documentation} window will present the relevant
+ page. You can bookmark pages of particular interest and you can click the
+ \gui{Previous} and \gui{Next} toolbar buttons to navigate within the pages
+ you have visited.
+
+ Although \QA can be used just like a Web browser to navigate through
+ the documentation, \QA offers a powerful means of navigation that Web
+ browsers do not provide. \QA uses an advanced full text search engine
+ to index all the pages in each compressed help file so that you can
+ search for particular words and phrases.
+
+ To perform an index search, click the \gui{Index} tab on the Sidebar
+ (or press \key{Alt+I}). In the \gui{'Look For'} line edit enter a word;
+ e.g., 'homedirpath'. As you type, words are found and highlighted in a list
+ beneath the line edit. If the highlighted text matches what you're
+ looking for, double click it, (or press \key{Enter}) and the
+ \e{Documentation} window will display the relevant page. You rarely have
+ to type in the whole word before \QA finds a match. Note that for some
+ words there may be more than one possible page that is relevant.
+
+ \QA also provides full text searching for finding specific words in
+ the documentation. To activate the full text search, either press \key(Alt+S)
+ or click on the \gui{Search} tab in the \e{Documentation} window. Then
+ enter the term you're looking for and hit the \gui{Search} button. All
+ documents containing the specified term will then be listed in the list box
+ below.
+
+ \chapter Introduction to the Qt Reference Documentation
+
+ The documentation for the Qt library is written in-line in the \c
+ .cpp files by the developers themselves. The documentation team
+ revises the documentation to ensure that it is accurate and usable,
+ and to provide quality control. The documentation team also writes the
+ larger texts, such as the class descriptions that introduce a class
+ along with the concepts the class uses, as well as introducing the
+ functions and properties that the class provides.
+
+ The documentation focuses on the API rather than the internals, since
+ we make great efforts to keep our API consistent and compatible with
+ each new version, but we may change the internals considerably to improve
+ performance and enhance functionality.
+
+ The Qt Reference Documentation consists of almost 1,500 HTML pages
+ (over 2,500 printed pages). The overwhelming majority of pages
+ document Qt classes. Since developers differ in the way they
+ think and work we provide a variety of approaches to navigating the
+ documentation set:
+
+ \list
+ \i The \menu{Qt's Classes} page lists every class
+ in Qt's public API, and consists of several hundred classes.
+ \i The \menu{Qt's Main Classes} page lists the
+ classes you're most likely to use most often, and provides a much
+ shorter and more managable list than the All Classes list.
+ \i The \menu{Grouped Classes} page presents a list
+ of groups, each of which leads to a list of related classes, for
+ example, the \menu{Advanced Widgets} list.
+ \i The \menu{Class Inheritance Hierarchy} page
+ presents a list of classes in terms of the hierarchy of Qt classes.
+ \i The \menu{Member Function Index} page lists all the
+ functions provided by Qt classes, each one with links to the class(es)
+ in which it appears.
+ \endlist
+
+ No matter where you find yourself in the Qt documentation, you will
+ find extensive cross-referencing. Even snippets of example code
+ contain clickable links, so that for example, if you come across a
+ class declaration in a code example, the class name will be a
+ clickable link to the class's documentation.
+
+ In addition to the class documentation some of Qt's modules have
+ extensive descriptions, and there are many overview documents which
+ describe various aspects of the Qt library; all these are linked from
+ the reference documentation home page. There are also two tutorials
+ and numerous example programs in the examples subdirectory of the Qt
+ distribution.
+
+ \chapter Qt Assistant in More Detail
+
+ \img assistant-assistant.png
+
+ \section1 Command Line Options
+
+ \QA handles the following command line options:
+
+ \table
+ \header
+ \o Command Line Option
+ \o Brief Description
+ \row
+ \o -collectionFile <file.qhc>
+ \o Uses the specified collection file instead of the default one.
+ \row
+ \o -showUrl URL
+ \o Shows the document referenced by URL.
+ \row
+ \o -enableRemoteControl
+ \o Enables \QA to be remotly controlled.
+ \row
+ \o -show <widget>
+ \o Shows the specified dockwidget which can be "contents", "index",
+ "bookmarks" or "search".
+ \row
+ \o -hide <widget>
+ \o Hides the specified dockwidget which can be "contents", "index",
+ "bookmarks" or "search.
+ \row
+ \o -activate <widget>
+ \o Activates the specified dockwidget which can be "contents",
+ "index", "bookmarks" or "search.
+ \row
+ \o -register <doc.qch>
+ \o Registers the specified compressed help file in the given help
+ collection.
+ \row
+ \o -unregister <doc.qch>
+ \o Unregisters the specified compressed help file from the given
+ collection file.
+ \row
+ \o -quiet
+ \o Doesn't show any error, warning or success messages.
+ \endtable
+
+ \section1 Tool Windows
+
+ \img assistant-dockwidgets.png
+
+ The tool windows provide four ways to navigate the documentation:
+
+ \list
+ \o The \gui{Contents} window presents a table of contents implemented as a
+ tree view for the documentation that is available. If you click an item,
+ its documentation will appear in the \e{Documentation} window. If you double
+ click an item or click on the control to the left of it, the item's sub-items
+ will appear. Click a sub-item to make its page appear in the \e{Documentation}
+ window. Click on the control next to an open item to hide its sub-items.
+ \o The \gui{Index} window is used to look up key words or phrases.
+ See \l{The One-Minute Guide to Using Qt Assistant} for how to use this
+ window.
+ \o The \gui{Bookmarks} window lists any bookmarks you have made. Double
+ click a bookmark to make its page appear in the \e{Documentation} window.
+ The \gui{Bookmarks} window provides a context menu with \gui{Show Item},
+ \gui{Delete Item} as well as \gui{Rename Item}. Click in the main menu
+ \menu{Bookmark|Add Bookmark...} (or press \key{Ctrl+B}) to bookmark the
+ page that is currently showing in the \e{Documentation} window. Right click
+ a bookmark in the list to rename or delete the highlighted bookmark.
+ \endlist
+
+ If you want the \gui{Documentation} window to use as much space as possible,
+ you can easily group, move or hide the tool windows. To group the windows,
+ drag one on top of the other and release the mouse. If one or all tool
+ windows are not shown, press \key{Alt+C}, \key{Alt+I} or \key{Alt+O} to show
+ the required window.
+
+ The tool windows can be docked into the main window, so you can drag them
+ to the top, left, right or bottom of \e{Qt Assistant's} window, or you can
+ drag them outside \QA to float them as independent windows.
+
+ \section1 Documentation Window
+
+ \img assistant-docwindow.png
+
+ The \gui{Documentation} window lets you create a tab for each
+ documentation page that you view. Click the \gui{Add Tab} button and a new
+ tab will appear with the page name as the tab's caption. This makes it
+ convenient to switch between pages when you are working with different
+ documentation. You can delete a tab by clicking the \gui{Close Tab} button
+ located on the right side of the \gui{Documentation} window.
+
+ \section1 Toolbars
+
+ \img assistant-toolbar.png
+
+ The main toolbar provides fast access to the most common actions.
+
+ \table
+ \header \o Action \o Description \o Menu Item \o Shortcut
+ \row \o \gui{Previous} \o Takes you to the previous page in the history.
+ \o \menu{Go|Previous} \o \key{Alt+Left Arrow}
+ \row \o \gui{Next} \o Takes you to the next page in the history.
+ \o \menu{Go|Next} \o \key{Alt+Right Arrow}
+ \row \o \gui{Home}
+ \o Takes you to the home page as specified in the Preferences Dialog.
+ \o \menu{Go|Home} \o \key{Ctrl+Home}.
+ \row \o \gui{Sync with Table of Contents}
+ \o Synchronizes the \gui{Contents} tool window with the page currently
+ shown in the \gui{Documentation} window.
+ \o \menu{Go|Sync with Table of Contents} \o
+ \row \o \gui{Copy} \o Copies any selected text to the clipboard.
+ \o \menu{Edit|Copy} \o \key{Ctrl+C}
+ \row \o \gui{Print} \o Opens the \gui{Print} dialog.
+ \o \menu{File|Print} \o \key{Ctrl+P}
+ \row \o \gui{Find in Text} \o Opens the \gui{Find Text} dialog.
+ \o \menu{Edit|Find in Text} \o \key{Ctrl+F}
+ \row \o \gui{Zoom in}
+ \o Increases the font size used to display text in the current tab.
+ \o \menu{View|Zoom in} \o \key{Ctrl++}
+ \row \o \gui{Zoom out}
+ \o Decreases the font size used to display text in the current tab.
+ \o \menu{View|Zoom out} \o \key{Ctrl+-}
+ \row \o \gui{Normal Size}
+ \o Resets the font size to its normal size in the current tab.
+ \o \menu{View|Normal Size} \o \key{Ctrl+0}
+ \endtable
+
+ \img assistant-address-toolbar.png
+
+ The address toolbar provides a fast way to enter a specific URL for a
+ documentation file. By default, the address toolbar is not shown, so it
+ has to be activated via \menu{View|Toolbars|Address Toolbar}.
+
+ \img assistant-filter-toolbar.png
+
+ The filter toolbar allows you to apply a filter to the currently installed
+ documentation. As with the address toolbar, the filter toolbar is not visible
+ by default and has to be activated via \menu{View|Toolbars|Filter Toolbar}.
+
+ \section1 Menus
+
+ \section2 File Menu
+
+ \list
+ \o \menu{File|Page Setup...} invokes a dialog allowing you to define
+ page layout properties, such as margin sizes, page orientation and paper size.
+ \o \menu{File|Print Preview...} provides a preview of the printed pages.
+ \o \menu{File|Print...} opens the \l{#Print Dialog}{\gui{Print} dialog}.
+ \o \menu{File|New Tab} opens a new empty tab in the \gui{Documentation}
+ window.
+ \o \menu{File|Close Tab} closes the current tab of the
+ \gui{Documentation} window.
+ \o \menu{File|Exit} closes the \QA application.
+ \endlist
+
+ \section2 Edit Menu
+
+ \list
+ \o \menu{Edit|Copy} copies any selected text to the clipboard.
+ \o \menu{Edit|Find in Text} invokes the \l{#Find Text Control}{\gui{Find Text}
+ control} at the lower end of the \gui{Documentation} window.
+ \o \menu{Edit|Find Next} looks for the next occurance of the specified
+ text in the \gui{Find Text} control.
+ \o \menu{Edit|Find Previous} looks for the previous occurance of
+ the specified text in the \l{#Find Text Control}{\gui{Find Text} control}.
+ \o \menu{Edit|Preferences} invokes the \l{#Preferences Dialog}{\gui{Preferences} dialog}.
+ \endlist
+
+ \section2 View Menu
+
+ \list
+ \o \menu{View|Zoom in} increases the font size in the current tab.
+ \o \menu{View|Zoom out} decreases the font size in the current tab.
+ \o \menu{View|Normal Size} resets the font size in the current tab.
+ \o \menu{View|Contents} toggles the display of the \gui{Contents} tool window.
+ \o \menu{View|Index} toggles the display of the \gui{Index} tool window.
+ \o \menu{View|Bookmarks} toggles the display of the \gui{Bookmarks} tool window.
+ \o \menu{View|Search} toggles the display of the Search in the \gui{Documentation} window.
+ \endlist
+
+ \section2 Go Menu
+
+ \list
+ \o \menu{Go|Home} goes to the home page.
+ \o \menu{Go|Back} displays the previous page in the history.
+ \o \menu{Go|Forward} displays the next page in the history.
+ \o \menu{Go|Sync with Table of Contents} syncs the \gui{Contents} tool window to the currently shown page.
+ \o \menu{Go|Next Page} selects the next tab in the \gui{Documentation} window.
+ \o \menu{Go|Previous Page} selects the previous tab in the \gui{Documentation} window.
+ \endlist
+
+ \section2 Bookmarks Menu
+
+ \list
+ \o \menu{Bookmarks|Add} adds the current page to the list of bookmarks.
+ \endlist
+
+ \section1 Dialogs
+
+ \section2 Print Dialog
+
+ This dialog is platform-specific. It gives access to various printer
+ options and can be used to print the document shown in the current tab.
+
+ \section2 Preferences Dialog
+
+ \img assistant-preferences-fonts.png
+
+ The \menu{Fonts} page allows you to change the font family and font sizes of the
+ browser window displaying the documentation or the application itself.
+
+ \img assistant-preferences-filters.png
+
+ The \menu{Filters} page lets you create and remove documentation
+ filters. To add a new filter, click the \gui{Add} button, specify a
+ filter name in the pop-up dialog and click \gui{OK}, then select
+ the filter attributes in the list box on the right hand side.
+ You can delete a filter by selecting it and clicking the \gui{Remove}
+ button.
+
+ \img assistant-preferences-documentation.png
+
+ The \menu{Documentation} page lets you install and remove compressed help
+ files. Click the \gui{Install} button and choose the path of the compressed
+ help file (*.qch) you would like to install.
+ To delete a help file, select a documentation set in the list and click
+ \gui{Remove}.
+
+ \img assistant-preferences-options.png
+
+ The \menu{Options} page lets you specify the homepage \QA will display when
+ you click the \gui{Home} button in \QA's main user interface. You can specify
+ the hompage by typing it here or clicking on one of the buttons below the
+ textbox. \gui{Current Page} sets the currently displayed page as your home
+ page while \gui{Restore to default} will reset your home page to the default
+ home page.
+
+ \section1 Find Text Control
+
+ This control is used to find text in the current page. Enter the text you want
+ to find in the line edit. The search is incremental, meaning that the most
+ relevant result is shown as you enter characters into the line edit.
+
+ If you check the \gui{Whole words only} checkbox, the search will only consider
+ whole words; for example, if you search for "spin" with this checkbox checked it will
+ not match "spinbox", but will match "spin". If you check the \gui{Case sensitive}
+ checkbox then, for example, "spin" will match "spin" but not "Spin". You can
+ search forwards or backwards from your current position in the page by clicking
+ the \gui{Previous} or \gui{Next} buttons. To hide the find control, either click the
+ \gui{Close} button or hit the \key{Esc} key.
+
+ \section1 Filtering Help Contents
+
+ \QA allows you to install any kind of documentation as long as it is organized
+ in Qt compressed help files (*.qch). For example, it is possible to install the
+ Qt reference documentation for Qt 4.4.0 and Qt 4.4.1 at the same time. In many
+ respects, this is very convenient since only one version of \QA is needed.
+ However, at the same time it becomes more complicated when performing tasks like
+ searching the index because nearly every keyword is defined in Qt 4.4.0 as well
+ as in Qt 4.4.1. This means that \QA will always ask the user to choose which one
+ should be displayed.
+
+ We use documentation filters to solve this issue. A filter is identified by its
+ name, and contains a list of filter attributes. An attribute is just a string and
+ can be freely chosen. Attributes are defined by the documentation itself, this
+ means that every documentation set usually has one or more attributes.
+
+ For example, the Qt 4.4.0 \QA documentation defines the attributes \c {assistant},
+ \c{tools} and \c{4.4.0}, \QD defines \c{designer}, \c{tools} and \c{4.4.0}.
+ The filter to display all tools would then define only the attribute
+ \c{tools} since this attribute is part of both documentation sets.
+ Adding the attribute \c{assistant} to the filter would then only show \QA
+ documentation since the \QD documentation does not contain this
+ attribute. Having an empty list of attributes in a filter will match all
+ documentation; i.e., it is equivalent to requesting unfiltered documentation.
+
+ \section1 Full Text Searching
+
+ \img assistant-search.png
+
+ \QA provides a powerful full text search engine. To search
+ for certain words or text, click the \gui{Search} tab in the \gui{Documentation}
+ window. Then enter the text you want to look for and press \key{Enter}
+ or click the \gui{Search} button. The search is not case sensitive, so,
+ for example, Foo, fOo and FOO are all treated as the same. The following are
+ examples of common search patterns:
+
+ \list
+ \o \c deep -- lists all the documents that contain the word 'deep'
+ \o \c{deep*} -- lists all the documents that contain a word beginning
+ with 'deep'
+ \o \c{deep copy} -- lists all documents that contain both 'deep' \e
+ and 'copy'
+ \o \c{"deep copy"} -- list all documents that contain the phrase 'deep copy'
+ \endlist
+
+ It is also possible to use the \gui{Advanced search} to get more flexibility.
+ You can specify some words so that hits containing these are excluded from the
+ result, or you can search for an exact phrase. Searching for similar words will
+ give results like these:
+
+ \list
+ \o \c{QStin} -- lists all the documents with titles that are similar, such as \c{QString}
+ \o \c{QSting} -- lists all the documents with titles that are similar, such as \c{QString}
+ \o \c{QStrin} -- lists all the documents with titles that are similar, such as \c{QString}
+ \endlist
+
+ Options can be combined to improve the search results.
+
+ The list of documents found is ordered according to the number of
+ occurrences of the search text which they contain, with those containing
+ the highest number of occurrences appearing first. Simply click any
+ document in the list to display it in the \gui{Documentation} window.
+
+ If the documentation has changed \mdash for example, if documents have been added
+ or removed \mdash \QA will index them again.
+*/
diff --git a/tools/assistant/tools/assistant/doc/assistant.qdocconf b/tools/assistant/tools/assistant/doc/assistant.qdocconf
new file mode 100644
index 0000000000..50f18c0e76
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/assistant.qdocconf
@@ -0,0 +1,17 @@
+include(../../../../qdoc3/test/qt.qdocconf)
+
+version =
+
+sourcedirs = $QTDIR/tools/assistant/tools/assistant/doc
+imagedirs = $QTDIR/tools/assistant/tools/assistant/doc/images
+outputdir = $QTDIR/tools/assistant/tools/assistant/doc/html
+project = assistant
+description = "Qt Assistant"
+HTML.{postheader,address} = ""
+HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
+ "<td width=\"30%\" align=\"left\">Copyright &copy; 2008 Nokia Corporation " \
+ "and/or its subsidiary(-ies)</td>\n" \
+ "<td width=\"40%\" align=\"center\">Trademarks</td>\n" \
+ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.5.0</div></td>\n" \
+ "</tr></table></div></address>"
diff --git a/tools/assistant/tools/assistant/doc/assistant.qhp b/tools/assistant/tools/assistant/doc/assistant.qhp
new file mode 100644
index 0000000000..7a26101859
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/assistant.qhp
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <virtualFolder>assistant</virtualFolder>
+ <namespace>com.trolltech.com.assistantinternal_1.0.0</namespace>
+ <filterSection>
+ <files>
+ <file>assistant.html</file>
+ <file>classic.css</file>
+ <file>images/assistant-address-toolbar.png</file>
+ <file>images/assistant-assistant.png</file>
+ <file>images/assistant-dockwidgets.png</file>
+ <file>images/assistant-docwindow.png</file>
+ <file>images/assistant-filter-toolbar.png</file>
+ <file>images/assistant-preferences-documentation.png</file>
+ <file>images/assistant-preferences-filters.png</file>
+ <file>images/assistant-preferences-fonts.png</file>
+ <file>images/assistant-preferences-options.png</file>
+ <file>images/assistant-search.png</file>
+ <file>images/assistant-toolbar.png</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/tools/assistant/tools/assistant/doc/classic.css b/tools/assistant/tools/assistant/doc/classic.css
new file mode 100644
index 0000000000..911354035c
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/classic.css
@@ -0,0 +1,92 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-address-toolbar.png b/tools/assistant/tools/assistant/doc/images/assistant-address-toolbar.png
new file mode 100644
index 0000000000..847b7debba
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-address-toolbar.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-assistant.png b/tools/assistant/tools/assistant/doc/images/assistant-assistant.png
new file mode 100644
index 0000000000..b825de0987
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-assistant.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-dockwidgets.png b/tools/assistant/tools/assistant/doc/images/assistant-dockwidgets.png
new file mode 100644
index 0000000000..17bc064c53
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-dockwidgets.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-docwindow.png b/tools/assistant/tools/assistant/doc/images/assistant-docwindow.png
new file mode 100644
index 0000000000..c5bac581f6
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-docwindow.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-examples.png b/tools/assistant/tools/assistant/doc/images/assistant-examples.png
new file mode 100644
index 0000000000..47c01bcda7
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-examples.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png b/tools/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png
new file mode 100644
index 0000000000..4e89a79b9f
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png b/tools/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png
new file mode 100644
index 0000000000..790fd9a1a7
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-preferences-filters.png b/tools/assistant/tools/assistant/doc/images/assistant-preferences-filters.png
new file mode 100644
index 0000000000..7453dd66d6
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-preferences-filters.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png b/tools/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png
new file mode 100644
index 0000000000..d42d190d00
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-preferences-options.png b/tools/assistant/tools/assistant/doc/images/assistant-preferences-options.png
new file mode 100644
index 0000000000..d6624151ad
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-preferences-options.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-search.png b/tools/assistant/tools/assistant/doc/images/assistant-search.png
new file mode 100644
index 0000000000..ef75c3329f
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-search.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-toolbar.png b/tools/assistant/tools/assistant/doc/images/assistant-toolbar.png
new file mode 100644
index 0000000000..1b41825c64
--- /dev/null
+++ b/tools/assistant/tools/assistant/doc/images/assistant-toolbar.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/filternamedialog.cpp b/tools/assistant/tools/assistant/filternamedialog.cpp
new file mode 100644
index 0000000000..fc137ed96a
--- /dev/null
+++ b/tools/assistant/tools/assistant/filternamedialog.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 <QtGui/QPushButton>
+
+#include "filternamedialog.h"
+
+QT_BEGIN_NAMESPACE
+
+FilterNameDialog::FilterNameDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Ok),
+ SIGNAL(clicked()), this, SLOT(accept()));
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel),
+ SIGNAL(clicked()), this, SLOT(reject()));
+ connect(m_ui.lineEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(updateOkButton()));
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
+
+}
+
+QString FilterNameDialog::filterName() const
+{
+ return m_ui.lineEdit->text();
+}
+
+void FilterNameDialog::updateOkButton()
+{
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)
+ ->setDisabled(m_ui.lineEdit->text().isEmpty());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/filternamedialog.h b/tools/assistant/tools/assistant/filternamedialog.h
new file mode 100644
index 0000000000..32e849c41b
--- /dev/null
+++ b/tools/assistant/tools/assistant/filternamedialog.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 FILTERNAMEDIALOG_H
+#define FILTERNAMEDIALOG_H
+
+#include <QtGui/QDialog>
+#include "ui_filternamedialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class FilterNameDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FilterNameDialog(QWidget *parent = 0);
+ QString filterName() const;
+
+private slots:
+ void updateOkButton();
+
+private:
+ Ui::FilterNameDialogClass m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif // FILTERNAMEDIALOG_H
diff --git a/tools/assistant/tools/assistant/filternamedialog.ui b/tools/assistant/tools/assistant/filternamedialog.ui
new file mode 100644
index 0000000000..755a934799
--- /dev/null
+++ b/tools/assistant/tools/assistant/filternamedialog.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>FilterNameDialogClass</class>
+ <widget class="QDialog" name="FilterNameDialogClass" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>312</width>
+ <height>95</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Add Filter Name</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Filter Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="lineEdit" />
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp
new file mode 100644
index 0000000000..9817f23dae
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer.cpp
@@ -0,0 +1,556 @@
+/****************************************************************************
+**
+** 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 "helpviewer.h"
+#include "centralwidget.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <QtCore/QByteArray>
+#include <QtCore/QTimer>
+
+#include <QtGui/QMenu>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+#include <QtGui/QMessageBox>
+#include <QtGui/QDesktopServices>
+
+#include <QtHelp/QHelpEngine>
+
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_WEBKIT)
+
+class HelpNetworkReply : public QNetworkReply
+{
+public:
+ HelpNetworkReply(const QNetworkRequest &request, const QByteArray &fileData,
+ const QString &mimeType);
+
+ virtual void abort();
+
+ virtual qint64 bytesAvailable() const
+ { return data.length() + QNetworkReply::bytesAvailable(); }
+
+protected:
+ virtual qint64 readData(char *data, qint64 maxlen);
+
+private:
+ QByteArray data;
+ qint64 origLen;
+};
+
+HelpNetworkReply::HelpNetworkReply(const QNetworkRequest &request,
+ const QByteArray &fileData, const QString& mimeType)
+ : data(fileData), origLen(fileData.length())
+{
+ setRequest(request);
+ setOpenMode(QIODevice::ReadOnly);
+
+ setHeader(QNetworkRequest::ContentTypeHeader, mimeType);
+ setHeader(QNetworkRequest::ContentLengthHeader, QByteArray::number(origLen));
+ QTimer::singleShot(0, this, SIGNAL(metaDataChanged()));
+ QTimer::singleShot(0, this, SIGNAL(readyRead()));
+}
+
+void HelpNetworkReply::abort()
+{
+ // nothing to do
+}
+
+qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
+{
+ qint64 len = qMin(qint64(data.length()), maxlen);
+ if (len) {
+ qMemCopy(buffer, data.constData(), len);
+ data.remove(0, len);
+ }
+ if (!data.length())
+ QTimer::singleShot(0, this, SIGNAL(finished()));
+ return len;
+}
+
+class HelpNetworkAccessManager : public QNetworkAccessManager
+{
+public:
+ HelpNetworkAccessManager(QHelpEngine *engine, QObject *parent);
+
+protected:
+ virtual QNetworkReply *createRequest(Operation op,
+ const QNetworkRequest &request, QIODevice *outgoingData = 0);
+
+private:
+ QHelpEngine *helpEngine;
+};
+
+HelpNetworkAccessManager::HelpNetworkAccessManager(QHelpEngine *engine,
+ QObject *parent)
+ : QNetworkAccessManager(parent), helpEngine(engine)
+{
+}
+
+QNetworkReply *HelpNetworkAccessManager::createRequest(Operation op,
+ const QNetworkRequest &request, QIODevice *outgoingData)
+{
+ const QString& scheme = request.url().scheme();
+ if (scheme == QLatin1String("qthelp") || scheme == QLatin1String("about")) {
+ const QUrl& url = request.url();
+ QString mimeType = url.toString();
+ if (mimeType.endsWith(QLatin1String(".svg"))
+ || mimeType.endsWith(QLatin1String(".svgz"))) {
+ mimeType = QLatin1String("image/svg+xml");
+ }
+ else if (mimeType.endsWith(QLatin1String(".css"))) {
+ mimeType = QLatin1String("text/css");
+ }
+ else if (mimeType.endsWith(QLatin1String(".js"))) {
+ mimeType = QLatin1String("text/javascript");
+ } else {
+ mimeType = QLatin1String("text/html");
+ }
+ return new HelpNetworkReply(request, helpEngine->fileData(url), mimeType);
+ }
+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
+}
+
+class HelpPage : public QWebPage
+{
+public:
+ HelpPage(CentralWidget *central, QHelpEngine *engine, QObject *parent);
+
+protected:
+ virtual QWebPage *createWindow(QWebPage::WebWindowType);
+
+ virtual bool acceptNavigationRequest(QWebFrame *frame,
+ const QNetworkRequest &request, NavigationType type);
+
+private:
+ CentralWidget *centralWidget;
+ QHelpEngine *helpEngine;
+};
+
+HelpPage::HelpPage(CentralWidget *central, QHelpEngine *engine, QObject *parent)
+ : QWebPage(parent), centralWidget(central), helpEngine(engine)
+{
+}
+
+QWebPage *HelpPage::createWindow(QWebPage::WebWindowType)
+{
+ return centralWidget->newEmptyTab()->page();
+}
+
+static bool isLocalUrl(const QUrl &url)
+{
+ const QString scheme = url.scheme();
+ if (scheme.isEmpty()
+ || scheme == QLatin1String("file")
+ || scheme == QLatin1String("qrc")
+ || scheme == QLatin1String("data")
+ || scheme == QLatin1String("qthelp")
+ || scheme == QLatin1String("about"))
+ return true;
+ return false;
+}
+
+bool HelpPage::acceptNavigationRequest(QWebFrame *,
+ const QNetworkRequest &request, QWebPage::NavigationType)
+{
+ const QUrl &url = request.url();
+ if (isLocalUrl(url)) {
+ if (url.path().endsWith(QLatin1String("pdf"))) {
+ QString fileName = url.toString();
+ fileName = QDir::tempPath() + QDir::separator() + fileName.right
+ (fileName.length() - fileName.lastIndexOf(QChar('/')));
+
+ QFile tmpFile(QDir::cleanPath(fileName));
+ if (tmpFile.open(QIODevice::ReadWrite)) {
+ tmpFile.write(helpEngine->fileData(url));
+ tmpFile.close();
+ }
+ QDesktopServices::openUrl(QUrl(tmpFile.fileName()));
+ return false;
+ }
+ return true;
+ }
+
+ QDesktopServices::openUrl(url);
+ return false;
+}
+
+HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent)
+ : QWebView(parent), helpEngine(engine), parentWidget(parent)
+{
+ setAcceptDrops(false);
+
+ setPage(new HelpPage(parent, helpEngine, this));
+
+ page()->setNetworkAccessManager(new HelpNetworkAccessManager(engine, this));
+
+ QAction* action = pageAction(QWebPage::OpenLinkInNewWindow);
+ action->setText(tr("Open Link in New Tab"));
+ if (!parent)
+ action->setVisible(false);
+
+ pageAction(QWebPage::DownloadLinkToDisk)->setVisible(false);
+ pageAction(QWebPage::DownloadImageToDisk)->setVisible(false);
+ pageAction(QWebPage::OpenImageInNewWindow)->setVisible(false);
+
+ connect(pageAction(QWebPage::Copy), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(pageAction(QWebPage::Back), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(pageAction(QWebPage::Forward), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(page(), SIGNAL(linkHovered(QString, QString, QString)), this,
+ SIGNAL(highlighted(QString)));
+ connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl)));
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ if (url.toString() == QLatin1String("help")) {
+ load(QUrl(QLatin1String("qthelp://com.trolltech.com."
+ "assistantinternal_1.0.0/assistant/assistant.html")));
+ } else {
+ load(url);
+ }
+}
+
+void HelpViewer::resetZoom()
+{
+ setTextSizeMultiplier(1.0);
+}
+
+void HelpViewer::zoomIn(qreal range)
+{
+ setTextSizeMultiplier(textSizeMultiplier() + range / 10.0);
+}
+
+void HelpViewer::zoomOut(qreal range)
+{
+ setTextSizeMultiplier(qMax(0.0, textSizeMultiplier() - range / 10.0));
+}
+
+void HelpViewer::home()
+{
+ QString homepage = helpEngine->customValue(QLatin1String("homepage"),
+ QLatin1String("")).toString();
+
+ if (homepage.isEmpty()) {
+ homepage = helpEngine->customValue(QLatin1String("defaultHomepage"),
+ QLatin1String("help")).toString();
+ }
+
+ setSource(homepage);
+}
+
+void HelpViewer::wheelEvent(QWheelEvent *e)
+{
+ if (e->modifiers() & Qt::ControlModifier) {
+ const int delta = e->delta();
+ if (delta > 0)
+ zoomIn(delta / 120);
+ else if (delta < 0)
+ zoomOut(-delta / 120);
+ e->accept();
+ return;
+ }
+ QWebView::wheelEvent(e);
+}
+
+void HelpViewer::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() == Qt::XButton1) {
+ triggerPageAction(QWebPage::Back);
+ return;
+ }
+
+ if (e->button() == Qt::XButton2) {
+ triggerPageAction(QWebPage::Forward);
+ return;
+ }
+
+ QWebView::mouseReleaseEvent(e);
+}
+
+void HelpViewer::actionChanged()
+{
+ QAction *a = qobject_cast<QAction *>(sender());
+ if (a == pageAction(QWebPage::Copy))
+ emit copyAvailable(a->isEnabled());
+ else if (a == pageAction(QWebPage::Back))
+ emit backwardAvailable(a->isEnabled());
+ else if (a == pageAction(QWebPage::Forward))
+ emit forwardAvailable(a->isEnabled());
+}
+
+#else // !defined(QT_NO_WEBKIT)
+
+HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent)
+ : QTextBrowser(parent)
+ , zoomCount(0)
+ , controlPressed(false)
+ , lastAnchor(QString())
+ , helpEngine(engine)
+ , parentWidget(parent)
+{
+ document()->setDocumentMargin(8);
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ bool help = url.toString() == QLatin1String("help");
+ if (url.isValid() && !help) {
+ if (launchedWithExternalApp(url))
+ return;
+
+ QUrl u = helpEngine->findFile(url);
+ if (u.isValid()) {
+ QTextBrowser::setSource(u);
+ return;
+ }
+ }
+
+ if (help) {
+ QTextBrowser::setSource(QUrl(QLatin1String("qthelp://com.trolltech.com."
+ "assistantinternal_1.0.0/assistant/assistant.html")));
+ } else {
+ QTextBrowser::setSource(url);
+ setHtml(tr("<title>Error 404...</title><div align=\"center\"><br><br>"
+ "<h1>The page could not be found</h1><br><h3>'%1'</h3></div>")
+ .arg(url.toString()));
+ emit sourceChanged(url);
+ }
+}
+
+void HelpViewer::resetZoom()
+{
+ if (zoomCount == 0)
+ return;
+
+ QTextBrowser::zoomOut(zoomCount);
+ zoomCount = 0;
+}
+
+void HelpViewer::zoomIn(int range)
+{
+ if (zoomCount == 10)
+ return;
+
+ QTextBrowser::zoomIn(range);
+ zoomCount++;
+}
+
+void HelpViewer::zoomOut(int range)
+{
+ if (zoomCount == -5)
+ return;
+
+ QTextBrowser::zoomOut(range);
+ zoomCount--;
+}
+
+bool HelpViewer::launchedWithExternalApp(const QUrl &url)
+{
+ bool isPdf = url.path().endsWith(QLatin1String("pdf"));
+ if (url.scheme() == QLatin1String("http")
+ || url.scheme() == QLatin1String("ftp")
+ || url.scheme() == QLatin1String("mailto") || isPdf) {
+ bool launched = false;
+ if (isPdf && url.scheme() == QLatin1String("qthelp")) {
+ QString fileName = url.toString();
+ fileName = QDir::tempPath() + QDir::separator() + fileName.right
+ (fileName.length() - fileName.lastIndexOf(QLatin1Char('/')));
+
+ QFile tmpFile(QDir::cleanPath(fileName));
+ if (tmpFile.open(QIODevice::ReadWrite)) {
+ tmpFile.write(helpEngine->fileData(url));
+ tmpFile.close();
+ }
+ launched = QDesktopServices::openUrl(QUrl(tmpFile.fileName()));
+ } else {
+ launched = QDesktopServices::openUrl(url);
+ }
+
+ if (!launched) {
+ QMessageBox::information(this, tr("Help"),
+ tr("Unable to launch external application.\n"), tr("OK"));
+ }
+ return true;
+ }
+ return false;
+}
+
+QVariant HelpViewer::loadResource(int type, const QUrl &name)
+{
+ QByteArray ba;
+ if (type < 4) {
+ ba = helpEngine->fileData(name);
+ if (name.toString().endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) {
+ QImage image;
+ image.loadFromData(ba, "svg");
+ if (!image.isNull())
+ return image;
+ }
+ }
+ return ba;
+}
+
+void HelpViewer::openLinkInNewTab()
+{
+ if(lastAnchor.isEmpty())
+ return;
+
+ parentWidget->setSourceInNewTab(QUrl(lastAnchor));
+ lastAnchor.clear();
+}
+
+void HelpViewer::openLinkInNewTab(const QString &link)
+{
+ lastAnchor = link;
+ openLinkInNewTab();
+}
+
+bool HelpViewer::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 HelpViewer::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\tCtrl+LMB"), this,
+ SLOT(openLinkInNewTab()));
+ menu.addSeparator();
+ }
+ menu.addActions(parentWidget->globalActions());
+ QAction *action = menu.exec(e->globalPos());
+ if (action == copyAnchorAction)
+ QApplication::clipboard()->setText(link.toString());
+}
+
+void HelpViewer::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() == Qt::XButton1) {
+ QTextBrowser::backward();
+ return;
+ }
+
+ if (e->button() == Qt::XButton2) {
+ QTextBrowser::forward();
+ return;
+ }
+
+ controlPressed = e->modifiers() & Qt::ControlModifier;
+ if ((controlPressed && hasAnchorAt(e->pos())) ||
+ (e->button() == Qt::MidButton && hasAnchorAt(e->pos()))) {
+ openLinkInNewTab();
+ return;
+ }
+
+ QTextBrowser::mouseReleaseEvent(e);
+}
+
+void HelpViewer::keyPressEvent(QKeyEvent *e)
+{
+ if ((e->key() == Qt::Key_Home && e->modifiers() != Qt::NoModifier)
+ || (e->key() == Qt::Key_End && e->modifiers() != Qt::NoModifier)) {
+ QKeyEvent* event = new QKeyEvent(e->type(), e->key(), Qt::NoModifier,
+ e->text(), e->isAutoRepeat(), e->count());
+ e = event;
+ }
+ QTextBrowser::keyPressEvent(e);
+}
+
+void HelpViewer::home()
+{
+ QString homepage = helpEngine->customValue(QLatin1String("homepage"),
+ QLatin1String("")).toString();
+
+ if (homepage.isEmpty()) {
+ homepage = helpEngine->customValue(QLatin1String("defaultHomepage"),
+ QLatin1String("help")).toString();
+ }
+
+ setSource(homepage);
+}
+
+void HelpViewer::wheelEvent(QWheelEvent *e)
+{
+ if (e->modifiers() == Qt::CTRL) {
+ e->accept();
+ (e->delta() > 0) ? zoomIn() : zoomOut();
+ } else {
+ e->ignore();
+ QTextBrowser::wheelEvent(e);
+ }
+}
+
+#endif // !defined(QT_NO_WEBKIT)
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/helpviewer.h b/tools/assistant/tools/assistant/helpviewer.h
new file mode 100644
index 0000000000..af5c1976cf
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** 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 HELPVIEWER_H
+#define HELPVIEWER_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+#include <QtGui/QTextBrowser>
+#include <QtGui/QAction>
+
+#if !defined(QT_NO_WEBKIT)
+#include <QWebView>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngine;
+class CentralWidget;
+
+class QPoint;
+class QString;
+class QKeyEvent;
+class QMouseEvent;
+class QContextMenuEvent;
+
+#if !defined(QT_NO_WEBKIT)
+
+class HelpViewer : public QWebView
+{
+ Q_OBJECT
+
+public:
+ HelpViewer(QHelpEngine *helpEngine, CentralWidget *parent);
+ void setSource(const QUrl &url);
+
+ inline QUrl source() const
+ { return url(); }
+
+ inline QString documentTitle() const
+ { return title(); }
+
+ inline bool hasSelection() const
+ { return !selectedText().isEmpty(); } // ### this is suboptimal
+
+ void resetZoom();
+ void zoomIn(qreal range = 1);
+ void zoomOut(qreal range = 1);
+
+ inline void copy()
+ { return triggerPageAction(QWebPage::Copy); }
+
+ inline bool isForwardAvailable() const
+ { return pageAction(QWebPage::Forward)->isEnabled(); }
+ inline bool isBackwardAvailable() const
+ { return pageAction(QWebPage::Back)->isEnabled(); }
+
+public Q_SLOTS:
+ void home();
+ void backward() { back(); }
+
+Q_SIGNALS:
+ void copyAvailable(bool enabled);
+ void forwardAvailable(bool enabled);
+ void backwardAvailable(bool enabled);
+ void highlighted(const QString &);
+ void sourceChanged(const QUrl &);
+
+protected:
+ virtual void wheelEvent(QWheelEvent *);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+private Q_SLOTS:
+ void actionChanged();
+
+private:
+ QHelpEngine *helpEngine;
+ CentralWidget* parentWidget;
+};
+
+#else
+
+class HelpViewer : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ HelpViewer(QHelpEngine *helpEngine, CentralWidget *parent);
+ void setSource(const QUrl &url);
+
+ void resetZoom();
+ void zoomIn(int range = 1);
+ void zoomOut(int range = 1);
+ int zoom() const { return zoomCount; }
+ void setZoom(int zoom) { zoomCount = zoom; }
+
+ inline bool hasSelection() const
+ { return textCursor().hasSelection(); }
+
+ bool launchedWithExternalApp(const QUrl &url);
+
+public Q_SLOTS:
+ void home();
+
+protected:
+ void wheelEvent(QWheelEvent *e);
+
+private:
+ QVariant loadResource(int type, const QUrl &name);
+ void openLinkInNewTab(const QString &link);
+ bool hasAnchorAt(const QPoint& pos);
+ void contextMenuEvent(QContextMenuEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+
+private slots:
+ void openLinkInNewTab();
+
+private:
+ int zoomCount;
+ bool controlPressed;
+ QString lastAnchor;
+ QHelpEngine *helpEngine;
+ CentralWidget* parentWidget;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/images/assistant-128.png b/tools/assistant/tools/assistant/images/assistant-128.png
new file mode 100644
index 0000000000..f05949f6d8
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/assistant-128.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/assistant.png b/tools/assistant/tools/assistant/images/assistant.png
new file mode 100644
index 0000000000..ea4d1e70c1
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/assistant.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/addtab.png b/tools/assistant/tools/assistant/images/mac/addtab.png
new file mode 100644
index 0000000000..20928fb402
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/addtab.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/book.png b/tools/assistant/tools/assistant/images/mac/book.png
new file mode 100644
index 0000000000..7a3204c870
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/book.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/closetab.png b/tools/assistant/tools/assistant/images/mac/closetab.png
new file mode 100644
index 0000000000..ab9d669eee
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/closetab.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/editcopy.png b/tools/assistant/tools/assistant/images/mac/editcopy.png
new file mode 100644
index 0000000000..f551364464
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/editcopy.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/find.png b/tools/assistant/tools/assistant/images/mac/find.png
new file mode 100644
index 0000000000..3561745f01
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/find.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/home.png b/tools/assistant/tools/assistant/images/mac/home.png
new file mode 100644
index 0000000000..78d94da18d
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/home.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/next.png b/tools/assistant/tools/assistant/images/mac/next.png
new file mode 100644
index 0000000000..a585cab80c
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/next.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/previous.png b/tools/assistant/tools/assistant/images/mac/previous.png
new file mode 100644
index 0000000000..612fb34dce
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/previous.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/print.png b/tools/assistant/tools/assistant/images/mac/print.png
new file mode 100644
index 0000000000..10ca56c82a
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/print.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/resetzoom.png b/tools/assistant/tools/assistant/images/mac/resetzoom.png
new file mode 100644
index 0000000000..759b382968
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/resetzoom.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/synctoc.png b/tools/assistant/tools/assistant/images/mac/synctoc.png
new file mode 100644
index 0000000000..067fa941b5
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/synctoc.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/zoomin.png b/tools/assistant/tools/assistant/images/mac/zoomin.png
new file mode 100644
index 0000000000..d46f5aff0d
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/zoomin.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/mac/zoomout.png b/tools/assistant/tools/assistant/images/mac/zoomout.png
new file mode 100644
index 0000000000..46326566d1
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/mac/zoomout.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/trolltech-logo.png b/tools/assistant/tools/assistant/images/trolltech-logo.png
new file mode 100644
index 0000000000..c53e744cab
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/trolltech-logo.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/addtab.png b/tools/assistant/tools/assistant/images/win/addtab.png
new file mode 100644
index 0000000000..4bb0feb92d
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/addtab.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/book.png b/tools/assistant/tools/assistant/images/win/book.png
new file mode 100644
index 0000000000..09ec4d33f7
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/book.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/closetab.png b/tools/assistant/tools/assistant/images/win/closetab.png
new file mode 100644
index 0000000000..ef9e02086c
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/closetab.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/editcopy.png b/tools/assistant/tools/assistant/images/win/editcopy.png
new file mode 100644
index 0000000000..1121b47d8b
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/editcopy.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/find.png b/tools/assistant/tools/assistant/images/win/find.png
new file mode 100644
index 0000000000..6ea35e930d
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/find.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/home.png b/tools/assistant/tools/assistant/images/win/home.png
new file mode 100644
index 0000000000..b1c6ae1913
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/home.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/next.png b/tools/assistant/tools/assistant/images/win/next.png
new file mode 100644
index 0000000000..8df4127a00
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/next.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/previous.png b/tools/assistant/tools/assistant/images/win/previous.png
new file mode 100644
index 0000000000..0780bc23dd
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/previous.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/print.png b/tools/assistant/tools/assistant/images/win/print.png
new file mode 100644
index 0000000000..ba7c02dc18
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/print.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/resetzoom.png b/tools/assistant/tools/assistant/images/win/resetzoom.png
new file mode 100644
index 0000000000..b69ae4e7fe
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/resetzoom.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/synctoc.png b/tools/assistant/tools/assistant/images/win/synctoc.png
new file mode 100644
index 0000000000..da301bc599
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/synctoc.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/zoomin.png b/tools/assistant/tools/assistant/images/win/zoomin.png
new file mode 100644
index 0000000000..2e586fc7bf
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/zoomin.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/win/zoomout.png b/tools/assistant/tools/assistant/images/win/zoomout.png
new file mode 100644
index 0000000000..a736d39343
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/win/zoomout.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/images/wrap.png b/tools/assistant/tools/assistant/images/wrap.png
new file mode 100644
index 0000000000..90f18d9f77
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/wrap.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/indexwindow.cpp b/tools/assistant/tools/assistant/indexwindow.cpp
new file mode 100644
index 0000000000..e7575fa140
--- /dev/null
+++ b/tools/assistant/tools/assistant/indexwindow.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** 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 "indexwindow.h"
+#include "centralwidget.h"
+#include "topicchooser.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QListWidgetItem>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexWidget>
+
+QT_BEGIN_NAMESPACE
+
+IndexWindow::IndexWindow(QHelpEngine *helpEngine, QWidget *parent)
+ : QWidget(parent)
+ , m_searchLineEdit(0)
+ , m_indexWidget(0)
+ , m_helpEngine(helpEngine)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QLabel *l = new QLabel(tr("&Look for:"));
+ layout->addWidget(l);
+
+ m_searchLineEdit = new QLineEdit();
+ l->setBuddy(m_searchLineEdit);
+ connect(m_searchLineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(filterIndices(QString)));
+ m_searchLineEdit->installEventFilter(this);
+ layout->setMargin(4);
+ layout->addWidget(m_searchLineEdit);
+
+ m_indexWidget = m_helpEngine->indexWidget();
+ m_indexWidget->installEventFilter(this);
+ connect(m_helpEngine->indexModel(), SIGNAL(indexCreationStarted()), this,
+ SLOT(disableSearchLineEdit()));
+ connect(m_helpEngine->indexModel(), SIGNAL(indexCreated()), this,
+ SLOT(enableSearchLineEdit()));
+ connect(m_indexWidget, SIGNAL(linkActivated(QUrl, QString)), this,
+ SIGNAL(linkActivated(QUrl)));
+ connect(m_indexWidget, SIGNAL(linksActivated(QMap<QString, QUrl>, QString)),
+ this, SIGNAL(linksActivated(QMap<QString, QUrl>, QString)));
+ connect(m_searchLineEdit, SIGNAL(returnPressed()), m_indexWidget,
+ SLOT(activateCurrentItem()));
+ layout->addWidget(m_indexWidget);
+
+ m_indexWidget->viewport()->installEventFilter(this);
+}
+
+IndexWindow::~IndexWindow()
+{
+}
+
+void IndexWindow::filterIndices(const QString &filter)
+{
+ if (filter.contains(QLatin1Char('*')))
+ m_indexWidget->filterIndices(filter, filter);
+ else
+ m_indexWidget->filterIndices(filter, QString());
+}
+
+bool IndexWindow::eventFilter(QObject *obj, QEvent *e)
+{
+ if (obj == m_searchLineEdit && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ QModelIndex idx = m_indexWidget->currentIndex();
+ switch (ke->key()) {
+ case Qt::Key_Up:
+ idx = m_indexWidget->model()->index(idx.row()-1,
+ idx.column(), idx.parent());
+ if (idx.isValid())
+ m_indexWidget->setCurrentIndex(idx);
+ break;
+ case Qt::Key_Down:
+ idx = m_indexWidget->model()->index(idx.row()+1,
+ idx.column(), idx.parent());
+ if (idx.isValid())
+ m_indexWidget->setCurrentIndex(idx);
+ break;
+ case Qt::Key_Escape:
+ emit escapePressed();
+ break;
+ default:
+ ;
+ }
+ } else if (obj == m_indexWidget && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *ctxtEvent = static_cast<QContextMenuEvent*>(e);
+ QModelIndex idx = m_indexWidget->indexAt(ctxtEvent->pos());
+ if (idx.isValid()) {
+ QMenu menu;
+ QAction *curTab = menu.addAction(tr("Open Link"));
+ QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
+ menu.move(m_indexWidget->mapToGlobal(ctxtEvent->pos()));
+
+ QAction *action = menu.exec();
+ if (curTab == action)
+ m_indexWidget->activateCurrentItem();
+ else if (newTab == action) {
+ QHelpIndexModel *model =
+ qobject_cast<QHelpIndexModel*>(m_indexWidget->model());
+ QString keyword = model->data(idx, Qt::DisplayRole).toString();
+ if (model) {
+ QMap<QString, QUrl> links = model->linksForKeyword(keyword);
+ if (links.count() == 1) {
+ CentralWidget::instance()->
+ setSourceInNewTab(links.constBegin().value());
+ } else {
+ TopicChooser tc(this, keyword, links);
+ if (tc.exec() == QDialog::Accepted) {
+ CentralWidget::instance()->setSourceInNewTab(tc.link());
+ }
+ }
+ }
+ }
+ }
+ } else if (m_indexWidget && obj == m_indexWidget->viewport()
+ && e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
+ QModelIndex idx = m_indexWidget->indexAt(mouseEvent->pos());
+ if (idx.isValid() && mouseEvent->button()==Qt::MidButton) {
+ QHelpIndexModel *model =
+ qobject_cast<QHelpIndexModel*>(m_indexWidget->model());
+ QString keyword = model->data(idx, Qt::DisplayRole).toString();
+ if (model) {
+ QMap<QString, QUrl> links = model->linksForKeyword(keyword);
+ if (links.count() > 1) {
+ TopicChooser tc(this, keyword, links);
+ if (tc.exec() == QDialog::Accepted) {
+ CentralWidget::instance()->setSourceInNewTab(tc.link());
+ }
+ } else if (links.count() == 1) {
+ CentralWidget::instance()->
+ setSourceInNewTab(links.constBegin().value());
+ }
+ }
+ }
+ }
+#ifdef Q_OS_MAC
+ else if (obj == m_indexWidget && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)
+ m_indexWidget->activateCurrentItem();
+ }
+#endif
+ return QWidget::eventFilter(obj, e);
+}
+
+void IndexWindow::enableSearchLineEdit()
+{
+ m_searchLineEdit->setDisabled(false);
+ filterIndices(m_searchLineEdit->text());
+}
+
+void IndexWindow::disableSearchLineEdit()
+{
+ m_searchLineEdit->setDisabled(true);
+}
+
+void IndexWindow::setSearchLineEditText(const QString &text)
+{
+ m_searchLineEdit->setText(text);
+}
+
+void IndexWindow::focusInEvent(QFocusEvent *e)
+{
+ if (e->reason() != Qt::MouseFocusReason) {
+ m_searchLineEdit->selectAll();
+ m_searchLineEdit->setFocus();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/indexwindow.h b/tools/assistant/tools/assistant/indexwindow.h
new file mode 100644
index 0000000000..f1f57f9442
--- /dev/null
+++ b/tools/assistant/tools/assistant/indexwindow.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 INDEXWINDOW_H
+#define INDEXWINDOW_H
+
+#include <QtCore/QUrl>
+#include <QtGui/QWidget>
+#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpIndexWidget;
+class QHelpEngine;
+
+class IndexWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0);
+ ~IndexWindow();
+
+ void setSearchLineEditText(const QString &text);
+ QString searchLineEditText() const
+ {
+ return m_searchLineEdit->text();
+ }
+
+signals:
+ void linkActivated(const QUrl &link);
+ void linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword);
+ void escapePressed();
+
+private slots:
+ void filterIndices(const QString &filter);
+ void enableSearchLineEdit();
+ void disableSearchLineEdit();
+
+private:
+ bool eventFilter(QObject *obj, QEvent *e);
+ void focusInEvent(QFocusEvent *e);
+
+ QLineEdit *m_searchLineEdit;
+ QHelpIndexWidget *m_indexWidget;
+ QHelpEngine *m_helpEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif // INDEXWINDOW_H
diff --git a/tools/assistant/tools/assistant/installdialog.cpp b/tools/assistant/tools/assistant/installdialog.cpp
new file mode 100644
index 0000000000..1f02ac1b1c
--- /dev/null
+++ b/tools/assistant/tools/assistant/installdialog.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** 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 "installdialog.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QUrl>
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QCryptographicHash>
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+
+#include <QtHelp/QHelpEngineCore>
+
+#include <QtNetwork/QHttp>
+
+QT_BEGIN_NAMESPACE
+
+#define QCH_FILENAME 92943
+#define QCH_NAMESPACE 92944
+#define QCH_CHECKSUM 92945
+
+InstallDialog::InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent,
+ const QString &host, int port)
+ : QDialog(parent), m_helpEngine(helpEngine), m_host(host), m_port(port)
+{
+ m_ui.setupUi(this);
+
+ m_ui.installButton->setEnabled(false);
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.pathLineEdit->setText(QFileInfo(m_helpEngine->collectionFile()).absolutePath());
+ m_ui.progressBar->hide();
+
+ m_windowTitle = tr("Install Documentation");
+
+ m_http = new QHttp(this);
+ connect(m_http, SIGNAL(requestFinished(int, bool)),
+ this, SLOT(httpRequestFinished(int, bool)));
+ connect(m_http, SIGNAL(dataReadProgress(int, int)),
+ this, SLOT(updateDataReadProgress(int, int)));
+ connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
+ this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
+ connect(m_ui.installButton, SIGNAL(clicked()), this, SLOT(install()));
+ connect(m_ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelDownload()));
+ connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseDirectories()));
+
+ connect(m_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
+ this, SLOT(updateInstallButton()));
+
+ QTimer::singleShot(0, this, SLOT(init()));
+}
+
+InstallDialog::~InstallDialog()
+{
+}
+
+QStringList InstallDialog::installedDocumentations() const
+{
+ return m_installedDocumentations;
+}
+
+void InstallDialog::init()
+{
+ m_ui.statusLabel->setText(tr("Downloading documentation info..."));
+ m_ui.progressBar->show();
+
+ QUrl url(QLatin1String("http://doc.trolltech.com/assistantdocs/docs.txt"));
+ m_buffer = new QBuffer();
+ m_buffer->open(QBuffer::ReadWrite);
+
+ if (m_port > -1)
+ m_http->setProxy(m_host, m_port);
+ m_http->setHost(url.host());
+ m_httpAborted = false;
+ m_docInfoId = m_http->get(url.path(), m_buffer);
+
+ m_ui.cancelButton->setEnabled(true);
+ m_ui.closeButton->setEnabled(false);
+}
+
+void InstallDialog::updateInstallButton()
+{
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ if (item->checkState() == Qt::Checked
+ && item->flags() & Qt::ItemIsEnabled) {
+ m_ui.installButton->setEnabled(true);
+ return;
+ }
+ }
+ m_ui.installButton->setEnabled(false);
+}
+
+void InstallDialog::updateDocItemList()
+{
+ QStringList registeredDocs = m_helpEngine->registeredDocumentations();
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ QString ns = item->data(QCH_NAMESPACE).toString();
+ if (!ns.isEmpty() && registeredDocs.contains(ns)) {
+ item->setFlags(Qt::ItemIsUserCheckable);
+ item->setCheckState(Qt::Checked);
+ }
+ item->setCheckState(Qt::Unchecked);
+ }
+}
+
+void InstallDialog::cancelDownload()
+{
+ m_ui.statusLabel->setText(tr("Download canceled."));
+ m_httpAborted = true;
+ m_itemsToInstall.clear();
+ m_http->abort();
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ updateInstallButton();
+}
+
+void InstallDialog::install()
+{
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ if (item->checkState() == Qt::Checked)
+ m_itemsToInstall.append(item);
+ }
+ m_ui.installButton->setEnabled(false);
+ downloadNextFile();
+}
+
+void InstallDialog::downloadNextFile()
+{
+ if (!m_itemsToInstall.count()) {
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ m_ui.statusLabel->setText(tr("Done."));
+ m_ui.progressBar->hide();
+ updateDocItemList();
+ updateInstallButton();
+ return;
+ }
+
+ QListWidgetItem *item = m_itemsToInstall.dequeue();
+ m_currentCheckSum = item->data(QCH_CHECKSUM).toString();
+ QString fileName = item->data(QCH_FILENAME).toString();
+ QString saveFileName = m_ui.pathLineEdit->text() + QDir::separator()
+ + fileName;
+
+ if (QFile::exists(saveFileName)
+ && QMessageBox::information(this, m_windowTitle,
+ tr("The file %1 already exists. Do you want to overwrite it?")
+ .arg(saveFileName), QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::Yes) == QMessageBox::No) {
+ installFile(saveFileName);
+ downloadNextFile();
+ return;
+ }
+
+ m_file = new QFile(saveFileName);
+ if (!m_file->open(QIODevice::WriteOnly|QIODevice::Truncate)) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Unable to save the file %1: %2.")
+ .arg(saveFileName).arg(m_file->errorString()));
+ delete m_file;
+ m_file = 0;
+ downloadNextFile();
+ return;
+ }
+
+ m_ui.statusLabel->setText(tr("Downloading %1...").arg(fileName));
+ m_ui.progressBar->show();
+
+ QLatin1String urlStr("http://doc.trolltech.com/assistantdocs/%1");
+ QUrl url(QString(urlStr).arg(fileName));
+
+ m_httpAborted = false;
+ m_docId = m_http->get(url.path(), m_file);
+
+ m_ui.cancelButton->setEnabled(true);
+ m_ui.closeButton->setEnabled(false);
+}
+
+void InstallDialog::httpRequestFinished(int requestId, bool error)
+{
+ if (requestId == m_docInfoId && m_buffer) {
+ m_ui.progressBar->hide();
+ if (error) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(m_http->errorString()));
+ } else if (!m_httpAborted) {
+ QStringList registeredDocs = m_helpEngine->registeredDocumentations();
+ m_buffer->seek(0);
+ while (m_buffer->canReadLine()) {
+ QByteArray ba = m_buffer->readLine();
+ QStringList lst = QString::fromAscii(ba.constData()).split(QLatin1Char('|'));
+ if (lst.count() != 4) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Documentation info file is corrupt!"));
+ } else {
+ QListWidgetItem *item = new QListWidgetItem(m_ui.listWidget);
+ item->setText(lst.at(2).trimmed());
+ item->setData(QCH_FILENAME, lst.first());
+ item->setData(QCH_NAMESPACE, lst.at(1));
+ item->setData(QCH_CHECKSUM, lst.last().trimmed());
+ }
+ }
+ updateDocItemList();
+ }
+ if (m_buffer)
+ m_buffer->close();
+ delete m_buffer;
+ m_buffer = 0;
+ m_ui.statusLabel->setText(tr("Done."));
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ updateInstallButton();
+ } else if (requestId == m_docId) {
+ m_file->close();
+ if (!m_httpAborted) {
+ QString checkSum;
+ if (m_file->open(QIODevice::ReadOnly)) {
+ QByteArray digest = QCryptographicHash::hash(m_file->readAll(),
+ QCryptographicHash::Md5);
+ m_file->close();
+ checkSum = QString::fromLatin1(digest.toHex());
+ }
+ if (error) {
+ m_file->remove();
+ QMessageBox::warning(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(m_http->errorString()));
+ } else if (checkSum.isEmpty() || m_currentCheckSum != checkSum) {
+ m_file->remove();
+ QMessageBox::warning(this, m_windowTitle,
+ tr("Download failed: Downloaded file is corrupted."));
+ } else {
+ m_ui.statusLabel->setText(tr("Installing documentation %1...")
+ .arg(QFileInfo(m_file->fileName()).fileName()));
+ m_ui.progressBar->setMaximum(0);
+ m_ui.statusLabel->setText(tr("Done."));
+ installFile(m_file->fileName());
+ }
+ } else {
+ m_file->remove();
+ }
+ delete m_file;
+ m_file = 0;
+ downloadNextFile();
+ }
+}
+
+void InstallDialog::installFile(const QString &fileName)
+{
+ if (m_helpEngine->registerDocumentation(fileName)) {
+ m_installedDocumentations
+ .append(QHelpEngineCore::namespaceName(fileName));
+ } else {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Error while installing documentation:\n%1")
+ .arg(m_helpEngine->error()));
+ }
+}
+
+void InstallDialog::readResponseHeader(const QHttpResponseHeader &responseHeader)
+{
+ if (responseHeader.statusCode() != 200) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(responseHeader.reasonPhrase()));
+ m_httpAborted = true;
+ m_ui.progressBar->hide();
+ m_http->abort();
+ return;
+ }
+}
+
+void InstallDialog::updateDataReadProgress(int bytesRead, int totalBytes)
+{
+ if (m_httpAborted)
+ return;
+
+ m_ui.progressBar->setMaximum(totalBytes);
+ m_ui.progressBar->setValue(bytesRead);
+}
+
+void InstallDialog::browseDirectories()
+{
+ QString dir = QFileDialog::getExistingDirectory(this, m_windowTitle,
+ m_ui.pathLineEdit->text());
+ if (!dir.isEmpty())
+ m_ui.pathLineEdit->setText(dir);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/installdialog.h b/tools/assistant/tools/assistant/installdialog.h
new file mode 100644
index 0000000000..88c882ca7c
--- /dev/null
+++ b/tools/assistant/tools/assistant/installdialog.h
@@ -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$
+**
+****************************************************************************/
+
+#ifndef INSTALLDIALOG_H
+#define INSTALLDIALOG_H
+
+#include <QtCore/QQueue>
+#include <QtGui/QDialog>
+#include <QtNetwork/QHttpResponseHeader>
+#include "ui_installdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class QHttp;
+class QBuffer;
+class QFile;
+class QHelpEngineCore;
+
+class InstallDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0,
+ const QString &host = QString(), int port = -1);
+ ~InstallDialog();
+
+ QStringList installedDocumentations() const;
+
+private slots:
+ void init();
+ void cancelDownload();
+ void install();
+ void httpRequestFinished(int requestId, bool error);
+ void readResponseHeader(const QHttpResponseHeader &responseHeader);
+ void updateDataReadProgress(int bytesRead, int totalBytes);
+ void updateInstallButton();
+ void browseDirectories();
+
+private:
+ void downloadNextFile();
+ void updateDocItemList();
+ void installFile(const QString &fileName);
+
+ Ui::InstallDialog m_ui;
+ QHelpEngineCore *m_helpEngine;
+ QHttp *m_http;
+ QBuffer *m_buffer;
+ QFile *m_file;
+ bool m_httpAborted;
+ int m_docInfoId;
+ int m_docId;
+ QQueue<QListWidgetItem*> m_itemsToInstall;
+ QString m_currentCheckSum;
+ QString m_windowTitle;
+ QStringList m_installedDocumentations;
+ QString m_host;
+ int m_port;
+};
+
+QT_END_NAMESPACE
+
+#endif // INSTALLDIALOG_H
diff --git a/tools/assistant/tools/assistant/installdialog.ui b/tools/assistant/tools/assistant/installdialog.ui
new file mode 100644
index 0000000000..21a05da77e
--- /dev/null
+++ b/tools/assistant/tools/assistant/installdialog.ui
@@ -0,0 +1,118 @@
+<ui version="4.0" >
+ <class>InstallDialog</class>
+ <widget class="QDialog" name="InstallDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>436</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Install Documentation</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="4" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Available Documentation:</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="4" row="1" column="0" colspan="4" >
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ <item row="1" column="4" >
+ <widget class="QPushButton" name="installButton" >
+ <property name="text" >
+ <string>Install</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4" >
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>56</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Installation Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="2" >
+ <widget class="QLineEdit" name="pathLineEdit" />
+ </item>
+ <item row="5" column="3" >
+ <widget class="QToolButton" name="browseButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="5" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="2" >
+ <widget class="QLabel" name="statusLabel" />
+ </item>
+ <item row="7" column="2" colspan="3" >
+ <widget class="QProgressBar" name="progressBar" >
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>InstallDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>330</x>
+ <y>107</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>332</x>
+ <y>158</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp
new file mode 100644
index 0000000000..794be02a69
--- /dev/null
+++ b/tools/assistant/tools/assistant/main.cpp
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** 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 <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QLocale>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QUrl>
+#include <QtCore/QStringList>
+
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopServices>
+
+#include <QtHelp/QHelpEngineCore>
+
+#include <QtSql/QSqlDatabase>
+
+#include "mainwindow.h"
+#include "cmdlineparser.h"
+
+QT_USE_NAMESPACE
+
+#if defined(USE_STATIC_SQLITE_PLUGIN)
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN(qsqlite)
+#endif
+
+void
+updateLastPagesOnUnregister(QHelpEngineCore& helpEngine, const QString& nsName)
+{
+ int lastPage = helpEngine.customValue(QLatin1String("LastTabPage")).toInt();
+
+ QLatin1String sep("|");
+ QLatin1String pages("LastShownPages");
+#if !defined(QT_NO_WEBKIT)
+ QLatin1String zoom("LastPagesZoomWebView");
+#else
+ QLatin1String zoom("LastPagesZoomTextBrowser");
+#endif
+
+ QStringList currentPages =
+ helpEngine.customValue(pages).toString().
+ split(QLatin1Char('|'), QString::SkipEmptyParts);
+
+ if (!currentPages.isEmpty()) {
+ QVector<QString>zoomList = helpEngine.customValue(zoom).toString().
+ split(sep, QString::SkipEmptyParts).toVector();
+ if (zoomList.isEmpty())
+ zoomList.fill(QLatin1String("0.0"), currentPages.size());
+ else if(zoomList.count() < currentPages.count()) {
+ zoomList.insert(zoomList.count(),
+ currentPages.count() - zoomList.count(), QLatin1String("0.0"));
+ }
+
+ for (int i = currentPages.count(); --i >= 0;) {
+ if (QUrl(currentPages.at(i)).host() == nsName) {
+ zoomList.remove(i);
+ currentPages.removeAt(i);
+ lastPage = (lastPage == (i + 1)) ? 1 : lastPage;
+ }
+ }
+
+ helpEngine.setCustomValue(pages, currentPages.join(sep));
+ helpEngine.setCustomValue(QLatin1String("LastTabPage"), lastPage);
+ helpEngine.setCustomValue(zoom, QStringList(zoomList.toList()).join(sep));
+ }
+}
+
+bool
+updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller)
+{
+ const uint callerCollectionCreationTime = caller.
+ customValue(QLatin1String("CreationTime"), 0).toUInt();
+ const uint userCollectionCreationTime = user.
+ customValue(QLatin1String("CreationTime"), 1).toUInt();
+
+ if (callerCollectionCreationTime == userCollectionCreationTime)
+ return false;
+
+ user.setCustomValue(QLatin1String("CreationTime"),
+ callerCollectionCreationTime);
+ user.setCustomValue(QLatin1String("WindowTitle"),
+ caller.customValue(QLatin1String("WindowTitle")));
+ user.setCustomValue(QLatin1String("LastShownPages"),
+ caller.customValue(QLatin1String("LastShownPages")));
+ user.setCustomValue(QLatin1String("CurrentFilter"),
+ caller.customValue(QLatin1String("CurrentFilter")));
+ user.setCustomValue(QLatin1String("CacheDirectory"),
+ caller.customValue(QLatin1String("CacheDirectory")));
+ user.setCustomValue(QLatin1String("EnableFilterFunctionality"),
+ caller.customValue(QLatin1String("EnableFilterFunctionality")));
+ user.setCustomValue(QLatin1String("HideFilterFunctionality"),
+ caller.customValue(QLatin1String("HideFilterFunctionality")));
+ user.setCustomValue(QLatin1String("EnableDocumentationManager"),
+ caller.customValue(QLatin1String("EnableDocumentationManager")));
+ user.setCustomValue(QLatin1String("EnableAddressBar"),
+ caller.customValue(QLatin1String("EnableAddressBar")));
+ user.setCustomValue(QLatin1String("HideAddressBar"),
+ caller.customValue(QLatin1String("HideAddressBar")));
+ user.setCustomValue(QLatin1String("ApplicationIcon"),
+ caller.customValue(QLatin1String("ApplicationIcon")));
+ user.setCustomValue(QLatin1String("AboutMenuTexts"),
+ caller.customValue(QLatin1String("AboutMenuTexts")));
+ user.setCustomValue(QLatin1String("AboutIcon"),
+ caller.customValue(QLatin1String("AboutIcon")));
+ user.setCustomValue(QLatin1String("AboutTexts"),
+ caller.customValue(QLatin1String("AboutTexts")));
+ user.setCustomValue(QLatin1String("AboutImages"),
+ caller.customValue(QLatin1String("AboutImages")));
+
+ return true;
+}
+
+bool
+referencedHelpFilesExistAll(QHelpEngineCore& user, QStringList& nameSpaces)
+{
+ QFileInfo fi;
+ int counter = nameSpaces.count();
+ for (int i = counter; --i >= 0;) {
+ const QString& nameSpace = nameSpaces.at(i);
+ fi.setFile(user.documentationFileName(nameSpace));
+ if (!fi.exists() || !fi.isFile()) {
+ user.unregisterDocumentation(nameSpace);
+ nameSpaces.removeAll(nameSpace);
+ }
+ }
+ return (counter != nameSpaces.count()) ? false : true;
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins"));
+
+ CmdLineParser cmd;
+ CmdLineParser::Result res = cmd.parse(a.arguments());
+ if (res == CmdLineParser::Help)
+ return 0;
+ else if (res == CmdLineParser::Error)
+ return -1;
+
+ QString cmdCollectionFile = cmd.collectionFile();
+ if (cmd.registerRequest() != CmdLineParser::None) {
+ if (cmdCollectionFile.isEmpty())
+ cmdCollectionFile = MainWindow::defaultHelpCollectionFileName();
+ QHelpEngineCore help(cmdCollectionFile);
+ help.setupData();
+ if (cmd.registerRequest() == CmdLineParser::Register) {
+ if (!help.registerDocumentation(cmd.helpFile())) {
+ cmd.showMessage(
+ QObject::tr("Could not register documentation file\n%1\n\nReason:\n%2")
+ .arg(cmd.helpFile()).arg(help.error()), true);
+ return -1;
+ } else {
+ cmd.showMessage(QObject::tr("Documentation successfully registered."),
+ false);
+ }
+ } else {
+ QString nsName = QHelpEngineCore::namespaceName(cmd.helpFile());
+ if (help.unregisterDocumentation(nsName)) {
+ updateLastPagesOnUnregister(help, nsName);
+ cmd.showMessage(
+ QObject::tr("Documentation successfully unregistered."),
+ false);
+ } else {
+ cmd.showMessage(QObject::tr("Could not unregister documentation"
+ " file\n%1\n\nReason:\n%2").arg(cmd.helpFile()).
+ arg(help.error()), true);
+ return -1;
+ }
+ }
+ help.setCustomValue(QLatin1String("DocUpdate"), true);
+ return 0;
+ }
+
+ {
+ QSqlDatabase db;
+ QStringList sqlDrivers(db.drivers());
+ if (sqlDrivers.isEmpty()
+ || !sqlDrivers.contains(QLatin1String("QSQLITE"))) {
+ cmd.showMessage(QObject::tr("Cannot load sqlite database driver!"),
+ true);
+ return -1;
+ }
+ }
+
+ if (!cmdCollectionFile.isEmpty()) {
+ QHelpEngineCore caller(cmdCollectionFile);
+ if (!caller.setupData()) {
+ cmd.showMessage(QObject::tr("The specified collection file could "
+ "not be read!"), true);
+ return -1;
+ }
+
+ QString fileName = QFileInfo(cmdCollectionFile).fileName();
+ QString dir = MainWindow::collectionFileDirectory(false,
+ caller.customValue(QLatin1String("CacheDirectory"),
+ QString()).toString());
+
+ bool collectionFileExists = true;
+ QFileInfo fi(dir + QDir::separator() + fileName);
+ if (!fi.exists()) {
+ collectionFileExists = false;
+ if (!caller.copyCollectionFile(fi.absoluteFilePath())) {
+ cmd.showMessage(caller.error(), true);
+ return -1;
+ }
+ }
+
+ if (collectionFileExists) {
+ QHelpEngineCore user(fi.absoluteFilePath());
+ if (user.setupData()) {
+ // some docs might have been un/registered
+ bool docUpdate = caller.
+ customValue(QLatin1String("DocUpdate"), false).toBool();
+
+ // update in case the passed collection file changed
+ if (updateUserCollection(user, caller))
+ docUpdate = true;
+
+ QStringList userDocs = user.registeredDocumentations();
+ // update user collection file, docs might have been (re)moved
+ if (!referencedHelpFilesExistAll(user, userDocs))
+ docUpdate = true;
+
+ if (docUpdate) {
+ QStringList callerDocs = caller.registeredDocumentations();
+ foreach (const QString &doc, callerDocs) {
+ if (!userDocs.contains(doc)) {
+ user.registerDocumentation(
+ caller.documentationFileName(doc));
+ }
+ }
+
+ QLatin1String intern("com.trolltech.com.assistantinternal_");
+ foreach (const QString &doc, userDocs) {
+ if (!callerDocs.contains(doc) && !doc.startsWith(intern))
+ user.unregisterDocumentation(doc);
+ }
+
+ caller.setCustomValue(QLatin1String("DocUpdate"), false);
+ }
+ }
+ }
+ cmd.setCollectionFile(fi.absoluteFilePath());
+ }
+
+ if (!cmd.currentFilter().isEmpty()) {
+ QString collectionFile;
+ if (cmdCollectionFile.isEmpty()) {
+ MainWindow::collectionFileDirectory(true);
+ cmdCollectionFile = MainWindow::defaultHelpCollectionFileName();
+ }
+
+ QHelpEngineCore user(cmdCollectionFile);
+ if (user.setupData())
+ user.setCurrentFilter(cmd.currentFilter());
+ }
+
+ const QString& locale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+
+ QTranslator translator(0);
+ translator.load(QLatin1String("assistant_") + locale, resourceDir);
+ a.installTranslator(&translator);
+
+ QTranslator qtTranslator(0);
+ qtTranslator.load(QLatin1String("qt_") + locale, resourceDir);
+ a.installTranslator(&qtTranslator);
+
+ QTranslator qtHelpTranslator(0);
+ qtHelpTranslator.load(QLatin1String("qt_help_") + locale, resourceDir);
+ a.installTranslator(&qtHelpTranslator);
+
+ MainWindow w(&cmd);
+ w.show();
+ a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+ return a.exec();
+}
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
new file mode 100644
index 0000000000..0f246bead0
--- /dev/null
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -0,0 +1,1008 @@
+/****************************************************************************
+**
+** 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 "centralwidget.h"
+#include "helpviewer.h"
+#include "indexwindow.h"
+#include "topicchooser.h"
+#include "contentwindow.h"
+#include "preferencesdialog.h"
+#include "bookmarkmanager.h"
+#include "remotecontrol.h"
+#include "cmdlineparser.h"
+#include "aboutdialog.h"
+#include "searchwidget.h"
+#include "qtdocinstaller.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+#include <QtCore/QResource>
+#include <QtCore/QByteArray>
+#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+#include <QtGui/QMenuBar>
+#include <QtGui/QAction>
+#include <QtGui/QToolBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QLayout>
+#include <QtGui/QDockWidget>
+#include <QtGui/QTreeView>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QComboBox>
+#include <QtGui/QProgressBar>
+#include <QtGui/QDesktopServices>
+#include <QtGui/QToolButton>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpSearchEngine>
+#include <QtHelp/QHelpContentModel>
+#include <QtHelp/QHelpIndexModel>
+
+QT_BEGIN_NAMESPACE
+
+MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
+ : QMainWindow(parent)
+ , m_toolBarMenu(0)
+ , m_cmdLine(cmdLine)
+ , m_searchWidget(0)
+ , m_progressWidget(0)
+ , m_qtDocInstaller(0)
+ , m_connectedInitSignals(false)
+{
+ if (usesDefaultCollection()) {
+ MainWindow::collectionFileDirectory(true);
+ m_helpEngine = new QHelpEngine(MainWindow::defaultHelpCollectionFileName(),
+ this);
+ } else {
+ m_helpEngine = new QHelpEngine(cmdLine->collectionFile(), this);
+ }
+
+ m_centralWidget = new CentralWidget(m_helpEngine, this);
+ setCentralWidget(m_centralWidget);
+
+ m_indexWindow = new IndexWindow(m_helpEngine);
+ QDockWidget *indexDock = new QDockWidget(tr("Index"), this);
+ indexDock->setObjectName(QLatin1String("IndexWindow"));
+ indexDock->setWidget(m_indexWindow);
+ addDockWidget(Qt::LeftDockWidgetArea, indexDock);
+
+ m_contentWindow = new ContentWindow(m_helpEngine);
+ QDockWidget *contentDock = new QDockWidget(tr("Contents"), this);
+ contentDock->setObjectName(QLatin1String("ContentWindow"));
+ contentDock->setWidget(m_contentWindow);
+ addDockWidget(Qt::LeftDockWidgetArea, contentDock);
+
+ QDockWidget *bookmarkDock = new QDockWidget(tr("Bookmarks"), this);
+ bookmarkDock->setObjectName(QLatin1String("BookmarkWindow"));
+ bookmarkDock->setWidget(setupBookmarkWidget());
+ addDockWidget(Qt::LeftDockWidgetArea, bookmarkDock);
+
+ QHelpSearchEngine *searchEngine = m_helpEngine->searchEngine();
+ connect(searchEngine, SIGNAL(indexingStarted()), this, SLOT(indexingStarted()));
+ connect(searchEngine, SIGNAL(indexingFinished()), this, SLOT(indexingFinished()));
+
+#ifdef QT_CLUCENE_SUPPORT
+ m_centralWidget->createSearchWidget(searchEngine);
+#else
+ QDockWidget *dock = new QDockWidget(tr("Search"), this);
+ dock->setObjectName(QLatin1String("SearchWindow"));
+ m_searchWidget = new SearchWidget(searchEngine, this);
+ dock->setWidget(m_searchWidget);
+ addDockWidget(Qt::LeftDockWidgetArea, dock);
+
+ connect(m_searchWidget, SIGNAL(requestShowLink(const QUrl&)),
+ m_centralWidget, SLOT(setSource(const QUrl&)));
+ connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(const QUrl&)),
+ m_centralWidget, SLOT(setSourceInNewTab(const QUrl&)));
+#endif
+
+ QString defWindowTitle = tr("Qt Assistant");
+ setWindowTitle(defWindowTitle);
+
+ setupActions();
+ statusBar()->show();
+
+ if (initHelpDB()) {
+ setupFilterToolbar();
+ setupAddressToolbar();
+ m_bookmarkManager->setupBookmarkModels();
+
+ setWindowTitle(m_helpEngine->customValue(QLatin1String("WindowTitle"),
+ defWindowTitle).toString());
+ QByteArray iconArray = m_helpEngine->customValue(QLatin1String("ApplicationIcon"),
+ QByteArray()).toByteArray();
+ if (iconArray.size() > 0) {
+ QPixmap pix;
+ pix.loadFromData(iconArray);
+ QIcon appIcon(pix);
+ qApp->setWindowIcon(appIcon);
+ } else {
+ QIcon appIcon(QLatin1String(":/trolltech/assistant/images/assistant-128.png"));
+ qApp->setWindowIcon(appIcon);
+ }
+
+ // Show the widget here, otherwise the restore geometry and state won't work
+ // on x11.
+ show();
+ QByteArray ba(m_helpEngine->customValue(QLatin1String("MainWindow")).toByteArray());
+ if (!ba.isEmpty())
+ restoreState(ba);
+
+ ba = m_helpEngine->customValue(QLatin1String("MainWindowGeometry")).toByteArray();
+ if (!ba.isEmpty()) {
+ restoreGeometry(ba);
+ } else {
+ tabifyDockWidget(contentDock, indexDock);
+ tabifyDockWidget(indexDock, bookmarkDock);
+ contentDock->raise();
+ resize(QSize(800, 600));
+ }
+
+ if (!m_helpEngine->customValue(QLatin1String("useAppFont")).isValid()) {
+ m_helpEngine->setCustomValue(QLatin1String("useAppFont"), false);
+ m_helpEngine->setCustomValue(QLatin1String("useBrowserFont"), false);
+ m_helpEngine->setCustomValue(QLatin1String("appFont"), qApp->font());
+ m_helpEngine->setCustomValue(QLatin1String("appWritingSystem"), QFontDatabase::Latin);
+ m_helpEngine->setCustomValue(QLatin1String("browserFont"), qApp->font());
+ m_helpEngine->setCustomValue(QLatin1String("browserWritingSystem"), QFontDatabase::Latin);
+ } else {
+ updateApplicationFont();
+ }
+
+ updateAboutMenuText();
+
+ QTimer::singleShot(0, this, SLOT(insertLastPages()));
+ if (m_cmdLine->enableRemoteControl())
+ (void)new RemoteControl(this, m_helpEngine);
+
+ if (m_cmdLine->contents() == CmdLineParser::Show)
+ showContents();
+ else if (m_cmdLine->contents() == CmdLineParser::Hide)
+ hideContents();
+
+ if (m_cmdLine->index() == CmdLineParser::Show)
+ showIndex();
+ else if (m_cmdLine->index() == CmdLineParser::Hide)
+ hideIndex();
+
+ if (m_cmdLine->bookmarks() == CmdLineParser::Show)
+ showBookmarks();
+ else if (m_cmdLine->bookmarks() == CmdLineParser::Hide)
+ hideBookmarks();
+
+ if (m_cmdLine->search() == CmdLineParser::Show)
+ showSearch();
+ else if (m_cmdLine->search() == CmdLineParser::Hide)
+ hideSearch();
+
+ if (m_cmdLine->contents() == CmdLineParser::Activate)
+ showContents();
+ else if (m_cmdLine->index() == CmdLineParser::Activate)
+ showIndex();
+ else if (m_cmdLine->bookmarks() == CmdLineParser::Activate)
+ showBookmarks();
+
+ if (usesDefaultCollection())
+ QTimer::singleShot(0, this, SLOT(lookForNewQtDocumentation()));
+ else
+ checkInitState();
+ }
+}
+
+MainWindow::~MainWindow()
+{
+ if (m_qtDocInstaller)
+ delete m_qtDocInstaller;
+}
+
+bool MainWindow::usesDefaultCollection() const
+{
+ return m_cmdLine->collectionFile().isEmpty();
+}
+
+void MainWindow::closeEvent(QCloseEvent *e)
+{
+ m_bookmarkManager->saveBookmarks();
+ m_helpEngine->setCustomValue(QLatin1String("MainWindow"), saveState());
+ m_helpEngine->setCustomValue(QLatin1String("MainWindowGeometry"),
+ saveGeometry());
+
+ QMainWindow::closeEvent(e);
+}
+
+bool MainWindow::initHelpDB()
+{
+ if (!m_helpEngine->setupData())
+ return false;
+
+ bool assistantInternalDocRegistered = false;
+ QString intern(QLatin1String("com.trolltech.com.assistantinternal_"));
+ foreach (const QString &ns, m_helpEngine->registeredDocumentations()) {
+ if (ns.startsWith(intern)) {
+ intern = ns;
+ assistantInternalDocRegistered = true;
+ break;
+ }
+ }
+
+ const QString &collectionFile = m_helpEngine->collectionFile();
+
+ QFileInfo fi(collectionFile);
+ QString helpFile;
+ QTextStream(&helpFile) << fi.absolutePath() << QDir::separator()
+ << QLatin1String("assistant.qch.") << (QT_VERSION >> 16)
+ << QLatin1Char('.') << ((QT_VERSION >> 8) & 0xFF);
+
+ bool needsSetup = false;
+ if (!assistantInternalDocRegistered || !QFile::exists(helpFile)) {
+ QFile file(helpFile);
+ if (file.open(QIODevice::WriteOnly)) {
+ QResource res(QLatin1String(":/trolltech/assistant/assistant.qch"));
+ if (file.write((const char*)res.data(), res.size()) != res.size())
+ qDebug() << QLatin1String("could not write assistant.qch...");
+
+ file.close();
+ }
+ QHelpEngineCore hc(fi.absoluteFilePath());
+ hc.setupData();
+ hc.unregisterDocumentation(intern);
+ hc.registerDocumentation(helpFile);
+ needsSetup = true;
+ }
+
+ const QLatin1String unfiltered("UnfilteredFilterInserted");
+ if (1 != m_helpEngine->customValue(unfiltered).toInt()) {
+ {
+ QHelpEngineCore hc(collectionFile);
+ hc.setupData();
+ hc.addCustomFilter(tr("Unfiltered"), QStringList());
+ hc.setCustomValue(unfiltered, 1);
+ }
+ m_helpEngine->blockSignals(true);
+ m_helpEngine->setCurrentFilter(tr("Unfiltered"));
+ m_helpEngine->blockSignals(false);
+ needsSetup = true;
+ }
+
+ if (needsSetup)
+ m_helpEngine->setupData();
+ return true;
+}
+
+void MainWindow::lookForNewQtDocumentation()
+{
+ m_qtDocInstaller = new QtDocInstaller(m_helpEngine->collectionFile());
+ connect(m_qtDocInstaller, SIGNAL(errorMessage(const QString&)),
+ this, SLOT(displayInstallationError(const QString&)));
+ connect(m_qtDocInstaller, SIGNAL(docsInstalled(bool)),
+ this, SLOT(qtDocumentationInstalled(bool)));
+
+ QString versionKey = QString(QLatin1String("qtVersion%1$$$qt")).
+ arg(QLatin1String(QT_VERSION_STR));
+ if (m_helpEngine->customValue(versionKey, 0).toInt() != 1)
+ statusBar()->showMessage(tr("Looking for Qt Documentation..."));
+ m_qtDocInstaller->installDocs();
+}
+
+void MainWindow::displayInstallationError(const QString &errorMessage)
+{
+ QMessageBox::warning(this, tr("Qt Assistant"), errorMessage);
+}
+
+void MainWindow::qtDocumentationInstalled(bool newDocsInstalled)
+{
+ if (newDocsInstalled)
+ m_helpEngine->setupData();
+ statusBar()->clearMessage();
+ checkInitState();
+}
+
+void MainWindow::checkInitState()
+{
+ if (!m_cmdLine->enableRemoteControl())
+ return;
+
+ if (m_helpEngine->contentModel()->isCreatingContents()
+ || m_helpEngine->indexModel()->isCreatingIndex()) {
+ if (!m_connectedInitSignals) {
+ connect(m_helpEngine->contentModel(), SIGNAL(contentsCreated()),
+ this, SLOT(checkInitState()));
+ connect(m_helpEngine->indexModel(), SIGNAL(indexCreated()),
+ this, SLOT(checkInitState()));
+ m_connectedInitSignals = true;
+ }
+ } else {
+ if (m_connectedInitSignals) {
+ disconnect(m_helpEngine->contentModel(), 0, this, 0);
+ disconnect(m_helpEngine->indexModel(), 0, this, 0);
+ }
+ emit initDone();
+ }
+}
+
+void MainWindow::insertLastPages()
+{
+ if (m_cmdLine->url().isValid())
+ m_centralWidget->setSource(m_cmdLine->url());
+ else
+ m_centralWidget->setLastShownPages();
+
+ if (m_cmdLine->search() == CmdLineParser::Activate)
+ showSearch();
+}
+
+void MainWindow::setupActions()
+{
+ QString system = QLatin1String("win");
+#ifdef Q_OS_MAC
+ system = QLatin1String("mac");
+ setUnifiedTitleAndToolBarOnMac(true);
+#endif
+
+ QMenu *menu = menuBar()->addMenu(tr("&File"));
+
+ m_pageSetupAction = menu->addAction(tr("Page Set&up..."), m_centralWidget, SLOT(pageSetup()));
+ m_printPreviewAction = menu->addAction(tr("Print Preview..."), m_centralWidget, SLOT(printPreview()));
+ m_printAction = menu->addAction(tr("&Print..."), m_centralWidget, SLOT(print()));
+ m_printAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/print.png").arg(system)));
+ m_printAction->setShortcut(tr("CTRL+P"));
+
+ menu->addSeparator();
+
+ m_newTabAction = menu->addAction(tr("New &Tab"), m_centralWidget, SLOT(newTab()));
+ m_newTabAction->setShortcut(tr("CTRL+T"));
+ m_closeTabAction = menu->addAction(tr("&Close Tab"), m_centralWidget, SLOT(closeTab()));
+ m_closeTabAction->setShortcut(tr("CTRL+W"));
+
+ QAction *tmp = menu->addAction(tr("&Quit"), this, SLOT(close()));
+ tmp->setShortcut(tr("CTRL+Q"));
+ tmp->setMenuRole(QAction::QuitRole);
+
+ menu = menuBar()->addMenu(tr("&Edit"));
+ m_copyAction = menu->addAction(tr("&Copy selected Text"),
+ m_centralWidget, SLOT(copySelection()));
+ m_copyAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/editcopy.png").arg(system)));
+ m_copyAction->setShortcut(tr("Ctrl+C"));
+ m_copyAction->setEnabled(false);
+
+ m_findAction = menu->addAction(tr("&Find in Text..."),
+ m_centralWidget, SLOT(showTextSearch()));
+ m_findAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/find.png").arg(system)));
+ m_findAction->setShortcut(tr("Ctrl+F"));
+ m_findAction->setShortcut(QKeySequence::Find);
+
+ QAction *findNextAction = menu->addAction(tr("Find &Next"),
+ m_centralWidget, SLOT(findNext()));
+ findNextAction->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("F3"))
+ << QKeySequence(tr("CTRL+G")));
+
+ QAction *findPreviousAction = menu->addAction(tr("Find &Previous"),
+ m_centralWidget, SLOT(findPrevious()));
+ findPreviousAction->setShortcuts(QList<QKeySequence>() <<
+ QKeySequence(tr("Shift+F3")) << QKeySequence(tr("CTRL+SHIFT+G")));
+
+ menu->addSeparator();
+ tmp = menu->addAction(tr("Preferences..."), this, SLOT(showPreferences()));
+ tmp->setMenuRole(QAction::PreferencesRole);
+
+ m_viewMenu = menuBar()->addMenu(tr("&View"));
+ m_zoomInAction = m_viewMenu->addAction(tr("Zoom &in"),
+ m_centralWidget, SLOT(zoomIn()));
+ m_zoomInAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/zoomin.png").arg(system)));
+ m_zoomInAction->setShortcut(tr("Ctrl++"));
+
+ m_zoomOutAction = m_viewMenu->addAction(tr("Zoom &out"),
+ m_centralWidget, SLOT(zoomOut()));
+ m_zoomOutAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/zoomout.png").arg(system)));
+ m_zoomOutAction->setShortcut(tr("Ctrl+-"));
+
+ m_resetZoomAction = m_viewMenu->addAction(tr("Normal &Size"),
+ m_centralWidget, SLOT(resetZoom()));
+ m_resetZoomAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/resetzoom.png").arg(system)));
+ m_resetZoomAction->setShortcut(tr("Ctrl+0"));
+
+ m_viewMenu->addSeparator();
+
+ m_viewMenu->addAction(tr("Contents"), this,
+ SLOT(showContents()), QKeySequence(tr("ALT+C")));
+ m_viewMenu->addAction(tr("Index"), this,
+ SLOT(showIndex()), QKeySequence(tr("ALT+I")));
+ m_viewMenu->addAction(tr("Bookmarks"), this,
+ SLOT(showBookmarks()), QKeySequence(tr("ALT+O")));
+ m_viewMenu->addAction(tr("Search"), this,
+ SLOT(showSearch()), QKeySequence(tr("ALT+S")));
+
+ menu = menuBar()->addMenu(tr("&Go"));
+ m_homeAction = menu->addAction(tr("&Home"),
+ m_centralWidget, SLOT(home()));
+ m_homeAction->setShortcut(tr("Ctrl+Home"));
+ m_homeAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/home.png").arg(system)));
+
+ m_backAction = menu->addAction(tr("&Back"),
+ m_centralWidget, SLOT(backward()));
+ m_backAction->setEnabled(false);
+ m_backAction->setShortcuts(QList<QKeySequence>()
+ << QKeySequence(Qt::CTRL|Qt::Key_Left) << QKeySequence::Back);
+ m_backAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/previous.png").arg(system)));
+
+ m_nextAction = menu->addAction(tr("&Forward"),
+ m_centralWidget, SLOT(forward()));
+ m_nextAction->setEnabled(false);
+ m_nextAction->setShortcuts(QList<QKeySequence>()
+ << QKeySequence(Qt::CTRL|Qt::Key_Right) << QKeySequence::Forward);
+ m_nextAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/next.png").arg(system)));
+
+ m_syncAction = menu->addAction(tr("Sync with Table of Contents"),
+ this, SLOT(syncContents()));
+ m_syncAction->setIcon(QIcon(
+ QString::fromUtf8(":/trolltech/assistant/images/%1/synctoc.png").arg(system)));
+
+ menu->addSeparator();
+
+ tmp = menu->addAction(tr("Next Page"), m_centralWidget, SLOT(nextPage()));
+ tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Right"))
+ << QKeySequence(Qt::CTRL + Qt::Key_PageDown));
+
+ tmp = menu->addAction(tr("Previous Page"),
+ m_centralWidget, SLOT(previousPage()));
+ tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Left"))
+ << QKeySequence(Qt::CTRL + Qt::Key_PageUp));
+
+ menu = menuBar()->addMenu(tr("&Bookmarks"));
+ tmp = menu->addAction(tr("Add Bookmark..."), this, SLOT(addBookmark()));
+ tmp->setShortcut(tr("CTRL+D"));
+
+ menu = menuBar()->addMenu(tr("&Help"));
+ m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog()));
+ m_aboutAction->setMenuRole(QAction::AboutRole);
+
+ QToolBar *navigationBar = addToolBar(tr("Navigation Toolbar"));
+ navigationBar->setObjectName(QLatin1String("NavigationToolBar"));
+ navigationBar->addAction(m_backAction);
+ navigationBar->addAction(m_nextAction);
+ navigationBar->addAction(m_homeAction);
+ navigationBar->addAction(m_syncAction);
+ QAction *sep = navigationBar->addSeparator();
+ navigationBar->addAction(m_copyAction);
+ navigationBar->addAction(m_printAction);
+ navigationBar->addAction(m_findAction);
+ QAction *sep2 = navigationBar->addSeparator();
+ navigationBar->addAction(m_zoomInAction);
+ navigationBar->addAction(m_zoomOutAction);
+ navigationBar->addAction(m_resetZoomAction);
+
+ QList<QAction*> actionList;
+ actionList << m_backAction << m_nextAction << m_homeAction;
+ actionList << sep << m_zoomInAction << m_zoomOutAction;
+ actionList << sep2 << m_copyAction << m_printAction << m_findAction;
+ m_centralWidget->setGlobalActions(actionList);
+
+#if defined(Q_WS_MAC)
+ QMenu *windowMenu = new QMenu(tr("&Window"), this);
+ menuBar()->insertMenu(menu->menuAction(), windowMenu);
+ windowMenu->addAction(tr("Minimize"), this,
+ SLOT(showMinimized()), QKeySequence(tr("Ctrl+M")));
+ windowMenu->addAction(tr("Zoom"), this,
+ SLOT(showMaximized()));
+#endif
+
+ // content viewer connections
+ connect(m_centralWidget, SIGNAL(copyAvailable(bool)),
+ this, SLOT(copyAvailable(bool)));
+ connect(m_centralWidget, SIGNAL(currentViewerChanged()),
+ this, SLOT(updateNavigationItems()));
+ connect(m_centralWidget, SIGNAL(forwardAvailable(bool)),
+ this, SLOT(updateNavigationItems()));
+ connect(m_centralWidget, SIGNAL(backwardAvailable(bool)),
+ this, SLOT(updateNavigationItems()));
+ connect(m_centralWidget, SIGNAL(highlighted(const QString&)),
+ statusBar(), SLOT(showMessage(const QString&)));
+ connect(m_centralWidget, SIGNAL(addNewBookmark(const QString&,
+ const QString&)), this, SLOT(addNewBookmark(const QString&, const QString&)));
+
+ // bookmarks
+ connect(m_bookmarkWidget, SIGNAL(requestShowLink(const QUrl&)),
+ m_centralWidget, SLOT(setSource(const QUrl&)));
+ connect(m_bookmarkWidget, SIGNAL(escapePressed()),
+ this, SLOT(activateCurrentCentralWidgetTab()));
+
+ // index window
+ connect(m_indexWindow, SIGNAL(linkActivated(const QUrl&)),
+ m_centralWidget, SLOT(setSource(const QUrl&)));
+ connect(m_indexWindow, SIGNAL(linksActivated(const QMap<QString, QUrl>&, const QString&)),
+ this, SLOT(showTopicChooser(const QMap<QString, QUrl>&, const QString&)));
+ connect(m_indexWindow, SIGNAL(escapePressed()),
+ this, SLOT(activateCurrentCentralWidgetTab()));
+
+ // content window
+ connect(m_contentWindow, SIGNAL(linkActivated(const QUrl&)),
+ m_centralWidget, SLOT(setSource(const QUrl&)));
+ connect(m_contentWindow, SIGNAL(escapePressed()),
+ this, SLOT(activateCurrentCentralWidgetTab()));
+
+#if defined(QT_NO_PRINTER)
+ m_pageSetupAction->setVisible(false);
+ m_printPreviewAction->setVisible(false);
+ m_printAction->setVisible(false);
+#endif
+}
+
+QMenu *MainWindow::toolBarMenu()
+{
+ if (!m_toolBarMenu) {
+ m_viewMenu->addSeparator();
+ m_toolBarMenu = m_viewMenu->addMenu(tr("Toolbars"));
+ }
+ return m_toolBarMenu;
+}
+
+void MainWindow::setupFilterToolbar()
+{
+ if (!m_helpEngine->
+ customValue(QLatin1String("EnableFilterFunctionality"), true).toBool())
+ return;
+
+ m_filterCombo = new QComboBox(this);
+ m_filterCombo->setMinimumWidth(QFontMetrics(QFont()).
+ width(QLatin1String("MakeTheComboBoxWidthEnough")));
+
+ QToolBar *filterToolBar = addToolBar(tr("Filter Toolbar"));
+ filterToolBar->setObjectName(QLatin1String("FilterToolBar"));
+ filterToolBar->addWidget(new QLabel(tr("Filtered by:").append(QLatin1String(" ")), this));
+ filterToolBar->addWidget(m_filterCombo);
+
+ if (m_helpEngine->customValue(QLatin1String("HideFilterFunctionality"), true).toBool())
+ filterToolBar->hide();
+ toolBarMenu()->addAction(filterToolBar->toggleViewAction());
+
+ connect(m_helpEngine, SIGNAL(setupFinished()),
+ this, SLOT(setupFilterCombo()));
+ connect(m_filterCombo, SIGNAL(activated(const QString&)),
+ this, SLOT(filterDocumentation(const QString&)));
+
+ setupFilterCombo();
+}
+
+void MainWindow::setupAddressToolbar()
+{
+ if (!m_helpEngine->customValue(QLatin1String("EnableAddressBar"), true).toBool())
+ return;
+
+ m_addressLineEdit = new QLineEdit(this);
+ QToolBar *addressToolBar = addToolBar(tr("Address Toolbar"));
+ addressToolBar->setObjectName(QLatin1String("AddressToolBar"));
+ insertToolBarBreak(addressToolBar);
+
+ addressToolBar->addWidget(new QLabel(tr("Address:").append(QLatin1String(" ")), this));
+ addressToolBar->addWidget(m_addressLineEdit);
+
+ if (m_helpEngine->customValue(QLatin1String("HideAddressBar"), true).toBool())
+ addressToolBar->hide();
+ toolBarMenu()->addAction(addressToolBar->toggleViewAction());
+
+ // address lineedit
+ connect(m_addressLineEdit, SIGNAL(returnPressed()),
+ this, SLOT(gotoAddress()));
+ connect(m_centralWidget, SIGNAL(currentViewerChanged()),
+ this, SLOT(showNewAddress()));
+ connect(m_centralWidget, SIGNAL(sourceChanged(const QUrl&)),
+ this, SLOT(showNewAddress(const QUrl&)));
+}
+
+void MainWindow::updateAboutMenuText()
+{
+ if (m_helpEngine) {
+ QByteArray ba = m_helpEngine->customValue(QLatin1String("AboutMenuTexts"),
+ QByteArray()).toByteArray();
+ if (ba.size() > 0) {
+ QString lang;
+ QString str;
+ QString trStr;
+ QString currentLang = QLocale::system().name();
+ int i = currentLang.indexOf(QLatin1Char('_'));
+ if (i > -1)
+ currentLang = currentLang.left(i);
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ while (!s.atEnd()) {
+ s >> lang;
+ s >> str;
+ if (lang == QLatin1String("default") && trStr.isEmpty()) {
+ trStr = str;
+ } else if (lang == currentLang) {
+ trStr = str;
+ break;
+ }
+ }
+ if (!trStr.isEmpty())
+ m_aboutAction->setText(trStr);
+ }
+ }
+}
+
+void MainWindow::showNewAddress()
+{
+ showNewAddress(m_centralWidget->currentSource());
+}
+
+void MainWindow::showNewAddress(const QUrl &url)
+{
+ m_addressLineEdit->setText(url.toString());
+}
+
+void MainWindow::addBookmark()
+{
+ addNewBookmark(m_centralWidget->currentTitle(), m_centralWidget->currentSource().toString());
+}
+
+void MainWindow::gotoAddress()
+{
+ m_centralWidget->setSource(m_addressLineEdit->text());
+}
+
+void MainWindow::updateNavigationItems()
+{
+ bool hasCurrentViewer = m_centralWidget->isHomeAvailable();
+ m_copyAction->setEnabled(m_centralWidget->hasSelection());
+ m_homeAction->setEnabled(hasCurrentViewer);
+ m_syncAction->setEnabled(hasCurrentViewer);
+ m_printPreviewAction->setEnabled(hasCurrentViewer);
+ m_printAction->setEnabled(hasCurrentViewer);
+ m_nextAction->setEnabled(m_centralWidget->isForwardAvailable());
+ m_backAction->setEnabled(m_centralWidget->isBackwardAvailable());
+ m_closeTabAction->setEnabled(hasCurrentViewer);
+ m_newTabAction->setEnabled(hasCurrentViewer);
+}
+
+void MainWindow::showTopicChooser(const QMap<QString, QUrl> &links,
+ const QString &keyword)
+{
+ TopicChooser tc(this, keyword, links);
+ if (tc.exec() == QDialog::Accepted) {
+ m_centralWidget->setSource(tc.link());
+ }
+}
+
+void MainWindow::showPreferences()
+{
+ PreferencesDialog dia(m_helpEngine, this);
+
+ connect(&dia, SIGNAL(updateApplicationFont()),
+ this, SLOT(updateApplicationFont()));
+ connect(&dia, SIGNAL(updateBrowserFont()),
+ m_centralWidget, SLOT(updateBrowserFont()));
+
+ dia.showDialog();
+}
+
+void MainWindow::syncContents()
+{
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+ const QUrl url = m_centralWidget->currentSource();
+ showContents();
+ if (!m_contentWindow->syncToContent(url))
+ statusBar()->showMessage(
+ tr("Could not find the associated content item."), 3000);
+ qApp->restoreOverrideCursor();
+}
+
+void MainWindow::copyAvailable(bool yes)
+{
+ m_copyAction->setEnabled(yes);
+}
+
+void MainWindow::addNewBookmark(const QString &title, const QString &url)
+{
+ if (url.isEmpty())
+ return;
+
+ m_bookmarkManager->showBookmarkDialog(this, title, url);
+}
+
+void MainWindow::showAboutDialog()
+{
+ QByteArray contents;
+ if (m_helpEngine) {
+ QByteArray ba = m_helpEngine->customValue(QLatin1String("AboutTexts"),
+ QByteArray()).toByteArray();
+ if (!ba.isEmpty()) {
+ QString lang;
+ QByteArray cba;
+ QString currentLang = QLocale::system().name();
+ int i = currentLang.indexOf(QLatin1Char('_'));
+ if (i > -1)
+ currentLang = currentLang.left(i);
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ while (!s.atEnd()) {
+ s >> lang;
+ s >> cba;
+ if (lang == QLatin1String("default") && contents.isEmpty()) {
+ contents = cba;
+ } else if (lang == currentLang) {
+ contents = cba;
+ break;
+ }
+ }
+ }
+ }
+
+ AboutDialog aboutDia(this);
+
+ QByteArray iconArray;
+ if (!contents.isEmpty()) {
+ iconArray = m_helpEngine->customValue(QLatin1String("AboutIcon"),
+ QByteArray()).toByteArray();
+ QByteArray resources = m_helpEngine->customValue(QLatin1String("AboutImages"),
+ QByteArray()).toByteArray();
+ QPixmap pix;
+ pix.loadFromData(iconArray);
+ aboutDia.setText(QString::fromUtf8(contents), resources);
+ if (!pix.isNull())
+ aboutDia.setPixmap(pix);
+ aboutDia.setWindowTitle(aboutDia.documentTitle());
+ } else {
+#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/about/businessmodel"
+ "\">http://qtsoftware.com/company/about/businessmodel</a> for an overview of Qt licensing.");
+#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
+ QByteArray resources;
+ aboutDia.setText(QString::fromLatin1("<center>"
+ "<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), resources);
+ aboutDia.setPixmap(QString::fromLatin1(":/trolltech/assistant/images/assistant-128.png"));
+ }
+ if (aboutDia.windowTitle().isEmpty())
+ aboutDia.setWindowTitle(tr("About %1").arg(windowTitle()));
+ aboutDia.exec();
+}
+
+void MainWindow::showContents()
+{
+ activateDockWidget(m_contentWindow);
+}
+
+void MainWindow::showIndex()
+{
+ activateDockWidget(m_indexWindow);
+}
+
+void MainWindow::showBookmarks()
+{
+ activateDockWidget(m_bookmarkWidget);
+}
+
+void MainWindow::activateDockWidget(QWidget *w)
+{
+ w->parentWidget()->show();
+ w->parentWidget()->raise();
+ w->setFocus();
+}
+
+void MainWindow::hideContents()
+{
+ m_contentWindow->parentWidget()->hide();
+}
+
+void MainWindow::hideIndex()
+{
+ m_indexWindow->parentWidget()->hide();
+}
+
+void MainWindow::hideBookmarks()
+{
+ m_bookmarkWidget->parentWidget()->hide();
+}
+
+void MainWindow::setIndexString(const QString &str)
+{
+ m_indexWindow->setSearchLineEditText(str);
+}
+
+void MainWindow::activateCurrentBrowser()
+{
+ CentralWidget *cw = CentralWidget::instance();
+ if (cw) {
+ cw->activateTab(true);
+ }
+}
+
+void MainWindow::activateCurrentCentralWidgetTab()
+{
+ m_centralWidget->activateTab();
+}
+
+void MainWindow::showSearch()
+{
+ if (m_searchWidget)
+ activateDockWidget(m_searchWidget);
+ else
+ m_centralWidget->activateSearch();
+}
+
+void MainWindow::hideSearch()
+{
+ if (m_searchWidget) {
+ m_searchWidget->parentWidget()->parentWidget()->hide();
+ } else {
+ m_centralWidget->removeSearchWidget();
+ }
+}
+
+void MainWindow::updateApplicationFont()
+{
+ QFont font = qApp->font();
+ if (m_helpEngine->customValue(QLatin1String("useAppFont")).toBool())
+ font = qVariantValue<QFont>(m_helpEngine->customValue(QLatin1String("appFont")));
+
+ qApp->setFont(font, "QWidget");
+}
+
+void MainWindow::setupFilterCombo()
+{
+ QString curFilter = m_filterCombo->currentText();
+ if (curFilter.isEmpty())
+ curFilter = m_helpEngine->currentFilter();
+ m_filterCombo->clear();
+ m_filterCombo->addItems(m_helpEngine->customFilters());
+ int idx = m_filterCombo->findText(curFilter);
+ if (idx < 0)
+ idx = 0;
+ m_filterCombo->setCurrentIndex(idx);
+}
+
+void MainWindow::filterDocumentation(const QString &customFilter)
+{
+ m_helpEngine->setCurrentFilter(customFilter);
+}
+
+void MainWindow::expandTOC(int depth)
+{
+ m_contentWindow->expandToDepth(depth);
+}
+
+void MainWindow::indexingStarted()
+{
+ m_progressWidget = new QWidget();
+ QLayout* hlayout = new QHBoxLayout(m_progressWidget);
+
+ QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
+
+ QLabel *label = new QLabel(tr("Updating search index"));
+ label->setSizePolicy(sizePolicy);
+ hlayout->addWidget(label);
+
+ QProgressBar *progressBar = new QProgressBar();
+ progressBar->setRange(0, 0);
+ progressBar->setTextVisible(false);
+ progressBar->setSizePolicy(sizePolicy);
+
+ hlayout->setSpacing(6);
+ hlayout->setMargin(0);
+ hlayout->addWidget(progressBar);
+
+ statusBar()->addPermanentWidget(m_progressWidget);
+}
+
+void MainWindow::indexingFinished()
+{
+ statusBar()->removeWidget(m_progressWidget);
+ delete m_progressWidget;
+ m_progressWidget = 0;
+}
+
+QWidget* MainWindow::setupBookmarkWidget()
+{
+ m_bookmarkManager = new BookmarkManager(m_helpEngine);
+ m_bookmarkWidget = new BookmarkWidget(m_bookmarkManager, this);
+ connect(m_bookmarkWidget, SIGNAL(addBookmark()),
+ this, SLOT(addBookmark()));
+ return m_bookmarkWidget;
+}
+
+QString MainWindow::collectionFileDirectory(bool createDir, const QString &cacheDir)
+{
+ QString collectionPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ if (collectionPath.isEmpty()) {
+ if (cacheDir.isEmpty())
+ collectionPath = QDir::homePath() + QDir::separator()
+ + QLatin1String(".assistant");
+ else
+ collectionPath = QDir::homePath() + QLatin1String("/.")
+ + cacheDir;
+ } else {
+ if (cacheDir.isEmpty())
+ collectionPath = collectionPath + QLatin1String("/Trolltech/Assistant");
+ else
+ collectionPath = collectionPath + QDir::separator()
+ + cacheDir;
+ }
+ collectionPath = QDir::cleanPath(collectionPath);
+ if (createDir) {
+ QDir dir;
+ if (!dir.exists(collectionPath))
+ dir.mkpath(collectionPath);
+ }
+ return collectionPath;
+}
+
+QString MainWindow::defaultHelpCollectionFileName()
+{
+ return collectionFileDirectory() + QDir::separator() +
+ QString(QLatin1String("qthelpcollection_%1.qhc")).
+ arg(QLatin1String(QT_VERSION_STR));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h
new file mode 100644
index 0000000000..8b87b7b9ea
--- /dev/null
+++ b/tools/assistant/tools/assistant/mainwindow.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** 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 <QtCore/QUrl>
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QLineEdit;
+class QComboBox;
+class QMenu;
+
+class IndexWindow;
+class QHelpEngineCore;
+class QHelpEngine;
+class CentralWidget;
+class ContentWindow;
+class BookmarkManager;
+class BookmarkWidget;
+class CmdLineParser;
+class QtDocInstaller;
+
+class SearchWidget;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(CmdLineParser *cmdLine, QWidget *parent = 0);
+ ~MainWindow();
+
+ static void activateCurrentBrowser();
+ static QString collectionFileDirectory(bool createDir = false,
+ const QString &cacheDir = QString());
+ static QString defaultHelpCollectionFileName();
+
+public:
+ void hideContents();
+ void hideIndex();
+ void hideBookmarks();
+ void hideSearch();
+ void setIndexString(const QString &str);
+ void expandTOC(int depth);
+ bool usesDefaultCollection() const;
+
+signals:
+ void initDone();
+
+public slots:
+ void showContents();
+ void showIndex();
+ void showBookmarks();
+ void showSearch();
+ void syncContents();
+ void activateCurrentCentralWidgetTab();
+
+private slots:
+ void insertLastPages();
+ void addBookmark();
+ void gotoAddress();
+ void showPreferences();
+ void showNewAddress();
+ void showAboutDialog();
+ void copyAvailable(bool yes);
+ void updateNavigationItems();
+ void showNewAddress(const QUrl &url);
+ void addNewBookmark(const QString &title, const QString &url);
+ void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword);
+ void updateApplicationFont();
+ void filterDocumentation(const QString &customFilter);
+ void setupFilterCombo();
+ void lookForNewQtDocumentation();
+ void indexingStarted();
+ void indexingFinished();
+ void displayInstallationError(const QString &errorMessage);
+ void qtDocumentationInstalled(bool newDocsInstalled);
+ void checkInitState();
+
+private:
+ bool initHelpDB();
+ void setupActions();
+ void closeEvent(QCloseEvent *e);
+ void activateDockWidget(QWidget *w);
+ void updateAboutMenuText();
+ void setupFilterToolbar();
+ void setupAddressToolbar();
+ QMenu *toolBarMenu();
+ QWidget *setupBookmarkWidget();
+
+ QHelpEngine *m_helpEngine;
+ CentralWidget *m_centralWidget;
+ IndexWindow *m_indexWindow;
+ ContentWindow *m_contentWindow;
+ BookmarkWidget *m_bookmarkWidget;
+ BookmarkManager *m_bookmarkManager;
+ QLineEdit *m_addressLineEdit;
+ QComboBox *m_filterCombo;
+
+ QAction *m_backAction;
+ QAction *m_nextAction;
+ QAction *m_homeAction;
+ QAction *m_syncAction;
+ QAction *m_copyAction;
+ QAction *m_findAction;
+ QAction *m_printAction;
+ QAction *m_printPreviewAction;
+ QAction *m_pageSetupAction;
+ QAction *m_zoomInAction;
+ QAction *m_zoomOutAction;
+ QAction *m_resetZoomAction;
+ QAction *m_aboutAction;
+ QAction *m_closeTabAction;
+ QAction *m_newTabAction;
+
+ QMenu *m_viewMenu;
+ QMenu *m_toolBarMenu;
+
+ CmdLineParser *m_cmdLine;
+ SearchWidget *m_searchWidget;
+
+ QWidget *m_progressWidget;
+ QtDocInstaller *m_qtDocInstaller;
+
+ bool m_connectedInitSignals;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/tools/assistant/tools/assistant/preferencesdialog.cpp b/tools/assistant/tools/assistant/preferencesdialog.cpp
new file mode 100644
index 0000000000..094bd9c02c
--- /dev/null
+++ b/tools/assistant/tools/assistant/preferencesdialog.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** 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 "preferencesdialog.h"
+#include "filternamedialog.h"
+#include "installdialog.h"
+#include "fontpanel.h"
+#include "centralwidget.h"
+
+#include <QtAlgorithms>
+
+#include <QtGui/QHeaderView>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QMenu>
+#include <QtGui/QFontDatabase>
+
+#include <QtHelp/QHelpEngineCore>
+
+QT_BEGIN_NAMESPACE
+
+PreferencesDialog::PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *parent)
+ : QDialog(parent)
+ , m_appFontChanged(false)
+ , m_browserFontChanged(false)
+{
+ m_helpEngine = helpEngine;
+ m_ui.setupUi(this);
+
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Ok),
+ SIGNAL(clicked()), this, SLOT(applyChanges()));
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel),
+ SIGNAL(clicked()), this, SLOT(reject()));
+
+ m_hideFiltersTab = !m_helpEngine->customValue(QLatin1String("EnableFilterFunctionality"),
+ true).toBool();
+ m_hideDocsTab = !m_helpEngine->customValue(QLatin1String("EnableDocumentationManager"),
+ true).toBool();
+
+ if (!m_hideFiltersTab) {
+ m_ui.attributeWidget->header()->hide();
+ m_ui.attributeWidget->setRootIsDecorated(false);
+ connect(m_ui.attributeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
+ this, SLOT(updateFilterMap()));
+
+ connect(m_ui.filterWidget,
+ SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(updateAttributes(QListWidgetItem*)));
+
+ connect(m_ui.filterAddButton, SIGNAL(clicked()),
+ this, SLOT(addFilter()));
+ connect(m_ui.filterRemoveButton, SIGNAL(clicked()),
+ this, SLOT(removeFilter()));
+
+ updateFilterPage();
+ } else {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab));
+ }
+
+ if (!m_hideDocsTab) {
+ connect(m_ui.docAddButton, SIGNAL(clicked()), this,
+ SLOT(addDocumentationLocal()));
+ connect(m_ui.docRemoveButton, SIGNAL(clicked()), this,
+ SLOT(removeDocumentation()));
+
+ m_docsBackup = m_helpEngine->registeredDocumentations();
+ m_ui.registeredDocsListWidget->addItems(m_docsBackup);
+ } else {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
+ }
+ updateFontSettingsPage();
+ updateOptionsPage();
+}
+
+PreferencesDialog::~PreferencesDialog()
+{
+ if (m_appFontChanged) {
+ m_helpEngine->setCustomValue(QLatin1String("appFont"), m_appFontPanel->selectedFont());
+ m_helpEngine->setCustomValue(QLatin1String("useAppFont"), m_appFontPanel->isChecked());
+ m_helpEngine->setCustomValue(QLatin1String("appWritingSystem"), m_appFontPanel->writingSystem());
+ }
+
+ if (m_browserFontChanged) {
+ m_helpEngine->setCustomValue(QLatin1String("browserFont"), m_browserFontPanel->selectedFont());
+ m_helpEngine->setCustomValue(QLatin1String("useBrowserFont"), m_browserFontPanel->isChecked());
+ m_helpEngine->setCustomValue(QLatin1String("browserWritingSystem"), m_browserFontPanel->writingSystem());
+ }
+
+ if (m_appFontChanged || m_browserFontChanged) {
+ emit updateApplicationFont();
+ emit updateBrowserFont();
+ }
+
+ if (!m_ui.homePageLineEdit->text().isEmpty())
+ m_helpEngine->setCustomValue(QLatin1String("homepage"), m_ui.homePageLineEdit->text());
+}
+
+void PreferencesDialog::showDialog()
+{
+ if (exec() != Accepted)
+ m_appFontChanged = m_browserFontChanged = false;
+}
+
+void PreferencesDialog::updateFilterPage()
+{
+ if (!m_helpEngine)
+ return;
+
+ m_ui.filterWidget->clear();
+ m_ui.attributeWidget->clear();
+
+ QHelpEngineCore help(m_helpEngine->collectionFile(), 0);
+ help.setupData();
+ m_filterMapBackup.clear();
+ const QStringList filters = help.customFilters();
+ foreach (const QString &filter, filters) {
+ QStringList atts = help.filterAttributes(filter);
+ m_filterMapBackup.insert(filter, atts);
+ if (!m_filterMap.contains(filter))
+ m_filterMap.insert(filter, atts);
+ }
+
+ m_ui.filterWidget->addItems(m_filterMap.keys());
+
+ foreach (const QString &a, help.filterAttributes())
+ new QTreeWidgetItem(m_ui.attributeWidget, QStringList() << a);
+
+ if (m_filterMap.keys().count())
+ m_ui.filterWidget->setCurrentRow(0);
+}
+
+void PreferencesDialog::updateAttributes(QListWidgetItem *item)
+{
+ QStringList checkedList;
+ if (item)
+ checkedList = m_filterMap.value(item->text());
+ QTreeWidgetItem *itm;
+ for (int i=0; i<m_ui.attributeWidget->topLevelItemCount(); ++i) {
+ itm = m_ui.attributeWidget->topLevelItem(i);
+ if (checkedList.contains(itm->text(0)))
+ itm->setCheckState(0, Qt::Checked);
+ else
+ itm->setCheckState(0, Qt::Unchecked);
+ }
+}
+
+void PreferencesDialog::updateFilterMap()
+{
+ if (!m_ui.filterWidget->currentItem())
+ return;
+ QString filter = m_ui.filterWidget->currentItem()->text();
+ if (!m_filterMap.contains(filter))
+ return;
+
+ QStringList newAtts;
+ QTreeWidgetItem *itm = 0;
+ for (int i=0; i<m_ui.attributeWidget->topLevelItemCount(); ++i) {
+ itm = m_ui.attributeWidget->topLevelItem(i);
+ if (itm->checkState(0) == Qt::Checked)
+ newAtts.append(itm->text(0));
+ }
+ m_filterMap[filter] = newAtts;
+}
+
+void PreferencesDialog::addFilter()
+{
+ FilterNameDialog dia(this);
+ if (dia.exec() == QDialog::Rejected)
+ return;
+
+ QString filterName = dia.filterName();
+ if (!m_filterMap.contains(filterName)) {
+ m_filterMap.insert(filterName, QStringList());
+ m_ui.filterWidget->addItem(filterName);
+ }
+
+ QList<QListWidgetItem*> lst = m_ui.filterWidget
+ ->findItems(filterName, Qt::MatchCaseSensitive);
+ m_ui.filterWidget->setCurrentItem(lst.first());
+}
+
+void PreferencesDialog::removeFilter()
+{
+ QListWidgetItem *item = m_ui.filterWidget
+ ->takeItem(m_ui.filterWidget->currentRow());
+ if (!item)
+ return;
+
+ m_filterMap.remove(item->text());
+ m_removedFilters.append(item->text());
+ delete item;
+ if (m_ui.filterWidget->count())
+ m_ui.filterWidget->setCurrentRow(0);
+}
+
+void PreferencesDialog::addDocumentationLocal()
+{
+ const QStringList fileNames = QFileDialog::getOpenFileNames(this,
+ tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)"));
+ if (fileNames.isEmpty())
+ return;
+
+ foreach (const QString &fileName, fileNames) {
+ const QString ns = QHelpEngineCore::namespaceName(fileName);
+ if (ns.isEmpty()) {
+ QMessageBox::warning(this, tr("Add Documentation"),
+ tr("The specified file is not a valid Qt Help File!"));
+ continue;
+ }
+
+ if (m_ui.registeredDocsListWidget->findItems(ns, Qt::MatchFixedString).count()) {
+ QMessageBox::warning(this, tr("Add Documentation"),
+ tr("The namespace %1 is already registered!").arg(ns));
+ continue;
+ }
+
+ m_helpEngine->registerDocumentation(fileName);
+ m_ui.registeredDocsListWidget->addItem(ns);
+ m_regDocs.append(ns);
+ m_unregDocs.removeAll(ns);
+ }
+ updateFilterPage();
+}
+
+void PreferencesDialog::removeDocumentation()
+{
+ bool foundBefore = false;
+ CentralWidget* widget = CentralWidget::instance();
+ QMap<int, QString> openedDocList = widget->currentSourceFileList();
+ QStringList values(openedDocList.values());
+
+ QList<QListWidgetItem*> l = m_ui.registeredDocsListWidget->selectedItems();
+ foreach (QListWidgetItem* item, l) {
+ const QString& ns = item->text();
+ if (!foundBefore && values.contains(ns)) {
+ if (0 == QMessageBox::information(this, tr("Remove Documentation"),
+ tr("Some documents currently opened in Assistant reference the "
+ "documentation you are attempting to remove. Removing the "
+ "documentation will close those documents."), tr("Cancel"),
+ tr("OK"))) return;
+ foundBefore = true;
+ }
+
+ m_unregDocs.append(ns);
+ m_TabsToClose += openedDocList.keys(ns);
+ delete m_ui.registeredDocsListWidget->takeItem(
+ m_ui.registeredDocsListWidget->row(item));
+ }
+
+ if (m_ui.registeredDocsListWidget->count()) {
+ m_ui.registeredDocsListWidget->setCurrentRow(0,
+ QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+void PreferencesDialog::applyChanges()
+{
+ bool filtersWereChanged = false;
+ if (!m_hideFiltersTab) {
+ if (m_filterMap.count() != m_filterMapBackup.count()) {
+ filtersWereChanged = true;
+ } else {
+ QMapIterator<QString, QStringList> it(m_filterMapBackup);
+ while (it.hasNext() && !filtersWereChanged) {
+ it.next();
+ if (!m_filterMap.contains(it.key())) {
+ filtersWereChanged = true;
+ } else {
+ QStringList a = it.value();
+ QStringList b = m_filterMap.value(it.key());
+ if (a.count() != b.count()) {
+ filtersWereChanged = true;
+ } else {
+ QStringList::const_iterator i(a.constBegin());
+ while (i != a.constEnd()) {
+ if (!b.contains(*i)) {
+ filtersWereChanged = true;
+ break;
+ }
+ ++i;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (filtersWereChanged) {
+ foreach (const QString &filter, m_removedFilters)
+ m_helpEngine->removeCustomFilter(filter);
+ QMapIterator<QString, QStringList> it(m_filterMap);
+ while (it.hasNext()) {
+ it.next();
+ m_helpEngine->addCustomFilter(it.key(), it.value());
+ }
+ }
+
+ qSort(m_TabsToClose);
+ CentralWidget* widget = CentralWidget::instance();
+ for (int i = m_TabsToClose.count(); --i >= 0;)
+ widget->closeTabAt(m_TabsToClose.at(i));
+
+ if (m_unregDocs.count()) {
+ foreach (const QString &doc, m_unregDocs)
+ m_helpEngine->unregisterDocumentation(doc);
+ }
+
+ if (filtersWereChanged || m_regDocs.count() || m_unregDocs.count())
+ m_helpEngine->setupData();
+
+ accept();
+}
+
+void PreferencesDialog::updateFontSettingsPage()
+{
+ m_browserFontPanel = new FontPanel(this);
+ m_browserFontPanel->setCheckable(true);
+ m_ui.stackedWidget_2->insertWidget(0, m_browserFontPanel);
+
+ m_appFontPanel = new FontPanel(this);
+ m_appFontPanel->setCheckable(true);
+ m_ui.stackedWidget_2->insertWidget(1, m_appFontPanel);
+
+ m_ui.stackedWidget_2->setCurrentIndex(0);
+
+ const QString customSettings(tr("Use custom settings"));
+ QFont font = qVariantValue<QFont>(m_helpEngine->customValue(QLatin1String("appFont")));
+ QFontDatabase::WritingSystem writingSystem = static_cast<QFontDatabase::WritingSystem>
+ (m_helpEngine->customValue(QLatin1String("appWritingSystem")).toInt());
+
+ m_appFontPanel->setTitle(customSettings);
+ m_appFontPanel->setSelectedFont(font);
+ m_appFontPanel->setWritingSystem(writingSystem);
+ m_appFontPanel->setChecked(m_helpEngine->customValue(QLatin1String("useAppFont")).toBool());
+
+ QFont font2 = qVariantValue<QFont>(m_helpEngine->customValue(QLatin1String("browserFont")));
+ writingSystem = static_cast<QFontDatabase::WritingSystem>
+ (m_helpEngine->customValue(QLatin1String("browserWritingSystem")).toInt());
+
+ m_browserFontPanel->setTitle(customSettings);
+ m_browserFontPanel->setSelectedFont(font2);
+ m_browserFontPanel->setWritingSystem(writingSystem);
+ m_browserFontPanel->setChecked(m_helpEngine->customValue(QLatin1String("useBrowserFont")).toBool());
+
+ connect(m_appFontPanel, SIGNAL(toggled(bool)), this, SLOT(appFontSettingToggled(bool)));
+ connect(m_browserFontPanel, SIGNAL(toggled(bool)), this, SLOT(browserFontSettingToggled(bool)));
+
+ QList<QComboBox*> allCombos = qFindChildren<QComboBox*>(m_appFontPanel);
+ foreach (QComboBox* box, allCombos)
+ connect(box, SIGNAL(currentIndexChanged(int)), this, SLOT(appFontSettingChanged(int)));
+
+ allCombos.clear();
+ allCombos = qFindChildren<QComboBox*>(m_browserFontPanel);
+ foreach (QComboBox* box, allCombos)
+ connect(box, SIGNAL(currentIndexChanged(int)), this, SLOT(browserFontSettingChanged(int)));
+}
+
+void PreferencesDialog::appFontSettingToggled(bool on)
+{
+ Q_UNUSED(on)
+ m_appFontChanged = true;
+}
+
+void PreferencesDialog::appFontSettingChanged(int index)
+{
+ Q_UNUSED(index)
+ m_appFontChanged = true;
+}
+
+void PreferencesDialog::browserFontSettingToggled(bool on)
+{
+ Q_UNUSED(on)
+ m_browserFontChanged = true;
+}
+
+void PreferencesDialog::browserFontSettingChanged(int index)
+{
+ Q_UNUSED(index)
+ m_browserFontChanged = true;
+}
+
+void PreferencesDialog::updateOptionsPage()
+{
+ QString homepage = m_helpEngine->customValue(QLatin1String("homepage"),
+ QLatin1String("")).toString();
+
+ if (homepage.isEmpty()) {
+ homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"),
+ QLatin1String("help")).toString();
+ }
+
+ m_ui.homePageLineEdit->setText(homepage);
+ connect(m_ui.currentPageButton, SIGNAL(pressed()), this,
+ SLOT(currentHomepageChanged()));
+ connect(m_ui.restoreDefaultHomePageButton, SIGNAL(pressed()), this,
+ SLOT(restoreDefaultHomepage()));
+}
+
+void PreferencesDialog::restoreDefaultHomepage()
+{
+ QString homepage = m_helpEngine->customValue(
+ QLatin1String("defaultHomepage"), QLatin1String("help")).toString();
+ m_ui.homePageLineEdit->setText(homepage);
+}
+
+void PreferencesDialog::currentHomepageChanged()
+{
+ QString homepage = CentralWidget::instance()->currentSource().toString();
+ if (homepage.isEmpty())
+ homepage = QLatin1String("help");
+
+ m_ui.homePageLineEdit->setText(homepage);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/preferencesdialog.h b/tools/assistant/tools/assistant/preferencesdialog.h
new file mode 100644
index 0000000000..a890500d76
--- /dev/null
+++ b/tools/assistant/tools/assistant/preferencesdialog.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** 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 PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QtGui/QDialog>
+#include "ui_preferencesdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class FontPanel;
+class QHelpEngineCore;
+
+class PreferencesDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0);
+ ~PreferencesDialog();
+
+ void showDialog();
+
+private slots:
+ void updateAttributes(QListWidgetItem *item);
+ void updateFilterMap();
+ void addFilter();
+ void removeFilter();
+ void addDocumentationLocal();
+ void removeDocumentation();
+ void applyChanges();
+ void appFontSettingToggled(bool on);
+ void appFontSettingChanged(int index);
+ void browserFontSettingToggled(bool on);
+ void browserFontSettingChanged(int index);
+ void restoreDefaultHomepage();
+ void currentHomepageChanged();
+
+signals:
+ void updateBrowserFont();
+ void updateApplicationFont();
+
+private:
+ void updateFilterPage();
+ void updateFontSettingsPage();
+ void updateOptionsPage();
+
+ Ui::PreferencesDialogClass m_ui;
+ QHelpEngineCore *m_helpEngine;
+ bool m_hideFiltersTab;
+ bool m_hideDocsTab;
+ QMap<QString, QStringList> m_filterMapBackup;
+ QMap<QString, QStringList> m_filterMap;
+ QStringList m_removedFilters;
+ QStringList m_docsBackup;
+ QStringList m_regDocs;
+ QStringList m_unregDocs;
+ QList<int> m_TabsToClose;
+ FontPanel *m_appFontPanel;
+ FontPanel *m_browserFontPanel;
+ bool m_appFontChanged;
+ bool m_browserFontChanged;
+};
+
+QT_END_NAMESPACE
+
+#endif // SETTINGSDIALOG_H
diff --git a/tools/assistant/tools/assistant/preferencesdialog.ui b/tools/assistant/tools/assistant/preferencesdialog.ui
new file mode 100644
index 0000000000..d848b498d2
--- /dev/null
+++ b/tools/assistant/tools/assistant/preferencesdialog.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PreferencesDialogClass</class>
+ <widget class="QDialog" name="PreferencesDialogClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>359</width>
+ <height>266</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Preferences</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="fontsTab">
+ <attribute name="title">
+ <string>Fonts</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="fontLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Font settings:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string>Browser</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Application</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QStackedWidget" name="stackedWidget_2">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page_4"/>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="filtersTab">
+ <attribute name="title">
+ <string>Filters</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_2">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="text">
+ <string>Attributes:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QListWidget" name="filterWidget"/>
+ </item>
+ <item row="1" column="2" rowspan="2">
+ <widget class="QTreeWidget" name="attributeWidget">
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="filterAddButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="filterRemoveButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="docsTab">
+ <attribute name="title">
+ <string>Documentation</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Registered Documentation:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="registeredDocsListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="docAddButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="docRemoveButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="optionsTab">
+ <attribute name="title">
+ <string>Options</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Homepage</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLineEdit" name="homePageLineEdit"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="currentPageButton">
+ <property name="text">
+ <string>Current Page</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="restoreDefaultHomePageButton">
+ <property name="text">
+ <string>Restore to default</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>72</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>comboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>stackedWidget_2</receiver>
+ <slot>setCurrentIndex(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>375</x>
+ <y>32</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>347</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/assistant/tools/assistant/qtdocinstaller.cpp b/tools/assistant/tools/assistant/qtdocinstaller.cpp
new file mode 100644
index 0000000000..9063847053
--- /dev/null
+++ b/tools/assistant/tools/assistant/qtdocinstaller.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** 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 <QtCore/QDir>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDateTime>
+#include <QtHelp/QHelpEngineCore>
+#include "qtdocinstaller.h"
+
+QT_BEGIN_NAMESPACE
+
+QtDocInstaller::QtDocInstaller(const QString &collectionFile)
+{
+ m_abort = false;
+ m_collectionFile = collectionFile;
+}
+
+QtDocInstaller::~QtDocInstaller()
+{
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+}
+
+void QtDocInstaller::installDocs()
+{
+ start(LowPriority);
+}
+
+void QtDocInstaller::run()
+{
+ QHelpEngineCore *helpEngine = new QHelpEngineCore(m_collectionFile);
+ helpEngine->setupData();
+ bool changes = false;
+
+ QStringList docs;
+ docs << QLatin1String("assistant")
+ << QLatin1String("designer")
+ << QLatin1String("linguist")
+ << QLatin1String("qmake")
+ << QLatin1String("qt");
+
+ foreach (const QString &doc, docs) {
+ changes |= installDoc(doc, helpEngine);
+ m_mutex.lock();
+ if (m_abort) {
+ delete helpEngine;
+ m_mutex.unlock();
+ return;
+ }
+ m_mutex.unlock();
+ }
+ delete helpEngine;
+ emit docsInstalled(changes);
+}
+
+bool QtDocInstaller::installDoc(const QString &name, QHelpEngineCore *helpEngine)
+{
+ QString versionKey = QString(QLatin1String("qtVersion%1$$$%2")).
+ arg(QLatin1String(QT_VERSION_STR)).arg(name);
+
+ QString info = helpEngine->customValue(versionKey, QString()).toString();
+ QStringList lst = info.split(QLatin1String("|"));
+
+ QDateTime dt;
+ if (lst.count() && !lst.first().isEmpty())
+ dt = QDateTime::fromString(lst.first(), Qt::ISODate);
+
+ QString qchFile;
+ if (lst.count() == 2)
+ qchFile = lst.last();
+
+ QDir dir(QLibraryInfo::location(QLibraryInfo::DocumentationPath)
+ + QDir::separator() + QLatin1String("qch"));
+
+ const QStringList files = dir.entryList(QStringList() << QLatin1String("*.qch"));
+ if (files.isEmpty()) {
+ helpEngine->setCustomValue(versionKey, QDateTime().toString(Qt::ISODate)
+ + QLatin1String("|"));
+ return false;
+ }
+ foreach (const QString &f, files) {
+ if (f.startsWith(name)) {
+ QFileInfo fi(dir.absolutePath() + QDir::separator() + f);
+ if (dt.isValid() && fi.lastModified().toString(Qt::ISODate) == dt.toString(Qt::ISODate)
+ && qchFile == fi.absoluteFilePath())
+ return false;
+
+ QString namespaceName = QHelpEngineCore::namespaceName(fi.absoluteFilePath());
+ if (namespaceName.isEmpty())
+ continue;
+
+ if (helpEngine->registeredDocumentations().contains(namespaceName))
+ helpEngine->unregisterDocumentation(namespaceName);
+
+ if (!helpEngine->registerDocumentation(fi.absoluteFilePath())) {
+ emit errorMessage(
+ tr("The file %1 could not be registered successfully!\n\nReason: %2")
+ .arg(fi.absoluteFilePath()).arg(helpEngine->error()));
+ }
+
+ helpEngine->setCustomValue(versionKey, fi.lastModified().toString(Qt::ISODate)
+ + QLatin1String("|") + fi.absoluteFilePath());
+ return true;
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/qtdocinstaller.h b/tools/assistant/tools/assistant/qtdocinstaller.h
new file mode 100644
index 0000000000..a8a98fac0a
--- /dev/null
+++ b/tools/assistant/tools/assistant/qtdocinstaller.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 QTDOCINSTALLER
+#define QTDOCINSTALLER
+
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngineCore;
+
+class QtDocInstaller : public QThread
+{
+ Q_OBJECT
+
+public:
+ QtDocInstaller(const QString &collectionFile);
+ ~QtDocInstaller();
+ void installDocs();
+
+signals:
+ void errorMessage(const QString &msg);
+ void docsInstalled(bool newDocsInstalled);
+
+private:
+ void run();
+ bool installDoc(const QString &name,
+ QHelpEngineCore *helpEngine);
+
+ bool m_abort;
+ QString m_collectionFile;
+ QMutex m_mutex;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/remotecontrol.cpp b/tools/assistant/tools/assistant/remotecontrol.cpp
new file mode 100644
index 0000000000..f3745380de
--- /dev/null
+++ b/tools/assistant/tools/assistant/remotecontrol.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** 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 "remotecontrol.h"
+#include "mainwindow.h"
+#include "centralwidget.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QThread>
+#include <QtCore/QTextStream>
+#include <QtCore/QSocketNotifier>
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexWidget>
+
+#ifdef Q_OS_WIN
+# include "remotecontrol_win.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+
+StdInListenerWin::StdInListenerWin(QObject *parent)
+ : QThread(parent)
+{
+}
+
+StdInListenerWin::~StdInListenerWin()
+{
+ terminate();
+ wait();
+}
+
+void StdInListenerWin::run()
+{
+ bool ok = true;
+ char chBuf[4096];
+ DWORD dwRead;
+ HANDLE hStdin, hStdinDup;
+
+ hStdin = GetStdHandle(STD_INPUT_HANDLE);
+ if (hStdin == INVALID_HANDLE_VALUE)
+ return;
+
+ DuplicateHandle(GetCurrentProcess(), hStdin,
+ GetCurrentProcess(), &hStdinDup,
+ 0, false, DUPLICATE_SAME_ACCESS);
+
+ CloseHandle(hStdin);
+
+ while (ok) {
+ ok = ReadFile(hStdinDup, chBuf, 4096, &dwRead, NULL);
+ if (ok && dwRead != 0)
+ emit receivedCommand(QString::fromLocal8Bit(chBuf));
+ }
+}
+#endif
+
+RemoteControl::RemoteControl(MainWindow *mainWindow, QHelpEngine *helpEngine)
+ : QObject(mainWindow)
+ , m_mainWindow(mainWindow)
+ , m_helpEngine(helpEngine)
+ , m_debug(false)
+ , m_caching(true)
+ , m_syncContents(false)
+ , m_expandTOC(-3)
+
+{
+ connect(m_mainWindow, SIGNAL(initDone()), this, SLOT(applyCache()));
+#ifdef Q_OS_WIN
+ StdInListenerWin *l = new StdInListenerWin(this);
+ connect(l, SIGNAL(receivedCommand(const QString&)),
+ this, SLOT(handleCommandString(const QString&)));
+ l->start();
+#else
+ QSocketNotifier *notifier = new QSocketNotifier(fileno(stdin),
+ QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(receivedData()));
+ notifier->setEnabled(true);
+#endif
+}
+
+void RemoteControl::receivedData()
+{
+ QByteArray ba;
+ while (true) {
+ char c = getc(stdin);
+ if (c == EOF || c == '\0')
+ break;
+ if (c)
+ ba.append(c);
+ if (c == '\n')
+ break;
+ }
+ handleCommandString(QString::fromLocal8Bit(ba));
+}
+
+void RemoteControl::handleCommandString(const QString &cmdString)
+{
+ QStringList cmds = cmdString.split(QLatin1Char(';'));
+ QStringList::const_iterator it = cmds.constBegin();
+ QString cmdLine, cmd, arg;
+ while (it != cmds.constEnd()) {
+ cmdLine = (*it).trimmed();
+ cmd = cmdLine;
+ arg.clear();
+ int i = cmdLine.indexOf(QLatin1Char(' '));
+ if (i > 0) {
+ cmd = cmdLine.left(i);
+ arg = cmdLine.mid(i+1);
+ }
+ cmd = cmd.toLower();
+
+ if (m_debug)
+ QMessageBox::information(0, tr("Debugging Remote Control"),
+ tr("Received Command: %1 %2").arg(cmd).arg(arg));
+
+ if (cmd == QLatin1String("debug")) {
+ if (arg == QLatin1String("on"))
+ m_debug = true;
+ else
+ m_debug = false;
+ } else if (cmd == QLatin1String("show")) {
+ if (arg.toLower() == QLatin1String("contents")) {
+ m_mainWindow->showContents();
+ } else if (arg.toLower() == QLatin1String("index")) {
+ m_mainWindow->showIndex();
+ } else if (arg.toLower() == QLatin1String("bookmarks")) {
+ m_mainWindow->showBookmarks();
+ } else if (arg.toLower() == QLatin1String("search")) {
+ m_mainWindow->showSearch();
+ }
+ } else if (cmd == QLatin1String("hide")) {
+ if (arg.toLower() == QLatin1String("contents")) {
+ m_mainWindow->hideContents();
+ } else if (arg.toLower() == QLatin1String("index")) {
+ m_mainWindow->hideIndex();
+ } else if (arg.toLower() == QLatin1String("bookmarks")) {
+ m_mainWindow->hideBookmarks();
+ } else if (arg.toLower() == QLatin1String("search")) {
+ m_mainWindow->hideSearch();
+ }
+ } else if (cmd == QLatin1String("setsource")) {
+ QUrl url(arg);
+ if (url.isValid()) {
+ if (url.isRelative())
+ url = CentralWidget::instance()->currentSource().resolved(url);
+ if (m_caching) {
+ clearCache();
+ m_setSource = url;
+ } else {
+ CentralWidget::instance()->setSource(url);
+ }
+ }
+ } else if (cmd == QLatin1String("synccontents")) {
+ if (m_caching)
+ m_syncContents = true;
+ else
+ m_mainWindow->syncContents();
+ } else if (cmd == QLatin1String("activatekeyword")) {
+ if (m_caching) {
+ clearCache();
+ m_activateKeyword = arg;
+ } else {
+ m_mainWindow->setIndexString(arg);
+ if (!arg.isEmpty())
+ m_helpEngine->indexWidget()->activateCurrentItem();
+ }
+ } else if (cmd == QLatin1String("activateidentifier")) {
+ if (m_caching) {
+ clearCache();
+ m_activateIdentifier = arg;
+ } else {
+ QMap<QString, QUrl> links =
+ m_helpEngine->linksForIdentifier(arg);
+ if (links.count())
+ CentralWidget::instance()->setSource(links.constBegin().value());
+ }
+ } else if (cmd == QLatin1String("expandtoc")) {
+ bool ok = false;
+ int depth = -1;
+ if (!arg.isEmpty())
+ depth = arg.toInt(&ok);
+ if (!ok)
+ depth = -1;
+
+ if (m_caching)
+ m_expandTOC = depth;
+ else
+ m_mainWindow->expandTOC(depth);
+ } else if (cmd == QLatin1String("setcurrentfilter")) {
+ if (m_caching) {
+ clearCache();
+ m_currentFilter = arg;
+ } else {
+ m_helpEngine->setCurrentFilter(arg);
+ }
+ } else {
+ return;
+ }
+ ++it;
+ }
+ m_mainWindow->raise();
+ m_mainWindow->activateWindow();
+}
+
+void RemoteControl::applyCache()
+{
+ if (m_setSource.isValid()) {
+ CentralWidget::instance()->setSource(m_setSource);
+ } else if (!m_activateKeyword.isEmpty()) {
+ m_mainWindow->setIndexString(m_activateKeyword);
+ m_helpEngine->indexWidget()->activateCurrentItem();
+ } else if (!m_activateIdentifier.isEmpty()) {
+ QMap<QString, QUrl> links =
+ m_helpEngine->linksForIdentifier(m_activateIdentifier);
+ if (links.count())
+ CentralWidget::instance()->setSource(links.constBegin().value());
+ } else if (!m_currentFilter.isEmpty()) {
+ m_helpEngine->setCurrentFilter(m_currentFilter);
+ }
+
+ if (m_syncContents)
+ m_mainWindow->syncContents();
+
+ if (m_expandTOC != -3)
+ m_mainWindow->expandTOC(m_expandTOC);
+
+ m_caching = false;
+}
+
+void RemoteControl::clearCache()
+{
+ m_currentFilter.clear();
+ m_setSource.clear();
+ m_syncContents = false;
+ m_activateKeyword.clear();
+ m_activateIdentifier.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/remotecontrol.h b/tools/assistant/tools/assistant/remotecontrol.h
new file mode 100644
index 0000000000..3c7c6c5fde
--- /dev/null
+++ b/tools/assistant/tools/assistant/remotecontrol.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 REMOTECONTROL_H
+#define REMOTECONTROL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class MainWindow;
+class QHelpEngine;
+
+class RemoteControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ RemoteControl(MainWindow *mainWindow, QHelpEngine *helpEngine);
+
+private slots:
+ void receivedData();
+ void handleCommandString(const QString &cmdString);
+ void applyCache();
+
+private:
+ void clearCache();
+
+private:
+ MainWindow *m_mainWindow;
+ QHelpEngine *m_helpEngine;
+ bool m_debug;
+
+ bool m_caching;
+ QUrl m_setSource;
+ bool m_syncContents;
+ QString m_activateKeyword;
+ QString m_activateIdentifier;
+ int m_expandTOC;
+ QString m_currentFilter;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/remotecontrol_win.h b/tools/assistant/tools/assistant/remotecontrol_win.h
new file mode 100644
index 0000000000..081eb25f66
--- /dev/null
+++ b/tools/assistant/tools/assistant/remotecontrol_win.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 REMOTECONTROL_WIN_H
+#define REMOTECONTROL_WIN_H
+
+#include <windows.h>
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+class StdInListenerWin : public QThread
+{
+ Q_OBJECT
+
+public:
+ StdInListenerWin(QObject *parent);
+ ~StdInListenerWin();
+
+signals:
+ void receivedCommand(const QString &cmd);
+
+private:
+ void run();
+ bool ok;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/assistant/searchwidget.cpp b/tools/assistant/tools/assistant/searchwidget.cpp
new file mode 100644
index 0000000000..000c73daf7
--- /dev/null
+++ b/tools/assistant/tools/assistant/searchwidget.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** 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 "searchwidget.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include <QtGui/QMenu>
+#include <QtGui/QLayout>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+#include <QtGui/QTextBrowser>
+
+#include <QtHelp/QHelpSearchEngine>
+#include <QtHelp/QHelpSearchQueryWidget>
+#include <QtHelp/QHelpSearchResultWidget>
+
+QT_BEGIN_NAMESPACE
+
+SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
+ : QWidget(parent)
+ , zoomCount(0)
+ , searchEngine(engine)
+{
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+
+ resultWidget = searchEngine->resultWidget();
+ QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget();
+
+ vLayout->addWidget(queryWidget);
+ vLayout->addWidget(resultWidget);
+
+ setFocusProxy(queryWidget);
+
+ connect(queryWidget, SIGNAL(search()), this, SLOT(search()));
+ connect(resultWidget, SIGNAL(requestShowLink(const QUrl&)),
+ this, SIGNAL(requestShowLink(const QUrl&)));
+
+ connect(searchEngine, SIGNAL(searchingStarted()), this, SLOT(searchingStarted()));
+ connect(searchEngine, SIGNAL(searchingFinished(int)), this, SLOT(searchingFinished(int)));
+
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ browser->viewport()->installEventFilter(this);
+}
+
+SearchWidget::~SearchWidget()
+{
+ // nothing todo
+}
+
+void SearchWidget::zoomIn()
+{
+#ifndef QT_CLUCENE_SUPPORT
+ return;
+#endif
+
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ if (browser && zoomCount != 10) {
+ zoomCount++;
+ browser->zoomIn();
+ }
+}
+
+void SearchWidget::zoomOut()
+{
+#ifndef QT_CLUCENE_SUPPORT
+ return;
+#endif
+
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ if (browser && zoomCount != -5) {
+ zoomCount--;
+ browser->zoomOut();
+ }
+}
+
+void SearchWidget::resetZoom()
+{
+#ifndef QT_CLUCENE_SUPPORT
+ return;
+#endif
+
+ if (zoomCount == 0)
+ return;
+
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ if (browser) {
+ browser->zoomOut(zoomCount);
+ zoomCount = 0;
+ }
+}
+
+void SearchWidget::search() const
+{
+ QList<QHelpSearchQuery> query = searchEngine->queryWidget()->query();
+ searchEngine->search(query);
+}
+
+void SearchWidget::searchingStarted()
+{
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+}
+
+void SearchWidget::searchingFinished(int hits)
+{
+ Q_UNUSED(hits)
+ qApp->restoreOverrideCursor();
+}
+
+bool SearchWidget::eventFilter(QObject* o, QEvent *e)
+{
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ if (browser && o == browser->viewport() && e->type() == QEvent::MouseButtonRelease){
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ QUrl link = resultWidget->linkAt(me->pos());
+ if (!link.isEmpty() || link.isValid()) {
+ bool controlPressed = me->modifiers() & Qt::ControlModifier;
+ if((me->button() == Qt::LeftButton && controlPressed)
+ || (me->button() == Qt::MidButton)) {
+ emit requestShowLinkInNewTab(link);
+ }
+ }
+ }
+ return QWidget::eventFilter(o,e);
+}
+
+void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
+{
+ if (keyEvent->key() == Qt::Key_Escape)
+ MainWindow::activateCurrentBrowser();
+ else
+ keyEvent->ignore();
+}
+
+void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
+{
+ QMenu menu;
+ QPoint point = contextMenuEvent->globalPos();
+
+#ifdef QT_CLUCENE_SUPPORT
+ QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
+ if (!browser)
+ return;
+
+ point = browser->mapFromGlobal(point);
+ if (!browser->rect().contains(point, true))
+ return;
+
+ QUrl link = browser->anchorAt(point);
+
+ QAction *copyAction = menu.addAction(tr("&Copy") +
+ QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL | Qt::Key_C))));
+ copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
+
+ QAction *copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
+ copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
+
+ QAction *newTabAction = menu.addAction(tr("Open Link in New Tab") +
+ QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL))) +
+ QLatin1String("LMB"));
+ newTabAction->setEnabled(!link.isEmpty() && link.isValid());
+
+ menu.addSeparator();
+
+ QAction *selectAllAction = menu.addAction(tr("Select All") +
+ QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL | Qt::Key_A))));
+
+ QAction *usedAction = menu.exec(mapToGlobal(contextMenuEvent->pos()));
+ if (usedAction == copyAction) {
+ QTextCursor cursor = browser->textCursor();
+ if (!cursor.isNull() && cursor.hasSelection()) {
+ QString selectedText = cursor.selectedText();
+ QMimeData *data = new QMimeData();
+ data->setText(selectedText);
+ QApplication::clipboard()->setMimeData(data);
+ }
+ }
+ else if (usedAction == copyAnchorAction) {
+ QApplication::clipboard()->setText(link.toString());
+ }
+ else if (usedAction == newTabAction) {
+ emit requestShowLinkInNewTab(link);
+ }
+ else if (usedAction == selectAllAction) {
+ browser->selectAll();
+ }
+#else
+ point = resultWidget->mapFromGlobal(point);
+ QUrl link = resultWidget->linkAt(point);
+ if (link.isEmpty() || !link.isValid())
+ return;
+
+ QAction *curTab = menu.addAction(tr("Open Link"));
+ QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
+
+ QAction *action = menu.exec(mapToGlobal(contextMenuEvent->pos()));
+ if (curTab == action)
+ emit requestShowLink(link);
+ else if (newTab == action)
+ emit requestShowLinkInNewTab(link);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/searchwidget.h b/tools/assistant/tools/assistant/searchwidget.h
new file mode 100644
index 0000000000..22fe80d823
--- /dev/null
+++ b/tools/assistant/tools/assistant/searchwidget.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 SEARCHWIDGET_H
+#define SEARCHWIDGET_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QPoint>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QHelpSearchEngine;
+class QHelpSearchResultWidget;
+
+class SearchWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ SearchWidget(QHelpSearchEngine *engine, QWidget *parent = 0);
+ ~SearchWidget();
+
+ void zoomIn();
+ void zoomOut();
+ void resetZoom();
+
+signals:
+ void requestShowLink(const QUrl &url);
+ void requestShowLinkInNewTab(const QUrl &url);
+
+private slots:
+ void search() const;
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ bool eventFilter(QObject* o, QEvent *e);
+ void keyPressEvent(QKeyEvent *keyEvent);
+ void contextMenuEvent(QContextMenuEvent *contextMenuEvent);
+
+private:
+ int zoomCount;
+ QHelpSearchEngine *searchEngine;
+ QHelpSearchResultWidget *resultWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // SEARCHWIDGET_H
diff --git a/tools/assistant/tools/assistant/topicchooser.cpp b/tools/assistant/tools/assistant/topicchooser.cpp
new file mode 100644
index 0000000000..3f30417ea5
--- /dev/null
+++ b/tools/assistant/tools/assistant/topicchooser.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** 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 <QtCore/QMap>
+#include <QtCore/QUrl>
+
+#include "topicchooser.h"
+
+QT_BEGIN_NAMESPACE
+
+TopicChooser::TopicChooser(QWidget *parent, const QString &keyword,
+ const QMap<QString, QUrl> &links)
+ : QDialog(parent)
+{
+ ui.setupUi(this);
+ ui.label->setText(tr("Choose a topic for <b>%1</b>:").arg(keyword));
+
+ m_links = links;
+ QMap<QString, QUrl>::const_iterator it = m_links.constBegin();
+ for (; it != m_links.constEnd(); ++it)
+ ui.listWidget->addItem(it.key());
+
+ if (ui.listWidget->count() != 0)
+ ui.listWidget->setCurrentRow(0);
+ ui.listWidget->setFocus();
+
+ connect(ui.buttonDisplay, SIGNAL(clicked()),
+ this, SLOT(accept()));
+ connect(ui.buttonCancel, SIGNAL(clicked()),
+ this, SLOT(reject()));
+ connect(ui.listWidget, SIGNAL(itemActivated(QListWidgetItem*)),
+ this, SLOT(accept()));
+}
+
+QUrl TopicChooser::link() const
+{
+ QListWidgetItem *item = ui.listWidget->currentItem();
+ if (!item)
+ return QUrl();
+
+ QString title = item->text();
+ if (title.isEmpty() || !m_links.contains(title))
+ return QUrl();
+
+ return m_links.value(title);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/topicchooser.h b/tools/assistant/tools/assistant/topicchooser.h
new file mode 100644
index 0000000000..58b3796f4c
--- /dev/null
+++ b/tools/assistant/tools/assistant/topicchooser.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 <QUrl>
+#include <QMap>
+#include <QString>
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class TopicChooser : public QDialog
+{
+ Q_OBJECT
+
+public:
+ TopicChooser(QWidget *parent, const QString &keyword,
+ const QMap<QString, QUrl> &links);
+
+ QUrl link() const;
+
+private:
+ Ui::TopicChooser ui;
+ QMap<QString, QUrl> m_links;
+};
+
+QT_END_NAMESPACE
+
+#endif // TOPICCHOOSER_H
diff --git a/tools/assistant/tools/assistant/topicchooser.ui b/tools/assistant/tools/assistant/topicchooser.ui
new file mode 100644
index 0000000000..d4c90bb4b3
--- /dev/null
+++ b/tools/assistant/tools/assistant/topicchooser.ui
@@ -0,0 +1,116 @@
+<UI version="4.0" stdsetdef="1" >
+ <class>TopicChooser</class>
+ <widget class="QDialog" name="TopicChooser" >
+ <property name="objectName" >
+ <string notr="true">TopicChooser</string>
+ </property>
+ <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="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true">unnamed</string>
+ </property>
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="objectName" >
+ <string notr="true">label</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Topics</string>
+ </property>
+ <property name="buddy" stdset="0" >
+ <cstring>listWidget</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="objectName" >
+ <string notr="true">listWidget</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="Layout16" >
+ <property name="objectName" >
+ <string notr="true">Layout16</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="objectName" >
+ <string notr="true">unnamed</string>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer name="Horizontal Spacing2" >
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="sizeType" >
+ <enum>Expanding</enum>
+ </property>
+ <property name="orientation" >
+ <enum>Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDisplay" >
+ <property name="objectName" >
+ <string notr="true">buttonDisplay</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="objectName" >
+ <string notr="true">buttonCancel</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+</UI>
diff --git a/tools/assistant/tools/qcollectiongenerator/main.cpp b/tools/assistant/tools/qcollectiongenerator/main.cpp
new file mode 100644
index 0000000000..68db53ff63
--- /dev/null
+++ b/tools/assistant/tools/qcollectiongenerator/main.cpp
@@ -0,0 +1,559 @@
+/****************************************************************************
+**
+** 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 "../shared/helpgenerator.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QMap>
+#include <QtCore/QFileInfo>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
+#include <QtCore/QBuffer>
+
+#include <private/qhelpgenerator_p.h>
+#include <private/qhelpprojectdata_p.h>
+#include <QtHelp/QHelpEngineCore>
+
+#include <QtXml/QXmlStreamReader>
+
+QT_USE_NAMESPACE
+
+class CollectionConfigReader : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+
+ QString title() const { return m_title; }
+ QString homePage() const { return m_homePage; }
+ QString startPage() const { return m_startPage; }
+ QString applicationIcon() const { return m_applicationIcon; }
+ QString currentFilter() const { return m_currentFilter; }
+ bool enableFilterFunctionality() const
+ { return m_enableFilterFunctionality; }
+ bool hideFilterFunctionality() const
+ { return m_hideFilterFunctionality; }
+ bool enableAddressBar() const { return m_enableAddressBar; }
+ bool hideAddressBar() const { return m_hideAddressBar; }
+ bool enableDocumentationManager() const
+ { return m_enableDocumentationManager; }
+
+ QMap<QString, QString> aboutMenuTexts() const
+ { return m_aboutMenuTexts; }
+ QString aboutIcon() const { return m_aboutIcon; }
+ QMap<QString, QString> aboutTextFiles() const
+ { return m_aboutTextFiles; }
+
+ QMap<QString, QString> filesToGenerate() const
+ { return m_filesToGenerate; }
+
+ QStringList filesToRegister() const { return m_filesToRegister; }
+
+ QString cacheDirectory() const { return m_cacheDirectory; }
+
+private:
+ void raiseErrorWithLine();
+ void readConfig();
+ void readAssistantSettings();
+ void readMenuTexts();
+ void readAboutDialog();
+ void readDocFiles();
+ void readGenerate();
+ void readFiles();
+ void readRegister();
+
+ QString m_title;
+ QString m_homePage;
+ QString m_startPage;
+ QString m_applicationIcon;
+ QString m_currentFilter;
+ bool m_enableFilterFunctionality;
+ bool m_hideFilterFunctionality;
+ bool m_enableAddressBar;
+ bool m_hideAddressBar;
+ bool m_enableDocumentationManager;
+ QMap<QString, QString> m_aboutMenuTexts;
+ QString m_aboutIcon;
+ QMap<QString, QString> m_aboutTextFiles;
+ QMap<QString, QString> m_filesToGenerate;
+ QStringList m_filesToRegister;
+ QString m_cacheDirectory;
+};
+
+void CollectionConfigReader::raiseErrorWithLine()
+{
+ raiseError(QObject::tr("Unknown token at line %1.")
+ .arg(lineNumber()));
+}
+
+void CollectionConfigReader::readData(const QByteArray &contents)
+{
+ m_enableFilterFunctionality = true;
+ m_hideFilterFunctionality = true;
+ m_enableAddressBar = true;
+ m_hideAddressBar = true;
+ m_enableDocumentationManager = true;
+
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("QHelpCollectionProject")
+ && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
+ readConfig();
+ else
+ raiseError(QObject::tr("Unknown token at line %1. Expected \"QtHelpCollectionProject\"!")
+ .arg(lineNumber()));
+ }
+ }
+}
+
+void CollectionConfigReader::readConfig()
+{
+ bool ok = false;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("assistant"))
+ readAssistantSettings();
+ else if (name() == QLatin1String("docFiles"))
+ readDocFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("QHelpCollectionProject")) {
+ ok = true;
+ }
+ }
+ if (!ok && !hasError())
+ raiseError(QLatin1String("Missing end tags."));
+}
+
+void CollectionConfigReader::readAssistantSettings()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("title")) {
+ m_title = readElementText();
+ } else if (name() == QLatin1String("homePage")) {
+ m_homePage = readElementText();
+ } else if (name() == QLatin1String("startPage")) {
+ m_startPage = readElementText();
+ } else if (name() == QLatin1String("currentFilter")) {
+ m_currentFilter = readElementText();
+ } else if (name() == QLatin1String("applicationIcon")) {
+ m_applicationIcon = readElementText();
+ } else if (name() == QLatin1String("enableFilterFunctionality")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideFilterFunctionality = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableFilterFunctionality = false;
+ } else if (name() == QLatin1String("enableDocumentationManager")) {
+ if (readElementText() == QLatin1String("false"))
+ m_enableDocumentationManager = false;
+ } else if (name() == QLatin1String("enableAddressBar")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideAddressBar = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableAddressBar = false;
+ } else if (name() == QLatin1String("aboutMenuText")) {
+ readMenuTexts();
+ } else if (name() == QLatin1String("aboutDialog")) {
+ readAboutDialog();
+ } else if (name() == "cacheDirectory") {
+ m_cacheDirectory = readElementText();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("assistant")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readMenuTexts()
+{
+ while (!atEnd())
+ {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("text")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutMenuTexts.insert(lang, readElementText());
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutMenuText")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readAboutDialog()
+{
+ while (!atEnd())
+ {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutTextFiles.insert(lang, readElementText());
+ } else if (name() == QLatin1String("icon")) {
+ m_aboutIcon = readElementText();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutDialog")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readDocFiles()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("generate")) {
+ readGenerate();
+ } else if (name() == QLatin1String("register")) {
+ readRegister();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("docFiles")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readGenerate()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ readFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("generate")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readFiles()
+{
+ QString input;
+ QString output;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("input"))
+ input = readElementText();
+ else if (name() == QLatin1String("output"))
+ output = readElementText();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("file")) {
+ break;
+ }
+ }
+ if (input.isEmpty() || output.isEmpty()) {
+ raiseError(QLatin1String("Missing input or output file for help file generation!"));
+ return;
+ }
+ m_filesToGenerate.insert(input, output);
+}
+
+void CollectionConfigReader::readRegister()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ m_filesToRegister.append(readElementText());
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("register")) {
+ break;
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QString error;
+ QString arg;
+ QString collectionFile;
+ QString configFile;
+ QString basePath;
+ bool showHelp = false;
+ bool showVersion = false;
+
+ for (int i=1; i<argc; ++i) {
+ arg = QString::fromLocal8Bit(argv[i]);
+ if (arg == QLatin1String("-o")) {
+ if (++i < argc) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[i]));
+ collectionFile = fi.absoluteFilePath();
+ } else {
+ error = QObject::tr("Missing output file name!");
+ }
+ } else if (arg == QLatin1String("-h")) {
+ showHelp = true;
+ } else if (arg == QLatin1String("-v")) {
+ showVersion = true;
+ } else {
+ QFileInfo fi(arg);
+ configFile = fi.absoluteFilePath();
+ basePath = fi.absolutePath();
+ }
+ }
+
+ if (showVersion) {
+ fprintf(stdout, "Qt Collection Generator version 1.0 (Qt %s)\n", QT_VERSION_STR);
+ return 0;
+ }
+
+ if (configFile.isEmpty() && !showHelp)
+ error = QObject::tr("Missing collection config file!");
+
+ QString help = QObject::tr("\nUsage:\n\n"
+ "qcollectiongenerator <collection-config-file> [options]\n\n"
+ " -o <collection-file> Generates a collection file\n"
+ " called <collection-file>. If\n"
+ " this option is not specified\n"
+ " a default name will be used.\n"
+ " -v Displays the version of\n"
+ " qcollectiongenerator.\n\n");
+
+ if (showHelp) {
+ fprintf(stdout, "%s", qPrintable(help));
+ return 0;
+ }else if (!error.isEmpty()) {
+ fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
+ return -1;
+ }
+
+ QFile file(configFile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Could not open %s!\n", qPrintable(configFile));
+ return -1;
+ }
+
+ if (collectionFile.isEmpty()) {
+ QFileInfo fi(configFile);
+ collectionFile = basePath + QDir::separator()
+ + fi.baseName() + QLatin1String(".qhc");
+ }
+
+ QCoreApplication app(argc, argv);
+
+ fprintf(stdout, "Reading collection config file...\n");
+ CollectionConfigReader config;
+ config.readData(file.readAll());
+ if (config.hasError()) {
+ fprintf(stderr, "Collection config file error: %s\n", qPrintable(config.errorString()));
+ return -1;
+ }
+
+ QMap<QString, QString>::const_iterator it = config.filesToGenerate().constBegin();
+ while (it != config.filesToGenerate().constEnd()) {
+ fprintf(stdout, "Generating help for %s...\n", qPrintable(it.key()));
+ QHelpProjectData helpData;
+ if (!helpData.readData(basePath + QDir::separator() + it.key())) {
+ fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
+ return -1;
+ }
+
+ HelpGenerator helpGenerator;
+ if (!helpGenerator.generate(&helpData, basePath + QDir::separator() + it.value())) {
+ fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
+ return -1;
+ }
+ ++it;
+ }
+
+ fprintf(stdout, "Creating collection file...\n");
+
+ QFileInfo colFi(collectionFile);
+ if (colFi.exists()) {
+ if (!colFi.dir().remove(colFi.fileName())) {
+ fprintf(stderr, "The file %s cannot be overwritten!\n", qPrintable(collectionFile));
+ return -1;
+ }
+ }
+
+ QHelpEngineCore helpEngine(collectionFile);
+ if (!helpEngine.setupData()) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+
+ foreach (const QString &file, config.filesToRegister()) {
+ if (!helpEngine.registerDocumentation(basePath + QDir::separator() + file)) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+ }
+
+ if (!config.title().isEmpty())
+ helpEngine.setCustomValue(QLatin1String("WindowTitle"), config.title());
+
+ if (!config.homePage().isEmpty()) {
+ helpEngine.setCustomValue(QLatin1String("defaultHomepage"),
+ config.homePage());
+ }
+
+ if (!config.startPage().isEmpty())
+ helpEngine.setCustomValue(QLatin1String("LastShownPages"), config.startPage());
+
+ if (!config.currentFilter().isEmpty())
+ helpEngine.setCustomValue(QLatin1String("CurrentFilter"), config.currentFilter());
+
+ if (!config.cacheDirectory().isEmpty())
+ helpEngine.setCustomValue(QLatin1String("CacheDirectory"), config.cacheDirectory());
+
+ helpEngine.setCustomValue(QLatin1String("EnableFilterFunctionality"),
+ config.enableFilterFunctionality());
+ helpEngine.setCustomValue(QLatin1String("HideFilterFunctionality"),
+ config.hideFilterFunctionality());
+ helpEngine.setCustomValue(QLatin1String("EnableDocumentationManager"),
+ config.enableDocumentationManager());
+ helpEngine.setCustomValue(QLatin1String("EnableAddressBar"),
+ config.enableAddressBar());
+ helpEngine.setCustomValue(QLatin1String("HideAddressBar"),
+ config.hideAddressBar());
+ helpEngine.setCustomValue(QLatin1String("CreationTime"),
+ QDateTime::currentDateTime().toTime_t());
+
+ if (!config.applicationIcon().isEmpty()) {
+ QFile icon(basePath + QDir::separator() + config.applicationIcon());
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName()));
+ return -1;
+ }
+ helpEngine.setCustomValue(QLatin1String("ApplicationIcon"), icon.readAll());
+ }
+
+ if (config.aboutMenuTexts().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ QMap<QString, QString>::const_iterator it = config.aboutMenuTexts().constBegin();
+ while (it != config.aboutMenuTexts().constEnd()) {
+ s << it.key();
+ s << it.value();
+ ++it;
+ }
+ helpEngine.setCustomValue(QLatin1String("AboutMenuTexts"), ba);
+ }
+
+ if (!config.aboutIcon().isEmpty()) {
+ QFile icon(basePath + QDir::separator() + config.aboutIcon());
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName()));
+ return -1;
+ }
+ helpEngine.setCustomValue(QLatin1String("AboutIcon"), icon.readAll());
+ }
+
+ if (config.aboutTextFiles().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ QMap<QString, QString>::const_iterator it = config.aboutTextFiles().constBegin();
+ QMap<QString, QByteArray> imgData;
+
+ QRegExp srcRegExp(QLatin1String("src=(\"(.+)\"|([^\"\\s]+)).*>"));
+ srcRegExp.setMinimal(true);
+ QRegExp imgRegExp(QLatin1String("(<img[^>]+>)"));
+ imgRegExp.setMinimal(true);
+
+ while (it != config.aboutTextFiles().constEnd()) {
+ s << it.key();
+ QFileInfo fi(basePath + QDir::separator() + it.value());
+ QFile f(fi.absoluteFilePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Cannot open %s!\n", qPrintable(f.fileName()));
+ return -1;
+ }
+ QByteArray data = f.readAll();
+ s << data;
+
+ QString contents = QString::fromUtf8(data);
+ int pos = 0;
+ while ((pos = imgRegExp.indexIn(contents, pos)) != -1) {
+ QString imgTag = imgRegExp.cap(1);
+ pos += imgRegExp.matchedLength();
+
+ if (srcRegExp.indexIn(imgTag, 0) != -1) {
+ QString src = srcRegExp.cap(2);
+ if (src.isEmpty())
+ src = srcRegExp.cap(3);
+
+ QFile img(fi.absolutePath() + QDir::separator() + src);
+ if (img.open(QIODevice::ReadOnly)) {
+ if (!imgData.contains(src))
+ imgData.insert(src, img.readAll());
+ } else {
+ fprintf(stderr, "Cannot open referenced image file %s!\n",
+ qPrintable(img.fileName()));
+ }
+ }
+ }
+ ++it;
+ }
+ helpEngine.setCustomValue(QLatin1String("AboutTexts"), ba);
+ if (imgData.count()) {
+ QByteArray imageData;
+ QBuffer buffer(&imageData);
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream out(&buffer);
+ out << imgData;
+ helpEngine.setCustomValue(QLatin1String("AboutImages"), imageData);
+ }
+ }
+
+ return 0;
+}
diff --git a/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro b/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
new file mode 100644
index 0000000000..cf70e48b9b
--- /dev/null
+++ b/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
@@ -0,0 +1,14 @@
+QT += xml network
+TEMPLATE = app
+DESTDIR = ../../../../bin
+TARGET = qcollectiongenerator
+CONFIG += qt warn_on help console
+CONFIG -= app_bundle
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+SOURCES += ../shared/helpgenerator.cpp \
+ main.cpp
+
+HEADERS += ../shared/helpgenerator.h
diff --git a/tools/assistant/tools/qhelpconverter/adpreader.cpp b/tools/assistant/tools/qhelpconverter/adpreader.cpp
new file mode 100644
index 0000000000..930417a26d
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/adpreader.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** 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 "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+void AdpReader::readData(const QByteArray &contents)
+{
+ clear();
+ m_contents.clear();
+ m_keywords.clear();
+ m_properties.clear();
+ m_files.clear();
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name().toString().toLower() == QLatin1String("assistantconfig")
+ && attributes().value(QLatin1String("version")) == QLatin1String("3.2.0")) {
+ readProject();
+ } else if (name().toString().toLower() == QLatin1String("dcf")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, 0));
+ readDCF();
+ } else {
+ raiseError();
+ }
+ }
+ }
+}
+
+QList<ContentItem> AdpReader::contents() const
+{
+ return m_contents;
+}
+
+QList<KeywordItem> AdpReader::keywords() const
+{
+ return m_keywords;
+}
+
+QSet<QString> AdpReader::files() const
+{
+ return m_files;
+}
+
+QMap<QString, QString> AdpReader::properties() const
+{
+ return m_properties;
+}
+
+void AdpReader::readProject()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ QString s = name().toString().toLower();
+ if (s == QLatin1String("profile")) {
+ readProfile();
+ } else if (s == QLatin1String("dcf")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, 0));
+ readDCF();
+ } else {
+ raiseError();
+ }
+ }
+ }
+}
+
+void AdpReader::readProfile()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name().toString().toLower() == QLatin1String("property")) {
+ QString prop = attributes().value(QLatin1String("name")).toString().toLower();
+ m_properties[prop] = readElementText();
+ } else {
+ raiseError();
+ }
+ } else if (isEndElement()) {
+ break;
+ }
+ }
+}
+
+void AdpReader::readDCF()
+{
+ int depth = 0;
+ while (!atEnd()) {
+ readNext();
+ QString str = name().toString().toLower();
+ if (isStartElement()) {
+ if (str == QLatin1String("section")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, ++depth));
+ } else if (str == QLatin1String("keyword")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_keywords.append(KeywordItem(readElementText(), ref));
+ } else {
+ raiseError();
+ }
+ } else if (isEndElement()) {
+ if (str == QLatin1String("section"))
+ --depth;
+ else if (str == QLatin1String("dcf"))
+ break;
+ }
+ }
+}
+
+void AdpReader::addFile(const QString &file)
+{
+ QString s = file;
+ if (s.startsWith(QLatin1String("./")))
+ s = s.mid(2);
+ int i = s.indexOf(QLatin1Char('#'));
+ if (i > -1)
+ s = s.left(i);
+ if (!m_files.contains(s))
+ m_files.insert(s);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/adpreader.h b/tools/assistant/tools/qhelpconverter/adpreader.h
new file mode 100644
index 0000000000..a7fa606c44
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/adpreader.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 ADPREADER_H
+#define ADPREADER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtXml/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+struct ContentItem {
+ ContentItem(const QString &t, const QString &r, int d)
+ : title(t), reference(r), depth(d) {}
+ QString title;
+ QString reference;
+ int depth;
+};
+
+struct KeywordItem {
+ KeywordItem(const QString &k, const QString &r)
+ : keyword(k), reference(r) {}
+ QString keyword;
+ QString reference;
+};
+
+class AdpReader : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+ QList<ContentItem> contents() const;
+ QList<KeywordItem> keywords() const;
+ QSet<QString> files() const;
+
+ QMap<QString, QString> properties() const;
+
+private:
+ void readProject();
+ void readProfile();
+ void readDCF();
+ void addFile(const QString &file);
+
+ QMap<QString, QString> m_properties;
+ QList<ContentItem> m_contents;
+ QList<KeywordItem> m_keywords;
+ QSet<QString> m_files;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/assistant-128.png b/tools/assistant/tools/qhelpconverter/assistant-128.png
new file mode 100644
index 0000000000..f05949f6d8
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/assistant-128.png
Binary files differ
diff --git a/tools/assistant/tools/qhelpconverter/assistant.png b/tools/assistant/tools/qhelpconverter/assistant.png
new file mode 100644
index 0000000000..ea4d1e70c1
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/assistant.png
Binary files differ
diff --git a/tools/assistant/tools/qhelpconverter/conversionwizard.cpp b/tools/assistant/tools/qhelpconverter/conversionwizard.cpp
new file mode 100644
index 0000000000..c3fe94a000
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/conversionwizard.cpp
@@ -0,0 +1,265 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QVariant>
+#include <QtCore/QTimer>
+#include <QtGui/QApplication>
+#include <QtGui/QMouseEvent>
+
+#include "conversionwizard.h"
+#include "inputpage.h"
+#include "generalpage.h"
+#include "filterpage.h"
+#include "identifierpage.h"
+#include "pathpage.h"
+#include "filespage.h"
+#include "outputpage.h"
+#include "finishpage.h"
+#include "qhpwriter.h"
+#include "qhcpwriter.h"
+#include "helpwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+ConversionWizard::ConversionWizard()
+{
+ setWindowIcon(QIcon(QLatin1String(":/trolltech/qhelpconverter/assistant.png")));
+ setWindowTitle(tr("Help Conversion Wizard"));
+ setPixmap(QWizard::WatermarkPixmap,
+ QPixmap(QLatin1String(":/trolltech/qhelpconverter/assistant-128.png"))) ;
+ setOptions(QWizard::IndependentPages|QWizard::NoBackButtonOnLastPage
+ |QWizard::HaveHelpButton);
+
+ m_inputPage = new InputPage(&m_adpReader);
+ setPage(Input_Page, m_inputPage);
+
+ m_generalPage = new GeneralPage();
+ setPage(General_Page, m_generalPage);
+
+ m_filterPage = new FilterPage();
+ setPage(Filter_Page, m_filterPage);
+ m_filterPage->setMaximumHeight(240);
+
+ m_identifierPage = new IdentifierPage();
+ setPage(Identifier_Page, m_identifierPage);
+
+ m_pathPage = new PathPage();
+ setPage(Path_Page, m_pathPage);
+ m_pathPage->setMaximumHeight(240);
+
+ m_filesPage = new FilesPage();
+ setPage(Files_Page, m_filesPage);
+ m_filesPage->setMaximumHeight(240);
+
+ m_outputPage = new OutputPage();
+ setPage(Output_Page, m_outputPage);
+ m_outputPage->setMaximumHeight(240);
+
+ m_finishPage = new FinishPage();
+ setPage(Finish_Page, m_finishPage);
+ m_finishPage->setMaximumHeight(240);
+
+ connect(this, SIGNAL(currentIdChanged(int)),
+ this, SLOT(pageChanged(int)));
+
+ m_helpWindow = 0;
+ qApp->installEventFilter(this);
+
+ QAbstractButton *btn = button(QWizard::HelpButton);
+ btn->setCheckable(true);
+ connect(btn, SIGNAL(toggled(bool)), this, SLOT(showHelp(bool)));
+}
+
+void ConversionWizard::setAdpFileName(const QString &fileName)
+{
+ setField(QLatin1String("adpFileName"), fileName);
+}
+
+void ConversionWizard::initializePage(int id)
+{
+ switch (id) {
+ case Path_Page: {
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_pathPage->setPath(fi.absolutePath());
+ break;
+ }
+ case Output_Page: {
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_outputPage->setPath(fi.absolutePath());
+ setField(QLatin1String("ProjectFileName"), fi.baseName()
+ + QLatin1String(".qhp"));
+ setField(QLatin1String("CollectionFileName"), fi.baseName()
+ + QLatin1String(".qhcp"));
+ break;
+ }
+ }
+}
+
+void ConversionWizard::pageChanged(int id)
+{
+ if (id == Files_Page) {
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ m_files.clear();
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ QDir rootDir = fi.absolutePath();
+ foreach (const QString &p, m_pathPage->paths()) {
+ QDir dir(p);
+ QString rel = rootDir.relativeFilePath(dir.absolutePath());
+ if (!rel.isEmpty())
+ rel.append(QLatin1Char('/'));
+ foreach (const QString &f, dir.entryList(m_pathPage->filters()))
+ m_files.append(rel + f);
+ }
+ m_filesPage->setFilesToRemove(getUnreferencedFiles(m_files));
+ QApplication::restoreOverrideCursor();
+ } else if (id == Output_Page) {
+ m_outputPage->setCollectionComponentEnabled(
+ !m_adpReader.properties().isEmpty());
+ } else if (id == Finish_Page) {
+ QTimer::singleShot(300, this, SLOT(convert()));
+ }
+}
+
+void ConversionWizard::showHelp(bool toggle)
+{
+ int w = 180;
+ int h = 180;
+ if (!m_helpWindow) {
+ m_helpWindow = new HelpWindow(this);
+ m_helpWindow->setMaximumWidth(w);
+ m_helpWindow->setMaximumHeight(h);
+ m_helpWindow->setMinimumHeight(h);
+ }
+
+ if (toggle) {
+ m_helpWindow->setHelp(currentPage()->objectName());
+ QAbstractButton *btn = button(QWizard::HelpButton);
+ QPoint p = btn->pos();
+ int x = p.x();
+ if (btn->pos().x() > w)
+ x = p.x() + btn->width() - w;
+ m_helpWindow->move(x, p.y()-h);
+ m_helpWindow->show();
+ } else {
+ m_helpWindow->hide();
+ }
+}
+
+bool ConversionWizard::eventFilter(QObject *obj, QEvent *e)
+{
+ if (m_helpWindow && m_helpWindow->isVisible()) {
+ if (obj != button(QWizard::HelpButton)
+ && e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (!m_helpWindow->geometry().contains(mapFromParent(me->globalPos()))) {
+ m_helpWindow->hide();
+ button(QWizard::HelpButton)->setChecked(false);
+ }
+ } else if (e->type() == QEvent::KeyPress) {
+ m_helpWindow->hide();
+ button(QWizard::HelpButton)->setChecked(false);
+ }
+ }
+ return QWizard::eventFilter(obj, e);
+}
+
+QStringList ConversionWizard::getUnreferencedFiles(const QStringList &files)
+{
+ QStringList lst;
+ QSet<QString> adpFiles = m_adpReader.files();
+ foreach (const QString &s, files) {
+ if (!adpFiles.contains(s))
+ lst.append(s);
+ }
+ return lst;
+}
+
+void ConversionWizard::convert()
+{
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_finishPage->appendMessage(tr("Converting %1...")
+ .arg(fi.fileName()));
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ QString qhpFileName = field(QLatin1String("ProjectFileName")).toString();
+ QhpWriter qhpWriter(field(QLatin1String("namespaceName")).toString(),
+ field(QLatin1String("virtualFolder")).toString());
+ qhpWriter.setAdpReader(&m_adpReader);
+ qhpWriter.setFilterAttributes(m_filterPage->filterAttributes());
+ qhpWriter.setCustomFilters(m_filterPage->customFilters());
+
+ foreach (const QString &f, m_filesPage->filesToRemove())
+ m_files.removeAll(f);
+ qhpWriter.setFiles(m_files);
+
+ if (field(QLatin1String("createIdentifier")).toBool()) {
+ if (field(QLatin1String("fileNamePrefix")).toBool())
+ qhpWriter.generateIdentifiers(QhpWriter::FilePrefix);
+ else
+ qhpWriter.generateIdentifiers(QhpWriter::GlobalPrefix,
+ field(QLatin1String("globalPrefix")).toString());
+ } else {
+ qhpWriter.generateIdentifiers(QhpWriter::SkipAll);
+ }
+
+ qhpWriter.writeFile(fi.absolutePath() + QDir::separator()
+ + qhpFileName);
+
+ m_finishPage->appendMessage(tr("Writing help collection file..."));
+
+ if (!m_adpReader.properties().isEmpty()) {
+ QhcpWriter qhcpWriter;
+ qhcpWriter.setHelpProjectFile(qhpFileName);
+ qhcpWriter.setProperties(m_adpReader.properties());
+ qhcpWriter.setTitlePath(QLatin1String("qthelp://")
+ + field(QLatin1String("namespaceName")).toString()
+ + QLatin1String("/")
+ +field(QLatin1String("virtualFolder")).toString());
+ qhcpWriter.writeFile(fi.absolutePath() + QDir::separator()
+ + field(QLatin1String("CollectionFileName")).toString());
+ }
+
+ m_finishPage->appendMessage(tr("Done."));
+ QApplication::restoreOverrideCursor();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/conversionwizard.h b/tools/assistant/tools/qhelpconverter/conversionwizard.h
new file mode 100644
index 0000000000..4c8fb02740
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/conversionwizard.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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 CONVERSIONWIZARD_H
+#define CONVERSIONWIZARD_H
+
+#include <QtGui/QWizard>
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+class InputPage;
+class GeneralPage;
+class FilterPage;
+class IdentifierPage;
+class PathPage;
+class FilesPage;
+class OutputPage;
+class FinishPage;
+class HelpWindow;
+
+class ConversionWizard : public QWizard
+{
+ Q_OBJECT
+
+public:
+ ConversionWizard();
+ void setAdpFileName(const QString &fileName);
+
+private slots:
+ void pageChanged(int id);
+ void showHelp(bool toggle);
+ void convert();
+
+private:
+ enum Pages {Input_Page, General_Page, Filter_Page,
+ Identifier_Page, Path_Page, Files_Page, Output_Page,
+ Finish_Page};
+ void initializePage(int id);
+ QStringList getUnreferencedFiles(const QStringList &files);
+ bool eventFilter(QObject *obj, QEvent *e);
+
+ AdpReader m_adpReader;
+ InputPage *m_inputPage;
+ GeneralPage *m_generalPage;
+ FilterPage *m_filterPage;
+ IdentifierPage *m_identifierPage;
+ PathPage *m_pathPage;
+ FilesPage *m_filesPage;
+ OutputPage *m_outputPage;
+ FinishPage *m_finishPage;
+ QStringList m_files;
+ HelpWindow *m_helpWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/doc/filespage.html b/tools/assistant/tools/qhelpconverter/doc/filespage.html
new file mode 100644
index 0000000000..a7aac18da5
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/filespage.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<p>Sometimes it can happen that the previously specified paths contain
+more or other files than actually needed for the documentation.</p>
+<p>This page lists all files which are likely to be unused because they
+are neither referenced by any keyword nor be the TOC.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/filterpage.html b/tools/assistant/tools/qhelpconverter/doc/filterpage.html
new file mode 100644
index 0000000000..7b3781bd5b
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/filterpage.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<p>The help system offers the possibility to filter all installed documentations
+for certain <b>attributes</b>. Commonly specified attributes are e.g. the company
+and product name as well as the product version.</p>
+<p>The help engine and Assistant use <b>custom filters</b> to do the actual
+documentation filtering. A custom filter is basically just a alias name for a
+list of filter attributes. So, if e.g. the custom filter "MyFilter" lists
+the attributes "mycompany, myproduct" then only the documentation with those
+attributes will be shown.</p>
+<p><b>Warning:</b> The filter attributes are case sensitive!</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/generalpage.html b/tools/assistant/tools/qhelpconverter/doc/generalpage.html
new file mode 100644
index 0000000000..8d106bec11
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/generalpage.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<p>The <b>namespace</b> is needed to identify this documentation when having
+several documentation sets installed in a collection.</p>
+<p><b>Virtual</b> folders are used to enable file references between all
+documents. Thereby, the virtual folder acts as the root path of all
+documents, even if those are part of different documentation sets,
+meaning listed under different namespaces.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/identifierpage.html b/tools/assistant/tools/qhelpconverter/doc/identifierpage.html
new file mode 100644
index 0000000000..952b88de81
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/identifierpage.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<p><b>Identifiers</b> are mostly used to make keywords unique, but they can also
+be used to specify keywords which should not be shown in the index. Identifiers
+are especially help full when using context sensitive help and one keyword has
+more links assigned to it.</p>
+<p>E.g. consider the keyword "replace" in Qt. It is
+included, among others, in QString and QList. To be able to retrieve the proper
+documentation, there is an identifier "QString::replace" and one
+"QList::replace".</p>
+<p>A <b>global prefix</b>, e.g. "MyApp::" is set for all keywords independent
+where they are located. When <b>inheriting</b> the prefix from the file name,
+the keywords get the prefix "[filename]::" where the file name is taken from the
+reference of the keyword. The file name is just the base name, i.e. without any
+directory or extension.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/inputpage.html b/tools/assistant/tools/qhelpconverter/doc/inputpage.html
new file mode 100644
index 0000000000..4054c54729
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/inputpage.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>Both, a .adp or .dcf file can be specified. If an .adp file is detected,
+the wizard generates a Qt help collection file in addition to the help
+project file.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/outputpage.html b/tools/assistant/tools/qhelpconverter/doc/outputpage.html
new file mode 100644
index 0000000000..332ef69fcc
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/outputpage.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>The specified output files will be located in the same directory as the
+.adp or .dcf file. The collection file will only be generated if the input
+file was an .adp file.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/doc/pathpage.html b/tools/assistant/tools/qhelpconverter/doc/pathpage.html
new file mode 100644
index 0000000000..95449b3c38
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/doc/pathpage.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<p>The new help system uses, in contrast to the old Qt Assistant, compressed
+help files containing all files (html files, images, stylesheets, ...)
+necessary to display the documentation correctly.</p>
+<p>To be able to find all those files, the source paths have to be given.</p>
+</body>
+</html>
diff --git a/tools/assistant/tools/qhelpconverter/filespage.cpp b/tools/assistant/tools/qhelpconverter/filespage.cpp
new file mode 100644
index 0000000000..29631557a7
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filespage.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 <QtGui/QKeyEvent>
+#include "filespage.h"
+
+QT_BEGIN_NAMESPACE
+
+FilesPage::FilesPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Unreferenced Files"));
+ setSubTitle(tr("Remove files which are neither referenced "
+ "by a keyword nor by the TOC."));
+
+ m_ui.setupUi(this);
+ m_ui.fileListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_ui.fileListWidget->installEventFilter(this);
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removeFile()));
+ connect(m_ui.removeAllButton, SIGNAL(clicked()),
+ this, SLOT(removeAllFiles()));
+
+ m_ui.fileLabel->setText(tr("<p><b>Warning:</b> Be aware "
+ "when removing images or stylesheets since those files "
+ "are not directly referenced by the .adp or .dcf "
+ "file.</p>"));
+}
+
+void FilesPage::setFilesToRemove(const QStringList &files)
+{
+ m_files = files;
+ m_ui.fileListWidget->clear();
+ m_ui.fileListWidget->addItems(files);
+}
+
+QStringList FilesPage::filesToRemove() const
+{
+ return m_filesToRemove;
+}
+
+void FilesPage::removeFile()
+{
+ int row = m_ui.fileListWidget->currentRow()
+ - m_ui.fileListWidget->selectedItems().count() + 1;
+ foreach (const QListWidgetItem *item, m_ui.fileListWidget->selectedItems()) {
+ m_filesToRemove.append(item->text());
+ delete item;
+ }
+ if (m_ui.fileListWidget->count() > row && row >= 0)
+ m_ui.fileListWidget->setCurrentRow(row);
+ else
+ m_ui.fileListWidget->setCurrentRow(m_ui.fileListWidget->count());
+}
+
+void FilesPage::removeAllFiles()
+{
+ m_ui.fileListWidget->clear();
+ m_filesToRemove = m_files;
+}
+
+bool FilesPage::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj == m_ui.fileListWidget && event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (ke->key() == Qt::Key_Delete) {
+ removeFile();
+ return true;
+ }
+ }
+ return QWizardPage::eventFilter(obj, event);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/filespage.h b/tools/assistant/tools/qhelpconverter/filespage.h
new file mode 100644
index 0000000000..584af873e2
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filespage.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 FILESPAGE_H
+#define FILESPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_filespage.h"
+
+QT_BEGIN_NAMESPACE
+
+class FilesPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FilesPage(QWidget *parent = 0);
+ void setFilesToRemove(const QStringList &files);
+ QStringList filesToRemove() const;
+
+private slots:
+ void removeFile();
+ void removeAllFiles();
+
+private:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ Ui::FilesPage m_ui;
+ QStringList m_files;
+ QStringList m_filesToRemove;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/filespage.ui b/tools/assistant/tools/qhelpconverter/filespage.ui
new file mode 100644
index 0000000000..d308b96646
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filespage.ui
@@ -0,0 +1,79 @@
+<ui version="4.0" >
+ <class>FilesPage</class>
+ <widget class="QWidget" name="FilesPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QLabel" name="fileLabel" >
+ <property name="text" >
+ <string>Files:</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="1" column="0" >
+ <widget class="QListWidget" name="fileListWidget" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QPushButton" name="removeAllButton" >
+ <property name="text" >
+ <string>Remove All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>75</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/filterpage.cpp b/tools/assistant/tools/qhelpconverter/filterpage.cpp
new file mode 100644
index 0000000000..9f7e3038c8
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filterpage.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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 <QtGui/QMessageBox>
+#include "filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+FilterPage::FilterPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Filter Settings"));
+ setSubTitle(tr("Specify the filter attributes for the "
+ "documentation. If filter attributes are used, "
+ "also define a custom filter for it. Both, the "
+ "filter attributes and the custom filters are "
+ "optional."));
+
+ m_ui.setupUi(this);
+ m_ui.customFilterWidget->headerItem()->setText(0, tr("Filter Name"));
+ m_ui.customFilterWidget->headerItem()->setText(1, tr("Filter Attributes"));
+ m_ui.customFilterWidget->setRootIsDecorated(false);
+ m_ui.removeButton->setDisabled(true);
+ connect(m_ui.addButton, SIGNAL(clicked()),
+ this, SLOT(addFilter()));
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removeFilter()));
+}
+
+bool FilterPage::validatePage()
+{
+ m_filterAttributes.clear();
+ foreach (const QString &f, m_ui.filterLineEdit->text().split(QLatin1Char(','))) {
+ if (!f.trimmed().isEmpty())
+ m_filterAttributes.append(f.trimmed());
+ }
+
+ m_customFilters.clear();
+ QSet<QString> names;
+ QSet<QString> atts;
+ QString str;
+ CustomFilter customFilter;
+ QTreeWidgetItem *item = 0;
+ for (int i=0; i<m_ui.customFilterWidget->topLevelItemCount(); ++i) {
+ item = m_ui.customFilterWidget->topLevelItem(i);
+ str = item->text(0);
+ if (str.isEmpty() || names.contains(str)) {
+ QMessageBox::critical(this, tr("Custom Filters"),
+ tr("The custom filter \'%1\' is defined multiple times.")
+ .arg(str));
+ return false;
+ }
+ names.insert(str);
+ customFilter.name = str;
+
+ str.clear();
+ QStringList lst;
+ foreach (const QString &s, item->text(1).split(QLatin1Char(','))) {
+ const QString st = s.trimmed();
+ if (!st.isEmpty()) {
+ str += QLatin1Char(',') + st;
+ lst.append(st);
+ }
+ }
+ if (atts.contains(str)) {
+ QMessageBox::critical(this, tr("Custom Filters"),
+ tr("The attributes for custom filter \'%1\' are defined multiple times.")
+ .arg(customFilter.name));
+ return false;
+ }
+ atts.insert(str);
+ customFilter.filterAttributes = lst;
+ m_customFilters.append(customFilter);
+ }
+ return true;
+}
+
+QStringList FilterPage::filterAttributes() const
+{
+ return m_filterAttributes;
+}
+
+QList<CustomFilter> FilterPage::customFilters() const
+{
+ return m_customFilters;
+}
+
+void FilterPage::addFilter()
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.customFilterWidget);
+ item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable);
+ item->setText(0, QLatin1String("unfiltered"));
+ item->setText(1, QLatin1String(""));
+ m_ui.customFilterWidget->editItem(item, 0);
+ m_ui.removeButton->setDisabled(false);
+}
+
+void FilterPage::removeFilter()
+{
+ QModelIndex idx = m_ui.customFilterWidget->currentIndex();
+ if (!idx.isValid())
+ return;
+ QTreeWidgetItem *item = m_ui.customFilterWidget->takeTopLevelItem(idx.row());
+ delete item;
+ if (!m_ui.customFilterWidget->topLevelItemCount())
+ m_ui.removeButton->setDisabled(true);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/filterpage.h b/tools/assistant/tools/qhelpconverter/filterpage.h
new file mode 100644
index 0000000000..5f0e1b1ef6
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filterpage.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 FILTERPAGE_H
+#define FILTERPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+struct CustomFilter
+{
+ QString name;
+ QStringList filterAttributes;
+};
+
+class FilterPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FilterPage(QWidget *parent = 0);
+ QStringList filterAttributes() const;
+ QList<CustomFilter> customFilters() const;
+
+private slots:
+ void addFilter();
+ void removeFilter();
+
+private:
+ bool validatePage();
+
+ Ui::FilterPage m_ui;
+ QStringList m_filterAttributes;
+ QList<CustomFilter> m_customFilters;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/filterpage.ui b/tools/assistant/tools/qhelpconverter/filterpage.ui
new file mode 100644
index 0000000000..7cda3d9bed
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/filterpage.ui
@@ -0,0 +1,125 @@
+<ui version="4.0" >
+ <class>FilterPage</class>
+ <widget class="QWidget" name="FilterPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>419</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Filter attributes for current documentation (comma separated list):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLineEdit" name="filterLineEdit" />
+ </item>
+ <item row="4" column="0" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Custom Filters</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item rowspan="3" row="0" column="0" >
+ <widget class="QTreeWidget" name="customFilterWidget" >
+ <property name="columnCount" >
+ <number>2</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QPushButton" name="addButton" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <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>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/finishpage.cpp b/tools/assistant/tools/qhelpconverter/finishpage.cpp
new file mode 100644
index 0000000000..0b3c33fe75
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/finishpage.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 <QtGui/QTextEdit>
+#include <QtGui/QLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QApplication>
+
+#include "finishpage.h"
+
+QT_BEGIN_NAMESPACE
+
+FinishPage::FinishPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Converting File"));
+ setSubTitle(QLatin1String("Creating the new Qt help files from the "
+ "old .adp file."));
+ setFinalPage(true);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum,
+ QSizePolicy::Fixed));
+
+ m_textEdit = new QTextEdit();
+ layout->addWidget(m_textEdit);
+
+ layout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum,
+ QSizePolicy::Expanding));
+}
+
+void FinishPage::appendMessage(const QString &msg)
+{
+ m_textEdit->append(msg);
+ qApp->processEvents();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/finishpage.h b/tools/assistant/tools/qhelpconverter/finishpage.h
new file mode 100644
index 0000000000..7a4689d1d9
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/finishpage.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 FINISHPAGE_H
+#define FINISHPAGE_H
+
+#include <QtGui/QWizardPage>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class FinishPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FinishPage(QWidget *parent = 0);
+ void appendMessage(const QString &msg);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/generalpage.cpp b/tools/assistant/tools/qhelpconverter/generalpage.cpp
new file mode 100644
index 0000000000..f59be49adc
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/generalpage.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 <QtGui/QMessageBox>
+#include "generalpage.h"
+
+QT_BEGIN_NAMESPACE
+
+GeneralPage::GeneralPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("General Settings"));
+ setSubTitle(tr("Specify the namespace and the virtual "
+ "folder for the documentation."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.namespaceLineEdit, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(completeChanged()));
+ connect(m_ui.folderLineEdit, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(completeChanged()));
+
+ m_ui.namespaceLineEdit->setText(QLatin1String("mycompany.com"));
+ m_ui.folderLineEdit->setText(QLatin1String("product_1.0"));
+
+ registerField(QLatin1String("namespaceName"), m_ui.namespaceLineEdit);
+ registerField(QLatin1String("virtualFolder"), m_ui.folderLineEdit);
+}
+
+bool GeneralPage::isComplete() const
+{
+ if (m_ui.namespaceLineEdit->text().isEmpty()
+ || m_ui.folderLineEdit->text().isEmpty())
+ return false;
+ return true;
+}
+
+bool GeneralPage::validatePage()
+{
+ QString s = m_ui.namespaceLineEdit->text();
+ if (s.contains(QLatin1Char('/')) || s.contains(QLatin1Char('\\'))) {
+ QMessageBox::critical(this, tr("Namespace Error"),
+ tr("The namespace contains some invalid characters."));
+ return false;
+ }
+ s = m_ui.folderLineEdit->text();
+ if (s.contains(QLatin1Char('/')) || s.contains(QLatin1Char('\\'))) {
+ QMessageBox::critical(this, tr("Virtual Folder Error"),
+ tr("The virtual folder contains some invalid characters."));
+ return false;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/generalpage.h b/tools/assistant/tools/qhelpconverter/generalpage.h
new file mode 100644
index 0000000000..c9d2b4dc16
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/generalpage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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 GENERALPAGE_H
+#define GENERALPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_generalpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class GeneralPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ GeneralPage(QWidget *parent = 0);
+
+private:
+ bool validatePage();
+ bool isComplete() const;
+
+ Ui::GeneralPage m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/generalpage.ui b/tools/assistant/tools/qhelpconverter/generalpage.ui
new file mode 100644
index 0000000000..9c2babb0ae
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/generalpage.ui
@@ -0,0 +1,69 @@
+<ui version="4.0" >
+ <class>GeneralPage</class>
+ <widget class="QWidget" name="GeneralPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Namespace:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="namespaceLineEdit" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Virtual Folder:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="folderLineEdit" />
+ </item>
+ <item row="0" column="1" >
+ <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="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/helpwindow.cpp b/tools/assistant/tools/qhelpconverter/helpwindow.cpp
new file mode 100644
index 0000000000..b41a410682
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/helpwindow.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QTextEdit>
+
+#include "helpwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+HelpWindow::HelpWindow(QWidget *parent)
+ : QWidget(parent, 0)
+{
+ setAutoFillBackground(true);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ QFrame *frame = new QFrame(this);
+ QPalette p = palette();
+ p.setColor(QPalette::Background, Qt::white);
+ setPalette(p);
+ frame->setFrameStyle(QFrame::Box | QFrame::Plain);
+ layout->addWidget(frame);
+
+ layout = new QVBoxLayout(frame);
+ layout->setMargin(2);
+ QLabel *l = new QLabel(QLatin1String("<center><b>Wizard Assistant</b></center>"));
+ layout->addWidget(l);
+ m_textEdit = new QTextEdit();
+ m_textEdit->setFrameStyle(QFrame::NoFrame);
+ m_textEdit->setReadOnly(true);
+ layout->addWidget(m_textEdit);
+}
+
+void HelpWindow::setHelp(const QString &topic)
+{
+ QLatin1String fileStr(":/trolltech/qhelpconverter/doc/%1.html");
+ QFile f(QString(fileStr).arg(topic.toLower()));
+ f.open(QIODevice::ReadOnly);
+ QTextStream s(&f);
+ m_textEdit->setText(s.readAll());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/helpwindow.h b/tools/assistant/tools/qhelpconverter/helpwindow.h
new file mode 100644
index 0000000000..9c0866a5cb
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/helpwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class HelpWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ HelpWindow(QWidget *parent = 0);
+ void setHelp(const QString &topic);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/identifierpage.cpp b/tools/assistant/tools/qhelpconverter/identifierpage.cpp
new file mode 100644
index 0000000000..64a23a684c
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/identifierpage.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 "identifierpage.h"
+
+QT_BEGIN_NAMESPACE
+
+IdentifierPage::IdentifierPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Identifiers"));
+ setSubTitle(tr("This page allows you to create identifiers from "
+ "the keywords found in the .adp or .dcf file."));
+
+ m_ui.setupUi(this);
+
+ connect(m_ui.identifierCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(setupButtons(bool)));
+
+ registerField(QLatin1String("createIdentifier"), m_ui.identifierCheckBox);
+ registerField(QLatin1String("globalPrefix"), m_ui.prefixLineEdit);
+ registerField(QLatin1String("fileNamePrefix"), m_ui.fileNameButton);
+}
+
+void IdentifierPage::setupButtons(bool checked)
+{
+ m_ui.globalButton->setEnabled(checked);
+ m_ui.fileNameButton->setEnabled(checked);
+ m_ui.prefixLineEdit->setEnabled(checked
+ && m_ui.globalButton->isChecked());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/identifierpage.h b/tools/assistant/tools/qhelpconverter/identifierpage.h
new file mode 100644
index 0000000000..fcebb496bc
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/identifierpage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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 IDENTIFIERPAGE_H
+#define IDENTIFIERPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_identifierpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class IdentifierPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ IdentifierPage(QWidget *parent = 0);
+
+private slots:
+ void setupButtons(bool checked);
+
+private:
+ Ui::IdentifierPage m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/identifierpage.ui b/tools/assistant/tools/qhelpconverter/identifierpage.ui
new file mode 100644
index 0000000000..cd0df75638
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/identifierpage.ui
@@ -0,0 +1,132 @@
+<ui version="4.0" >
+ <class>IdentifierPage</class>
+ <widget class="QWidget" name="IdentifierPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="1" >
+ <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="1" column="0" colspan="3" >
+ <widget class="QCheckBox" name="identifierCheckBox" >
+ <property name="text" >
+ <string>Create identifiers</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>161</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>30</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QRadioButton" name="globalButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Global prefix:</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLineEdit" name="prefixLineEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <widget class="QRadioButton" name="fileNameButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Inherit prefix from file names</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>globalButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>prefixLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>122</x>
+ <y>72</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>161</x>
+ <y>71</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/inputpage.cpp b/tools/assistant/tools/qhelpconverter/inputpage.cpp
new file mode 100644
index 0000000000..5872523c5e
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/inputpage.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFile>
+#include <QtCore/QVariant>
+
+#include <QtGui/QLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QToolButton>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+
+#include "inputpage.h"
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+InputPage::InputPage(AdpReader *reader, QWidget *parent)
+ : QWizardPage(parent)
+{
+ m_adpReader = reader;
+ setTitle(tr("Input File"));
+ setSubTitle(tr("Specify the .adp or .dcf file you want "
+ "to convert to the new Qt help project format and/or "
+ "collection format."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.browseButton, SIGNAL(clicked()),
+ this, SLOT(getFileName()));
+
+ registerField(QLatin1String("adpFileName"), m_ui.fileLineEdit);
+}
+
+void InputPage::getFileName()
+{
+ QString f = QFileDialog::getOpenFileName(this, tr("Open file"), QString(),
+ tr("Qt Help Files (*.adp *.dcf)"));
+ if (!f.isEmpty())
+ m_ui.fileLineEdit->setText(f);
+}
+
+bool InputPage::validatePage()
+{
+ QFile f(m_ui.fileLineEdit->text().trimmed());
+ if (!f.exists() || !f.open(QIODevice::ReadOnly)) {
+ QMessageBox::critical(this, tr("File Open Error"),
+ tr("The specified file could not be opened!"));
+ return false;
+ }
+
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ m_adpReader->readData(f.readAll());
+ QApplication::restoreOverrideCursor();
+ if (m_adpReader->hasError()) {
+ QMessageBox::critical(this, tr("File Parsing Error"),
+ tr("Parsing error in line %1!").arg(m_adpReader->lineNumber()));
+ return false;
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/inputpage.h b/tools/assistant/tools/qhelpconverter/inputpage.h
new file mode 100644
index 0000000000..dddf80d84f
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/inputpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 INPUTPAGE_H
+#define INPUTPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_inputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class AdpReader;
+
+class InputPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ InputPage(AdpReader *reader, QWidget *parent = 0);
+
+private slots:
+ void getFileName();
+
+private:
+ bool validatePage();
+
+ Ui::InputPage m_ui;
+ AdpReader *m_adpReader;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/inputpage.ui b/tools/assistant/tools/qhelpconverter/inputpage.ui
new file mode 100644
index 0000000000..e7cd3a0fad
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/inputpage.ui
@@ -0,0 +1,79 @@
+<ui version="4.0" >
+ <class>InputPage</class>
+ <widget class="QWidget" name="InputPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="2" >
+ <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="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>File name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="fileLineEdit" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="browseButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/main.cpp b/tools/assistant/tools/qhelpconverter/main.cpp
new file mode 100644
index 0000000000..2b0f60243b
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/main.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFileInfo>
+#include <QtGui/QApplication>
+
+#include "conversionwizard.h"
+
+QT_USE_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ ConversionWizard w;
+ if (argc == 2) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[1]));
+ if (fi.exists())
+ w.setAdpFileName(fi.absoluteFilePath());
+ }
+ w.show();
+ return app.exec();
+}
+
diff --git a/tools/assistant/tools/qhelpconverter/outputpage.cpp b/tools/assistant/tools/qhelpconverter/outputpage.cpp
new file mode 100644
index 0000000000..77cbf4cb0a
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/outputpage.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtGui/QMessageBox>
+
+#include "outputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+OutputPage::OutputPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Output File Names"));
+ setSubTitle(tr("Specify the file names for the output files."));
+ setButtonText(QWizard::NextButton, tr("Convert..."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.projectLineEdit, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(completeChanged()));
+ connect(m_ui.collectionLineEdit, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(completeChanged()));
+
+ registerField(QLatin1String("ProjectFileName"),
+ m_ui.projectLineEdit);
+ registerField(QLatin1String("CollectionFileName"),
+ m_ui.collectionLineEdit);
+}
+
+void OutputPage::setPath(const QString &path)
+{
+ m_path = path;
+}
+
+void OutputPage::setCollectionComponentEnabled(bool enabled)
+{
+ m_ui.collectionLineEdit->setEnabled(enabled);
+ m_ui.label_2->setEnabled(enabled);
+}
+
+bool OutputPage::isComplete() const
+{
+ if (m_ui.projectLineEdit->text().isEmpty()
+ || m_ui.collectionLineEdit->text().isEmpty())
+ return false;
+ return true;
+}
+
+bool OutputPage::validatePage()
+{
+ return checkFile(m_ui.projectLineEdit->text(),
+ tr("Qt Help Project File"))
+ && checkFile(m_ui.collectionLineEdit->text(),
+ tr("Qt Help Collection Project File"));
+}
+
+bool OutputPage::checkFile(const QString &fileName, const QString &title)
+{
+ QFile fi(m_path + QDir::separator() + fileName);
+ if (!fi.exists())
+ return true;
+
+ if (QMessageBox::warning(this, title,
+ tr("The specified file %1 already exist.\n\nDo you want to remove it?")
+ .arg(fileName), tr("Remove"), tr("Cancel")) == 0) {
+ return fi.remove();
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/outputpage.h b/tools/assistant/tools/qhelpconverter/outputpage.h
new file mode 100644
index 0000000000..3907ae5a4e
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/outputpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 OUTPUTPAGE_H
+#define OUTPUTPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_outputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class OutputPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ OutputPage(QWidget *parent = 0);
+ void setPath(const QString &path);
+ void setCollectionComponentEnabled(bool enabled);
+
+private:
+ bool isComplete() const;
+ bool validatePage();
+ bool checkFile(const QString &fileName,
+ const QString &title);
+
+ Ui::OutputPage m_ui;
+ QString m_path;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/outputpage.ui b/tools/assistant/tools/qhelpconverter/outputpage.ui
new file mode 100644
index 0000000000..755f818085
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/outputpage.ui
@@ -0,0 +1,95 @@
+<ui version="4.0" >
+ <class>OutputPage</class>
+ <widget class="QWidget" name="OutputPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="1" >
+ <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="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Project file name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="projectLineEdit" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Collection file name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="collectionLineEdit" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/pathpage.cpp b/tools/assistant/tools/qhelpconverter/pathpage.cpp
new file mode 100644
index 0000000000..83019d63ff
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/pathpage.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 <QtGui/QFileDialog>
+
+#include "pathpage.h"
+
+QT_BEGIN_NAMESPACE
+
+PathPage::PathPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Source File Paths"));
+ setSubTitle(tr("Specify the paths where the sources files "
+ "are located. By default, all files in those directories "
+ "matched by the file filter will be included."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.addButton, SIGNAL(clicked()),
+ this, SLOT(addPath()));
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removePath()));
+
+ m_ui.filterLineEdit->setText(QLatin1String("*.html, *.htm, *.png, *.jpg, *.css"));
+
+ registerField(QLatin1String("sourcePathList"), m_ui.pathListWidget);
+ m_firstTime = true;
+}
+
+void PathPage::setPath(const QString &path)
+{
+ if (!m_firstTime)
+ return;
+
+ m_ui.pathListWidget->addItem(path);
+ m_firstTime = false;
+ m_ui.pathListWidget->setCurrentRow(0);
+}
+
+QStringList PathPage::paths() const
+{
+ QStringList lst;
+ for (int i = 0; i<m_ui.pathListWidget->count(); ++i)
+ lst.append(m_ui.pathListWidget->item(i)->text());
+ return lst;
+}
+
+QStringList PathPage::filters() const
+{
+ QStringList lst;
+ foreach (const QString &s, m_ui.filterLineEdit->text().split(QLatin1Char(','))) {
+ lst.append(s.trimmed());
+ }
+ return lst;
+}
+
+void PathPage::addPath()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Source File Path"));
+ if (!dir.isEmpty())
+ m_ui.pathListWidget->addItem(dir);
+}
+
+void PathPage::removePath()
+{
+ QListWidgetItem *i = m_ui.pathListWidget
+ ->takeItem(m_ui.pathListWidget->currentRow());
+ delete i;
+ if (!m_ui.pathListWidget->count())
+ m_ui.removeButton->setEnabled(false);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/pathpage.h b/tools/assistant/tools/qhelpconverter/pathpage.h
new file mode 100644
index 0000000000..e081b73dec
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/pathpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 PATHPAGE_H
+#define PATHPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_pathpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class PathPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ PathPage(QWidget *parent = 0);
+ void setPath(const QString &path);
+ QStringList paths() const;
+ QStringList filters() const;
+
+private slots:
+ void addPath();
+ void removePath();
+
+private:
+ Ui::PathPage m_ui;
+ bool m_firstTime;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/pathpage.ui b/tools/assistant/tools/qhelpconverter/pathpage.ui
new file mode 100644
index 0000000000..89083915dd
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/pathpage.ui
@@ -0,0 +1,114 @@
+<ui version="4.0" >
+ <class>PathPage</class>
+ <widget class="QWidget" name="PathPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>File filters:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="filterLineEdit" />
+ </item>
+ <item row="1" column="1" >
+ <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>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Documentation source file paths:</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="3" column="0" colspan="3" >
+ <widget class="QListWidget" name="pathListWidget" />
+ </item>
+ <item row="3" column="3" >
+ <widget class="QPushButton" name="addButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/qhelpconverter/qhcpwriter.cpp b/tools/assistant/tools/qhelpconverter/qhcpwriter.cpp
new file mode 100644
index 0000000000..55a1b1265c
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhcpwriter.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** 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 <QtCore/QFile>
+
+#include "qhcpwriter.h"
+
+QT_BEGIN_NAMESPACE
+
+QhcpWriter::QhcpWriter()
+{
+ setAutoFormatting(true);
+}
+
+void QhcpWriter::setHelpProjectFile(const QString &qhpFile)
+{
+ m_qhpFile = qhpFile;
+}
+
+void QhcpWriter::setProperties(const QMap<QString, QString> props)
+{
+ m_properties = props;
+}
+
+void QhcpWriter::setTitlePath(const QString &path)
+{
+ m_titlePath = path;
+}
+
+bool QhcpWriter::writeFile(const QString &fileName)
+{
+ QFile out(fileName);
+ if (!out.open(QIODevice::WriteOnly))
+ return false;
+
+ setDevice(&out);
+ writeStartDocument();
+ writeStartElement(QLatin1String("QHelpCollectionProject"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+ writeAssistantSettings();
+ writeDocuments();
+ writeEndDocument();
+ return true;
+}
+
+void QhcpWriter::writeAssistantSettings()
+{
+ if (m_properties.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("assistant"));
+
+ if (m_properties.contains(QLatin1String("title")))
+ writeTextElement(QLatin1String("title"), m_properties.value(QLatin1String("title")));
+ if (m_properties.contains(QLatin1String("applicationicon")))
+ writeTextElement(QLatin1String("applicationIcon"),
+ m_properties.value(QLatin1String("applicationicon")));
+ if (m_properties.contains(QLatin1String("startpage")))
+ writeTextElement(QLatin1String("startPage"), m_titlePath + QLatin1String("/")
+ + m_properties.value(QLatin1String("startpage")));
+ if (m_properties.contains(QLatin1String("aboutmenutext"))) {
+ writeStartElement(QLatin1String("aboutMenuText"));
+ writeTextElement(QLatin1String("text"),
+ m_properties.value(QLatin1String("aboutmenutext")));
+ writeEndElement();
+ }
+ if (m_properties.contains(QLatin1String("abouturl"))) {
+ writeStartElement(QLatin1String("aboutDialog"));
+ writeTextElement(QLatin1String("file"), m_properties.value(QLatin1String("abouturl")));
+ writeEndElement();
+ }
+ if (m_properties.contains(QLatin1String("name"))) {
+ writeTextElement(QLatin1String("cacheDirectory"),
+ QLatin1String(".") + m_properties.value(QLatin1String("name")));
+ }
+
+ writeEndElement();
+}
+
+void QhcpWriter::writeDocuments()
+{
+ if (m_qhpFile.isEmpty())
+ return;
+
+ QString out = m_qhpFile;
+ int i = out.indexOf(QLatin1Char('.'));
+ if (i > -1)
+ out = out.left(i);
+ out.append(QLatin1String(".qch"));
+
+ writeStartElement(QLatin1String("docFiles"));
+
+ writeStartElement(QLatin1String("generate"));
+ writeStartElement(QLatin1String("file"));
+ writeTextElement(QLatin1String("input"), m_qhpFile);
+ writeTextElement(QLatin1String("output"), out);
+ writeEndElement();
+ writeEndElement();
+
+ writeStartElement(QLatin1String("register"));
+ writeTextElement(QLatin1String("file"), out);
+ writeEndElement();
+
+ writeEndElement();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/qhcpwriter.h b/tools/assistant/tools/qhelpconverter/qhcpwriter.h
new file mode 100644
index 0000000000..ba448a50a0
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhcpwriter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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 QHCPWRITER_H
+#define QHCPWRITER_H
+
+#include <QtXml/QXmlStreamWriter>
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+class QhcpWriter : public QXmlStreamWriter
+{
+public:
+ QhcpWriter();
+ bool writeFile(const QString &fileName);
+ void setHelpProjectFile(const QString &qhpFile);
+ void setProperties(const QMap<QString, QString> props);
+ void setTitlePath(const QString &path);
+
+private:
+ void writeAssistantSettings();
+ void writeDocuments();
+
+ QString m_qhpFile;
+ QMap<QString, QString> m_properties;
+ QString m_titlePath;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpconverter/qhelpconverter.pro b/tools/assistant/tools/qhelpconverter/qhelpconverter.pro
new file mode 100644
index 0000000000..341faf346e
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhelpconverter.pro
@@ -0,0 +1,47 @@
+QT += xml
+TEMPLATE = app
+TARGET = qhelpconverter
+DESTDIR = ../../../../bin
+CONFIG += qt warn_on help
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+SOURCES += conversionwizard.cpp \
+ inputpage.cpp \
+ generalpage.cpp \
+ filterpage.cpp \
+ identifierpage.cpp \
+ pathpage.cpp \
+ filespage.cpp \
+ outputpage.cpp \
+ finishpage.cpp \
+ adpreader.cpp \
+ qhpwriter.cpp \
+ qhcpwriter.cpp \
+ helpwindow.cpp \
+ main.cpp
+
+HEADERS += conversionwizard.h \
+ inputpage.h \
+ generalpage.h \
+ filterpage.h \
+ identifierpage.h \
+ pathpage.h \
+ filespage.h \
+ outputpage.h \
+ finishpage.h \
+ adpreader.h \
+ qhcpwriter.h \
+ qhpwriter.h \
+ helpwindow.h
+
+FORMS += inputpage.ui \
+ generalpage.ui \
+ filterpage.ui \
+ identifierpage.ui \
+ pathpage.ui \
+ filespage.ui \
+ outputpage.ui
+
+RESOURCES += qhelpconverter.qrc
diff --git a/tools/assistant/tools/qhelpconverter/qhelpconverter.qrc b/tools/assistant/tools/qhelpconverter/qhelpconverter.qrc
new file mode 100644
index 0000000000..e2a68ab433
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhelpconverter.qrc
@@ -0,0 +1,13 @@
+<RCC>
+ <qresource prefix="/trolltech/qhelpconverter" >
+ <file>assistant-128.png</file>
+ <file>assistant.png</file>
+ <file>doc/inputpage.html</file>
+ <file>doc/generalpage.html</file>
+ <file>doc/filterpage.html</file>
+ <file>doc/identifierpage.html</file>
+ <file>doc/pathpage.html</file>
+ <file>doc/filespage.html</file>
+ <file>doc/outputpage.html</file>
+ </qresource>
+</RCC>
diff --git a/tools/assistant/tools/qhelpconverter/qhpwriter.cpp b/tools/assistant/tools/qhelpconverter/qhpwriter.cpp
new file mode 100644
index 0000000000..cd5453792e
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhpwriter.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+
+#include "qhpwriter.h"
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+QhpWriter::QhpWriter(const QString &namespaceName,
+ const QString &virtualFolder)
+{
+ m_namespaceName = namespaceName;
+ m_virtualFolder = virtualFolder;
+ setAutoFormatting(true);
+}
+
+void QhpWriter::setAdpReader(AdpReader *reader)
+{
+ m_adpReader = reader;
+}
+
+void QhpWriter::setFilterAttributes(const QStringList &attributes)
+{
+ m_filterAttributes = attributes;
+}
+
+void QhpWriter::setCustomFilters(const QList<CustomFilter> filters)
+{
+ m_customFilters = filters;
+}
+
+void QhpWriter::setFiles(const QStringList &files)
+{
+ m_files = files;
+}
+
+void QhpWriter::generateIdentifiers(IdentifierPrefix prefix,
+ const QString prefixString)
+{
+ m_prefix = prefix;
+ m_prefixString = prefixString;
+}
+
+bool QhpWriter::writeFile(const QString &fileName)
+{
+ QFile out(fileName);
+ if (!out.open(QIODevice::WriteOnly))
+ return false;
+
+ setDevice(&out);
+ writeStartDocument();
+ writeStartElement(QLatin1String("QtHelpProject"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+ writeTextElement(QLatin1String("namespace"), m_namespaceName);
+ writeTextElement(QLatin1String("virtualFolder"), m_virtualFolder);
+ writeCustomFilters();
+ writeFilterSection();
+ writeEndDocument();
+
+ out.close();
+ return true;
+}
+
+void QhpWriter::writeCustomFilters()
+{
+ if (!m_customFilters.count())
+ return;
+
+ foreach (const CustomFilter &f, m_customFilters) {
+ writeStartElement(QLatin1String("customFilter"));
+ writeAttribute(QLatin1String("name"), f.name);
+ foreach (const QString &a, f.filterAttributes)
+ writeTextElement(QLatin1String("filterAttribute"), a);
+ writeEndElement();
+ }
+}
+
+void QhpWriter::writeFilterSection()
+{
+ writeStartElement(QLatin1String("filterSection"));
+ foreach (const QString &a, m_filterAttributes)
+ writeTextElement(QLatin1String("filterAttribute"), a);
+
+ writeToc();
+ writeKeywords();
+ writeFiles();
+ writeEndElement();
+}
+
+void QhpWriter::writeToc()
+{
+ QList<ContentItem> lst = m_adpReader->contents();
+ if (lst.isEmpty())
+ return;
+
+ int depth = -1;
+ writeStartElement(QLatin1String("toc"));
+ foreach (const ContentItem &i, lst) {
+ while (depth-- >= i.depth)
+ writeEndElement();
+ writeStartElement(QLatin1String("section"));
+ writeAttribute(QLatin1String("title"), i.title);
+ writeAttribute(QLatin1String("ref"), i.reference);
+ depth = i.depth;
+ }
+ while (depth-- >= -1)
+ writeEndElement();
+}
+
+void QhpWriter::writeKeywords()
+{
+ QList<KeywordItem> lst = m_adpReader->keywords();
+ if (lst.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("keywords"));
+ foreach (const KeywordItem &i, lst) {
+ writeEmptyElement(QLatin1String("keyword"));
+ writeAttribute(QLatin1String("name"), i.keyword);
+ writeAttribute(QLatin1String("ref"), i.reference);
+ if (m_prefix == FilePrefix) {
+ QString str = i.reference.mid(
+ i.reference.lastIndexOf(QLatin1Char('/'))+1);
+ str = str.left(str.lastIndexOf(QLatin1Char('.')));
+ writeAttribute(QLatin1String("id"), str + QLatin1String("::") + i.keyword);
+ } else if (m_prefix == GlobalPrefix) {
+ writeAttribute(QLatin1String("id"), m_prefixString + i.keyword);
+ }
+ }
+ writeEndElement();
+}
+
+void QhpWriter::writeFiles()
+{
+ if (m_files.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("files"));
+ foreach (const QString &f, m_files)
+ writeTextElement(QLatin1String("file"), f);
+ writeEndElement();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/qhelpconverter/qhpwriter.h b/tools/assistant/tools/qhelpconverter/qhpwriter.h
new file mode 100644
index 0000000000..bba3fcb705
--- /dev/null
+++ b/tools/assistant/tools/qhelpconverter/qhpwriter.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 QHPWRITER_H
+#define QHPWRITER_H
+
+#include <QtXml/QXmlStreamWriter>
+#include "filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class AdpReader;
+
+class QhpWriter : public QXmlStreamWriter
+{
+public:
+ enum IdentifierPrefix {SkipAll, FilePrefix, GlobalPrefix};
+ QhpWriter(const QString &namespaceName,
+ const QString &virtualFolder);
+ void setAdpReader(AdpReader *reader);
+ void setFilterAttributes(const QStringList &attributes);
+ void setCustomFilters(const QList<CustomFilter> filters);
+ void setFiles(const QStringList &files);
+ void generateIdentifiers(IdentifierPrefix prefix,
+ const QString prefixString = QString());
+ bool writeFile(const QString &fileName);
+
+private:
+ void writeCustomFilters();
+ void writeFilterSection();
+ void writeToc();
+ void writeKeywords();
+ void writeFiles();
+
+ QString m_namespaceName;
+ QString m_virtualFolder;
+ AdpReader *m_adpReader;
+ QStringList m_filterAttributes;
+ QList<CustomFilter> m_customFilters;
+ QStringList m_files;
+ IdentifierPrefix m_prefix;
+ QString m_prefixString;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/qhelpgenerator/main.cpp b/tools/assistant/tools/qhelpgenerator/main.cpp
new file mode 100644
index 0000000000..42a15950b2
--- /dev/null
+++ b/tools/assistant/tools/qhelpgenerator/main.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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 "../shared/helpgenerator.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QCoreApplication>
+
+#include <private/qhelpprojectdata_p.h>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ QString error;
+ QString arg;
+ QString compressedFile;
+ QString projectFile;
+ QString basePath;
+ bool showHelp = false;
+ bool showVersion = false;
+
+ for (int i = 1; i < argc; ++i) {
+ arg = QString::fromLocal8Bit(argv[i]);
+ if (arg == QLatin1String("-o")) {
+ if (++i < argc) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[i]));
+ compressedFile = fi.absoluteFilePath();
+ } else {
+ error = QObject::tr("Missing output file name!");
+ }
+ } else if (arg == QLatin1String("-v")) {
+ showVersion = true;
+ } else if (arg == QLatin1String("-h")) {
+ showHelp = true;
+ } else {
+ QFileInfo fi(arg);
+ projectFile = fi.absoluteFilePath();
+ basePath = fi.absolutePath();
+ }
+ }
+
+ if (showVersion) {
+ fprintf(stdout, "Qt Help Generator version 1.0 (Qt %s)\n", QT_VERSION_STR);
+ return 0;
+ }
+
+ if (projectFile.isEmpty() && !showHelp)
+ error = QObject::tr("Missing Qt help project file!");
+
+ QString help = QObject::tr("\nUsage:\n\n"
+ "qhelpgenerator <help-project-file> [options]\n\n"
+ " -o <compressed-file> Generates a Qt compressed help\n"
+ " file called <compressed-file>.\n"
+ " If this option is not specified\n"
+ " a default name will be used.\n"
+ " -v Displays the version of \n"
+ " qhelpgenerator.\n\n");
+
+ if (showHelp) {
+ fprintf(stdout, "%s", qPrintable(help));
+ return 0;
+ }else if (!error.isEmpty()) {
+ fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
+ return -1;
+ }
+
+ QFile file(projectFile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Could not open %s!\n", qPrintable(projectFile));
+ return -1;
+ }
+
+ if (compressedFile.isEmpty()) {
+ QFileInfo fi(projectFile);
+ compressedFile = basePath + QDir::separator()
+ + fi.baseName() + QLatin1String(".qch");
+ } else {
+ // check if the output dir exists -- create if it doesn't
+ QFileInfo fi(compressedFile);
+ QDir parentDir = fi.dir();
+ if (!parentDir.exists()) {
+ if (!parentDir.mkpath(QLatin1String("."))) {
+ fprintf(stderr, "Could not create output directory: %s\n",
+ qPrintable(parentDir.path()));
+ }
+ }
+ }
+
+ QHelpProjectData *helpData = new QHelpProjectData();
+ if (!helpData->readData(projectFile)) {
+ fprintf(stderr, "%s\n", qPrintable(helpData->errorMessage()));
+ return -1;
+ }
+
+ QCoreApplication app(argc, argv);
+ HelpGenerator generator;
+ bool success = generator.generate(helpData, compressedFile);
+ delete helpData;
+ if (!success) {
+ fprintf(stderr, "%s\n", qPrintable(generator.error()));
+ return -1;
+ }
+ return 0;
+}
diff --git a/tools/assistant/tools/qhelpgenerator/qhelpgenerator.pro b/tools/assistant/tools/qhelpgenerator/qhelpgenerator.pro
new file mode 100644
index 0000000000..68efcf5932
--- /dev/null
+++ b/tools/assistant/tools/qhelpgenerator/qhelpgenerator.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = qhelpgenerator
+DESTDIR = ../../../../bin
+CONFIG += qt warn_on help console
+CONFIG -= app_bundle
+QT += network
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+SOURCES += ../shared/helpgenerator.cpp \
+ main.cpp
+
+HEADERS += ../shared/helpgenerator.h
diff --git a/tools/assistant/tools/shared/helpgenerator.cpp b/tools/assistant/tools/shared/helpgenerator.cpp
new file mode 100644
index 0000000000..a40cc4dff8
--- /dev/null
+++ b/tools/assistant/tools/shared/helpgenerator.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 "helpgenerator.h"
+
+#include <private/qhelpgenerator_p.h>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+HelpGenerator::HelpGenerator()
+{
+ generator = new QHelpGenerator(this);
+ connect(generator, SIGNAL(statusChanged(const QString&)),
+ this, SLOT(printStatus(const QString&)));
+ connect(generator, SIGNAL(warning(const QString&)),
+ this, SLOT(printWarning(const QString&)));
+}
+
+bool HelpGenerator::generate(QHelpDataInterface *helpData,
+ const QString &outputFileName)
+{
+ return generator->generate(helpData, outputFileName);
+}
+
+QString HelpGenerator::error() const
+{
+ return generator->error();
+}
+
+void HelpGenerator::printStatus(const QString &msg)
+{
+ fprintf(stdout, "%s\n", qPrintable(msg));
+}
+
+void HelpGenerator::printWarning(const QString &msg)
+{
+ fprintf(stdout, "Warning: %s\n", qPrintable(msg));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/shared/helpgenerator.h b/tools/assistant/tools/shared/helpgenerator.h
new file mode 100644
index 0000000000..ba8a47968f
--- /dev/null
+++ b/tools/assistant/tools/shared/helpgenerator.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 HELPGENERATOR_H
+#define HELPGENERATOR_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpDataInterface;
+class QHelpGenerator;
+
+class HelpGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ HelpGenerator();
+ bool generate(QHelpDataInterface *helpData,
+ const QString &outputFileName);
+ QString error() const;
+
+private slots:
+ void printStatus(const QString &msg);
+ void printWarning(const QString &msg);
+
+private:
+ QHelpGenerator *generator;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/assistant/tools/tools.pro b/tools/assistant/tools/tools.pro
new file mode 100644
index 0000000000..8bb8cd7006
--- /dev/null
+++ b/tools/assistant/tools/tools.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += assistant \
+ qhelpgenerator \
+ qcollectiongenerator \
+ qhelpconverter
+
diff --git a/tools/assistant/translations/qt_help.pro b/tools/assistant/translations/qt_help.pro
new file mode 100644
index 0000000000..1684ac5b9d
--- /dev/null
+++ b/tools/assistant/translations/qt_help.pro
@@ -0,0 +1,49 @@
+# Include those manually as they do not contain any directory specification
+
+SOURCES += ../lib/qhelpcollectionhandler.cpp \
+ ../lib/qhelpcontentwidget.cpp \
+ ../lib/qhelpdatainterface.cpp \
+ ../lib/qhelpdbreader.cpp \
+ ../lib/qhelpengine.cpp \
+ ../lib/qhelpenginecore.cpp \
+ ../lib/qhelpgenerator.cpp \
+ ../lib/qhelpindexwidget.cpp \
+ ../lib/qhelpprojectdata.cpp \
+ ../lib/qhelpsearchengine.cpp \
+ ../lib/qhelpsearchindexreader_clucene.cpp \
+ ../lib/qhelpsearchindexreader_default.cpp \
+ ../lib/qhelpsearchindexwriter_clucene.cpp \
+ ../lib/qhelpsearchindexwriter_default.cpp \
+ ../lib/qhelpsearchindex_default.cpp \
+ ../lib/qhelpsearchquerywidget.cpp \
+ ../lib/qhelpsearchresultwidget.cpp
+
+HEADERS += ../lib/qhelpcollectionhandler_p.h \
+ ../lib/qhelpcontentwidget.h \
+ ../lib/qhelpdatainterface_p.h \
+ ../lib/qhelpdbreader_p.h \
+ ../lib/qhelpengine.h \
+ ../lib/qhelpenginecore.h \
+ ../lib/qhelpengine_p.h \
+ ../lib/qhelpgenerator_p.h \
+ ../lib/qhelpindexwidget.h \
+ ../lib/qhelpprojectdata_p.h \
+ ../lib/qhelpsearchengine.h \
+ ../lib/qhelpsearchindexreader_clucene_p.h \
+ ../lib/qhelpsearchindexreader_default_p.h \
+ ../lib/qhelpsearchindexwriter_clucene_p.h \
+ ../lib/qhelpsearchindexwriter_default_p.h \
+ ../lib/qhelpsearchindex_default_p.h \
+ ../lib/qhelpsearchquerywidget.h \
+ ../lib/qhelpsearchresultwidget.h \
+ ../lib/qhelp_global.h
+
+
+TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qt_help_de.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_ja.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_untranslated.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_tr_TR.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_CN.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_TW.ts
+error("This is a dummy profile to be used for translations ONLY.")
diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro
new file mode 100644
index 0000000000..84bde8c0b6
--- /dev/null
+++ b/tools/assistant/translations/translations.pro
@@ -0,0 +1,49 @@
+# Include those manually as they do not contain any directory specification
+
+FORMS += ../tools/assistant/filternamedialog.ui \
+ ../tools/assistant/installdialog.ui \
+ ../tools/assistant/preferencesdialog.ui \
+ ../tools/assistant/topicchooser.ui \
+ ../tools/assistant/bookmarkdialog.ui
+
+SOURCES += ../tools/assistant/aboutdialog.cpp \
+ ../tools/assistant/bookmarkmanager.cpp \
+ ../tools/assistant/centralwidget.cpp \
+ ../tools/assistant/cmdlineparser.cpp \
+ ../tools/assistant/contentwindow.cpp \
+ ../tools/assistant/filternamedialog.cpp \
+ ../tools/assistant/helpviewer.cpp \
+ ../tools/assistant/indexwindow.cpp \
+ ../tools/assistant/installdialog.cpp \
+ ../tools/assistant/main.cpp \
+ ../tools/assistant/mainwindow.cpp \
+ ../tools/assistant/preferencesdialog.cpp \
+ ../tools/assistant/remotecontrol.cpp \
+ ../tools/assistant/searchwidget.cpp \
+ ../tools/assistant/topicchooser.cpp \
+
+SOURCES += ../../shared/fontpanel/fontpanel.cpp
+
+HEADERS += ../tools/assistant/aboutdialog.h \
+ ../tools/assistant/bookmarkmanager.h \
+ ../tools/assistant/centralwidget.h \
+ ../tools/assistant/cmdlineparser.h \
+ ../tools/assistant/contentwindow.h \
+ ../tools/assistant/filternamedialog.h \
+ ../tools/assistant/helpviewer.h \
+ ../tools/assistant/indexwindow.h \
+ ../tools/assistant/installdialog.h \
+ ../tools/assistant/mainwindow.h \
+ ../tools/assistant/preferencesdialog.h \
+ ../tools/assistant/remotecontrol.h \
+ ../tools/assistant/remotecontrol_win.h \
+ ../tools/assistant/searchwidget.h \
+ ../tools/assistant/topicchooser.h \
+
+TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_de.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_ja.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_untranslated.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_tr_TR.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_CN.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_TW.ts
diff --git a/tools/assistant/translations/translations_adp.pro b/tools/assistant/translations/translations_adp.pro
new file mode 100644
index 0000000000..f6ab62ed16
--- /dev/null
+++ b/tools/assistant/translations/translations_adp.pro
@@ -0,0 +1,41 @@
+# Include those manually as they do not contain any directory specification
+
+FORMS += ../compat/helpdialog.ui \
+ ../compat/mainwindow.ui \
+ ../compat/tabbedbrowser.ui \
+ ../compat/topicchooser.ui
+
+SOURCES += ../compat/main.cpp \
+ ../compat/helpwindow.cpp \
+ ../compat/topicchooser.cpp \
+ ../compat/docuparser.cpp \
+ ../compat/index.cpp \
+ ../compat/profile.cpp \
+ ../compat/config.cpp \
+ ../compat/helpdialog.cpp \
+ ../compat/mainwindow.cpp \
+ ../compat/tabbedbrowser.cpp \
+ ../compat/fontsettingsdialog.cpp
+
+SOURCES += ../../shared/fontpanel/fontpanel.cpp
+
+HEADERS += ../compat/helpwindow.h \
+ ../compat/topicchooser.h \
+ ../compat/docuparser.h \
+ ../compat/index.h \
+ ../compat/profile.h \
+ ../compat/helpdialog.h \
+ ../compat/mainwindow.h \
+ ../compat/tabbedbrowser.h \
+ ../compat/config.h \
+ ../compat/fontsettingsdialog.h
+
+
+TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_adp_de.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_ja.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_untranslated.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_tr_TR.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_zh_CN.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_zh_TW.ts
+error("This is a dummy profile to be used for translations ONLY.")